├── .env.sample ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── checkpointers ├── empty │ └── checkpointer.go └── redis │ ├── checkpointer.go │ └── checkpointer_test.go ├── circle.yml ├── cmd └── kinesumer │ ├── cmd_shards.go │ ├── cmd_status.go │ ├── cmd_tail.go │ ├── flags_redis.go │ ├── flags_stream.go │ ├── main.go │ └── table.go ├── err_handler.go ├── error.go ├── integration_test.go ├── interface ├── checkpointer.go ├── error.go ├── kinesis.go ├── kinesumer.go ├── provisioner.go └── record.go ├── interfaces.go ├── kinesumer.go ├── kinesumer_test.go ├── mocks ├── checkpointer.go ├── kinesis.go ├── kinesumer.go └── provisioner.go ├── provisioners ├── empty │ └── provisioner.go └── redis │ ├── provisioner.go │ └── provisioner_test.go ├── reader.go ├── reader_test.go ├── record.go ├── redispool └── redis.go ├── shard_worker.go ├── shard_worker_test.go ├── unit.go └── vendor ├── github.com ├── aws │ └── aws-sdk-go │ │ ├── LICENSE.txt │ │ ├── NOTICE.txt │ │ ├── aws │ │ ├── awserr │ │ │ ├── error.go │ │ │ └── types.go │ │ ├── awsutil │ │ │ ├── copy.go │ │ │ ├── equal.go │ │ │ ├── path_value.go │ │ │ ├── prettify.go │ │ │ └── string_value.go │ │ ├── client │ │ │ ├── client.go │ │ │ ├── default_retryer.go │ │ │ └── metadata │ │ │ │ └── client_info.go │ │ ├── config.go │ │ ├── convert_types.go │ │ ├── corehandlers │ │ │ ├── handlers.go │ │ │ └── param_validator.go │ │ ├── credentials │ │ │ ├── chain_provider.go │ │ │ ├── credentials.go │ │ │ ├── ec2rolecreds │ │ │ │ └── ec2_role_provider.go │ │ │ ├── env_provider.go │ │ │ ├── example.ini │ │ │ ├── shared_credentials_provider.go │ │ │ └── static_provider.go │ │ ├── defaults │ │ │ └── defaults.go │ │ ├── ec2metadata │ │ │ ├── api.go │ │ │ └── service.go │ │ ├── errors.go │ │ ├── logger.go │ │ ├── request │ │ │ ├── handlers.go │ │ │ ├── http_request.go │ │ │ ├── http_request_1_4.go │ │ │ ├── offset_reader.go │ │ │ ├── request.go │ │ │ ├── request_pagination.go │ │ │ ├── retryer.go │ │ │ └── validation.go │ │ ├── session │ │ │ └── session.go │ │ ├── types.go │ │ └── version.go │ │ ├── private │ │ ├── endpoints │ │ │ ├── endpoints.go │ │ │ ├── endpoints.json │ │ │ └── endpoints_map.go │ │ ├── protocol │ │ │ ├── idempotency.go │ │ │ ├── json │ │ │ │ └── jsonutil │ │ │ │ │ ├── build.go │ │ │ │ │ └── unmarshal.go │ │ │ ├── jsonrpc │ │ │ │ └── jsonrpc.go │ │ │ ├── rest │ │ │ │ ├── build.go │ │ │ │ ├── payload.go │ │ │ │ └── unmarshal.go │ │ │ └── unmarshal.go │ │ ├── signer │ │ │ └── v4 │ │ │ │ ├── header_rules.go │ │ │ │ └── v4.go │ │ └── waiter │ │ │ └── waiter.go │ │ └── service │ │ └── kinesis │ │ ├── api.go │ │ ├── kinesisiface │ │ └── interface.go │ │ ├── service.go │ │ └── waiters.go ├── codegangsta │ └── cli │ │ ├── LICENSE │ │ ├── README.md │ │ ├── app.go │ │ ├── cli.go │ │ ├── command.go │ │ ├── context.go │ │ ├── flag.go │ │ └── help.go ├── fatih │ └── color │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── color.go │ │ └── doc.go ├── garyburd │ └── redigo │ │ ├── LICENSE │ │ ├── internal │ │ ├── commandinfo.go │ │ └── redistest │ │ │ └── testdb.go │ │ └── redis │ │ ├── conn.go │ │ ├── doc.go │ │ ├── log.go │ │ ├── pool.go │ │ ├── pubsub.go │ │ ├── redis.go │ │ ├── reply.go │ │ ├── scan.go │ │ └── script.go ├── go-ini │ └── ini │ │ ├── LICENSE │ │ ├── README.md │ │ ├── README_ZH.md │ │ ├── ini.go │ │ └── struct.go ├── jmespath │ └── go-jmespath │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── api.go │ │ ├── astnodetype_string.go │ │ ├── functions.go │ │ ├── interpreter.go │ │ ├── lexer.go │ │ ├── parser.go │ │ ├── toktype_string.go │ │ └── util.go ├── joho │ └── godotenv │ │ ├── LICENCE │ │ ├── README.md │ │ ├── autoload │ │ └── autoload.go │ │ ├── cmd │ │ └── godotenv │ │ │ └── cmd.go │ │ ├── godotenv.go │ │ └── wercker.yml ├── mattn │ └── go-isatty │ │ ├── LICENSE │ │ ├── README.md │ │ ├── doc.go │ │ ├── isatty_bsd.go │ │ ├── isatty_linux.go │ │ └── isatty_windows.go ├── pborman │ └── uuid │ │ ├── CONTRIBUTORS │ │ ├── LICENSE │ │ ├── dce.go │ │ ├── doc.go │ │ ├── hash.go │ │ ├── json.go │ │ ├── node.go │ │ ├── sql.go │ │ ├── time.go │ │ ├── util.go │ │ ├── uuid.go │ │ ├── version1.go │ │ └── version4.go ├── shiena │ └── ansicolor │ │ ├── LICENSE │ │ ├── README.md │ │ ├── ansicolor.go │ │ ├── ansicolor │ │ └── main.go │ │ ├── ansicolor_ansi.go │ │ └── ansicolor_windows.go └── stretchr │ ├── objx │ ├── LICENSE.md │ ├── README.md │ ├── accessors.go │ ├── constants.go │ ├── conversions.go │ ├── doc.go │ ├── map.go │ ├── mutations.go │ ├── security.go │ ├── tests.go │ ├── type_specific_codegen.go │ └── value.go │ └── testify │ ├── assert │ ├── assertions.go │ ├── doc.go │ ├── errors.go │ ├── forward_assertions.go │ └── http_assertions.go │ └── mock │ ├── doc.go │ └── mock.go └── vendor.json /.env.sample: -------------------------------------------------------------------------------- 1 | AWS_ACCESS_KEY_ID=AAAAAAAAAAAAAAAAAAAA 2 | AWS_SECRET_ACCESS_KEY=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 3 | AWS_REGION=us-east-1 4 | AWS_KINESIS_STREAM=kinesumer-integration-test 5 | REDIS_URL=redis://127.0.0.1:6379 6 | REDIS_PREFIX=kinesumer 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | cmd/kinesumer/kinesumer 2 | .env 3 | .idea 4 | build 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Remind101 Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | mocks: mocks/kinesis.go 2 | 3 | clean: 4 | rm -rf build/* 5 | 6 | build/kinesumer: 7 | go build -o build/kinesumer ./cmd/kinesumer 8 | 9 | mocks/kinesis.go: 10 | mockery \ 11 | -dir=./Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/kinesis/kinesisiface \ 12 | -name=KinesisAPI -print=true \ 13 | | sed -e s/KinesisAPI/Kinesis/g > mocks/kinesis.go 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Kinesumer 2 | === 3 | [![Circle CI](https://circleci.com/gh/remind101/kinesumer.svg?style=svg&circle-token=ab11c0337d5aa1aca644e0420b228e86eecdd862)](https://circleci.com/gh/remind101/kinesumer) 4 | 5 | Kinesumer is a simple [Go](http://golang.org/) client library for Amazon AWS [Kinesis](http://aws.amazon.com/kinesis/). It aims to be a native Go alternative to Amazon's [KCL](https://github.com/awslabs/amazon-kinesis-client). Kinesumer includes a tool (called `kinesumer`) that lets you tail Kinesis streams and check the status of Kinesumer workers. 6 | 7 | Features 8 | --- 9 | * Automatically manages one consumer goroutine per shard. 10 | * Handles shard splitting and merging properly. 11 | * Provides a simple channel interface for incoming Kinesis records. 12 | * Provides a tool for managing Kinesis streams: 13 | * Tailing a stream 14 | 15 | Using the package 16 | --- 17 | Install 18 | ```bash 19 | go get github.com/remind101/kinesumer 20 | ``` 21 | 22 | Example Program 23 | ```golang 24 | package main 25 | 26 | import ( 27 | "fmt" 28 | "os" 29 | 30 | "github.com/remind101/kinesumer" 31 | ) 32 | 33 | func main() { 34 | k, err := kinesumer.NewDefault( 35 | "Stream", 36 | ) 37 | if err != nil { 38 | panic(err) 39 | } 40 | k.Begin() 41 | defer k.End() 42 | for i := 0; i < 100; i++ { 43 | rec := <-k.Records() 44 | fmt.Println(string(rec.Data())) 45 | } 46 | } 47 | ``` 48 | 49 | Using the tool 50 | --- 51 | Install 52 | ```bash 53 | go get -u github.com/remind101/kinesumer/cmd/kinesumer 54 | ``` 55 | 56 | To tail a stream make sure you have AWS credentials ready (either in ~/.aws or in env vars) and run: 57 | ```bash 58 | kinesumer tail -s STREAM_NAME 59 | ``` 60 | -------------------------------------------------------------------------------- /checkpointers/empty/checkpointer.go: -------------------------------------------------------------------------------- 1 | package emptycheckpointer 2 | 3 | import ( 4 | k "github.com/remind101/kinesumer/interface" 5 | ) 6 | 7 | type Checkpointer struct { 8 | } 9 | 10 | func (p Checkpointer) DoneC() chan<- k.Record { 11 | return nil 12 | } 13 | 14 | func (p Checkpointer) Begin() error { 15 | return nil 16 | } 17 | 18 | func (p Checkpointer) End() { 19 | } 20 | 21 | func (p Checkpointer) GetStartSequence(string) string { 22 | return "" 23 | } 24 | 25 | func (p Checkpointer) Sync() { 26 | } 27 | 28 | func (p Checkpointer) TryAcquire(shardID string) error { 29 | return nil 30 | } 31 | 32 | func (p Checkpointer) Release(shardID string) error { 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /checkpointers/redis/checkpointer.go: -------------------------------------------------------------------------------- 1 | package redischeckpointer 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "sync" 7 | "time" 8 | 9 | "github.com/garyburd/redigo/redis" 10 | k "github.com/remind101/kinesumer/interface" 11 | ) 12 | 13 | type Checkpointer struct { 14 | heads map[string]string 15 | c chan k.Record 16 | mut sync.Mutex 17 | pool *redis.Pool 18 | redisPrefix string 19 | savePeriod time.Duration 20 | wg sync.WaitGroup 21 | modified bool 22 | errHandler func(k.Error) 23 | readOnly bool 24 | } 25 | 26 | type Options struct { 27 | ReadOnly bool 28 | SavePeriod time.Duration 29 | RedisPool *redis.Pool 30 | RedisPrefix string 31 | ErrHandler func(k.Error) 32 | } 33 | 34 | type Error struct { 35 | origin error 36 | severity string 37 | } 38 | 39 | func (e *Error) Severity() string { return e.severity } 40 | 41 | func (e *Error) Origin() error { return e.origin } 42 | 43 | func (e *Error) Error() string { return e.origin.Error() } 44 | 45 | func New(opt *Options) (*Checkpointer, error) { 46 | save := opt.SavePeriod 47 | if save == 0 { 48 | save = 5 * time.Second 49 | } 50 | 51 | if opt.ErrHandler == nil { 52 | opt.ErrHandler = func(err k.Error) { 53 | panic(err) 54 | } 55 | } 56 | 57 | return &Checkpointer{ 58 | heads: make(map[string]string), 59 | c: make(chan k.Record), 60 | mut: sync.Mutex{}, 61 | pool: opt.RedisPool, 62 | redisPrefix: opt.RedisPrefix, 63 | savePeriod: save, 64 | modified: true, 65 | errHandler: opt.ErrHandler, 66 | readOnly: opt.ReadOnly, 67 | }, nil 68 | } 69 | 70 | func (r *Checkpointer) DoneC() chan<- k.Record { 71 | return r.c 72 | } 73 | 74 | func (r *Checkpointer) Sync() { 75 | if r.readOnly { 76 | return 77 | } 78 | 79 | r.mut.Lock() 80 | defer r.mut.Unlock() 81 | if len(r.heads) > 0 && r.modified { 82 | conn := r.pool.Get() 83 | defer conn.Close() 84 | if _, err := conn.Do("HMSET", redis.Args{r.redisPrefix + ".sequence"}.AddFlat(r.heads)...); err != nil { 85 | r.errHandler(&Error{err, k.EWarn}) 86 | } 87 | r.modified = false 88 | } 89 | } 90 | 91 | func (r *Checkpointer) RunCheckpointer() { 92 | defer func() { 93 | if val := recover(); val != nil { 94 | err := errors.New(fmt.Sprintf("%v", val)) 95 | r.errHandler(&Error{err, k.ECrit}) 96 | } 97 | }() 98 | saveTicker := time.NewTicker(r.savePeriod).C 99 | loop: 100 | for { 101 | select { 102 | case <-saveTicker: 103 | r.Sync() 104 | case state, ok := <-r.c: 105 | if !ok { 106 | break loop 107 | } 108 | r.mut.Lock() 109 | r.heads[state.ShardId()] = state.SequenceNumber() 110 | r.modified = true 111 | r.mut.Unlock() 112 | } 113 | } 114 | r.Sync() 115 | r.wg.Done() 116 | } 117 | 118 | func (r *Checkpointer) Begin() error { 119 | r.wg.Add(1) 120 | go r.RunCheckpointer() 121 | return nil 122 | } 123 | 124 | func (r *Checkpointer) End() { 125 | close(r.c) 126 | r.wg.Wait() 127 | } 128 | 129 | func (r *Checkpointer) GetStartSequence(shardID string) string { 130 | conn := r.pool.Get() 131 | defer conn.Close() 132 | 133 | var seq string 134 | res, err := conn.Do("HGET", r.redisPrefix+".sequence", shardID) 135 | seq, err = redis.String(res, err) 136 | 137 | if err == nil { 138 | return seq 139 | } else { 140 | return "" 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /checkpointers/redis/checkpointer_test.go: -------------------------------------------------------------------------------- 1 | package redischeckpointer 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/garyburd/redigo/redis" 8 | "github.com/remind101/kinesumer/redispool" 9 | ) 10 | 11 | var ( 12 | prefix = "testing" 13 | sequenceKey = prefix + ".sequence" 14 | ) 15 | 16 | func makeCheckpointer() (*Checkpointer, error) { 17 | pool, err := redispool.NewRedisPool("redis://127.0.0.1:6379") 18 | if err != nil { 19 | return nil, err 20 | } 21 | r, err := New(&Options{ 22 | SavePeriod: time.Hour, 23 | RedisPool: pool, 24 | RedisPrefix: prefix, 25 | }) 26 | return r, err 27 | } 28 | 29 | func makeCheckpointerWithSamples() *Checkpointer { 30 | r, _ := makeCheckpointer() 31 | conn := r.pool.Get() 32 | defer conn.Close() 33 | conn.Do("DEL", sequenceKey) 34 | conn.Do("HSET", sequenceKey, "shard1", "1000") 35 | conn.Do("HSET", sequenceKey, "shard2", "2000") 36 | r, _ = makeCheckpointer() 37 | return r 38 | } 39 | 40 | func TestRedisGoodLogin(t *testing.T) { 41 | r, err := makeCheckpointer() 42 | if err != nil { 43 | t.Error("Failed to connect to redis at localhost:6379") 44 | } 45 | 46 | conn := r.pool.Get() 47 | defer conn.Close() 48 | reply, err := conn.Do("ECHO", "hey") 49 | 50 | re, err := redis.String(reply, err) 51 | if err != nil || re != "hey" { 52 | t.Error("Redis ECHO failed") 53 | } 54 | } 55 | 56 | func TestCheckpointerBeginEnd(t *testing.T) { 57 | r := makeCheckpointerWithSamples() 58 | err := r.Begin() 59 | if err != nil { 60 | t.Error(err) 61 | } 62 | r.End() 63 | 64 | if len(r.heads) > 0 { 65 | t.Error("Begin should not fetch state from redis") 66 | } 67 | } 68 | 69 | func TestCheckpointerGetStartSequence(t *testing.T) { 70 | r := makeCheckpointerWithSamples() 71 | _ = r.Begin() 72 | r.End() 73 | shard1 := "shard1" 74 | seq := r.GetStartSequence(shard1) 75 | if seq != "1000" { 76 | t.Error("Expected nonempty sequence number") 77 | } 78 | } 79 | 80 | func TestCheckpointerSync(t *testing.T) { 81 | r := makeCheckpointerWithSamples() 82 | r.Begin() 83 | r.DoneC() <- &FakeRecord{shardId: "shard2", sequenceNumber: "2001"} 84 | r.Sync() 85 | r.End() 86 | r, _ = makeCheckpointer() 87 | r.Begin() 88 | r.DoneC() <- &FakeRecord{shardId: "shard1", sequenceNumber: "1002"} 89 | r.Sync() 90 | r.End() 91 | if r.heads["shard1"] != "1002" { 92 | t.Error("Expected sequence number to be written") 93 | } 94 | if r.GetStartSequence("shard2") != "2001" { 95 | t.Error("Expected sequence number to be written by first checkpointer") 96 | } 97 | if len(r.heads) != 1 { 98 | t.Error("Heads should not know about any other shards") 99 | } 100 | } 101 | 102 | type FakeRecord struct { 103 | sequenceNumber string 104 | shardId string 105 | } 106 | 107 | func (r *FakeRecord) Data() []byte { 108 | return nil 109 | } 110 | 111 | func (r *FakeRecord) PartitionKey() string { 112 | return "" 113 | } 114 | 115 | func (r *FakeRecord) SequenceNumber() string { 116 | return r.sequenceNumber 117 | } 118 | 119 | func (r *FakeRecord) ShardId() string { 120 | return r.shardId 121 | } 122 | 123 | func (r *FakeRecord) MillisBehindLatest() int64 { 124 | return -1 125 | } 126 | 127 | func (r *FakeRecord) Done() { 128 | } 129 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | environment: 3 | GO15VENDOREXPERIMENT: 1 4 | 5 | checkout: 6 | post: 7 | - rm -rf ~/.go_workspace/src/github.com/remind101 8 | - mkdir -p ~/.go_workspace/src/github.com/remind101 9 | - cp -R ~/kinesumer ~/.go_workspace/src/github.com/remind101/kinesumer 10 | 11 | dependencies: 12 | override: 13 | - /bin/true 14 | 15 | test: 16 | override: 17 | - cd ~/.go_workspace/src/github.com/remind101/kinesumer && go test 18 | -------------------------------------------------------------------------------- /cmd/kinesumer/cmd_shards.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | "sort" 7 | "strings" 8 | "time" 9 | 10 | "github.com/codegangsta/cli" 11 | "github.com/remind101/kinesumer" 12 | ) 13 | 14 | var cmdShards = cli.Command{ 15 | Name: "shards", 16 | Aliases: []string{"sh"}, 17 | Usage: "Gets the shards of a stream", 18 | Action: runShards, 19 | Flags: flagsStream, 20 | } 21 | 22 | type ShardHashEndpoints []*big.Int 23 | 24 | func (n ShardHashEndpoints) Len() int { 25 | return len(n) 26 | } 27 | 28 | func (n ShardHashEndpoints) Swap(i, j int) { 29 | n[i], n[j] = n[j], n[i] 30 | } 31 | 32 | func (n ShardHashEndpoints) Less(i, j int) bool { 33 | return n[i].Cmp(n[j]) < 0 34 | } 35 | 36 | func (n *ShardHashEndpoints) UniqSort() { 37 | sort.Sort(n) 38 | 39 | tmp := make(ShardHashEndpoints, 0) 40 | for _, key := range *n { 41 | if len(tmp) == 0 || tmp[len(tmp)-1].Cmp(key) != 0 { 42 | tmp = append(tmp, key) 43 | } 44 | } 45 | 46 | *n = tmp 47 | } 48 | 49 | func (n ShardHashEndpoints) Clone() ShardHashEndpoints { 50 | p := make(ShardHashEndpoints, len(n)) 51 | for i := 0; i < len(n); i++ { 52 | p[i] = &big.Int{} 53 | p[i].Set(n[i]) 54 | } 55 | return p 56 | } 57 | 58 | func runShards(ctx *cli.Context) { 59 | stream := getStream(ctx) 60 | k, err := kinesumer.NewDefault( 61 | stream, 62 | time.Duration(0), 63 | ) 64 | if err != nil { 65 | panic(err) 66 | } 67 | 68 | shards, err := k.GetShards() 69 | if err != nil { 70 | panic(err) 71 | } 72 | if len(shards) == 0 { 73 | fmt.Printf("No shards found on stream %s\n", stream) 74 | } 75 | 76 | keys := make(ShardHashEndpoints, 0) 77 | 78 | for _, shard := range shards { 79 | begin := &big.Int{} 80 | begin.SetString(*shard.HashKeyRange.StartingHashKey, 10) 81 | keys = append(keys, begin) 82 | 83 | end := &big.Int{} 84 | end.SetString(*shard.HashKeyRange.EndingHashKey, 10) 85 | end.Add(end, big.NewInt(1)) 86 | keys = append(keys, end) 87 | } 88 | 89 | keys.UniqSort() 90 | 91 | // Only support < 100 shards for now 92 | maxShardIdLen := 0 93 | for _, shard := range shards { 94 | if maxShardIdLen < len(*shard.ShardId) { 95 | maxShardIdLen = len(*shard.ShardId) 96 | } 97 | } 98 | 99 | fmt.Printf("SHARD ID%s ", strings.Repeat(" ", maxShardIdLen-len("SHARD ID"))) 100 | for i := 0; i < len(keys); i++ { 101 | if i < 10 { 102 | fmt.Printf("%d ", i) 103 | } else { 104 | fmt.Printf("%d ", i) 105 | } 106 | } 107 | fmt.Println() 108 | 109 | for _, shard := range shards { 110 | fmt.Printf("%s%s ", *shard.ShardId, strings.Repeat(" ", maxShardIdLen-len(*shard.ShardId))) 111 | for _, key := range keys { 112 | begin := &big.Int{} 113 | begin.SetString(*shard.HashKeyRange.StartingHashKey, 10) 114 | if key.Cmp(begin) < 0 { 115 | fmt.Printf(" ") 116 | continue 117 | } 118 | end := &big.Int{} 119 | end.SetString(*shard.HashKeyRange.EndingHashKey, 10) 120 | end.Add(end, big.NewInt(1)) 121 | if key.Cmp(end) < 0 { 122 | fmt.Printf("o--") 123 | } else { 124 | fmt.Printf("o\n") 125 | break 126 | } 127 | } 128 | } 129 | fmt.Printf("\nHash keys:\n") 130 | for i, key := range keys { 131 | fmt.Printf("%d: %s\n", i, key.String()) 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /cmd/kinesumer/cmd_status.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/codegangsta/cli" 7 | "github.com/fatih/color" 8 | "github.com/remind101/kinesumer" 9 | "github.com/remind101/kinesumer/checkpointers/redis" 10 | "github.com/remind101/kinesumer/provisioners/redis" 11 | "github.com/remind101/kinesumer/redispool" 12 | ) 13 | 14 | var cmdStatus = cli.Command{ 15 | Name: "status", 16 | Aliases: []string{"s"}, 17 | Usage: "Gets the status of a kinesis stream", 18 | Action: runStatus, 19 | Flags: append(flagsStream, flagsRedis...), 20 | } 21 | 22 | func runStatus(ctx *cli.Context) { 23 | k, err := kinesumer.NewDefault( 24 | getStream(ctx), 25 | time.Duration(0), 26 | ) 27 | if err != nil { 28 | panic(err) 29 | } 30 | 31 | var prov *redisprovisioner.Provisioner 32 | var cp *redischeckpointer.Checkpointer 33 | redis := false 34 | if redisURL := ctx.String(fRedisURL); len(redisURL) > 0 { 35 | pool, err := redispool.NewRedisPool(redisURL) 36 | if err != nil { 37 | panic(err) 38 | } 39 | prefix := ctx.String(fRedisPrefix) 40 | 41 | prov, err = redisprovisioner.New(&redisprovisioner.Options{ 42 | TTL: time.Second, 43 | RedisPool: pool, 44 | RedisPrefix: prefix, 45 | }) 46 | if err != nil { 47 | panic(err) 48 | } 49 | 50 | cp, err = redischeckpointer.New(&redischeckpointer.Options{ 51 | ReadOnly: true, 52 | RedisPool: pool, 53 | RedisPrefix: prefix, 54 | }) 55 | 56 | err = cp.Begin() 57 | if err != nil { 58 | panic(err) 59 | } 60 | defer cp.End() 61 | 62 | redis = true 63 | } 64 | 65 | table := NewTable() 66 | header := table.AddRowWith("Shard ID", "Status") 67 | header.Header = true 68 | if redis { 69 | header.AddCellWithf("Worker") 70 | header.AddCellWithf("Sequence Number") 71 | } 72 | 73 | shards, err := k.GetShards() 74 | if err != nil { 75 | panic(err) 76 | } 77 | 78 | for _, shard := range shards { 79 | row := table.AddRow() 80 | row.AddCellWithf("%s", *shard.ShardId) 81 | if shard.SequenceNumberRange.EndingSequenceNumber == nil { 82 | row.AddCellWithf("OPEN").Color = color.New(color.FgGreen) 83 | } else { 84 | row.AddCellWithf("CLOSED").Color = color.New(color.FgRed) 85 | } 86 | if redis { 87 | cell := row.AddCell() 88 | lock, err := prov.Check(*shard.ShardId) 89 | if err != nil { 90 | lock = err.Error() 91 | cell.Color = color.New(color.FgRed) 92 | } 93 | cell.Printf("%s", lock) 94 | seqStart := StrShorten(cp.GetStartSequence(*shard.ShardId), 8, 8) 95 | cell = row.AddCell() 96 | if len(seqStart) == 0 { 97 | seqStart = "???" 98 | cell.Color = color.New(color.FgRed) 99 | } 100 | cell.Printf("%s", seqStart) 101 | } 102 | } 103 | 104 | table.Done() 105 | } 106 | -------------------------------------------------------------------------------- /cmd/kinesumer/cmd_tail.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "os" 6 | "time" 7 | 8 | "github.com/codegangsta/cli" 9 | "github.com/fatih/color" 10 | "github.com/remind101/kinesumer" 11 | "github.com/remind101/kinesumer/checkpointers/redis" 12 | "github.com/remind101/kinesumer/redispool" 13 | ) 14 | 15 | var cmdTail = cli.Command{ 16 | Name: "tail", 17 | Aliases: []string{"t"}, 18 | Usage: "Pipes a Kinesis stream to standard out", 19 | Action: runTail, 20 | Flags: append( 21 | []cli.Flag{ 22 | cli.StringFlag{ 23 | Name: "stream, s", 24 | Usage: "The Kinesis stream to tail", 25 | }, 26 | cli.StringFlag{ 27 | Name: "duration, d", 28 | Usage: "Duration to go back and stream logs from", 29 | }, 30 | }, flagsRedis..., 31 | ), 32 | } 33 | 34 | func errHandler(err kinesumer.IError) { 35 | switch err.Severity() { 36 | case kinesumer.ECrit: 37 | fallthrough 38 | case kinesumer.EError: 39 | color.Red("%s:%s\n", err.Severity(), err.Error()) 40 | panic(err) 41 | default: 42 | color.Yellow("%s:%s\n", err.Severity(), err.Error()) 43 | } 44 | } 45 | 46 | func runTail(ctx *cli.Context) { 47 | var duration time.Duration 48 | var err error 49 | if ctx.String("duration") != "" { 50 | duration, err = time.ParseDuration(ctx.String("duration")) 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | k, err := kinesumer.NewDefault( 56 | ctx.String("stream"), 57 | duration, 58 | ) 59 | if err != nil { 60 | panic(err) 61 | } 62 | 63 | k.Options.ErrHandler = kinesumer.ErrHandler(errHandler) 64 | 65 | if redisURL := ctx.String(fRedisURL); len(redisURL) > 0 { 66 | pool, err := redispool.NewRedisPool(redisURL) 67 | if err != nil { 68 | panic(err) 69 | } 70 | 71 | cp, err := redischeckpointer.New(&redischeckpointer.Options{ 72 | ReadOnly: true, 73 | RedisPool: pool, 74 | RedisPrefix: ctx.String(fRedisPrefix), 75 | }) 76 | if err != nil { 77 | panic(err) 78 | } 79 | 80 | k.Checkpointer = cp 81 | } 82 | 83 | _, err = k.Begin() 84 | if err != nil { 85 | panic(err) 86 | } 87 | defer k.End() 88 | 89 | r := kinesumer.NewReader(k.Records()) 90 | io.Copy(os.Stdout, r) 91 | } 92 | -------------------------------------------------------------------------------- /cmd/kinesumer/flags_redis.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/codegangsta/cli" 5 | ) 6 | 7 | var ( 8 | fRedisURL = "redis.url" 9 | fRedisPrefix = "redis.prefix" 10 | ) 11 | 12 | var flagsRedis = []cli.Flag{ 13 | cli.StringFlag{ 14 | Name: fRedisURL, 15 | Usage: "The Redis URL", 16 | EnvVar: "REDIS_URL", 17 | }, 18 | cli.StringFlag{ 19 | Name: fRedisPrefix, 20 | Usage: "The Redis key prefix", 21 | EnvVar: "REDIS_PREFIX", 22 | }, 23 | } 24 | 25 | func getRedisURL(ctx *cli.Context) string { 26 | return ctx.String("redis.url") 27 | } 28 | -------------------------------------------------------------------------------- /cmd/kinesumer/flags_stream.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/codegangsta/cli" 5 | ) 6 | 7 | var flagsStream = []cli.Flag{ 8 | cli.StringFlag{ 9 | Name: "stream, s", 10 | Usage: "The Kinesis stream to tail", 11 | }, 12 | } 13 | 14 | func getStream(ctx *cli.Context) string { 15 | return ctx.String("stream") 16 | } 17 | -------------------------------------------------------------------------------- /cmd/kinesumer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/codegangsta/cli" 7 | _ "github.com/joho/godotenv/autoload" 8 | ) 9 | 10 | func main() { 11 | app := cli.NewApp() 12 | app.Name = "kinesumer" 13 | app.Usage = "A tool working with AWS Kinesis and kinesumer" 14 | app.Version = "0.0.0" 15 | app.Authors = []cli.Author{ 16 | { 17 | Name: "Tony Zou", 18 | Email: "", 19 | }, 20 | } 21 | app.Commands = []cli.Command{ 22 | cmdShards, 23 | cmdStatus, 24 | cmdTail, 25 | } 26 | app.Run(os.Args) 27 | } 28 | -------------------------------------------------------------------------------- /cmd/kinesumer/table.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/fatih/color" 8 | ) 9 | 10 | type Table struct { 11 | Rows []Row 12 | } 13 | 14 | type Row struct { 15 | Cells []Cell 16 | Header bool 17 | } 18 | 19 | type Cell struct { 20 | Color *color.Color 21 | Text string 22 | } 23 | 24 | func NewTable() *Table { 25 | return &Table{ 26 | Rows: make([]Row, 0), 27 | } 28 | } 29 | 30 | func (t *Table) Done() { 31 | cols := 0 32 | for _, row := range t.Rows { 33 | if cols < len(row.Cells) { 34 | cols = len(row.Cells) 35 | } 36 | } 37 | 38 | widths := make([]int, cols) 39 | for _, row := range t.Rows { 40 | for col, cell := range row.Cells { 41 | if widths[col] < len(cell.Text) { 42 | widths[col] = len(cell.Text) 43 | } 44 | } 45 | } 46 | 47 | for _, row := range t.Rows { 48 | for col, cell := range row.Cells { 49 | if row.Header { 50 | cell.Color.Printf("%s%s ", strings.ToUpper(cell.Text), strings.Repeat(" ", widths[col]-len(cell.Text))) 51 | } else { 52 | cell.Color.Printf("%s%s ", cell.Text, strings.Repeat(" ", widths[col]-len(cell.Text))) 53 | } 54 | } 55 | fmt.Println() 56 | } 57 | } 58 | 59 | func (t *Table) AddRow() *Row { 60 | t.Rows = append(t.Rows, Row{ 61 | Cells: make([]Cell, 0), 62 | }) 63 | return &t.Rows[len(t.Rows)-1] 64 | } 65 | 66 | func (t *Table) AddRowWith(labels ...string) *Row { 67 | row := t.AddRow() 68 | for _, label := range labels { 69 | row.AddCellWithf("%s", label) 70 | } 71 | return row 72 | } 73 | 74 | func (r *Row) AddCell() *Cell { 75 | r.Cells = append(r.Cells, Cell{ 76 | Color: color.New(), 77 | Text: "-", 78 | }) 79 | return &r.Cells[len(r.Cells)-1] 80 | } 81 | 82 | func (r *Row) AddCellWithf(format string, a ...interface{}) *Cell { 83 | cell := r.AddCell() 84 | cell.Printf(format, a...) 85 | return cell 86 | } 87 | 88 | func (c *Cell) Printf(format string, a ...interface{}) { 89 | c.Text = fmt.Sprintf(format, a...) 90 | } 91 | 92 | func StrShorten(s string, pre, post int) string { 93 | if len(s) <= pre+post+3 { 94 | return s 95 | } 96 | return s[0:pre] + "..." + s[len(s)-post:len(s)] 97 | } 98 | -------------------------------------------------------------------------------- /err_handler.go: -------------------------------------------------------------------------------- 1 | package kinesumer 2 | 3 | import ( 4 | "fmt" 5 | 6 | k "github.com/remind101/kinesumer/interface" 7 | ) 8 | 9 | func DefaultErrHandler(err k.Error) { 10 | fmt.Println(err.Severity()+":", err.Error()) 11 | 12 | severity := err.Severity() 13 | if severity == ECrit || severity == EError { 14 | panic(err) 15 | } 16 | } 17 | 18 | func ErrHandler(errHandler func(IError)) func(k.Error) { 19 | return func(e k.Error) { 20 | errHandler(e) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /error.go: -------------------------------------------------------------------------------- 1 | package kinesumer 2 | 3 | const ( 4 | ECrit = "crit" 5 | EError = "error" 6 | EWarn = "warn" 7 | EInfo = "info" 8 | EDebug = "debug" 9 | ) 10 | 11 | type Error struct { 12 | // One of "crit", "error", "warn", "info", "debug" 13 | severity string 14 | message string 15 | origin error 16 | } 17 | 18 | func NewError(severity, message string, origin error) *Error { 19 | return &Error{ 20 | severity: severity, 21 | message: message, 22 | origin: origin, 23 | } 24 | } 25 | 26 | func (e *Error) Severity() string { 27 | return e.severity 28 | } 29 | 30 | func (e *Error) Origin() error { 31 | return e.origin 32 | } 33 | 34 | func (e *Error) Error() string { 35 | if e.origin == nil { 36 | return e.message 37 | } else { 38 | return e.message + " from " + e.origin.Error() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /interface/checkpointer.go: -------------------------------------------------------------------------------- 1 | package kinesumeriface 2 | 3 | type Checkpointer interface { 4 | DoneC() chan<- Record 5 | Begin() error 6 | End() 7 | GetStartSequence(shardID string) string 8 | Sync() 9 | } 10 | -------------------------------------------------------------------------------- /interface/error.go: -------------------------------------------------------------------------------- 1 | package kinesumeriface 2 | 3 | const ( 4 | ECrit = "crit" 5 | EError = "error" 6 | EWarn = "warn" 7 | EInfo = "info" 8 | EDebug = "debug" 9 | ) 10 | 11 | type Error interface { 12 | Severity() string 13 | Origin() error 14 | Error() string 15 | } 16 | -------------------------------------------------------------------------------- /interface/kinesis.go: -------------------------------------------------------------------------------- 1 | package kinesumeriface 2 | 3 | import ( 4 | "github.com/aws/aws-sdk-go/service/kinesis/kinesisiface" 5 | ) 6 | 7 | type Kinesis kinesisiface.KinesisAPI 8 | -------------------------------------------------------------------------------- /interface/kinesumer.go: -------------------------------------------------------------------------------- 1 | package kinesumeriface 2 | 3 | type Kinesumer interface { 4 | Begin() (int, error) 5 | End() 6 | Records() <-chan Record 7 | } 8 | -------------------------------------------------------------------------------- /interface/provisioner.go: -------------------------------------------------------------------------------- 1 | package kinesumeriface 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Provisioner interface { 8 | TryAcquire(shardID string) error 9 | Release(shardID string) error 10 | Heartbeat(shardID string) error 11 | TTL() time.Duration 12 | } 13 | -------------------------------------------------------------------------------- /interface/record.go: -------------------------------------------------------------------------------- 1 | package kinesumeriface 2 | 3 | type Record interface { 4 | Data() []byte 5 | PartitionKey() string 6 | SequenceNumber() string 7 | ShardId() string 8 | MillisBehindLatest() int64 9 | Done() 10 | } 11 | -------------------------------------------------------------------------------- /interfaces.go: -------------------------------------------------------------------------------- 1 | package kinesumer 2 | 3 | import ( 4 | "github.com/remind101/kinesumer/interface" 5 | ) 6 | 7 | type ICheckpointer kinesumeriface.Checkpointer 8 | 9 | type IError kinesumeriface.Error 10 | 11 | type IKinesis kinesumeriface.Kinesis 12 | 13 | type IKinesumer kinesumeriface.Kinesumer 14 | 15 | type IProvisioner kinesumeriface.Provisioner 16 | 17 | type IRecord kinesumeriface.Record 18 | -------------------------------------------------------------------------------- /kinesumer_test.go: -------------------------------------------------------------------------------- 1 | package kinesumer 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | 8 | "github.com/aws/aws-sdk-go/aws" 9 | "github.com/aws/aws-sdk-go/aws/awserr" 10 | "github.com/aws/aws-sdk-go/service/kinesis" 11 | "github.com/remind101/kinesumer/mocks" 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/mock" 14 | ) 15 | 16 | func makeTestKinesumer(t *testing.T) (*Kinesumer, *mocks.Kinesis, *mocks.Checkpointer, 17 | *mocks.Provisioner) { 18 | kin := new(mocks.Kinesis) 19 | sssm := new(mocks.Checkpointer) 20 | prov := new(mocks.Provisioner) 21 | k, err := New( 22 | kin, 23 | sssm, 24 | prov, 25 | rand.NewSource(0), 26 | "TestStream", 27 | nil, 28 | time.Duration(0), 29 | ) 30 | if err != nil { 31 | t.Error(err) 32 | } 33 | return k, kin, sssm, prov 34 | } 35 | 36 | func TestKinesumerGetStreams(t *testing.T) { 37 | k, kin, _, _ := makeTestKinesumer(t) 38 | kin.On("ListStreamsPages", mock.Anything, mock.Anything).Return(nil) 39 | streams, err := k.GetStreams() 40 | assert.Nil(t, err) 41 | kin.AssertNumberOfCalls(t, "ListStreamsPages", 1) 42 | assert.Equal(t, 3, len(streams)) 43 | assert.Equal(t, streams[2], "c") 44 | } 45 | 46 | func TestKinesumerStreamExists(t *testing.T) { 47 | k, kin, _, _ := makeTestKinesumer(t) 48 | k.Stream = "c" 49 | kin.On("ListStreamsPages", mock.Anything, mock.Anything).Return(nil) 50 | e, err := k.StreamExists() 51 | assert.Nil(t, err) 52 | kin.AssertNumberOfCalls(t, "ListStreamsPages", 1) 53 | assert.True(t, e) 54 | } 55 | 56 | func TestKinesumerGetShards(t *testing.T) { 57 | k, kin, _, _ := makeTestKinesumer(t) 58 | k.Stream = "c" 59 | kin.On("DescribeStreamPages", mock.Anything, mock.Anything).Return(nil) 60 | shards, err := k.GetShards() 61 | assert.Nil(t, err) 62 | kin.AssertNumberOfCalls(t, "DescribeStreamPages", 1) 63 | assert.Equal(t, 2, len(shards)) 64 | assert.Equal(t, "shard1", *shards[1].ShardId) 65 | } 66 | 67 | func TestKinesumerBeginEnd(t *testing.T) { 68 | k, kin, sssm, prov := makeTestKinesumer(t) 69 | k.Stream = "c" 70 | 71 | kin.On("DescribeStreamPages", mock.Anything, mock.Anything).Return(awserr.New("bad", "bad", nil)).Once() 72 | _, err := k.Begin() 73 | assert.Error(t, err) 74 | 75 | prov.On("TTL").Return(time.Millisecond * 10) 76 | prov.On("TryAcquire", mock.Anything).Return(nil) 77 | prov.On("Heartbeat", mock.Anything).Return(nil) 78 | prov.On("Release", mock.Anything).Return(nil) 79 | kin.On("DescribeStreamPages", mock.Anything, mock.Anything).Return(awserr.Error(nil)) 80 | sssm.On("Begin", mock.Anything).Return(nil) 81 | sssm.On("GetStartSequence", mock.Anything).Return("0").Once() 82 | sssm.On("GetStartSequence", mock.Anything).Return("") 83 | sssm.On("TryAcquire", mock.Anything).Return(nil) 84 | kin.On("GetShardIterator", mock.Anything).Return(&kinesis.GetShardIteratorOutput{ 85 | ShardIterator: aws.String("0"), 86 | }, awserr.Error(nil)) 87 | kin.On("GetRecords", mock.Anything).Return(&kinesis.GetRecordsOutput{ 88 | MillisBehindLatest: aws.Int64(0), 89 | NextShardIterator: aws.String("AAAAA"), 90 | Records: []*kinesis.Record{}, 91 | }, awserr.Error(nil)) 92 | sssm.On("End").Return() 93 | _, err = k.Begin() 94 | assert.Nil(t, err) 95 | assert.Equal(t, 2, k.nRunning) 96 | k.End() 97 | } 98 | -------------------------------------------------------------------------------- /mocks/checkpointer.go: -------------------------------------------------------------------------------- 1 | package mocks 2 | 3 | import ( 4 | k "github.com/remind101/kinesumer/interface" 5 | "github.com/stretchr/testify/mock" 6 | ) 7 | 8 | type Checkpointer struct { 9 | mock.Mock 10 | } 11 | 12 | func (m *Checkpointer) DoneC() chan<- k.Record { 13 | ret := m.Called() 14 | 15 | var r0 chan k.Record 16 | if ret.Get(0) != nil { 17 | r0 = ret.Get(0).(chan k.Record) 18 | } 19 | 20 | return r0 21 | } 22 | func (m *Checkpointer) Begin() error { 23 | ret := m.Called() 24 | 25 | r0 := ret.Error(0) 26 | 27 | return r0 28 | } 29 | func (m *Checkpointer) End() { 30 | m.Called() 31 | } 32 | func (m *Checkpointer) GetStartSequence(shardID string) string { 33 | ret := m.Called(shardID) 34 | 35 | r0 := ret.String(0) 36 | 37 | return r0 38 | } 39 | func (m *Checkpointer) Sync() { 40 | m.Called() 41 | } 42 | func (m *Checkpointer) TryAcquire(shardID string) error { 43 | ret := m.Called(shardID) 44 | 45 | r0 := ret.Error(0) 46 | 47 | return r0 48 | } 49 | func (m *Checkpointer) Release(shardID string) error { 50 | ret := m.Called(shardID) 51 | 52 | r0 := ret.Error(0) 53 | 54 | return r0 55 | } 56 | -------------------------------------------------------------------------------- /mocks/kinesumer.go: -------------------------------------------------------------------------------- 1 | package mocks 2 | 3 | import ( 4 | k "github.com/remind101/kinesumer/interface" 5 | "github.com/stretchr/testify/mock" 6 | ) 7 | 8 | type Kinesumer struct { 9 | mock.Mock 10 | } 11 | 12 | func (m *Kinesumer) Begin() (int, error) { 13 | ret := m.Called() 14 | 15 | r0 := ret.Int(0) 16 | r1 := ret.Error(1) 17 | 18 | return r0, r1 19 | } 20 | func (m *Kinesumer) End() { 21 | m.Called() 22 | } 23 | func (m *Kinesumer) Records() <-chan k.Record { 24 | ret := m.Called() 25 | 26 | var r0 <-chan k.Record 27 | if ret.Get(0) != nil { 28 | r0 = ret.Get(0).(<-chan k.Record) 29 | } 30 | 31 | return r0 32 | } 33 | -------------------------------------------------------------------------------- /mocks/provisioner.go: -------------------------------------------------------------------------------- 1 | package mocks 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/stretchr/testify/mock" 7 | ) 8 | 9 | type Provisioner struct { 10 | mock.Mock 11 | } 12 | 13 | func (m *Provisioner) TryAcquire(shardID string) error { 14 | ret := m.Called(shardID) 15 | 16 | r0 := ret.Error(0) 17 | 18 | return r0 19 | } 20 | func (m *Provisioner) Release(shardID string) error { 21 | ret := m.Called(shardID) 22 | 23 | r0 := ret.Error(0) 24 | 25 | return r0 26 | } 27 | func (m *Provisioner) Heartbeat(shardID string) error { 28 | ret := m.Called(shardID) 29 | 30 | r0 := ret.Error(0) 31 | 32 | return r0 33 | } 34 | func (m *Provisioner) TTL() time.Duration { 35 | ret := m.Called() 36 | 37 | r0 := ret.Get(0).(time.Duration) 38 | 39 | return r0 40 | } 41 | -------------------------------------------------------------------------------- /provisioners/empty/provisioner.go: -------------------------------------------------------------------------------- 1 | package emptyprovisioner 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Provisioner struct { 8 | } 9 | 10 | func (p Provisioner) TryAcquire(shardID string) error { 11 | return nil 12 | } 13 | 14 | func (p Provisioner) Release(shardID string) error { 15 | return nil 16 | } 17 | 18 | func (p Provisioner) Heartbeat(shardID string) error { 19 | return nil 20 | } 21 | 22 | func (p Provisioner) TTL() time.Duration { 23 | return time.Hour 24 | } 25 | -------------------------------------------------------------------------------- /provisioners/redis/provisioner.go: -------------------------------------------------------------------------------- 1 | package redisprovisioner 2 | 3 | import ( 4 | "errors" 5 | "sync" 6 | "time" 7 | 8 | "github.com/garyburd/redigo/redis" 9 | "github.com/pborman/uuid" // Exported from code.google.com/p/go-uuid/uuid 10 | ) 11 | 12 | type Provisioner struct { 13 | acquired map[string]bool 14 | heartbeats map[string]time.Time 15 | heartbeatsMut sync.RWMutex 16 | ttl time.Duration 17 | pool *redis.Pool 18 | redisPrefix string 19 | lock string 20 | } 21 | 22 | type Options struct { 23 | TTL time.Duration 24 | Lock string 25 | RedisPool *redis.Pool 26 | RedisPrefix string 27 | } 28 | 29 | func New(opt *Options) (*Provisioner, error) { 30 | if opt.Lock == "" { 31 | opt.Lock = uuid.New() 32 | } 33 | 34 | return &Provisioner{ 35 | acquired: make(map[string]bool), 36 | heartbeats: make(map[string]time.Time), 37 | ttl: opt.TTL, 38 | lock: opt.Lock, 39 | pool: opt.RedisPool, 40 | redisPrefix: opt.RedisPrefix, 41 | }, nil 42 | } 43 | 44 | func (p *Provisioner) TryAcquire(shardID string) error { 45 | if len(shardID) == 0 { 46 | return errors.New("ShardId cannot be empty") 47 | } 48 | 49 | conn := p.pool.Get() 50 | defer conn.Close() 51 | 52 | res, err := conn.Do("SET", p.redisPrefix+":lock:"+shardID, p.lock, "PX", int64(p.ttl/time.Millisecond), "NX") 53 | if err != nil { 54 | return err 55 | } 56 | if res != "OK" { 57 | return errors.New("Failed to acquire lock") 58 | } 59 | 60 | p.acquired[shardID] = true 61 | return nil 62 | } 63 | 64 | func (p *Provisioner) Release(shardID string) error { 65 | conn := p.pool.Get() 66 | defer conn.Close() 67 | 68 | delete(p.acquired, shardID) 69 | 70 | key := p.redisPrefix + ":lock:" + shardID 71 | res, err := redis.String(conn.Do("GET", key)) 72 | if err != nil { 73 | return err 74 | } 75 | if res != p.lock { 76 | return errors.New("Bad lock") 77 | } 78 | 79 | _, err = conn.Do("DEL", key) 80 | if err != nil { 81 | return err 82 | } 83 | 84 | return nil 85 | } 86 | 87 | func (p *Provisioner) Check(shardID string) (string, error) { 88 | conn := p.pool.Get() 89 | defer conn.Close() 90 | return redis.String(conn.Do("GET", p.redisPrefix+":lock:"+shardID)) 91 | } 92 | 93 | func (p *Provisioner) Heartbeat(shardID string) error { 94 | if !p.acquired[shardID] { 95 | return errors.New("Cannot heartbeat on lock not originally acquired") 96 | } 97 | 98 | var ( 99 | lastHeartbeat time.Time 100 | ok bool 101 | ) 102 | 103 | func() { 104 | p.heartbeatsMut.RLock() 105 | defer p.heartbeatsMut.RUnlock() 106 | lastHeartbeat, ok = p.heartbeats[shardID] 107 | }() 108 | 109 | if !ok { 110 | lastHeartbeat = time.Now().Add(-(p.ttl + time.Second)) 111 | } 112 | 113 | now := time.Now() 114 | 115 | if 2*(now.Sub(lastHeartbeat)) < p.ttl { 116 | return nil 117 | } 118 | 119 | conn := p.pool.Get() 120 | defer conn.Close() 121 | 122 | lockKey := p.redisPrefix + ":lock:" + shardID 123 | 124 | res, err := conn.Do("GET", lockKey) 125 | if err != nil { 126 | return err 127 | } 128 | 129 | lock, err := redis.String(res, err) 130 | if lock == "" { 131 | return p.TryAcquire(shardID) 132 | } 133 | if lock != p.lock { 134 | return errors.New("Lock changed from " + p.lock + " to " + lock) 135 | } 136 | 137 | res, err = conn.Do("PEXPIRE", lockKey, int64(p.ttl/time.Millisecond)) 138 | if err != nil { 139 | err := p.TryAcquire(shardID) 140 | if err != nil { 141 | return err 142 | } 143 | } 144 | 145 | p.heartbeatsMut.Lock() 146 | defer p.heartbeatsMut.Unlock() 147 | p.heartbeats[shardID] = now 148 | 149 | return nil 150 | } 151 | 152 | func (p *Provisioner) TTL() time.Duration { 153 | return p.ttl 154 | } 155 | -------------------------------------------------------------------------------- /provisioners/redis/provisioner_test.go: -------------------------------------------------------------------------------- 1 | package redisprovisioner 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/remind101/kinesumer/redispool" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func makeProvisioner() *Provisioner { 12 | pool, err := redispool.NewRedisPool("redis://127.0.0.1:6379") 13 | if err != nil { 14 | panic(err) 15 | } 16 | 17 | conn := pool.Get() 18 | defer conn.Close() 19 | 20 | conn.Do("DEL", "testing:lock:shard0") 21 | 22 | prov, err := New(&Options{ 23 | TTL: time.Second, 24 | RedisPool: pool, 25 | RedisPrefix: "testing", 26 | Lock: "lock", 27 | }) 28 | if err != nil { 29 | panic(err) 30 | } 31 | 32 | return prov 33 | } 34 | 35 | func TestProvisionerTryAcquire(t *testing.T) { 36 | p := makeProvisioner() 37 | assert.NoError(t, p.TryAcquire("shard0"), "Couldn't acquire lock") 38 | 39 | assert.Error(t, p.TryAcquire("shard0"), "Acquired lock") 40 | } 41 | 42 | func TestProvisionerRelease(t *testing.T) { 43 | p := makeProvisioner() 44 | assert.NoError(t, p.TryAcquire("shard0"), "Couldn't acquire lock") 45 | 46 | assert.NoError(t, p.Release("shard0"), "Couldn't release lock") 47 | 48 | assert.NoError(t, p.TryAcquire("shard0"), "Couldn't reacquire lock") 49 | } 50 | 51 | func TestProvisionerHeartbeat(t *testing.T) { 52 | p := makeProvisioner() 53 | err := p.Heartbeat("shard0") 54 | assert.Error(t, err, "managed to heartbeat without acquiring lock") 55 | 56 | assert.NoError(t, p.TryAcquire("shard0"), "Couldn't acquire lock") 57 | 58 | assert.NoError(t, p.Heartbeat("shard0"), "Couldn't heartbeat") 59 | 60 | assert.Equal(t, 1, len(p.heartbeats)) 61 | } 62 | -------------------------------------------------------------------------------- /reader.go: -------------------------------------------------------------------------------- 1 | package kinesumer 2 | 3 | import ( 4 | "io" 5 | 6 | k "github.com/remind101/kinesumer/interface" 7 | ) 8 | 9 | // Reader provides an io.Reader implementation that can read data from a kinesis 10 | // stream. 11 | type Reader struct { 12 | records <-chan k.Record 13 | 14 | // buffered data for the current record. 15 | buf []byte 16 | // done is called when the current buffer is fully consumed. 17 | done func() 18 | } 19 | 20 | // NewReader returns a new Reader instance that reads data from records. 21 | func NewReader(records <-chan k.Record) *Reader { 22 | return &Reader{records: records} 23 | } 24 | 25 | // Read implements io.Reader Read. Read will copy <= len(b) bytes from the kinesis 26 | // stream into b. 27 | func (r *Reader) Read(b []byte) (n int, err error) { 28 | for { 29 | // If there's no data in the buffer, we'll grab the next record 30 | // and set the internal buffer to point to the data in that 31 | // record. When all data from buf is read, Done() will be called 32 | // on the record. 33 | if len(r.buf) == 0 { 34 | select { 35 | case record, ok := <-r.records: 36 | if !ok { 37 | // Channel is closed, return io.EOF. 38 | err = io.EOF 39 | return 40 | } 41 | 42 | r.buf = record.Data() 43 | r.done = record.Done 44 | default: 45 | // By convention, Read should return rather than wait 46 | // for data to become available. If no data is available 47 | // at this time, we'll return what we've copied 48 | // so far. 49 | return 50 | } 51 | } 52 | 53 | n += r.copy(b[n:]) 54 | if n == len(b) { 55 | return 56 | } 57 | } 58 | 59 | return 60 | } 61 | 62 | // copy copies as much as it can from r.buf into b. If it succeeds in copying 63 | // all of the data, r.done is called. 64 | func (r *Reader) copy(b []byte) (n int) { 65 | n += copy(b, r.buf) 66 | if len(r.buf) >= n { 67 | // If there's still some buffered data left, truncate the buffer 68 | // and return. 69 | r.buf = r.buf[n:] 70 | } 71 | 72 | if len(r.buf) == 0 { 73 | r.done() 74 | } 75 | 76 | return 77 | } 78 | -------------------------------------------------------------------------------- /reader_test.go: -------------------------------------------------------------------------------- 1 | package kinesumer 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "testing" 7 | 8 | k "github.com/remind101/kinesumer/interface" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestReader_Read_NoData(t *testing.T) { 13 | ch := make(chan k.Record) 14 | r := NewReader(ch) 15 | 16 | b := make([]byte, 1) 17 | n, err := r.Read(b) 18 | assert.Nil(t, err) 19 | assert.Equal(t, 0, n) 20 | } 21 | 22 | func TestReader_Read_SingleByte(t *testing.T) { 23 | ch := make(chan k.Record, 1) 24 | checkpointC := make(chan k.Record, 1) 25 | r := NewReader(ch) 26 | 27 | // Check that we can read a single byte into a byte slice of size 1. 28 | record := &Record{data: []byte{0x01}, checkpointC: checkpointC} 29 | ch <- record 30 | b := make([]byte, 1) 31 | 32 | n, err := r.Read(b) 33 | assert.Nil(t, err) 34 | assert.Equal(t, 1, n) 35 | assert.Equal(t, []byte{0x01}, b) 36 | assertCheckpointed(t, checkpointC, record) 37 | } 38 | 39 | func TestReader_Read_SmallBuffer(t *testing.T) { 40 | ch := make(chan k.Record, 1) 41 | checkpointC := make(chan k.Record, 1) 42 | r := NewReader(ch) 43 | 44 | // Check that, if the record has more data than the size of the buffer 45 | // we're provided, we buffer the data. 46 | record := &Record{data: []byte{0x01, 0x02}, checkpointC: checkpointC} 47 | ch <- record 48 | b := make([]byte, 1) 49 | 50 | n, err := r.Read(b) 51 | assert.Nil(t, err) 52 | assert.Equal(t, 1, n) 53 | assert.Equal(t, []byte{0x01}, b) 54 | assertNotCheckpointed(t, checkpointC) 55 | 56 | n, err = r.Read(b) 57 | assert.Nil(t, err) 58 | assert.Equal(t, 1, n) 59 | assert.Equal(t, []byte{0x02}, b) 60 | assertCheckpointed(t, checkpointC, record) 61 | } 62 | 63 | func TestReader_Read_LargeBuffer(t *testing.T) { 64 | ch := make(chan k.Record, 2) 65 | checkpointC := make(chan k.Record, 2) 66 | r := NewReader(ch) 67 | 68 | record := &Record{data: []byte{0x01}, checkpointC: checkpointC} 69 | ch <- record 70 | b := make([]byte, 2) 71 | 72 | n, err := r.Read(b) 73 | assert.Nil(t, err) 74 | assert.Equal(t, 1, n) 75 | assert.Equal(t, []byte{0x01, 0x00}, b) 76 | assertCheckpointed(t, checkpointC, record) 77 | 78 | record = &Record{data: []byte{0x01}, checkpointC: checkpointC} 79 | ch <- record 80 | n, err = r.Read(b) 81 | assert.Nil(t, err) 82 | assert.Equal(t, 1, n) 83 | assert.Equal(t, []byte{0x01, 0x00}, b) 84 | assertCheckpointed(t, checkpointC, record) 85 | } 86 | 87 | func TestReader_Read_MultipleRecords(t *testing.T) { 88 | ch := make(chan k.Record, 2) 89 | checkpointC := make(chan k.Record, 2) 90 | r := NewReader(ch) 91 | 92 | record1 := &Record{data: []byte{0x01}, checkpointC: checkpointC} 93 | ch <- record1 94 | record2 := &Record{data: []byte{0x02}, checkpointC: checkpointC} 95 | ch <- record2 96 | 97 | b := make([]byte, 2) 98 | n, err := r.Read(b) 99 | assert.Nil(t, err) 100 | assert.Equal(t, 2, n) 101 | assert.Equal(t, []byte{0x01, 0x02}, b) 102 | 103 | assertCheckpointed(t, checkpointC, record1) 104 | assertCheckpointed(t, checkpointC, record2) 105 | } 106 | 107 | func TestReader_Read_Copy(t *testing.T) { 108 | ch := make(chan k.Record, 2) 109 | checkpointC := make(chan k.Record, 2) 110 | r := NewReader(ch) 111 | 112 | ch <- &Record{data: []byte{'a'}, checkpointC: checkpointC} 113 | ch <- &Record{data: []byte{'b'}, checkpointC: checkpointC} 114 | close(ch) 115 | 116 | b := new(bytes.Buffer) 117 | 118 | _, err := io.Copy(b, r) 119 | assert.Nil(t, err) 120 | assert.Equal(t, "ab", b.String()) 121 | } 122 | 123 | func assertCheckpointed(t testing.TB, checkpointC chan k.Record, record k.Record) { 124 | select { 125 | case r := <-checkpointC: 126 | assert.Equal(t, record, r) 127 | default: 128 | t.Fatalf("Expected Done to be called on record: %v", record) 129 | } 130 | } 131 | 132 | func assertNotCheckpointed(t testing.TB, checkpointC chan k.Record) { 133 | select { 134 | case <-checkpointC: 135 | t.Fatal("Expected no checkpoint") 136 | default: 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /record.go: -------------------------------------------------------------------------------- 1 | package kinesumer 2 | 3 | import ( 4 | k "github.com/remind101/kinesumer/interface" 5 | ) 6 | 7 | type Record struct { 8 | data []byte 9 | partitionKey string 10 | sequenceNumber string 11 | shardId string 12 | millisBehindLatest int64 13 | checkpointC chan<- k.Record 14 | } 15 | 16 | func (r *Record) Data() []byte { 17 | return r.data 18 | } 19 | 20 | func (r *Record) PartitionKey() string { 21 | return r.partitionKey 22 | } 23 | 24 | func (r *Record) SequenceNumber() string { 25 | return r.sequenceNumber 26 | } 27 | 28 | func (r *Record) ShardId() string { 29 | return r.shardId 30 | } 31 | 32 | func (r *Record) MillisBehindLatest() int64 { 33 | return r.millisBehindLatest 34 | } 35 | 36 | func (r *Record) Done() { 37 | if r.checkpointC != nil { 38 | r.checkpointC <- r 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /redispool/redis.go: -------------------------------------------------------------------------------- 1 | package redispool 2 | 3 | import ( 4 | "net/url" 5 | "time" 6 | 7 | "github.com/garyburd/redigo/redis" 8 | ) 9 | 10 | func newPool(server, password string) *redis.Pool { 11 | return &redis.Pool{ 12 | MaxIdle: 10, 13 | MaxActive: 100, 14 | IdleTimeout: 240 * time.Second, 15 | Dial: func() (redis.Conn, error) { 16 | c, err := redis.Dial("tcp", server) 17 | if err != nil { 18 | return nil, err 19 | } 20 | if password != "" { 21 | if _, err := c.Do("AUTH", password); err != nil { 22 | c.Close() 23 | return nil, err 24 | } 25 | } 26 | return c, err 27 | }, 28 | TestOnBorrow: func(c redis.Conn, t time.Time) error { 29 | _, err := c.Do("PING") 30 | return err 31 | }, 32 | } 33 | } 34 | 35 | // redis://x:passwd@host:port 36 | func NewRedisPool(connstr string) (*redis.Pool, error) { 37 | 38 | u, err := url.Parse(connstr) 39 | if err != nil { 40 | return nil, err 41 | } 42 | 43 | // auth if necessary 44 | passwd := "" 45 | if u.User != nil { 46 | passwd, _ = u.User.Password() 47 | } 48 | 49 | pool := newPool(u.Host, passwd) 50 | 51 | return pool, nil 52 | } 53 | -------------------------------------------------------------------------------- /unit.go: -------------------------------------------------------------------------------- 1 | package kinesumer 2 | 3 | // Unit has only one possible value, Unit{}, and is used to make signal channels to tell the workers 4 | // when to stop 5 | type Unit struct{} 6 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/NOTICE.txt: -------------------------------------------------------------------------------- 1 | AWS SDK for Go 2 | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | Copyright 2014-2015 Stripe, Inc. 4 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go: -------------------------------------------------------------------------------- 1 | package awsutil 2 | 3 | import ( 4 | "io" 5 | "reflect" 6 | ) 7 | 8 | // Copy deeply copies a src structure to dst. Useful for copying request and 9 | // response structures. 10 | // 11 | // Can copy between structs of different type, but will only copy fields which 12 | // are assignable, and exist in both structs. Fields which are not assignable, 13 | // or do not exist in both structs are ignored. 14 | func Copy(dst, src interface{}) { 15 | dstval := reflect.ValueOf(dst) 16 | if !dstval.IsValid() { 17 | panic("Copy dst cannot be nil") 18 | } 19 | 20 | rcopy(dstval, reflect.ValueOf(src), true) 21 | } 22 | 23 | // CopyOf returns a copy of src while also allocating the memory for dst. 24 | // src must be a pointer type or this operation will fail. 25 | func CopyOf(src interface{}) (dst interface{}) { 26 | dsti := reflect.New(reflect.TypeOf(src).Elem()) 27 | dst = dsti.Interface() 28 | rcopy(dsti, reflect.ValueOf(src), true) 29 | return 30 | } 31 | 32 | // rcopy performs a recursive copy of values from the source to destination. 33 | // 34 | // root is used to skip certain aspects of the copy which are not valid 35 | // for the root node of a object. 36 | func rcopy(dst, src reflect.Value, root bool) { 37 | if !src.IsValid() { 38 | return 39 | } 40 | 41 | switch src.Kind() { 42 | case reflect.Ptr: 43 | if _, ok := src.Interface().(io.Reader); ok { 44 | if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() { 45 | dst.Elem().Set(src) 46 | } else if dst.CanSet() { 47 | dst.Set(src) 48 | } 49 | } else { 50 | e := src.Type().Elem() 51 | if dst.CanSet() && !src.IsNil() { 52 | dst.Set(reflect.New(e)) 53 | } 54 | if src.Elem().IsValid() { 55 | // Keep the current root state since the depth hasn't changed 56 | rcopy(dst.Elem(), src.Elem(), root) 57 | } 58 | } 59 | case reflect.Struct: 60 | t := dst.Type() 61 | for i := 0; i < t.NumField(); i++ { 62 | name := t.Field(i).Name 63 | srcVal := src.FieldByName(name) 64 | dstVal := dst.FieldByName(name) 65 | if srcVal.IsValid() && dstVal.CanSet() { 66 | rcopy(dstVal, srcVal, false) 67 | } 68 | } 69 | case reflect.Slice: 70 | if src.IsNil() { 71 | break 72 | } 73 | 74 | s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap()) 75 | dst.Set(s) 76 | for i := 0; i < src.Len(); i++ { 77 | rcopy(dst.Index(i), src.Index(i), false) 78 | } 79 | case reflect.Map: 80 | if src.IsNil() { 81 | break 82 | } 83 | 84 | s := reflect.MakeMap(src.Type()) 85 | dst.Set(s) 86 | for _, k := range src.MapKeys() { 87 | v := src.MapIndex(k) 88 | v2 := reflect.New(v.Type()).Elem() 89 | rcopy(v2, v, false) 90 | dst.SetMapIndex(k, v2) 91 | } 92 | default: 93 | // Assign the value if possible. If its not assignable, the value would 94 | // need to be converted and the impact of that may be unexpected, or is 95 | // not compatible with the dst type. 96 | if src.Type().AssignableTo(dst.Type()) { 97 | dst.Set(src) 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go: -------------------------------------------------------------------------------- 1 | package awsutil 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | // DeepEqual returns if the two values are deeply equal like reflect.DeepEqual. 8 | // In addition to this, this method will also dereference the input values if 9 | // possible so the DeepEqual performed will not fail if one parameter is a 10 | // pointer and the other is not. 11 | // 12 | // DeepEqual will not perform indirection of nested values of the input parameters. 13 | func DeepEqual(a, b interface{}) bool { 14 | ra := reflect.Indirect(reflect.ValueOf(a)) 15 | rb := reflect.Indirect(reflect.ValueOf(b)) 16 | 17 | if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid { 18 | // If the elements are both nil, and of the same type the are equal 19 | // If they are of different types they are not equal 20 | return reflect.TypeOf(a) == reflect.TypeOf(b) 21 | } else if raValid != rbValid { 22 | // Both values must be valid to be equal 23 | return false 24 | } 25 | 26 | return reflect.DeepEqual(ra.Interface(), rb.Interface()) 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go: -------------------------------------------------------------------------------- 1 | package awsutil 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "reflect" 8 | "strings" 9 | ) 10 | 11 | // Prettify returns the string representation of a value. 12 | func Prettify(i interface{}) string { 13 | var buf bytes.Buffer 14 | prettify(reflect.ValueOf(i), 0, &buf) 15 | return buf.String() 16 | } 17 | 18 | // prettify will recursively walk value v to build a textual 19 | // representation of the value. 20 | func prettify(v reflect.Value, indent int, buf *bytes.Buffer) { 21 | for v.Kind() == reflect.Ptr { 22 | v = v.Elem() 23 | } 24 | 25 | switch v.Kind() { 26 | case reflect.Struct: 27 | strtype := v.Type().String() 28 | if strtype == "time.Time" { 29 | fmt.Fprintf(buf, "%s", v.Interface()) 30 | break 31 | } else if strings.HasPrefix(strtype, "io.") { 32 | buf.WriteString("") 33 | break 34 | } 35 | 36 | buf.WriteString("{\n") 37 | 38 | names := []string{} 39 | for i := 0; i < v.Type().NumField(); i++ { 40 | name := v.Type().Field(i).Name 41 | f := v.Field(i) 42 | if name[0:1] == strings.ToLower(name[0:1]) { 43 | continue // ignore unexported fields 44 | } 45 | if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() { 46 | continue // ignore unset fields 47 | } 48 | names = append(names, name) 49 | } 50 | 51 | for i, n := range names { 52 | val := v.FieldByName(n) 53 | buf.WriteString(strings.Repeat(" ", indent+2)) 54 | buf.WriteString(n + ": ") 55 | prettify(val, indent+2, buf) 56 | 57 | if i < len(names)-1 { 58 | buf.WriteString(",\n") 59 | } 60 | } 61 | 62 | buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") 63 | case reflect.Slice: 64 | nl, id, id2 := "", "", "" 65 | if v.Len() > 3 { 66 | nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) 67 | } 68 | buf.WriteString("[" + nl) 69 | for i := 0; i < v.Len(); i++ { 70 | buf.WriteString(id2) 71 | prettify(v.Index(i), indent+2, buf) 72 | 73 | if i < v.Len()-1 { 74 | buf.WriteString("," + nl) 75 | } 76 | } 77 | 78 | buf.WriteString(nl + id + "]") 79 | case reflect.Map: 80 | buf.WriteString("{\n") 81 | 82 | for i, k := range v.MapKeys() { 83 | buf.WriteString(strings.Repeat(" ", indent+2)) 84 | buf.WriteString(k.String() + ": ") 85 | prettify(v.MapIndex(k), indent+2, buf) 86 | 87 | if i < v.Len()-1 { 88 | buf.WriteString(",\n") 89 | } 90 | } 91 | 92 | buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") 93 | default: 94 | if !v.IsValid() { 95 | fmt.Fprint(buf, "") 96 | return 97 | } 98 | format := "%v" 99 | switch v.Interface().(type) { 100 | case string: 101 | format = "%q" 102 | case io.ReadSeeker, io.Reader: 103 | format = "buffer(%p)" 104 | } 105 | fmt.Fprintf(buf, format, v.Interface()) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go: -------------------------------------------------------------------------------- 1 | package awsutil 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "reflect" 7 | "strings" 8 | ) 9 | 10 | // StringValue returns the string representation of a value. 11 | func StringValue(i interface{}) string { 12 | var buf bytes.Buffer 13 | stringValue(reflect.ValueOf(i), 0, &buf) 14 | return buf.String() 15 | } 16 | 17 | func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) { 18 | for v.Kind() == reflect.Ptr { 19 | v = v.Elem() 20 | } 21 | 22 | switch v.Kind() { 23 | case reflect.Struct: 24 | buf.WriteString("{\n") 25 | 26 | names := []string{} 27 | for i := 0; i < v.Type().NumField(); i++ { 28 | name := v.Type().Field(i).Name 29 | f := v.Field(i) 30 | if name[0:1] == strings.ToLower(name[0:1]) { 31 | continue // ignore unexported fields 32 | } 33 | if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice) && f.IsNil() { 34 | continue // ignore unset fields 35 | } 36 | names = append(names, name) 37 | } 38 | 39 | for i, n := range names { 40 | val := v.FieldByName(n) 41 | buf.WriteString(strings.Repeat(" ", indent+2)) 42 | buf.WriteString(n + ": ") 43 | stringValue(val, indent+2, buf) 44 | 45 | if i < len(names)-1 { 46 | buf.WriteString(",\n") 47 | } 48 | } 49 | 50 | buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") 51 | case reflect.Slice: 52 | nl, id, id2 := "", "", "" 53 | if v.Len() > 3 { 54 | nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) 55 | } 56 | buf.WriteString("[" + nl) 57 | for i := 0; i < v.Len(); i++ { 58 | buf.WriteString(id2) 59 | stringValue(v.Index(i), indent+2, buf) 60 | 61 | if i < v.Len()-1 { 62 | buf.WriteString("," + nl) 63 | } 64 | } 65 | 66 | buf.WriteString(nl + id + "]") 67 | case reflect.Map: 68 | buf.WriteString("{\n") 69 | 70 | for i, k := range v.MapKeys() { 71 | buf.WriteString(strings.Repeat(" ", indent+2)) 72 | buf.WriteString(k.String() + ": ") 73 | stringValue(v.MapIndex(k), indent+2, buf) 74 | 75 | if i < v.Len()-1 { 76 | buf.WriteString(",\n") 77 | } 78 | } 79 | 80 | buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") 81 | default: 82 | format := "%v" 83 | switch v.Interface().(type) { 84 | case string: 85 | format = "%q" 86 | } 87 | fmt.Fprintf(buf, format, v.Interface()) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/client/client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net/http/httputil" 7 | 8 | "github.com/aws/aws-sdk-go/aws" 9 | "github.com/aws/aws-sdk-go/aws/client/metadata" 10 | "github.com/aws/aws-sdk-go/aws/request" 11 | ) 12 | 13 | // A Config provides configuration to a service client instance. 14 | type Config struct { 15 | Config *aws.Config 16 | Handlers request.Handlers 17 | Endpoint, SigningRegion string 18 | } 19 | 20 | // ConfigProvider provides a generic way for a service client to receive 21 | // the ClientConfig without circular dependencies. 22 | type ConfigProvider interface { 23 | ClientConfig(serviceName string, cfgs ...*aws.Config) Config 24 | } 25 | 26 | // A Client implements the base client request and response handling 27 | // used by all service clients. 28 | type Client struct { 29 | request.Retryer 30 | metadata.ClientInfo 31 | 32 | Config aws.Config 33 | Handlers request.Handlers 34 | } 35 | 36 | // New will return a pointer to a new initialized service client. 37 | func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, options ...func(*Client)) *Client { 38 | svc := &Client{ 39 | Config: cfg, 40 | ClientInfo: info, 41 | Handlers: handlers, 42 | } 43 | 44 | switch retryer, ok := cfg.Retryer.(request.Retryer); { 45 | case ok: 46 | svc.Retryer = retryer 47 | case cfg.Retryer != nil && cfg.Logger != nil: 48 | s := fmt.Sprintf("WARNING: %T does not implement request.Retryer; using DefaultRetryer instead", cfg.Retryer) 49 | cfg.Logger.Log(s) 50 | fallthrough 51 | default: 52 | maxRetries := aws.IntValue(cfg.MaxRetries) 53 | if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries { 54 | maxRetries = 3 55 | } 56 | svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries} 57 | } 58 | 59 | svc.AddDebugHandlers() 60 | 61 | for _, option := range options { 62 | option(svc) 63 | } 64 | 65 | return svc 66 | } 67 | 68 | // NewRequest returns a new Request pointer for the service API 69 | // operation and parameters. 70 | func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request { 71 | return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data) 72 | } 73 | 74 | // AddDebugHandlers injects debug logging handlers into the service to log request 75 | // debug information. 76 | func (c *Client) AddDebugHandlers() { 77 | if !c.Config.LogLevel.AtLeast(aws.LogDebug) { 78 | return 79 | } 80 | 81 | c.Handlers.Send.PushFront(logRequest) 82 | c.Handlers.Send.PushBack(logResponse) 83 | } 84 | 85 | const logReqMsg = `DEBUG: Request %s/%s Details: 86 | ---[ REQUEST POST-SIGN ]----------------------------- 87 | %s 88 | -----------------------------------------------------` 89 | 90 | func logRequest(r *request.Request) { 91 | logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) 92 | dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody) 93 | 94 | if logBody { 95 | // Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's 96 | // Body as a NoOpCloser and will not be reset after read by the HTTP 97 | // client reader. 98 | r.Body.Seek(r.BodyStart, 0) 99 | r.HTTPRequest.Body = ioutil.NopCloser(r.Body) 100 | } 101 | 102 | r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody))) 103 | } 104 | 105 | const logRespMsg = `DEBUG: Response %s/%s Details: 106 | ---[ RESPONSE ]-------------------------------------- 107 | %s 108 | -----------------------------------------------------` 109 | 110 | func logResponse(r *request.Request) { 111 | var msg = "no response data" 112 | if r.HTTPResponse != nil { 113 | logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) 114 | dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody) 115 | msg = string(dumpedBody) 116 | } else if r.Error != nil { 117 | msg = r.Error.Error() 118 | } 119 | r.Config.Logger.Log(fmt.Sprintf(logRespMsg, r.ClientInfo.ServiceName, r.Operation.Name, msg)) 120 | } 121 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "math/rand" 5 | "sync" 6 | "time" 7 | 8 | "github.com/aws/aws-sdk-go/aws/request" 9 | ) 10 | 11 | // DefaultRetryer implements basic retry logic using exponential backoff for 12 | // most services. If you want to implement custom retry logic, implement the 13 | // request.Retryer interface or create a structure type that composes this 14 | // struct and override the specific methods. For example, to override only 15 | // the MaxRetries method: 16 | // 17 | // type retryer struct { 18 | // service.DefaultRetryer 19 | // } 20 | // 21 | // // This implementation always has 100 max retries 22 | // func (d retryer) MaxRetries() uint { return 100 } 23 | type DefaultRetryer struct { 24 | NumMaxRetries int 25 | } 26 | 27 | // MaxRetries returns the number of maximum returns the service will use to make 28 | // an individual API request. 29 | func (d DefaultRetryer) MaxRetries() int { 30 | return d.NumMaxRetries 31 | } 32 | 33 | var seededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())}) 34 | 35 | // RetryRules returns the delay duration before retrying this request again 36 | func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration { 37 | // Set the upper limit of delay in retrying at ~five minutes 38 | minTime := 30 39 | throttle := d.shouldThrottle(r) 40 | if throttle { 41 | minTime = 500 42 | } 43 | 44 | retryCount := r.RetryCount 45 | if retryCount > 13 { 46 | retryCount = 13 47 | } else if throttle && retryCount > 8 { 48 | retryCount = 8 49 | } 50 | 51 | delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime) 52 | return time.Duration(delay) * time.Millisecond 53 | } 54 | 55 | // ShouldRetry returns true if the request should be retried. 56 | func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { 57 | if r.HTTPResponse.StatusCode >= 500 { 58 | return true 59 | } 60 | return r.IsErrorRetryable() || d.shouldThrottle(r) 61 | } 62 | 63 | // ShouldThrottle returns true if the request should be throttled. 64 | func (d DefaultRetryer) shouldThrottle(r *request.Request) bool { 65 | if r.HTTPResponse.StatusCode == 502 || 66 | r.HTTPResponse.StatusCode == 503 || 67 | r.HTTPResponse.StatusCode == 504 { 68 | return true 69 | } 70 | return r.IsErrorThrottle() 71 | } 72 | 73 | // lockedSource is a thread-safe implementation of rand.Source 74 | type lockedSource struct { 75 | lk sync.Mutex 76 | src rand.Source 77 | } 78 | 79 | func (r *lockedSource) Int63() (n int64) { 80 | r.lk.Lock() 81 | n = r.src.Int63() 82 | r.lk.Unlock() 83 | return 84 | } 85 | 86 | func (r *lockedSource) Seed(seed int64) { 87 | r.lk.Lock() 88 | r.src.Seed(seed) 89 | r.lk.Unlock() 90 | } 91 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go: -------------------------------------------------------------------------------- 1 | package metadata 2 | 3 | // ClientInfo wraps immutable data from the client.Client structure. 4 | type ClientInfo struct { 5 | ServiceName string 6 | APIVersion string 7 | Endpoint string 8 | SigningName string 9 | SigningRegion string 10 | JSONVersion string 11 | TargetPrefix string 12 | } 13 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go: -------------------------------------------------------------------------------- 1 | package corehandlers 2 | 3 | import "github.com/aws/aws-sdk-go/aws/request" 4 | 5 | // ValidateParametersHandler is a request handler to validate the input parameters. 6 | // Validating parameters only has meaning if done prior to the request being sent. 7 | var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) { 8 | if !r.ParamsFilled() { 9 | return 10 | } 11 | 12 | if v, ok := r.Params.(request.Validator); ok { 13 | if err := v.Validate(); err != nil { 14 | r.Error = err 15 | } 16 | } 17 | }} 18 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go: -------------------------------------------------------------------------------- 1 | package credentials 2 | 3 | import ( 4 | "github.com/aws/aws-sdk-go/aws/awserr" 5 | ) 6 | 7 | var ( 8 | // ErrNoValidProvidersFoundInChain Is returned when there are no valid 9 | // providers in the ChainProvider. 10 | // 11 | // This has been deprecated. For verbose error messaging set 12 | // aws.Config.CredentialsChainVerboseErrors to true 13 | // 14 | // @readonly 15 | ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders", 16 | `no valid providers in chain. Deprecated. 17 | For verbose messaging see aws.Config.CredentialsChainVerboseErrors`, 18 | nil) 19 | ) 20 | 21 | // A ChainProvider will search for a provider which returns credentials 22 | // and cache that provider until Retrieve is called again. 23 | // 24 | // The ChainProvider provides a way of chaining multiple providers together 25 | // which will pick the first available using priority order of the Providers 26 | // in the list. 27 | // 28 | // If none of the Providers retrieve valid credentials Value, ChainProvider's 29 | // Retrieve() will return the error ErrNoValidProvidersFoundInChain. 30 | // 31 | // If a Provider is found which returns valid credentials Value ChainProvider 32 | // will cache that Provider for all calls to IsExpired(), until Retrieve is 33 | // called again. 34 | // 35 | // Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider. 36 | // In this example EnvProvider will first check if any credentials are available 37 | // vai the environment variables. If there are none ChainProvider will check 38 | // the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider 39 | // does not return any credentials ChainProvider will return the error 40 | // ErrNoValidProvidersFoundInChain 41 | // 42 | // creds := NewChainCredentials( 43 | // []Provider{ 44 | // &EnvProvider{}, 45 | // &EC2RoleProvider{ 46 | // Client: ec2metadata.New(sess), 47 | // }, 48 | // }) 49 | // 50 | // // Usage of ChainCredentials with aws.Config 51 | // svc := ec2.New(&aws.Config{Credentials: creds}) 52 | // 53 | type ChainProvider struct { 54 | Providers []Provider 55 | curr Provider 56 | VerboseErrors bool 57 | } 58 | 59 | // NewChainCredentials returns a pointer to a new Credentials object 60 | // wrapping a chain of providers. 61 | func NewChainCredentials(providers []Provider) *Credentials { 62 | return NewCredentials(&ChainProvider{ 63 | Providers: append([]Provider{}, providers...), 64 | }) 65 | } 66 | 67 | // Retrieve returns the credentials value or error if no provider returned 68 | // without error. 69 | // 70 | // If a provider is found it will be cached and any calls to IsExpired() 71 | // will return the expired state of the cached provider. 72 | func (c *ChainProvider) Retrieve() (Value, error) { 73 | var errs []error 74 | for _, p := range c.Providers { 75 | creds, err := p.Retrieve() 76 | if err == nil { 77 | c.curr = p 78 | return creds, nil 79 | } 80 | errs = append(errs, err) 81 | } 82 | c.curr = nil 83 | 84 | var err error 85 | err = ErrNoValidProvidersFoundInChain 86 | if c.VerboseErrors { 87 | err = awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs) 88 | } 89 | return Value{}, err 90 | } 91 | 92 | // IsExpired will returned the expired state of the currently cached provider 93 | // if there is one. If there is no current provider, true will be returned. 94 | func (c *ChainProvider) IsExpired() bool { 95 | if c.curr != nil { 96 | return c.curr.IsExpired() 97 | } 98 | 99 | return true 100 | } 101 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go: -------------------------------------------------------------------------------- 1 | package credentials 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/aws/aws-sdk-go/aws/awserr" 7 | ) 8 | 9 | // EnvProviderName provides a name of Env provider 10 | const EnvProviderName = "EnvProvider" 11 | 12 | var ( 13 | // ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be 14 | // found in the process's environment. 15 | // 16 | // @readonly 17 | ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil) 18 | 19 | // ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key 20 | // can't be found in the process's environment. 21 | // 22 | // @readonly 23 | ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil) 24 | ) 25 | 26 | // A EnvProvider retrieves credentials from the environment variables of the 27 | // running process. Environment credentials never expire. 28 | // 29 | // Environment variables used: 30 | // 31 | // * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY 32 | // * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY 33 | type EnvProvider struct { 34 | retrieved bool 35 | } 36 | 37 | // NewEnvCredentials returns a pointer to a new Credentials object 38 | // wrapping the environment variable provider. 39 | func NewEnvCredentials() *Credentials { 40 | return NewCredentials(&EnvProvider{}) 41 | } 42 | 43 | // Retrieve retrieves the keys from the environment. 44 | func (e *EnvProvider) Retrieve() (Value, error) { 45 | e.retrieved = false 46 | 47 | id := os.Getenv("AWS_ACCESS_KEY_ID") 48 | if id == "" { 49 | id = os.Getenv("AWS_ACCESS_KEY") 50 | } 51 | 52 | secret := os.Getenv("AWS_SECRET_ACCESS_KEY") 53 | if secret == "" { 54 | secret = os.Getenv("AWS_SECRET_KEY") 55 | } 56 | 57 | if id == "" { 58 | return Value{ProviderName: EnvProviderName}, ErrAccessKeyIDNotFound 59 | } 60 | 61 | if secret == "" { 62 | return Value{ProviderName: EnvProviderName}, ErrSecretAccessKeyNotFound 63 | } 64 | 65 | e.retrieved = true 66 | return Value{ 67 | AccessKeyID: id, 68 | SecretAccessKey: secret, 69 | SessionToken: os.Getenv("AWS_SESSION_TOKEN"), 70 | ProviderName: EnvProviderName, 71 | }, nil 72 | } 73 | 74 | // IsExpired returns if the credentials have been retrieved. 75 | func (e *EnvProvider) IsExpired() bool { 76 | return !e.retrieved 77 | } 78 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini: -------------------------------------------------------------------------------- 1 | [default] 2 | aws_access_key_id = accessKey 3 | aws_secret_access_key = secret 4 | aws_session_token = token 5 | 6 | [no_token] 7 | aws_access_key_id = accessKey 8 | aws_secret_access_key = secret 9 | 10 | [with_colon] 11 | aws_access_key_id: accessKey 12 | aws_secret_access_key: secret 13 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go: -------------------------------------------------------------------------------- 1 | package credentials 2 | 3 | import ( 4 | "github.com/aws/aws-sdk-go/aws/awserr" 5 | ) 6 | 7 | // StaticProviderName provides a name of Static provider 8 | const StaticProviderName = "StaticProvider" 9 | 10 | var ( 11 | // ErrStaticCredentialsEmpty is emitted when static credentials are empty. 12 | // 13 | // @readonly 14 | ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil) 15 | ) 16 | 17 | // A StaticProvider is a set of credentials which are set programmatically, 18 | // and will never expire. 19 | type StaticProvider struct { 20 | Value 21 | } 22 | 23 | // NewStaticCredentials returns a pointer to a new Credentials object 24 | // wrapping a static credentials value provider. 25 | func NewStaticCredentials(id, secret, token string) *Credentials { 26 | return NewCredentials(&StaticProvider{Value: Value{ 27 | AccessKeyID: id, 28 | SecretAccessKey: secret, 29 | SessionToken: token, 30 | }}) 31 | } 32 | 33 | // Retrieve returns the credentials or error if the credentials are invalid. 34 | func (s *StaticProvider) Retrieve() (Value, error) { 35 | if s.AccessKeyID == "" || s.SecretAccessKey == "" { 36 | return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty 37 | } 38 | 39 | s.Value.ProviderName = StaticProviderName 40 | return s.Value, nil 41 | } 42 | 43 | // IsExpired returns if the credentials are expired. 44 | // 45 | // For StaticProvider, the credentials never expired. 46 | func (s *StaticProvider) IsExpired() bool { 47 | return false 48 | } 49 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go: -------------------------------------------------------------------------------- 1 | // Package defaults is a collection of helpers to retrieve the SDK's default 2 | // configuration and handlers. 3 | // 4 | // Generally this package shouldn't be used directly, but session.Session 5 | // instead. This package is useful when you need to reset the defaults 6 | // of a session or service client to the SDK defaults before setting 7 | // additional parameters. 8 | package defaults 9 | 10 | import ( 11 | "net/http" 12 | "os" 13 | "time" 14 | 15 | "github.com/aws/aws-sdk-go/aws" 16 | "github.com/aws/aws-sdk-go/aws/corehandlers" 17 | "github.com/aws/aws-sdk-go/aws/credentials" 18 | "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" 19 | "github.com/aws/aws-sdk-go/aws/ec2metadata" 20 | "github.com/aws/aws-sdk-go/aws/request" 21 | "github.com/aws/aws-sdk-go/private/endpoints" 22 | ) 23 | 24 | // A Defaults provides a collection of default values for SDK clients. 25 | type Defaults struct { 26 | Config *aws.Config 27 | Handlers request.Handlers 28 | } 29 | 30 | // Get returns the SDK's default values with Config and handlers pre-configured. 31 | func Get() Defaults { 32 | cfg := Config() 33 | handlers := Handlers() 34 | cfg.Credentials = CredChain(cfg, handlers) 35 | 36 | return Defaults{ 37 | Config: cfg, 38 | Handlers: handlers, 39 | } 40 | } 41 | 42 | // Config returns the default configuration without credentials. 43 | // To retrieve a config with credentials also included use 44 | // `defaults.Get().Config` instead. 45 | // 46 | // Generally you shouldn't need to use this method directly, but 47 | // is available if you need to reset the configuration of an 48 | // existing service client or session. 49 | func Config() *aws.Config { 50 | return aws.NewConfig(). 51 | WithCredentials(credentials.AnonymousCredentials). 52 | WithRegion(os.Getenv("AWS_REGION")). 53 | WithHTTPClient(http.DefaultClient). 54 | WithMaxRetries(aws.UseServiceDefaultRetries). 55 | WithLogger(aws.NewDefaultLogger()). 56 | WithLogLevel(aws.LogOff). 57 | WithSleepDelay(time.Sleep) 58 | } 59 | 60 | // Handlers returns the default request handlers. 61 | // 62 | // Generally you shouldn't need to use this method directly, but 63 | // is available if you need to reset the request handlers of an 64 | // existing service client or session. 65 | func Handlers() request.Handlers { 66 | var handlers request.Handlers 67 | 68 | handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler) 69 | handlers.Validate.AfterEachFn = request.HandlerListStopOnError 70 | handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler) 71 | handlers.Build.AfterEachFn = request.HandlerListStopOnError 72 | handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler) 73 | handlers.Send.PushBackNamed(corehandlers.SendHandler) 74 | handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) 75 | handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler) 76 | 77 | return handlers 78 | } 79 | 80 | // CredChain returns the default credential chain. 81 | // 82 | // Generally you shouldn't need to use this method directly, but 83 | // is available if you need to reset the credentials of an 84 | // existing service client or session's Config. 85 | func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials { 86 | endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, *cfg.Region, true) 87 | 88 | return credentials.NewCredentials(&credentials.ChainProvider{ 89 | VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), 90 | Providers: []credentials.Provider{ 91 | &credentials.EnvProvider{}, 92 | &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, 93 | &ec2rolecreds.EC2RoleProvider{ 94 | Client: ec2metadata.NewClient(*cfg, handlers, endpoint, signingRegion), 95 | ExpiryWindow: 5 * time.Minute, 96 | }, 97 | }}) 98 | } 99 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go: -------------------------------------------------------------------------------- 1 | // Package ec2metadata provides the client for making API calls to the 2 | // EC2 Metadata service. 3 | package ec2metadata 4 | 5 | import ( 6 | "bytes" 7 | "errors" 8 | "io" 9 | "net/http" 10 | "time" 11 | 12 | "github.com/aws/aws-sdk-go/aws" 13 | "github.com/aws/aws-sdk-go/aws/awserr" 14 | "github.com/aws/aws-sdk-go/aws/client" 15 | "github.com/aws/aws-sdk-go/aws/client/metadata" 16 | "github.com/aws/aws-sdk-go/aws/request" 17 | ) 18 | 19 | // ServiceName is the name of the service. 20 | const ServiceName = "ec2metadata" 21 | 22 | // A EC2Metadata is an EC2 Metadata service Client. 23 | type EC2Metadata struct { 24 | *client.Client 25 | } 26 | 27 | // New creates a new instance of the EC2Metadata client with a session. 28 | // This client is safe to use across multiple goroutines. 29 | // 30 | // 31 | // Example: 32 | // // Create a EC2Metadata client from just a session. 33 | // svc := ec2metadata.New(mySession) 34 | // 35 | // // Create a EC2Metadata client with additional configuration 36 | // svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody)) 37 | func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata { 38 | c := p.ClientConfig(ServiceName, cfgs...) 39 | return NewClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion) 40 | } 41 | 42 | // NewClient returns a new EC2Metadata client. Should be used to create 43 | // a client when not using a session. Generally using just New with a session 44 | // is preferred. 45 | // 46 | // If an unmodified HTTP client is provided from the stdlib default, or no client 47 | // the EC2RoleProvider's EC2Metadata HTTP client's timeout will be shortened. 48 | // To disable this set Config.EC2MetadataDisableTimeoutOverride to false. Enabled by default. 49 | func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string, opts ...func(*client.Client)) *EC2Metadata { 50 | if !aws.BoolValue(cfg.EC2MetadataDisableTimeoutOverride) && httpClientZero(cfg.HTTPClient) { 51 | // If the http client is unmodified and this feature is not disabled 52 | // set custom timeouts for EC2Metadata requests. 53 | cfg.HTTPClient = &http.Client{ 54 | // use a shorter timeout than default because the metadata 55 | // service is local if it is running, and to fail faster 56 | // if not running on an ec2 instance. 57 | Timeout: 5 * time.Second, 58 | } 59 | } 60 | 61 | svc := &EC2Metadata{ 62 | Client: client.New( 63 | cfg, 64 | metadata.ClientInfo{ 65 | ServiceName: ServiceName, 66 | Endpoint: endpoint, 67 | APIVersion: "latest", 68 | }, 69 | handlers, 70 | ), 71 | } 72 | 73 | svc.Handlers.Unmarshal.PushBack(unmarshalHandler) 74 | svc.Handlers.UnmarshalError.PushBack(unmarshalError) 75 | svc.Handlers.Validate.Clear() 76 | svc.Handlers.Validate.PushBack(validateEndpointHandler) 77 | 78 | // Add additional options to the service config 79 | for _, option := range opts { 80 | option(svc.Client) 81 | } 82 | 83 | return svc 84 | } 85 | 86 | func httpClientZero(c *http.Client) bool { 87 | return c == nil || (c.Transport == nil && c.CheckRedirect == nil && c.Jar == nil && c.Timeout == 0) 88 | } 89 | 90 | type metadataOutput struct { 91 | Content string 92 | } 93 | 94 | func unmarshalHandler(r *request.Request) { 95 | defer r.HTTPResponse.Body.Close() 96 | b := &bytes.Buffer{} 97 | if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { 98 | r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err) 99 | return 100 | } 101 | 102 | if data, ok := r.Data.(*metadataOutput); ok { 103 | data.Content = b.String() 104 | } 105 | } 106 | 107 | func unmarshalError(r *request.Request) { 108 | defer r.HTTPResponse.Body.Close() 109 | b := &bytes.Buffer{} 110 | if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { 111 | r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err) 112 | return 113 | } 114 | 115 | // Response body format is not consistent between metadata endpoints. 116 | // Grab the error message as a string and include that as the source error 117 | r.Error = awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String())) 118 | } 119 | 120 | func validateEndpointHandler(r *request.Request) { 121 | if r.ClientInfo.Endpoint == "" { 122 | r.Error = aws.ErrMissingEndpoint 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/errors.go: -------------------------------------------------------------------------------- 1 | package aws 2 | 3 | import "github.com/aws/aws-sdk-go/aws/awserr" 4 | 5 | var ( 6 | // ErrMissingRegion is an error that is returned if region configuration is 7 | // not found. 8 | // 9 | // @readonly 10 | ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil) 11 | 12 | // ErrMissingEndpoint is an error that is returned if an endpoint cannot be 13 | // resolved for a service. 14 | // 15 | // @readonly 16 | ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil) 17 | ) 18 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/logger.go: -------------------------------------------------------------------------------- 1 | package aws 2 | 3 | import ( 4 | "log" 5 | "os" 6 | ) 7 | 8 | // A LogLevelType defines the level logging should be performed at. Used to instruct 9 | // the SDK which statements should be logged. 10 | type LogLevelType uint 11 | 12 | // LogLevel returns the pointer to a LogLevel. Should be used to workaround 13 | // not being able to take the address of a non-composite literal. 14 | func LogLevel(l LogLevelType) *LogLevelType { 15 | return &l 16 | } 17 | 18 | // Value returns the LogLevel value or the default value LogOff if the LogLevel 19 | // is nil. Safe to use on nil value LogLevelTypes. 20 | func (l *LogLevelType) Value() LogLevelType { 21 | if l != nil { 22 | return *l 23 | } 24 | return LogOff 25 | } 26 | 27 | // Matches returns true if the v LogLevel is enabled by this LogLevel. Should be 28 | // used with logging sub levels. Is safe to use on nil value LogLevelTypes. If 29 | // LogLevel is nill, will default to LogOff comparison. 30 | func (l *LogLevelType) Matches(v LogLevelType) bool { 31 | c := l.Value() 32 | return c&v == v 33 | } 34 | 35 | // AtLeast returns true if this LogLevel is at least high enough to satisfies v. 36 | // Is safe to use on nil value LogLevelTypes. If LogLevel is nill, will default 37 | // to LogOff comparison. 38 | func (l *LogLevelType) AtLeast(v LogLevelType) bool { 39 | c := l.Value() 40 | return c >= v 41 | } 42 | 43 | const ( 44 | // LogOff states that no logging should be performed by the SDK. This is the 45 | // default state of the SDK, and should be use to disable all logging. 46 | LogOff LogLevelType = iota * 0x1000 47 | 48 | // LogDebug state that debug output should be logged by the SDK. This should 49 | // be used to inspect request made and responses received. 50 | LogDebug 51 | ) 52 | 53 | // Debug Logging Sub Levels 54 | const ( 55 | // LogDebugWithSigning states that the SDK should log request signing and 56 | // presigning events. This should be used to log the signing details of 57 | // requests for debugging. Will also enable LogDebug. 58 | LogDebugWithSigning LogLevelType = LogDebug | (1 << iota) 59 | 60 | // LogDebugWithHTTPBody states the SDK should log HTTP request and response 61 | // HTTP bodys in addition to the headers and path. This should be used to 62 | // see the body content of requests and responses made while using the SDK 63 | // Will also enable LogDebug. 64 | LogDebugWithHTTPBody 65 | 66 | // LogDebugWithRequestRetries states the SDK should log when service requests will 67 | // be retried. This should be used to log when you want to log when service 68 | // requests are being retried. Will also enable LogDebug. 69 | LogDebugWithRequestRetries 70 | 71 | // LogDebugWithRequestErrors states the SDK should log when service requests fail 72 | // to build, send, validate, or unmarshal. 73 | LogDebugWithRequestErrors 74 | ) 75 | 76 | // A Logger is a minimalistic interface for the SDK to log messages to. Should 77 | // be used to provide custom logging writers for the SDK to use. 78 | type Logger interface { 79 | Log(...interface{}) 80 | } 81 | 82 | // A LoggerFunc is a convenience type to convert a function taking a variadic 83 | // list of arguments and wrap it so the Logger interface can be used. 84 | // 85 | // Example: 86 | // s3.New(sess, &aws.Config{Logger: aws.LoggerFunc(func(args ...interface{}) { 87 | // fmt.Fprintln(os.Stdout, args...) 88 | // })}) 89 | type LoggerFunc func(...interface{}) 90 | 91 | // Log calls the wrapped function with the arguments provided 92 | func (f LoggerFunc) Log(args ...interface{}) { 93 | f(args...) 94 | } 95 | 96 | // NewDefaultLogger returns a Logger which will write log messages to stdout, and 97 | // use same formatting runes as the stdlib log.Logger 98 | func NewDefaultLogger() Logger { 99 | return &defaultLogger{ 100 | logger: log.New(os.Stdout, "", log.LstdFlags), 101 | } 102 | } 103 | 104 | // A defaultLogger provides a minimalistic logger satisfying the Logger interface. 105 | type defaultLogger struct { 106 | logger *log.Logger 107 | } 108 | 109 | // Log logs the parameters to the stdlib logger. See log.Println. 110 | func (l defaultLogger) Log(args ...interface{}) { 111 | l.logger.Println(args...) 112 | } 113 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go: -------------------------------------------------------------------------------- 1 | // +build go1.5 2 | 3 | package request 4 | 5 | import ( 6 | "io" 7 | "net/http" 8 | "net/url" 9 | ) 10 | 11 | func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request { 12 | req := &http.Request{ 13 | URL: &url.URL{}, 14 | Header: http.Header{}, 15 | Close: r.Close, 16 | Body: body, 17 | Host: r.Host, 18 | Method: r.Method, 19 | Proto: r.Proto, 20 | ContentLength: r.ContentLength, 21 | // Cancel will be deprecated in 1.7 and will be replaced with Context 22 | Cancel: r.Cancel, 23 | } 24 | 25 | *req.URL = *r.URL 26 | for k, v := range r.Header { 27 | for _, vv := range v { 28 | req.Header.Add(k, vv) 29 | } 30 | } 31 | 32 | return req 33 | } 34 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/request/http_request_1_4.go: -------------------------------------------------------------------------------- 1 | // +build !go1.5 2 | 3 | package request 4 | 5 | import ( 6 | "io" 7 | "net/http" 8 | "net/url" 9 | ) 10 | 11 | func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request { 12 | req := &http.Request{ 13 | URL: &url.URL{}, 14 | Header: http.Header{}, 15 | Close: r.Close, 16 | Body: body, 17 | Host: r.Host, 18 | Method: r.Method, 19 | Proto: r.Proto, 20 | ContentLength: r.ContentLength, 21 | } 22 | 23 | *req.URL = *r.URL 24 | for k, v := range r.Header { 25 | for _, vv := range v { 26 | req.Header.Add(k, vv) 27 | } 28 | } 29 | 30 | return req 31 | } 32 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import ( 4 | "io" 5 | "sync" 6 | ) 7 | 8 | // offsetReader is a thread-safe io.ReadCloser to prevent racing 9 | // with retrying requests 10 | type offsetReader struct { 11 | buf io.ReadSeeker 12 | lock sync.RWMutex 13 | closed bool 14 | } 15 | 16 | func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader { 17 | reader := &offsetReader{} 18 | buf.Seek(offset, 0) 19 | 20 | reader.buf = buf 21 | return reader 22 | } 23 | 24 | // Close is a thread-safe close. Uses the write lock. 25 | func (o *offsetReader) Close() error { 26 | o.lock.Lock() 27 | defer o.lock.Unlock() 28 | o.closed = true 29 | return nil 30 | } 31 | 32 | // Read is a thread-safe read using a read lock. 33 | func (o *offsetReader) Read(p []byte) (int, error) { 34 | o.lock.RLock() 35 | defer o.lock.RUnlock() 36 | 37 | if o.closed { 38 | return 0, io.EOF 39 | } 40 | 41 | return o.buf.Read(p) 42 | } 43 | 44 | // CloseAndCopy will return a new offsetReader with a copy of the old buffer 45 | // and close the old buffer. 46 | func (o *offsetReader) CloseAndCopy(offset int64) *offsetReader { 47 | o.Close() 48 | return newOffsetReader(o.buf, offset) 49 | } 50 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import ( 4 | "reflect" 5 | 6 | "github.com/aws/aws-sdk-go/aws" 7 | "github.com/aws/aws-sdk-go/aws/awsutil" 8 | ) 9 | 10 | //type Paginater interface { 11 | // HasNextPage() bool 12 | // NextPage() *Request 13 | // EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error 14 | //} 15 | 16 | // HasNextPage returns true if this request has more pages of data available. 17 | func (r *Request) HasNextPage() bool { 18 | return len(r.nextPageTokens()) > 0 19 | } 20 | 21 | // nextPageTokens returns the tokens to use when asking for the next page of 22 | // data. 23 | func (r *Request) nextPageTokens() []interface{} { 24 | if r.Operation.Paginator == nil { 25 | return nil 26 | } 27 | 28 | if r.Operation.TruncationToken != "" { 29 | tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken) 30 | if len(tr) == 0 { 31 | return nil 32 | } 33 | 34 | switch v := tr[0].(type) { 35 | case *bool: 36 | if !aws.BoolValue(v) { 37 | return nil 38 | } 39 | case bool: 40 | if v == false { 41 | return nil 42 | } 43 | } 44 | } 45 | 46 | tokens := []interface{}{} 47 | tokenAdded := false 48 | for _, outToken := range r.Operation.OutputTokens { 49 | v, _ := awsutil.ValuesAtPath(r.Data, outToken) 50 | if len(v) > 0 { 51 | tokens = append(tokens, v[0]) 52 | tokenAdded = true 53 | } else { 54 | tokens = append(tokens, nil) 55 | } 56 | } 57 | if !tokenAdded { 58 | return nil 59 | } 60 | 61 | return tokens 62 | } 63 | 64 | // NextPage returns a new Request that can be executed to return the next 65 | // page of result data. Call .Send() on this request to execute it. 66 | func (r *Request) NextPage() *Request { 67 | tokens := r.nextPageTokens() 68 | if len(tokens) == 0 { 69 | return nil 70 | } 71 | 72 | data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface() 73 | nr := New(r.Config, r.ClientInfo, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data) 74 | for i, intok := range nr.Operation.InputTokens { 75 | awsutil.SetValueAtPath(nr.Params, intok, tokens[i]) 76 | } 77 | return nr 78 | } 79 | 80 | // EachPage iterates over each page of a paginated request object. The fn 81 | // parameter should be a function with the following sample signature: 82 | // 83 | // func(page *T, lastPage bool) bool { 84 | // return true // return false to stop iterating 85 | // } 86 | // 87 | // Where "T" is the structure type matching the output structure of the given 88 | // operation. For example, a request object generated by 89 | // DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput 90 | // as the structure "T". The lastPage value represents whether the page is 91 | // the last page of data or not. The return value of this function should 92 | // return true to keep iterating or false to stop. 93 | func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error { 94 | for page := r; page != nil; page = page.NextPage() { 95 | if err := page.Send(); err != nil { 96 | return err 97 | } 98 | if getNextPage := fn(page.Data, !page.HasNextPage()); !getNextPage { 99 | return page.Error 100 | } 101 | } 102 | 103 | return nil 104 | } 105 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/aws/aws-sdk-go/aws" 7 | "github.com/aws/aws-sdk-go/aws/awserr" 8 | ) 9 | 10 | // Retryer is an interface to control retry logic for a given service. 11 | // The default implementation used by most services is the service.DefaultRetryer 12 | // structure, which contains basic retry logic using exponential backoff. 13 | type Retryer interface { 14 | RetryRules(*Request) time.Duration 15 | ShouldRetry(*Request) bool 16 | MaxRetries() int 17 | } 18 | 19 | // WithRetryer sets a config Retryer value to the given Config returning it 20 | // for chaining. 21 | func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config { 22 | cfg.Retryer = retryer 23 | return cfg 24 | } 25 | 26 | // retryableCodes is a collection of service response codes which are retry-able 27 | // without any further action. 28 | var retryableCodes = map[string]struct{}{ 29 | "RequestError": {}, 30 | "RequestTimeout": {}, 31 | } 32 | 33 | var throttleCodes = map[string]struct{}{ 34 | "ProvisionedThroughputExceededException": {}, 35 | "Throttling": {}, 36 | "ThrottlingException": {}, 37 | "RequestLimitExceeded": {}, 38 | "RequestThrottled": {}, 39 | "LimitExceededException": {}, // Deleting 10+ DynamoDb tables at once 40 | "TooManyRequestsException": {}, // Lambda functions 41 | } 42 | 43 | // credsExpiredCodes is a collection of error codes which signify the credentials 44 | // need to be refreshed. Expired tokens require refreshing of credentials, and 45 | // resigning before the request can be retried. 46 | var credsExpiredCodes = map[string]struct{}{ 47 | "ExpiredToken": {}, 48 | "ExpiredTokenException": {}, 49 | "RequestExpired": {}, // EC2 Only 50 | } 51 | 52 | func isCodeThrottle(code string) bool { 53 | _, ok := throttleCodes[code] 54 | return ok 55 | } 56 | 57 | func isCodeRetryable(code string) bool { 58 | if _, ok := retryableCodes[code]; ok { 59 | return true 60 | } 61 | 62 | return isCodeExpiredCreds(code) 63 | } 64 | 65 | func isCodeExpiredCreds(code string) bool { 66 | _, ok := credsExpiredCodes[code] 67 | return ok 68 | } 69 | 70 | // IsErrorRetryable returns whether the error is retryable, based on its Code. 71 | // Returns false if the request has no Error set. 72 | func (r *Request) IsErrorRetryable() bool { 73 | if r.Error != nil { 74 | if err, ok := r.Error.(awserr.Error); ok { 75 | return isCodeRetryable(err.Code()) 76 | } 77 | } 78 | return false 79 | } 80 | 81 | // IsErrorThrottle returns whether the error is to be throttled based on its code. 82 | // Returns false if the request has no Error set 83 | func (r *Request) IsErrorThrottle() bool { 84 | if r.Error != nil { 85 | if err, ok := r.Error.(awserr.Error); ok { 86 | return isCodeThrottle(err.Code()) 87 | } 88 | } 89 | return false 90 | } 91 | 92 | // IsErrorExpired returns whether the error code is a credential expiry error. 93 | // Returns false if the request has no Error set. 94 | func (r *Request) IsErrorExpired() bool { 95 | if r.Error != nil { 96 | if err, ok := r.Error.(awserr.Error); ok { 97 | return isCodeExpiredCreds(err.Code()) 98 | } 99 | } 100 | return false 101 | } 102 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/types.go: -------------------------------------------------------------------------------- 1 | package aws 2 | 3 | import ( 4 | "io" 5 | "sync" 6 | ) 7 | 8 | // ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser 9 | func ReadSeekCloser(r io.Reader) ReaderSeekerCloser { 10 | return ReaderSeekerCloser{r} 11 | } 12 | 13 | // ReaderSeekerCloser represents a reader that can also delegate io.Seeker and 14 | // io.Closer interfaces to the underlying object if they are available. 15 | type ReaderSeekerCloser struct { 16 | r io.Reader 17 | } 18 | 19 | // Read reads from the reader up to size of p. The number of bytes read, and 20 | // error if it occurred will be returned. 21 | // 22 | // If the reader is not an io.Reader zero bytes read, and nil error will be returned. 23 | // 24 | // Performs the same functionality as io.Reader Read 25 | func (r ReaderSeekerCloser) Read(p []byte) (int, error) { 26 | switch t := r.r.(type) { 27 | case io.Reader: 28 | return t.Read(p) 29 | } 30 | return 0, nil 31 | } 32 | 33 | // Seek sets the offset for the next Read to offset, interpreted according to 34 | // whence: 0 means relative to the origin of the file, 1 means relative to the 35 | // current offset, and 2 means relative to the end. Seek returns the new offset 36 | // and an error, if any. 37 | // 38 | // If the ReaderSeekerCloser is not an io.Seeker nothing will be done. 39 | func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) { 40 | switch t := r.r.(type) { 41 | case io.Seeker: 42 | return t.Seek(offset, whence) 43 | } 44 | return int64(0), nil 45 | } 46 | 47 | // Close closes the ReaderSeekerCloser. 48 | // 49 | // If the ReaderSeekerCloser is not an io.Closer nothing will be done. 50 | func (r ReaderSeekerCloser) Close() error { 51 | switch t := r.r.(type) { 52 | case io.Closer: 53 | return t.Close() 54 | } 55 | return nil 56 | } 57 | 58 | // A WriteAtBuffer provides a in memory buffer supporting the io.WriterAt interface 59 | // Can be used with the s3manager.Downloader to download content to a buffer 60 | // in memory. Safe to use concurrently. 61 | type WriteAtBuffer struct { 62 | buf []byte 63 | m sync.Mutex 64 | 65 | // GrowthCoeff defines the growth rate of the internal buffer. By 66 | // default, the growth rate is 1, where expanding the internal 67 | // buffer will allocate only enough capacity to fit the new expected 68 | // length. 69 | GrowthCoeff float64 70 | } 71 | 72 | // NewWriteAtBuffer creates a WriteAtBuffer with an internal buffer 73 | // provided by buf. 74 | func NewWriteAtBuffer(buf []byte) *WriteAtBuffer { 75 | return &WriteAtBuffer{buf: buf} 76 | } 77 | 78 | // WriteAt writes a slice of bytes to a buffer starting at the position provided 79 | // The number of bytes written will be returned, or error. Can overwrite previous 80 | // written slices if the write ats overlap. 81 | func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) { 82 | pLen := len(p) 83 | expLen := pos + int64(pLen) 84 | b.m.Lock() 85 | defer b.m.Unlock() 86 | if int64(len(b.buf)) < expLen { 87 | if int64(cap(b.buf)) < expLen { 88 | if b.GrowthCoeff < 1 { 89 | b.GrowthCoeff = 1 90 | } 91 | newBuf := make([]byte, expLen, int64(b.GrowthCoeff*float64(expLen))) 92 | copy(newBuf, b.buf) 93 | b.buf = newBuf 94 | } 95 | b.buf = b.buf[:expLen] 96 | } 97 | copy(b.buf[pos:], p) 98 | return pLen, nil 99 | } 100 | 101 | // Bytes returns a slice of bytes written to the buffer. 102 | func (b *WriteAtBuffer) Bytes() []byte { 103 | b.m.Lock() 104 | defer b.m.Unlock() 105 | return b.buf[:len(b.buf):len(b.buf)] 106 | } 107 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/aws/version.go: -------------------------------------------------------------------------------- 1 | // Package aws provides core functionality for making requests to AWS services. 2 | package aws 3 | 4 | // SDKName is the name of this AWS SDK 5 | const SDKName = "aws-sdk-go" 6 | 7 | // SDKVersion is the version of this SDK 8 | const SDKVersion = "1.1.30" 9 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go: -------------------------------------------------------------------------------- 1 | // Package endpoints validates regional endpoints for services. 2 | package endpoints 3 | 4 | //go:generate go run ../model/cli/gen-endpoints/main.go endpoints.json endpoints_map.go 5 | //go:generate gofmt -s -w endpoints_map.go 6 | 7 | import ( 8 | "fmt" 9 | "regexp" 10 | "strings" 11 | ) 12 | 13 | // NormalizeEndpoint takes and endpoint and service API information to return a 14 | // normalized endpoint and signing region. If the endpoint is not an empty string 15 | // the service name and region will be used to look up the service's API endpoint. 16 | // If the endpoint is provided the scheme will be added if it is not present. 17 | func NormalizeEndpoint(endpoint, serviceName, region string, disableSSL bool) (normEndpoint, signingRegion string) { 18 | if endpoint == "" { 19 | return EndpointForRegion(serviceName, region, disableSSL) 20 | } 21 | 22 | return AddScheme(endpoint, disableSSL), "" 23 | } 24 | 25 | // EndpointForRegion returns an endpoint and its signing region for a service and region. 26 | // if the service and region pair are not found endpoint and signingRegion will be empty. 27 | func EndpointForRegion(svcName, region string, disableSSL bool) (endpoint, signingRegion string) { 28 | derivedKeys := []string{ 29 | region + "/" + svcName, 30 | region + "/*", 31 | "*/" + svcName, 32 | "*/*", 33 | } 34 | 35 | for _, key := range derivedKeys { 36 | if val, ok := endpointsMap.Endpoints[key]; ok { 37 | ep := val.Endpoint 38 | ep = strings.Replace(ep, "{region}", region, -1) 39 | ep = strings.Replace(ep, "{service}", svcName, -1) 40 | 41 | endpoint = ep 42 | signingRegion = val.SigningRegion 43 | break 44 | } 45 | } 46 | 47 | return AddScheme(endpoint, disableSSL), signingRegion 48 | } 49 | 50 | // Regular expression to determine if the endpoint string is prefixed with a scheme. 51 | var schemeRE = regexp.MustCompile("^([^:]+)://") 52 | 53 | // AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no 54 | // scheme. If disableSSL is true HTTP will be added instead of the default HTTPS. 55 | func AddScheme(endpoint string, disableSSL bool) string { 56 | if endpoint != "" && !schemeRE.MatchString(endpoint) { 57 | scheme := "https" 58 | if disableSSL { 59 | scheme = "http" 60 | } 61 | endpoint = fmt.Sprintf("%s://%s", scheme, endpoint) 62 | } 63 | 64 | return endpoint 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "endpoints": { 4 | "*/*": { 5 | "endpoint": "{service}.{region}.amazonaws.com" 6 | }, 7 | "cn-north-1/*": { 8 | "endpoint": "{service}.{region}.amazonaws.com.cn", 9 | "signatureVersion": "v4" 10 | }, 11 | "cn-north-1/ec2metadata": { 12 | "endpoint": "http://169.254.169.254/latest" 13 | }, 14 | "us-gov-west-1/iam": { 15 | "endpoint": "iam.us-gov.amazonaws.com" 16 | }, 17 | "us-gov-west-1/sts": { 18 | "endpoint": "sts.us-gov-west-1.amazonaws.com" 19 | }, 20 | "us-gov-west-1/s3": { 21 | "endpoint": "s3-{region}.amazonaws.com" 22 | }, 23 | "us-gov-west-1/ec2metadata": { 24 | "endpoint": "http://169.254.169.254/latest" 25 | }, 26 | "*/cloudfront": { 27 | "endpoint": "cloudfront.amazonaws.com", 28 | "signingRegion": "us-east-1" 29 | }, 30 | "*/cloudsearchdomain": { 31 | "endpoint": "", 32 | "signingRegion": "us-east-1" 33 | }, 34 | "*/data.iot": { 35 | "endpoint": "", 36 | "signingRegion": "us-east-1" 37 | }, 38 | "*/ec2metadata": { 39 | "endpoint": "http://169.254.169.254/latest" 40 | }, 41 | "*/iam": { 42 | "endpoint": "iam.amazonaws.com", 43 | "signingRegion": "us-east-1" 44 | }, 45 | "*/importexport": { 46 | "endpoint": "importexport.amazonaws.com", 47 | "signingRegion": "us-east-1" 48 | }, 49 | "*/route53": { 50 | "endpoint": "route53.amazonaws.com", 51 | "signingRegion": "us-east-1" 52 | }, 53 | "*/sts": { 54 | "endpoint": "sts.amazonaws.com", 55 | "signingRegion": "us-east-1" 56 | }, 57 | "*/waf": { 58 | "endpoint": "waf.amazonaws.com", 59 | "signingRegion": "us-east-1" 60 | }, 61 | "us-east-1/sdb": { 62 | "endpoint": "sdb.amazonaws.com", 63 | "signingRegion": "us-east-1" 64 | }, 65 | "*/s3": { 66 | "endpoint": "s3-{region}.amazonaws.com" 67 | }, 68 | "us-east-1/s3": { 69 | "endpoint": "s3.amazonaws.com" 70 | }, 71 | "eu-central-1/s3": { 72 | "endpoint": "{service}.{region}.amazonaws.com" 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go: -------------------------------------------------------------------------------- 1 | package endpoints 2 | 3 | // THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. 4 | 5 | type endpointStruct struct { 6 | Version int 7 | Endpoints map[string]endpointEntry 8 | } 9 | 10 | type endpointEntry struct { 11 | Endpoint string 12 | SigningRegion string 13 | } 14 | 15 | var endpointsMap = endpointStruct{ 16 | Version: 2, 17 | Endpoints: map[string]endpointEntry{ 18 | "*/*": { 19 | Endpoint: "{service}.{region}.amazonaws.com", 20 | }, 21 | "*/cloudfront": { 22 | Endpoint: "cloudfront.amazonaws.com", 23 | SigningRegion: "us-east-1", 24 | }, 25 | "*/cloudsearchdomain": { 26 | Endpoint: "", 27 | SigningRegion: "us-east-1", 28 | }, 29 | "*/data.iot": { 30 | Endpoint: "", 31 | SigningRegion: "us-east-1", 32 | }, 33 | "*/ec2metadata": { 34 | Endpoint: "http://169.254.169.254/latest", 35 | }, 36 | "*/iam": { 37 | Endpoint: "iam.amazonaws.com", 38 | SigningRegion: "us-east-1", 39 | }, 40 | "*/importexport": { 41 | Endpoint: "importexport.amazonaws.com", 42 | SigningRegion: "us-east-1", 43 | }, 44 | "*/route53": { 45 | Endpoint: "route53.amazonaws.com", 46 | SigningRegion: "us-east-1", 47 | }, 48 | "*/s3": { 49 | Endpoint: "s3-{region}.amazonaws.com", 50 | }, 51 | "*/sts": { 52 | Endpoint: "sts.amazonaws.com", 53 | SigningRegion: "us-east-1", 54 | }, 55 | "*/waf": { 56 | Endpoint: "waf.amazonaws.com", 57 | SigningRegion: "us-east-1", 58 | }, 59 | "cn-north-1/*": { 60 | Endpoint: "{service}.{region}.amazonaws.com.cn", 61 | }, 62 | "cn-north-1/ec2metadata": { 63 | Endpoint: "http://169.254.169.254/latest", 64 | }, 65 | "eu-central-1/s3": { 66 | Endpoint: "{service}.{region}.amazonaws.com", 67 | }, 68 | "us-east-1/s3": { 69 | Endpoint: "s3.amazonaws.com", 70 | }, 71 | "us-east-1/sdb": { 72 | Endpoint: "sdb.amazonaws.com", 73 | SigningRegion: "us-east-1", 74 | }, 75 | "us-gov-west-1/ec2metadata": { 76 | Endpoint: "http://169.254.169.254/latest", 77 | }, 78 | "us-gov-west-1/iam": { 79 | Endpoint: "iam.us-gov.amazonaws.com", 80 | }, 81 | "us-gov-west-1/s3": { 82 | Endpoint: "s3-{region}.amazonaws.com", 83 | }, 84 | "us-gov-west-1/sts": { 85 | Endpoint: "sts.us-gov-west-1.amazonaws.com", 86 | }, 87 | }, 88 | } 89 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | import ( 4 | "crypto/rand" 5 | "fmt" 6 | "reflect" 7 | ) 8 | 9 | // RandReader is the random reader the protocol package will use to read 10 | // random bytes from. This is exported for testing, and should not be used. 11 | var RandReader = rand.Reader 12 | 13 | const idempotencyTokenFillTag = `idempotencyToken` 14 | 15 | // CanSetIdempotencyToken returns true if the struct field should be 16 | // automatically populated with a Idempotency token. 17 | // 18 | // Only *string and string type fields that are tagged with idempotencyToken 19 | // which are not already set can be auto filled. 20 | func CanSetIdempotencyToken(v reflect.Value, f reflect.StructField) bool { 21 | switch u := v.Interface().(type) { 22 | // To auto fill an Idempotency token the field must be a string, 23 | // tagged for auto fill, and have a zero value. 24 | case *string: 25 | return u == nil && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 26 | case string: 27 | return len(u) == 0 && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 28 | } 29 | 30 | return false 31 | } 32 | 33 | // GetIdempotencyToken returns a randomly generated idempotency token. 34 | func GetIdempotencyToken() string { 35 | b := make([]byte, 16) 36 | RandReader.Read(b) 37 | 38 | return UUIDVersion4(b) 39 | } 40 | 41 | // SetIdempotencyToken will set the value provided with a Idempotency Token. 42 | // Given that the value can be set. Will panic if value is not setable. 43 | func SetIdempotencyToken(v reflect.Value) { 44 | if v.Kind() == reflect.Ptr { 45 | if v.IsNil() && v.CanSet() { 46 | v.Set(reflect.New(v.Type().Elem())) 47 | } 48 | v = v.Elem() 49 | } 50 | v = reflect.Indirect(v) 51 | 52 | if !v.CanSet() { 53 | panic(fmt.Sprintf("unable to set idempotnecy token %v", v)) 54 | } 55 | 56 | b := make([]byte, 16) 57 | _, err := rand.Read(b) 58 | if err != nil { 59 | // TODO handle error 60 | return 61 | } 62 | 63 | v.Set(reflect.ValueOf(UUIDVersion4(b))) 64 | } 65 | 66 | // UUIDVersion4 returns a Version 4 random UUID from the byte slice provided 67 | func UUIDVersion4(u []byte) string { 68 | // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29 69 | // 13th character is "4" 70 | u[6] = (u[6] | 0x40) & 0x4F 71 | // 17th character is "8", "9", "a", or "b" 72 | u[8] = (u[8] | 0x80) & 0xBF 73 | 74 | return fmt.Sprintf(`%X-%X-%X-%X-%X`, u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go: -------------------------------------------------------------------------------- 1 | // Package jsonrpc provides JSON RPC utilities for serialisation of AWS 2 | // requests and responses. 3 | package jsonrpc 4 | 5 | //go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/json.json build_test.go 6 | //go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go 7 | 8 | import ( 9 | "encoding/json" 10 | "io/ioutil" 11 | "strings" 12 | 13 | "github.com/aws/aws-sdk-go/aws/awserr" 14 | "github.com/aws/aws-sdk-go/aws/request" 15 | "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" 16 | "github.com/aws/aws-sdk-go/private/protocol/rest" 17 | ) 18 | 19 | var emptyJSON = []byte("{}") 20 | 21 | // BuildHandler is a named request handler for building jsonrpc protocol requests 22 | var BuildHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Build", Fn: Build} 23 | 24 | // UnmarshalHandler is a named request handler for unmarshaling jsonrpc protocol requests 25 | var UnmarshalHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Unmarshal", Fn: Unmarshal} 26 | 27 | // UnmarshalMetaHandler is a named request handler for unmarshaling jsonrpc protocol request metadata 28 | var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalMeta", Fn: UnmarshalMeta} 29 | 30 | // UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc protocol request errors 31 | var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalError", Fn: UnmarshalError} 32 | 33 | // Build builds a JSON payload for a JSON RPC request. 34 | func Build(req *request.Request) { 35 | var buf []byte 36 | var err error 37 | if req.ParamsFilled() { 38 | buf, err = jsonutil.BuildJSON(req.Params) 39 | if err != nil { 40 | req.Error = awserr.New("SerializationError", "failed encoding JSON RPC request", err) 41 | return 42 | } 43 | } else { 44 | buf = emptyJSON 45 | } 46 | 47 | if req.ClientInfo.TargetPrefix != "" || string(buf) != "{}" { 48 | req.SetBufferBody(buf) 49 | } 50 | 51 | if req.ClientInfo.TargetPrefix != "" { 52 | target := req.ClientInfo.TargetPrefix + "." + req.Operation.Name 53 | req.HTTPRequest.Header.Add("X-Amz-Target", target) 54 | } 55 | if req.ClientInfo.JSONVersion != "" { 56 | jsonVersion := req.ClientInfo.JSONVersion 57 | req.HTTPRequest.Header.Add("Content-Type", "application/x-amz-json-"+jsonVersion) 58 | } 59 | } 60 | 61 | // Unmarshal unmarshals a response for a JSON RPC service. 62 | func Unmarshal(req *request.Request) { 63 | defer req.HTTPResponse.Body.Close() 64 | if req.DataFilled() { 65 | err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body) 66 | if err != nil { 67 | req.Error = awserr.New("SerializationError", "failed decoding JSON RPC response", err) 68 | } 69 | } 70 | return 71 | } 72 | 73 | // UnmarshalMeta unmarshals headers from a response for a JSON RPC service. 74 | func UnmarshalMeta(req *request.Request) { 75 | rest.UnmarshalMeta(req) 76 | } 77 | 78 | // UnmarshalError unmarshals an error response for a JSON RPC service. 79 | func UnmarshalError(req *request.Request) { 80 | defer req.HTTPResponse.Body.Close() 81 | bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body) 82 | if err != nil { 83 | req.Error = awserr.New("SerializationError", "failed reading JSON RPC error response", err) 84 | return 85 | } 86 | if len(bodyBytes) == 0 { 87 | req.Error = awserr.NewRequestFailure( 88 | awserr.New("SerializationError", req.HTTPResponse.Status, nil), 89 | req.HTTPResponse.StatusCode, 90 | "", 91 | ) 92 | return 93 | } 94 | var jsonErr jsonErrorResponse 95 | if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { 96 | req.Error = awserr.New("SerializationError", "failed decoding JSON RPC error response", err) 97 | return 98 | } 99 | 100 | codes := strings.SplitN(jsonErr.Code, "#", 2) 101 | req.Error = awserr.NewRequestFailure( 102 | awserr.New(codes[len(codes)-1], jsonErr.Message, nil), 103 | req.HTTPResponse.StatusCode, 104 | req.RequestID, 105 | ) 106 | } 107 | 108 | type jsonErrorResponse struct { 109 | Code string `json:"__type"` 110 | Message string `json:"message"` 111 | } 112 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go: -------------------------------------------------------------------------------- 1 | package rest 2 | 3 | import "reflect" 4 | 5 | // PayloadMember returns the payload field member of i if there is one, or nil. 6 | func PayloadMember(i interface{}) interface{} { 7 | if i == nil { 8 | return nil 9 | } 10 | 11 | v := reflect.ValueOf(i).Elem() 12 | if !v.IsValid() { 13 | return nil 14 | } 15 | if field, ok := v.Type().FieldByName("_"); ok { 16 | if payloadName := field.Tag.Get("payload"); payloadName != "" { 17 | field, _ := v.Type().FieldByName(payloadName) 18 | if field.Tag.Get("type") != "structure" { 19 | return nil 20 | } 21 | 22 | payload := v.FieldByName(payloadName) 23 | if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) { 24 | return payload.Interface() 25 | } 26 | } 27 | } 28 | return nil 29 | } 30 | 31 | // PayloadType returns the type of a payload field member of i if there is one, or "". 32 | func PayloadType(i interface{}) string { 33 | v := reflect.Indirect(reflect.ValueOf(i)) 34 | if !v.IsValid() { 35 | return "" 36 | } 37 | if field, ok := v.Type().FieldByName("_"); ok { 38 | if payloadName := field.Tag.Get("payload"); payloadName != "" { 39 | if member, ok := v.Type().FieldByName(payloadName); ok { 40 | return member.Tag.Get("type") 41 | } 42 | } 43 | } 44 | return "" 45 | } 46 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go: -------------------------------------------------------------------------------- 1 | package protocol 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | 7 | "github.com/aws/aws-sdk-go/aws/request" 8 | ) 9 | 10 | // UnmarshalDiscardBodyHandler is a named request handler to empty and close a response's body 11 | var UnmarshalDiscardBodyHandler = request.NamedHandler{Name: "awssdk.shared.UnmarshalDiscardBody", Fn: UnmarshalDiscardBody} 12 | 13 | // UnmarshalDiscardBody is a request handler to empty a response's body and closing it. 14 | func UnmarshalDiscardBody(r *request.Request) { 15 | if r.HTTPResponse == nil || r.HTTPResponse.Body == nil { 16 | return 17 | } 18 | 19 | io.Copy(ioutil.Discard, r.HTTPResponse.Body) 20 | r.HTTPResponse.Body.Close() 21 | } 22 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/private/signer/v4/header_rules.go: -------------------------------------------------------------------------------- 1 | package v4 2 | 3 | import ( 4 | "net/http" 5 | "strings" 6 | ) 7 | 8 | // validator houses a set of rule needed for validation of a 9 | // string value 10 | type rules []rule 11 | 12 | // rule interface allows for more flexible rules and just simply 13 | // checks whether or not a value adheres to that rule 14 | type rule interface { 15 | IsValid(value string) bool 16 | } 17 | 18 | // IsValid will iterate through all rules and see if any rules 19 | // apply to the value and supports nested rules 20 | func (r rules) IsValid(value string) bool { 21 | for _, rule := range r { 22 | if rule.IsValid(value) { 23 | return true 24 | } 25 | } 26 | return false 27 | } 28 | 29 | // mapRule generic rule for maps 30 | type mapRule map[string]struct{} 31 | 32 | // IsValid for the map rule satisfies whether it exists in the map 33 | func (m mapRule) IsValid(value string) bool { 34 | _, ok := m[value] 35 | return ok 36 | } 37 | 38 | // whitelist is a generic rule for whitelisting 39 | type whitelist struct { 40 | rule 41 | } 42 | 43 | // IsValid for whitelist checks if the value is within the whitelist 44 | func (w whitelist) IsValid(value string) bool { 45 | return w.rule.IsValid(value) 46 | } 47 | 48 | // blacklist is a generic rule for blacklisting 49 | type blacklist struct { 50 | rule 51 | } 52 | 53 | // IsValid for whitelist checks if the value is within the whitelist 54 | func (b blacklist) IsValid(value string) bool { 55 | return !b.rule.IsValid(value) 56 | } 57 | 58 | type patterns []string 59 | 60 | // IsValid for patterns checks each pattern and returns if a match has 61 | // been found 62 | func (p patterns) IsValid(value string) bool { 63 | for _, pattern := range p { 64 | if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) { 65 | return true 66 | } 67 | } 68 | return false 69 | } 70 | 71 | // inclusiveRules rules allow for rules to depend on one another 72 | type inclusiveRules []rule 73 | 74 | // IsValid will return true if all rules are true 75 | func (r inclusiveRules) IsValid(value string) bool { 76 | for _, rule := range r { 77 | if !rule.IsValid(value) { 78 | return false 79 | } 80 | } 81 | return true 82 | } 83 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/private/waiter/waiter.go: -------------------------------------------------------------------------------- 1 | package waiter 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "time" 7 | 8 | "github.com/aws/aws-sdk-go/aws" 9 | "github.com/aws/aws-sdk-go/aws/awserr" 10 | "github.com/aws/aws-sdk-go/aws/awsutil" 11 | "github.com/aws/aws-sdk-go/aws/request" 12 | ) 13 | 14 | // A Config provides a collection of configuration values to setup a generated 15 | // waiter code with. 16 | type Config struct { 17 | Name string 18 | Delay int 19 | MaxAttempts int 20 | Operation string 21 | Acceptors []WaitAcceptor 22 | } 23 | 24 | // A WaitAcceptor provides the information needed to wait for an API operation 25 | // to complete. 26 | type WaitAcceptor struct { 27 | Expected interface{} 28 | Matcher string 29 | State string 30 | Argument string 31 | } 32 | 33 | // A Waiter provides waiting for an operation to complete. 34 | type Waiter struct { 35 | Config 36 | Client interface{} 37 | Input interface{} 38 | } 39 | 40 | // Wait waits for an operation to complete, expire max attempts, or fail. Error 41 | // is returned if the operation fails. 42 | func (w *Waiter) Wait() error { 43 | client := reflect.ValueOf(w.Client) 44 | in := reflect.ValueOf(w.Input) 45 | method := client.MethodByName(w.Config.Operation + "Request") 46 | 47 | for i := 0; i < w.MaxAttempts; i++ { 48 | res := method.Call([]reflect.Value{in}) 49 | req := res[0].Interface().(*request.Request) 50 | req.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Waiter")) 51 | 52 | err := req.Send() 53 | for _, a := range w.Acceptors { 54 | result := false 55 | var vals []interface{} 56 | switch a.Matcher { 57 | case "pathAll", "path": 58 | // Require all matches to be equal for result to match 59 | vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) 60 | if len(vals) == 0 { 61 | break 62 | } 63 | result = true 64 | for _, val := range vals { 65 | if !awsutil.DeepEqual(val, a.Expected) { 66 | result = false 67 | break 68 | } 69 | } 70 | case "pathAny": 71 | // Only a single match needs to equal for the result to match 72 | vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) 73 | for _, val := range vals { 74 | if awsutil.DeepEqual(val, a.Expected) { 75 | result = true 76 | break 77 | } 78 | } 79 | case "status": 80 | s := a.Expected.(int) 81 | result = s == req.HTTPResponse.StatusCode 82 | case "error": 83 | if aerr, ok := err.(awserr.Error); ok { 84 | result = aerr.Code() == a.Expected.(string) 85 | } 86 | case "pathList": 87 | // ignored matcher 88 | default: 89 | logf(client, "WARNING: Waiter for %s encountered unexpected matcher: %s", 90 | w.Config.Operation, a.Matcher) 91 | } 92 | 93 | if !result { 94 | // If there was no matching result found there is nothing more to do 95 | // for this response, retry the request. 96 | continue 97 | } 98 | 99 | switch a.State { 100 | case "success": 101 | // waiter completed 102 | return nil 103 | case "failure": 104 | // Waiter failure state triggered 105 | return awserr.New("ResourceNotReady", 106 | fmt.Sprintf("failed waiting for successful resource state"), err) 107 | case "retry": 108 | // clear the error and retry the operation 109 | err = nil 110 | default: 111 | logf(client, "WARNING: Waiter for %s encountered unexpected state: %s", 112 | w.Config.Operation, a.State) 113 | } 114 | } 115 | if err != nil { 116 | return err 117 | } 118 | 119 | time.Sleep(time.Second * time.Duration(w.Delay)) 120 | } 121 | 122 | return awserr.New("ResourceNotReady", 123 | fmt.Sprintf("exceeded %d wait attempts", w.MaxAttempts), nil) 124 | } 125 | 126 | func logf(client reflect.Value, msg string, args ...interface{}) { 127 | cfgVal := client.FieldByName("Config") 128 | if !cfgVal.IsValid() { 129 | return 130 | } 131 | if cfg, ok := cfgVal.Interface().(*aws.Config); ok && cfg.Logger != nil { 132 | cfg.Logger.Log(fmt.Sprintf(msg, args...)) 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/service/kinesis/kinesisiface/interface.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. 2 | 3 | // Package kinesisiface provides an interface for the Amazon Kinesis. 4 | package kinesisiface 5 | 6 | import ( 7 | "github.com/aws/aws-sdk-go/aws/request" 8 | "github.com/aws/aws-sdk-go/service/kinesis" 9 | ) 10 | 11 | // KinesisAPI is the interface type for kinesis.Kinesis. 12 | type KinesisAPI interface { 13 | AddTagsToStreamRequest(*kinesis.AddTagsToStreamInput) (*request.Request, *kinesis.AddTagsToStreamOutput) 14 | 15 | AddTagsToStream(*kinesis.AddTagsToStreamInput) (*kinesis.AddTagsToStreamOutput, error) 16 | 17 | CreateStreamRequest(*kinesis.CreateStreamInput) (*request.Request, *kinesis.CreateStreamOutput) 18 | 19 | CreateStream(*kinesis.CreateStreamInput) (*kinesis.CreateStreamOutput, error) 20 | 21 | DecreaseStreamRetentionPeriodRequest(*kinesis.DecreaseStreamRetentionPeriodInput) (*request.Request, *kinesis.DecreaseStreamRetentionPeriodOutput) 22 | 23 | DecreaseStreamRetentionPeriod(*kinesis.DecreaseStreamRetentionPeriodInput) (*kinesis.DecreaseStreamRetentionPeriodOutput, error) 24 | 25 | DeleteStreamRequest(*kinesis.DeleteStreamInput) (*request.Request, *kinesis.DeleteStreamOutput) 26 | 27 | DeleteStream(*kinesis.DeleteStreamInput) (*kinesis.DeleteStreamOutput, error) 28 | 29 | DescribeStreamRequest(*kinesis.DescribeStreamInput) (*request.Request, *kinesis.DescribeStreamOutput) 30 | 31 | DescribeStream(*kinesis.DescribeStreamInput) (*kinesis.DescribeStreamOutput, error) 32 | 33 | DescribeStreamPages(*kinesis.DescribeStreamInput, func(*kinesis.DescribeStreamOutput, bool) bool) error 34 | 35 | DisableEnhancedMonitoringRequest(*kinesis.DisableEnhancedMonitoringInput) (*request.Request, *kinesis.EnhancedMonitoringOutput) 36 | 37 | DisableEnhancedMonitoring(*kinesis.DisableEnhancedMonitoringInput) (*kinesis.EnhancedMonitoringOutput, error) 38 | 39 | EnableEnhancedMonitoringRequest(*kinesis.EnableEnhancedMonitoringInput) (*request.Request, *kinesis.EnhancedMonitoringOutput) 40 | 41 | EnableEnhancedMonitoring(*kinesis.EnableEnhancedMonitoringInput) (*kinesis.EnhancedMonitoringOutput, error) 42 | 43 | GetRecordsRequest(*kinesis.GetRecordsInput) (*request.Request, *kinesis.GetRecordsOutput) 44 | 45 | GetRecords(*kinesis.GetRecordsInput) (*kinesis.GetRecordsOutput, error) 46 | 47 | GetShardIteratorRequest(*kinesis.GetShardIteratorInput) (*request.Request, *kinesis.GetShardIteratorOutput) 48 | 49 | GetShardIterator(*kinesis.GetShardIteratorInput) (*kinesis.GetShardIteratorOutput, error) 50 | 51 | IncreaseStreamRetentionPeriodRequest(*kinesis.IncreaseStreamRetentionPeriodInput) (*request.Request, *kinesis.IncreaseStreamRetentionPeriodOutput) 52 | 53 | IncreaseStreamRetentionPeriod(*kinesis.IncreaseStreamRetentionPeriodInput) (*kinesis.IncreaseStreamRetentionPeriodOutput, error) 54 | 55 | ListStreamsRequest(*kinesis.ListStreamsInput) (*request.Request, *kinesis.ListStreamsOutput) 56 | 57 | ListStreams(*kinesis.ListStreamsInput) (*kinesis.ListStreamsOutput, error) 58 | 59 | ListStreamsPages(*kinesis.ListStreamsInput, func(*kinesis.ListStreamsOutput, bool) bool) error 60 | 61 | ListTagsForStreamRequest(*kinesis.ListTagsForStreamInput) (*request.Request, *kinesis.ListTagsForStreamOutput) 62 | 63 | ListTagsForStream(*kinesis.ListTagsForStreamInput) (*kinesis.ListTagsForStreamOutput, error) 64 | 65 | MergeShardsRequest(*kinesis.MergeShardsInput) (*request.Request, *kinesis.MergeShardsOutput) 66 | 67 | MergeShards(*kinesis.MergeShardsInput) (*kinesis.MergeShardsOutput, error) 68 | 69 | PutRecordRequest(*kinesis.PutRecordInput) (*request.Request, *kinesis.PutRecordOutput) 70 | 71 | PutRecord(*kinesis.PutRecordInput) (*kinesis.PutRecordOutput, error) 72 | 73 | PutRecordsRequest(*kinesis.PutRecordsInput) (*request.Request, *kinesis.PutRecordsOutput) 74 | 75 | PutRecords(*kinesis.PutRecordsInput) (*kinesis.PutRecordsOutput, error) 76 | 77 | RemoveTagsFromStreamRequest(*kinesis.RemoveTagsFromStreamInput) (*request.Request, *kinesis.RemoveTagsFromStreamOutput) 78 | 79 | RemoveTagsFromStream(*kinesis.RemoveTagsFromStreamInput) (*kinesis.RemoveTagsFromStreamOutput, error) 80 | 81 | SplitShardRequest(*kinesis.SplitShardInput) (*request.Request, *kinesis.SplitShardOutput) 82 | 83 | SplitShard(*kinesis.SplitShardInput) (*kinesis.SplitShardOutput, error) 84 | } 85 | 86 | var _ KinesisAPI = (*kinesis.Kinesis)(nil) 87 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/service/kinesis/service.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. 2 | 3 | package kinesis 4 | 5 | import ( 6 | "github.com/aws/aws-sdk-go/aws" 7 | "github.com/aws/aws-sdk-go/aws/client" 8 | "github.com/aws/aws-sdk-go/aws/client/metadata" 9 | "github.com/aws/aws-sdk-go/aws/request" 10 | "github.com/aws/aws-sdk-go/private/protocol/jsonrpc" 11 | "github.com/aws/aws-sdk-go/private/signer/v4" 12 | ) 13 | 14 | // Amazon Kinesis Streams is a managed service that scales elastically for real 15 | // time processing of streaming big data. 16 | //The service client's operations are safe to be used concurrently. 17 | // It is not safe to mutate any of the client's properties though. 18 | type Kinesis struct { 19 | *client.Client 20 | } 21 | 22 | // Used for custom client initialization logic 23 | var initClient func(*client.Client) 24 | 25 | // Used for custom request initialization logic 26 | var initRequest func(*request.Request) 27 | 28 | // A ServiceName is the name of the service the client will make API calls to. 29 | const ServiceName = "kinesis" 30 | 31 | // New creates a new instance of the Kinesis client with a session. 32 | // If additional configuration is needed for the client instance use the optional 33 | // aws.Config parameter to add your extra config. 34 | // 35 | // Example: 36 | // // Create a Kinesis client from just a session. 37 | // svc := kinesis.New(mySession) 38 | // 39 | // // Create a Kinesis client with additional configuration 40 | // svc := kinesis.New(mySession, aws.NewConfig().WithRegion("us-west-2")) 41 | func New(p client.ConfigProvider, cfgs ...*aws.Config) *Kinesis { 42 | c := p.ClientConfig(ServiceName, cfgs...) 43 | return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion) 44 | } 45 | 46 | // newClient creates, initializes and returns a new service client instance. 47 | func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *Kinesis { 48 | svc := &Kinesis{ 49 | Client: client.New( 50 | cfg, 51 | metadata.ClientInfo{ 52 | ServiceName: ServiceName, 53 | SigningRegion: signingRegion, 54 | Endpoint: endpoint, 55 | APIVersion: "2013-12-02", 56 | JSONVersion: "1.1", 57 | TargetPrefix: "Kinesis_20131202", 58 | }, 59 | handlers, 60 | ), 61 | } 62 | 63 | // Handlers 64 | svc.Handlers.Sign.PushBack(v4.Sign) 65 | svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler) 66 | svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler) 67 | svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler) 68 | svc.Handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler) 69 | 70 | // Run custom client initialization if present 71 | if initClient != nil { 72 | initClient(svc.Client) 73 | } 74 | 75 | return svc 76 | } 77 | 78 | // newRequest creates a new request for a Kinesis operation and runs any 79 | // custom request initialization. 80 | func (c *Kinesis) newRequest(op *request.Operation, params, data interface{}) *request.Request { 81 | req := c.NewRequest(op, params, data) 82 | 83 | // Run custom request initialization if present 84 | if initRequest != nil { 85 | initRequest(req) 86 | } 87 | 88 | return req 89 | } 90 | -------------------------------------------------------------------------------- /vendor/github.com/aws/aws-sdk-go/service/kinesis/waiters.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. 2 | 3 | package kinesis 4 | 5 | import ( 6 | "github.com/aws/aws-sdk-go/private/waiter" 7 | ) 8 | 9 | func (c *Kinesis) WaitUntilStreamExists(input *DescribeStreamInput) error { 10 | waiterCfg := waiter.Config{ 11 | Operation: "DescribeStream", 12 | Delay: 10, 13 | MaxAttempts: 18, 14 | Acceptors: []waiter.WaitAcceptor{ 15 | { 16 | State: "success", 17 | Matcher: "path", 18 | Argument: "StreamDescription.StreamStatus", 19 | Expected: "ACTIVE", 20 | }, 21 | }, 22 | } 23 | 24 | w := waiter.Waiter{ 25 | Client: c, 26 | Input: input, 27 | Config: waiterCfg, 28 | } 29 | return w.Wait() 30 | } 31 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 Jeremy Saenz 2 | All Rights Reserved. 3 | 4 | MIT LICENSE 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/cli.go: -------------------------------------------------------------------------------- 1 | // Package cli provides a minimal framework for creating and organizing command line 2 | // Go applications. cli is designed to be easy to understand and write, the most simple 3 | // cli application can be written as follows: 4 | // func main() { 5 | // cli.NewApp().Run(os.Args) 6 | // } 7 | // 8 | // Of course this application does not do much, so let's make this an actual application: 9 | // func main() { 10 | // app := cli.NewApp() 11 | // app.Name = "greet" 12 | // app.Usage = "say a greeting" 13 | // app.Action = func(c *cli.Context) { 14 | // println("Greetings") 15 | // } 16 | // 17 | // app.Run(os.Args) 18 | // } 19 | package cli 20 | 21 | import ( 22 | "strings" 23 | ) 24 | 25 | type MultiError struct { 26 | Errors []error 27 | } 28 | 29 | func NewMultiError(err ...error) MultiError { 30 | return MultiError{Errors: err} 31 | } 32 | 33 | func (m MultiError) Error() string { 34 | errs := make([]string, len(m.Errors)) 35 | for i, err := range m.Errors { 36 | errs[i] = err.Error() 37 | } 38 | 39 | return strings.Join(errs, "\n") 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/fatih/color/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Fatih Arslan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/fatih/color/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package color is an ANSI color package to output colorized or SGR defined 3 | output to the standard output. The API can be used in several way, pick one 4 | that suits you. 5 | 6 | Use simple and default helper functions with predefined foreground colors: 7 | 8 | color.Cyan("Prints text in cyan.") 9 | 10 | // a newline will be appended automatically 11 | color.Blue("Prints %s in blue.", "text") 12 | 13 | // More default foreground colors.. 14 | color.Red("We have red") 15 | color.Yellow("Yellow color too!") 16 | color.Magenta("And many others ..") 17 | 18 | However there are times where custom color mixes are required. Below are some 19 | examples to create custom color objects and use the print functions of each 20 | separate color object. 21 | 22 | // Create a new color object 23 | c := color.New(color.FgCyan).Add(color.Underline) 24 | c.Println("Prints cyan text with an underline.") 25 | 26 | // Or just add them to New() 27 | d := color.New(color.FgCyan, color.Bold) 28 | d.Printf("This prints bold cyan %s\n", "too!.") 29 | 30 | 31 | // Mix up foreground and background colors, create new mixes! 32 | red := color.New(color.FgRed) 33 | 34 | boldRed := red.Add(color.Bold) 35 | boldRed.Println("This will print text in bold red.") 36 | 37 | whiteBackground := red.Add(color.BgWhite) 38 | whiteBackground.Println("Red text with White background.") 39 | 40 | 41 | You can create PrintXxx functions to simplify even more: 42 | 43 | // Create a custom print function for convenient 44 | red := color.New(color.FgRed).PrintfFunc() 45 | red("warning") 46 | red("error: %s", err) 47 | 48 | // Mix up multiple attributes 49 | notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() 50 | notice("don't forget this...") 51 | 52 | 53 | Or create SprintXxx functions to mix strings with other non-colorized strings: 54 | 55 | yellow := New(FgYellow).SprintFunc() 56 | red := New(FgRed).SprintFunc() 57 | 58 | fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) 59 | 60 | info := New(FgWhite, BgGreen).SprintFunc() 61 | fmt.Printf("this %s rocks!\n", info("package")) 62 | 63 | Windows support is enabled by default. All Print functions works as intended. 64 | However only for color.SprintXXX functions, user should use fmt.FprintXXX and 65 | set the output to color.Output: 66 | 67 | fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) 68 | 69 | info := New(FgWhite, BgGreen).SprintFunc() 70 | fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) 71 | 72 | Using with existing code is possible. Just use the Set() method to set the 73 | standard output to the given parameters. That way a rewrite of an existing 74 | code is not required. 75 | 76 | // Use handy standard colors. 77 | color.Set(color.FgYellow) 78 | 79 | fmt.Println("Existing text will be now in Yellow") 80 | fmt.Printf("This one %s\n", "too") 81 | 82 | color.Unset() // don't forget to unset 83 | 84 | // You can mix up parameters 85 | color.Set(color.FgMagenta, color.Bold) 86 | defer color.Unset() // use it in your function 87 | 88 | fmt.Println("All text will be now bold magenta.") 89 | 90 | There might be a case where you want to disable color output (for example to 91 | pipe the standard output of your app to somewhere else). `Color` has support to 92 | disable colors both globally and for single color definition. For example 93 | suppose you have a CLI app and a `--no-color` bool flag. You can easily disable 94 | the color output with: 95 | 96 | var flagNoColor = flag.Bool("no-color", false, "Disable color output") 97 | 98 | if *flagNoColor { 99 | color.NoColor = true // disables colorized output 100 | } 101 | 102 | It also has support for single color definitions (local). You can 103 | disable/enable color output on the fly: 104 | 105 | c := color.New(color.FgCyan) 106 | c.Println("Prints cyan text") 107 | 108 | c.DisableColor() 109 | c.Println("This is printed without any color") 110 | 111 | c.EnableColor() 112 | c.Println("This prints again cyan...") 113 | */ 114 | package color 115 | -------------------------------------------------------------------------------- /vendor/github.com/garyburd/redigo/internal/commandinfo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package internal // import "github.com/garyburd/redigo/internal" 16 | 17 | import ( 18 | "strings" 19 | ) 20 | 21 | const ( 22 | WatchState = 1 << iota 23 | MultiState 24 | SubscribeState 25 | MonitorState 26 | ) 27 | 28 | type CommandInfo struct { 29 | Set, Clear int 30 | } 31 | 32 | var commandInfos = map[string]CommandInfo{ 33 | "WATCH": {Set: WatchState}, 34 | "UNWATCH": {Clear: WatchState}, 35 | "MULTI": {Set: MultiState}, 36 | "EXEC": {Clear: WatchState | MultiState}, 37 | "DISCARD": {Clear: WatchState | MultiState}, 38 | "PSUBSCRIBE": {Set: SubscribeState}, 39 | "SUBSCRIBE": {Set: SubscribeState}, 40 | "MONITOR": {Set: MonitorState}, 41 | } 42 | 43 | func init() { 44 | for n, ci := range commandInfos { 45 | commandInfos[strings.ToLower(n)] = ci 46 | } 47 | } 48 | 49 | func LookupCommandInfo(commandName string) CommandInfo { 50 | if ci, ok := commandInfos[commandName]; ok { 51 | return ci 52 | } 53 | return commandInfos[strings.ToUpper(commandName)] 54 | } 55 | -------------------------------------------------------------------------------- /vendor/github.com/garyburd/redigo/internal/redistest/testdb.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | // Package redistest contains utilities for writing Redigo tests. 16 | package redistest 17 | 18 | import ( 19 | "errors" 20 | "time" 21 | 22 | "github.com/garyburd/redigo/redis" 23 | ) 24 | 25 | type testConn struct { 26 | redis.Conn 27 | } 28 | 29 | func (t testConn) Close() error { 30 | _, err := t.Conn.Do("SELECT", "9") 31 | if err != nil { 32 | return nil 33 | } 34 | _, err = t.Conn.Do("FLUSHDB") 35 | if err != nil { 36 | return err 37 | } 38 | return t.Conn.Close() 39 | } 40 | 41 | // Dial dials the local Redis server and selects database 9. To prevent 42 | // stomping on real data, DialTestDB fails if database 9 contains data. The 43 | // returned connection flushes database 9 on close. 44 | func Dial() (redis.Conn, error) { 45 | c, err := redis.DialTimeout("tcp", ":6379", 0, 1*time.Second, 1*time.Second) 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | _, err = c.Do("SELECT", "9") 51 | if err != nil { 52 | return nil, err 53 | } 54 | 55 | n, err := redis.Int(c.Do("DBSIZE")) 56 | if err != nil { 57 | return nil, err 58 | } 59 | 60 | if n != 0 { 61 | return nil, errors.New("database #9 is not empty, test can not continue") 62 | } 63 | 64 | return testConn{c}, nil 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/garyburd/redigo/redis/log.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | import ( 18 | "bytes" 19 | "fmt" 20 | "log" 21 | ) 22 | 23 | // NewLoggingConn returns a logging wrapper around a connection. 24 | func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn { 25 | if prefix != "" { 26 | prefix = prefix + "." 27 | } 28 | return &loggingConn{conn, logger, prefix} 29 | } 30 | 31 | type loggingConn struct { 32 | Conn 33 | logger *log.Logger 34 | prefix string 35 | } 36 | 37 | func (c *loggingConn) Close() error { 38 | err := c.Conn.Close() 39 | var buf bytes.Buffer 40 | fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err) 41 | c.logger.Output(2, buf.String()) 42 | return err 43 | } 44 | 45 | func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) { 46 | const chop = 32 47 | switch v := v.(type) { 48 | case []byte: 49 | if len(v) > chop { 50 | fmt.Fprintf(buf, "%q...", v[:chop]) 51 | } else { 52 | fmt.Fprintf(buf, "%q", v) 53 | } 54 | case string: 55 | if len(v) > chop { 56 | fmt.Fprintf(buf, "%q...", v[:chop]) 57 | } else { 58 | fmt.Fprintf(buf, "%q", v) 59 | } 60 | case []interface{}: 61 | if len(v) == 0 { 62 | buf.WriteString("[]") 63 | } else { 64 | sep := "[" 65 | fin := "]" 66 | if len(v) > chop { 67 | v = v[:chop] 68 | fin = "...]" 69 | } 70 | for _, vv := range v { 71 | buf.WriteString(sep) 72 | c.printValue(buf, vv) 73 | sep = ", " 74 | } 75 | buf.WriteString(fin) 76 | } 77 | default: 78 | fmt.Fprint(buf, v) 79 | } 80 | } 81 | 82 | func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) { 83 | var buf bytes.Buffer 84 | fmt.Fprintf(&buf, "%s%s(", c.prefix, method) 85 | if method != "Receive" { 86 | buf.WriteString(commandName) 87 | for _, arg := range args { 88 | buf.WriteString(", ") 89 | c.printValue(&buf, arg) 90 | } 91 | } 92 | buf.WriteString(") -> (") 93 | if method != "Send" { 94 | c.printValue(&buf, reply) 95 | buf.WriteString(", ") 96 | } 97 | fmt.Fprintf(&buf, "%v)", err) 98 | c.logger.Output(3, buf.String()) 99 | } 100 | 101 | func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) { 102 | reply, err := c.Conn.Do(commandName, args...) 103 | c.print("Do", commandName, args, reply, err) 104 | return reply, err 105 | } 106 | 107 | func (c *loggingConn) Send(commandName string, args ...interface{}) error { 108 | err := c.Conn.Send(commandName, args...) 109 | c.print("Send", commandName, args, nil, err) 110 | return err 111 | } 112 | 113 | func (c *loggingConn) Receive() (interface{}, error) { 114 | reply, err := c.Conn.Receive() 115 | c.print("Receive", "", nil, reply, err) 116 | return reply, err 117 | } 118 | -------------------------------------------------------------------------------- /vendor/github.com/garyburd/redigo/redis/pubsub.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | import "errors" 18 | 19 | // Subscription represents a subscribe or unsubscribe notification. 20 | type Subscription struct { 21 | 22 | // Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe" 23 | Kind string 24 | 25 | // The channel that was changed. 26 | Channel string 27 | 28 | // The current number of subscriptions for connection. 29 | Count int 30 | } 31 | 32 | // Message represents a message notification. 33 | type Message struct { 34 | 35 | // The originating channel. 36 | Channel string 37 | 38 | // The message data. 39 | Data []byte 40 | } 41 | 42 | // PMessage represents a pmessage notification. 43 | type PMessage struct { 44 | 45 | // The matched pattern. 46 | Pattern string 47 | 48 | // The originating channel. 49 | Channel string 50 | 51 | // The message data. 52 | Data []byte 53 | } 54 | 55 | // Pong represents a pubsub pong notification. 56 | type Pong struct { 57 | Data string 58 | } 59 | 60 | // PubSubConn wraps a Conn with convenience methods for subscribers. 61 | type PubSubConn struct { 62 | Conn Conn 63 | } 64 | 65 | // Close closes the connection. 66 | func (c PubSubConn) Close() error { 67 | return c.Conn.Close() 68 | } 69 | 70 | // Subscribe subscribes the connection to the specified channels. 71 | func (c PubSubConn) Subscribe(channel ...interface{}) error { 72 | c.Conn.Send("SUBSCRIBE", channel...) 73 | return c.Conn.Flush() 74 | } 75 | 76 | // PSubscribe subscribes the connection to the given patterns. 77 | func (c PubSubConn) PSubscribe(channel ...interface{}) error { 78 | c.Conn.Send("PSUBSCRIBE", channel...) 79 | return c.Conn.Flush() 80 | } 81 | 82 | // Unsubscribe unsubscribes the connection from the given channels, or from all 83 | // of them if none is given. 84 | func (c PubSubConn) Unsubscribe(channel ...interface{}) error { 85 | c.Conn.Send("UNSUBSCRIBE", channel...) 86 | return c.Conn.Flush() 87 | } 88 | 89 | // PUnsubscribe unsubscribes the connection from the given patterns, or from all 90 | // of them if none is given. 91 | func (c PubSubConn) PUnsubscribe(channel ...interface{}) error { 92 | c.Conn.Send("PUNSUBSCRIBE", channel...) 93 | return c.Conn.Flush() 94 | } 95 | 96 | // Ping sends a PING to the server with the specified data. 97 | func (c PubSubConn) Ping(data string) error { 98 | c.Conn.Send("PING", data) 99 | return c.Conn.Flush() 100 | } 101 | 102 | // Receive returns a pushed message as a Subscription, Message, PMessage, Pong 103 | // or error. The return value is intended to be used directly in a type switch 104 | // as illustrated in the PubSubConn example. 105 | func (c PubSubConn) Receive() interface{} { 106 | reply, err := Values(c.Conn.Receive()) 107 | if err != nil { 108 | return err 109 | } 110 | 111 | var kind string 112 | reply, err = Scan(reply, &kind) 113 | if err != nil { 114 | return err 115 | } 116 | 117 | switch kind { 118 | case "message": 119 | var m Message 120 | if _, err := Scan(reply, &m.Channel, &m.Data); err != nil { 121 | return err 122 | } 123 | return m 124 | case "pmessage": 125 | var pm PMessage 126 | if _, err := Scan(reply, &pm.Pattern, &pm.Channel, &pm.Data); err != nil { 127 | return err 128 | } 129 | return pm 130 | case "subscribe", "psubscribe", "unsubscribe", "punsubscribe": 131 | s := Subscription{Kind: kind} 132 | if _, err := Scan(reply, &s.Channel, &s.Count); err != nil { 133 | return err 134 | } 135 | return s 136 | case "pong": 137 | var p Pong 138 | if _, err := Scan(reply, &p.Data); err != nil { 139 | return err 140 | } 141 | return p 142 | } 143 | return errors.New("redigo: unknown pubsub notification") 144 | } 145 | -------------------------------------------------------------------------------- /vendor/github.com/garyburd/redigo/redis/redis.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | // Error represents an error returned in a command reply. 18 | type Error string 19 | 20 | func (err Error) Error() string { return string(err) } 21 | 22 | // Conn represents a connection to a Redis server. 23 | type Conn interface { 24 | // Close closes the connection. 25 | Close() error 26 | 27 | // Err returns a non-nil value if the connection is broken. The returned 28 | // value is either the first non-nil value returned from the underlying 29 | // network connection or a protocol parsing error. Applications should 30 | // close broken connections. 31 | Err() error 32 | 33 | // Do sends a command to the server and returns the received reply. 34 | Do(commandName string, args ...interface{}) (reply interface{}, err error) 35 | 36 | // Send writes the command to the client's output buffer. 37 | Send(commandName string, args ...interface{}) error 38 | 39 | // Flush flushes the output buffer to the Redis server. 40 | Flush() error 41 | 42 | // Receive receives a single reply from the Redis server 43 | Receive() (reply interface{}, err error) 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/garyburd/redigo/redis/script.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Gary Burd 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package redis 16 | 17 | import ( 18 | "crypto/sha1" 19 | "encoding/hex" 20 | "io" 21 | "strings" 22 | ) 23 | 24 | // Script encapsulates the source, hash and key count for a Lua script. See 25 | // http://redis.io/commands/eval for information on scripts in Redis. 26 | type Script struct { 27 | keyCount int 28 | src string 29 | hash string 30 | } 31 | 32 | // NewScript returns a new script object. If keyCount is greater than or equal 33 | // to zero, then the count is automatically inserted in the EVAL command 34 | // argument list. If keyCount is less than zero, then the application supplies 35 | // the count as the first value in the keysAndArgs argument to the Do, Send and 36 | // SendHash methods. 37 | func NewScript(keyCount int, src string) *Script { 38 | h := sha1.New() 39 | io.WriteString(h, src) 40 | return &Script{keyCount, src, hex.EncodeToString(h.Sum(nil))} 41 | } 42 | 43 | func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} { 44 | var args []interface{} 45 | if s.keyCount < 0 { 46 | args = make([]interface{}, 1+len(keysAndArgs)) 47 | args[0] = spec 48 | copy(args[1:], keysAndArgs) 49 | } else { 50 | args = make([]interface{}, 2+len(keysAndArgs)) 51 | args[0] = spec 52 | args[1] = s.keyCount 53 | copy(args[2:], keysAndArgs) 54 | } 55 | return args 56 | } 57 | 58 | // Do evaluates the script. Under the covers, Do optimistically evaluates the 59 | // script using the EVALSHA command. If the command fails because the script is 60 | // not loaded, then Do evaluates the script using the EVAL command (thus 61 | // causing the script to load). 62 | func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) { 63 | v, err := c.Do("EVALSHA", s.args(s.hash, keysAndArgs)...) 64 | if e, ok := err.(Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") { 65 | v, err = c.Do("EVAL", s.args(s.src, keysAndArgs)...) 66 | } 67 | return v, err 68 | } 69 | 70 | // SendHash evaluates the script without waiting for the reply. The script is 71 | // evaluated with the EVALSHA command. The application must ensure that the 72 | // script is loaded by a previous call to Send, Do or Load methods. 73 | func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error { 74 | return c.Send("EVALSHA", s.args(s.hash, keysAndArgs)...) 75 | } 76 | 77 | // Send evaluates the script without waiting for the reply. 78 | func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error { 79 | return c.Send("EVAL", s.args(s.src, keysAndArgs)...) 80 | } 81 | 82 | // Load loads the script without evaluating it. 83 | func (s *Script) Load(c Conn) error { 84 | _, err := c.Do("SCRIPT", "LOAD", s.src) 85 | return err 86 | } 87 | -------------------------------------------------------------------------------- /vendor/github.com/jmespath/go-jmespath/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015 James Saryerwinnie 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /vendor/github.com/jmespath/go-jmespath/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CMD = jpgo 3 | 4 | help: 5 | @echo "Please use \`make ' where is one of" 6 | @echo " test to run all the tests" 7 | @echo " build to build the library and jp executable" 8 | @echo " generate to run codegen" 9 | 10 | 11 | generate: 12 | go generate ./... 13 | 14 | build: 15 | rm -f $(CMD) 16 | go build ./... 17 | rm -f cmd/$(CMD)/$(CMD) && cd cmd/$(CMD)/ && go build ./... 18 | mv cmd/$(CMD)/$(CMD) . 19 | 20 | test: 21 | go test -v ./... 22 | 23 | check: 24 | go vet ./... 25 | @echo "golint ./..." 26 | @lint=`golint ./...`; \ 27 | lint=`echo "$$lint" | grep -v "astnodetype_string.go" | grep -v "toktype_string.go"`; \ 28 | echo "$$lint"; \ 29 | if [ "$$lint" != "" ]; then exit 1; fi 30 | 31 | htmlc: 32 | go test -coverprofile="/tmp/jpcov" && go tool cover -html="/tmp/jpcov" && unlink /tmp/jpcov 33 | 34 | buildfuzz: 35 | go-fuzz-build github.com/jmespath/go-jmespath/fuzz 36 | 37 | fuzz: buildfuzz 38 | go-fuzz -bin=./jmespath-fuzz.zip -workdir=fuzz/corpus 39 | 40 | bench: 41 | go test -bench . -cpuprofile cpu.out 42 | 43 | pprof-cpu: 44 | go tool pprof ./go-jmespath.test ./cpu.out 45 | -------------------------------------------------------------------------------- /vendor/github.com/jmespath/go-jmespath/README.md: -------------------------------------------------------------------------------- 1 | # go-jmespath - A JMESPath implementation in Go 2 | 3 | [![Build Status](https://img.shields.io/travis/jmespath/go-jmespath.svg)](https://travis-ci.org/jmespath/go-jmespath) 4 | 5 | 6 | 7 | See http://jmespath.org for more info. 8 | -------------------------------------------------------------------------------- /vendor/github.com/jmespath/go-jmespath/api.go: -------------------------------------------------------------------------------- 1 | package jmespath 2 | 3 | // Search evaluates a JMESPath expression against input data and returns the result. 4 | func Search(expression string, data interface{}) (interface{}, error) { 5 | intr := newInterpreter() 6 | parser := NewParser() 7 | ast, err := parser.Parse(expression) 8 | if err != nil { 9 | return nil, err 10 | } 11 | return intr.Execute(ast, data) 12 | } 13 | -------------------------------------------------------------------------------- /vendor/github.com/jmespath/go-jmespath/astnodetype_string.go: -------------------------------------------------------------------------------- 1 | // generated by stringer -type astNodeType; DO NOT EDIT 2 | 3 | package jmespath 4 | 5 | import "fmt" 6 | 7 | const _astNodeType_name = "ASTEmptyASTComparatorASTCurrentNodeASTExpRefASTFunctionExpressionASTFieldASTFilterProjectionASTFlattenASTIdentityASTIndexASTIndexExpressionASTKeyValPairASTLiteralASTMultiSelectHashASTMultiSelectListASTOrExpressionASTAndExpressionASTNotExpressionASTPipeASTProjectionASTSubexpressionASTSliceASTValueProjection" 8 | 9 | var _astNodeType_index = [...]uint16{0, 8, 21, 35, 44, 65, 73, 92, 102, 113, 121, 139, 152, 162, 180, 198, 213, 229, 245, 252, 265, 281, 289, 307} 10 | 11 | func (i astNodeType) String() string { 12 | if i < 0 || i >= astNodeType(len(_astNodeType_index)-1) { 13 | return fmt.Sprintf("astNodeType(%d)", i) 14 | } 15 | return _astNodeType_name[_astNodeType_index[i]:_astNodeType_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /vendor/github.com/jmespath/go-jmespath/toktype_string.go: -------------------------------------------------------------------------------- 1 | // generated by stringer -type=tokType; DO NOT EDIT 2 | 3 | package jmespath 4 | 5 | import "fmt" 6 | 7 | const _tokType_name = "tUnknowntStartDottFiltertFlattentLparentRparentLbrackettRbrackettLbracetRbracetOrtPipetNumbertUnquotedIdentifiertQuotedIdentifiertCommatColontLTtLTEtGTtGTEtEQtNEtJSONLiteraltStringLiteraltCurrenttExpreftAndtNottEOF" 8 | 9 | var _tokType_index = [...]uint8{0, 8, 13, 17, 24, 32, 39, 46, 55, 64, 71, 78, 81, 86, 93, 112, 129, 135, 141, 144, 148, 151, 155, 158, 161, 173, 187, 195, 202, 206, 210, 214} 10 | 11 | func (i tokType) String() string { 12 | if i < 0 || i >= tokType(len(_tokType_index)-1) { 13 | return fmt.Sprintf("tokType(%d)", i) 14 | } 15 | return _tokType_name[_tokType_index[i]:_tokType_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /vendor/github.com/joho/godotenv/LICENCE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 John Barton 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | -------------------------------------------------------------------------------- /vendor/github.com/joho/godotenv/README.md: -------------------------------------------------------------------------------- 1 | # GoDotEnv [![wercker status](https://app.wercker.com/status/507594c2ec7e60f19403a568dfea0f78 "wercker status")](https://app.wercker.com/project/bykey/507594c2ec7e60f19403a568dfea0f78) 2 | 3 | A Go (golang) port of the Ruby dotenv project (which loads env vars from a .env file) 4 | 5 | From the original Library: 6 | 7 | > Storing configuration in the environment is one of the tenets of a twelve-factor app. Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment variables. 8 | > 9 | > But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run. Dotenv load variables from a .env file into ENV when the environment is bootstrapped. 10 | 11 | It can be used as a library (for loading in env for your own daemons etc) or as a bin command. 12 | 13 | There is test coverage and CI for both linuxish and windows environments, but I make no guarantees about the bin version working on windows. 14 | 15 | ## Installation 16 | 17 | As a library 18 | 19 | ```shell 20 | go get github.com/joho/godotenv 21 | ``` 22 | 23 | or if you want to use it as a bin command 24 | ```shell 25 | go get github.com/joho/godotenv/cmd/godotenv 26 | ``` 27 | 28 | ## Usage 29 | 30 | Add your application configuration to your `.env` file in the root of your project: 31 | 32 | ```shell 33 | S3_BUCKET=YOURS3BUCKET 34 | SECRET_KEY=YOURSECRETKEYGOESHERE 35 | ``` 36 | 37 | Then in your Go app you can do something like 38 | 39 | ```go 40 | package main 41 | 42 | import ( 43 | "github.com/joho/godotenv" 44 | "log" 45 | "os" 46 | ) 47 | 48 | func main() { 49 | err := godotenv.Load() 50 | if err != nil { 51 | log.Fatal("Error loading .env file") 52 | } 53 | 54 | s3Bucket := os.Getenv("S3_BUCKET") 55 | secretKey := os.Getenv("SECRET_KEY") 56 | 57 | // now do something with s3 or whatever 58 | } 59 | ``` 60 | 61 | If you're even lazier than that, you can just take advantage of the autoload package which will read in `.env` on import 62 | 63 | ```go 64 | import _ "github.com/joho/godotenv/autoload" 65 | ``` 66 | 67 | While `.env` in the project root is the default, you don't have to be constrained, both examples below are 100% legit 68 | 69 | ```go 70 | _ = godotenv.Load("somerandomfile") 71 | _ = godotenv.Load("filenumberone.env", "filenumbertwo.env") 72 | ``` 73 | 74 | If you want to be really fancy with your env file you can do comments and exports (below is a valid env file) 75 | 76 | ```shell 77 | # I am a comment and that is OK 78 | SOME_VAR=someval 79 | FOO=BAR # comments at line end are OK too 80 | export BAR=BAZ 81 | ``` 82 | 83 | Or finally you can do YAML(ish) style 84 | 85 | ```yaml 86 | FOO: bar 87 | BAR: baz 88 | ``` 89 | 90 | as a final aside, if you don't want godotenv munging your env you can just get a map back instead 91 | 92 | ```go 93 | var myEnv map[string]string 94 | myEnv, err := godotenv.Read() 95 | 96 | s3Bucket := myEnv["S3_BUCKET"] 97 | ``` 98 | 99 | ### Command Mode 100 | 101 | Assuming you've installed the command as above and you've got `$GOPATH/bin` in your `$PATH` 102 | 103 | ``` 104 | godotenv -f /some/path/to/.env some_command with some args 105 | ``` 106 | 107 | If you don't specify `-f` it will fall back on the default of loading `.env` in `PWD` 108 | 109 | ## Contributing 110 | 111 | Contributions are most welcome! The parser itself is pretty stupidly naive and I wouldn't be surprised if it breaks with edge cases. 112 | 113 | *code changes without tests will not be accepted* 114 | 115 | 1. Fork it 116 | 2. Create your feature branch (`git checkout -b my-new-feature`) 117 | 3. Commit your changes (`git commit -am 'Added some feature'`) 118 | 4. Push to the branch (`git push origin my-new-feature`) 119 | 5. Create new Pull Request 120 | 121 | ## CI 122 | 123 | Linux: [![wercker status](https://app.wercker.com/status/507594c2ec7e60f19403a568dfea0f78/m "wercker status")](https://app.wercker.com/project/bykey/507594c2ec7e60f19403a568dfea0f78) Windows: [![Build status](https://ci.appveyor.com/api/projects/status/9v40vnfvvgde64u4)](https://ci.appveyor.com/project/joho/godotenv) 124 | 125 | ## Who? 126 | 127 | The original library [dotenv](https://github.com/bkeepers/dotenv) was written by [Brandon Keepers](http://opensoul.org/), and this port was done by [John Barton](http://whoisjohnbarton.com) based off the tests/fixtures in the original library. 128 | -------------------------------------------------------------------------------- /vendor/github.com/joho/godotenv/autoload/autoload.go: -------------------------------------------------------------------------------- 1 | package autoload 2 | 3 | /* 4 | You can just read the .env file on import just by doing 5 | 6 | import _ "github.com/joho/godotenv/autoload" 7 | 8 | And bob's your mother's brother 9 | */ 10 | 11 | import "github.com/joho/godotenv" 12 | 13 | func init() { 14 | godotenv.Load() 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/joho/godotenv/cmd/godotenv/cmd.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "log" 7 | 8 | "strings" 9 | 10 | "github.com/joho/godotenv" 11 | ) 12 | 13 | func main() { 14 | var showHelp bool 15 | flag.BoolVar(&showHelp, "h", false, "show help") 16 | var rawEnvFilenames string 17 | flag.StringVar(&rawEnvFilenames, "f", "", "comma separated paths to .env files") 18 | 19 | flag.Parse() 20 | 21 | usage := ` 22 | Run a process with a env setup from a .env file 23 | 24 | godotenv [-f ENV_FILE_PATHS] COMMAND_ARGS 25 | 26 | ENV_FILE_PATHS: comma separated paths to .env files 27 | COMMAND_ARGS: command and args you want to run 28 | 29 | example 30 | godotenv -f /path/to/something/.env,/another/path/.env fortune 31 | ` 32 | // if no args or -h flag 33 | // print usage and return 34 | args := flag.Args() 35 | if showHelp || len(args) == 0 { 36 | fmt.Println(usage) 37 | return 38 | } 39 | 40 | // load env 41 | var envFilenames []string 42 | if rawEnvFilenames != "" { 43 | envFilenames = strings.Split(rawEnvFilenames, ",") 44 | } 45 | 46 | // take rest of args and "exec" them 47 | cmd := args[0] 48 | cmdArgs := args[1:] 49 | 50 | err := godotenv.Exec(envFilenames, cmd, cmdArgs) 51 | if err != nil { 52 | log.Fatal(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /vendor/github.com/joho/godotenv/wercker.yml: -------------------------------------------------------------------------------- 1 | box: pjvds/golang 2 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Yasuhiro MATSUMOTO 2 | 3 | MIT License (Expat) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/README.md: -------------------------------------------------------------------------------- 1 | # go-isatty 2 | 3 | isatty for golang 4 | 5 | ## Usage 6 | 7 | ```go 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | "github.com/mattn/go-isatty" 13 | "os" 14 | ) 15 | 16 | func main() { 17 | if isatty.IsTerminal(os.Stdout.Fd()) { 18 | fmt.Println("Is Terminal") 19 | } else { 20 | fmt.Println("Is Not Terminal") 21 | } 22 | } 23 | ``` 24 | 25 | ## Installation 26 | 27 | ``` 28 | $ go get github.com/mattn/go-isatty 29 | ``` 30 | 31 | # License 32 | 33 | MIT 34 | 35 | # Author 36 | 37 | Yasuhiro Matsumoto (a.k.a mattn) 38 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/doc.go: -------------------------------------------------------------------------------- 1 | // Package isatty implements interface to isatty 2 | package isatty 3 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/isatty_bsd.go: -------------------------------------------------------------------------------- 1 | // +build darwin freebsd openbsd netbsd 2 | 3 | package isatty 4 | 5 | import ( 6 | "syscall" 7 | "unsafe" 8 | ) 9 | 10 | const ioctlReadTermios = syscall.TIOCGETA 11 | 12 | // IsTerminal return true if the file descriptor is terminal. 13 | func IsTerminal(fd uintptr) bool { 14 | var termios syscall.Termios 15 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) 16 | return err == 0 17 | } 18 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/isatty_linux.go: -------------------------------------------------------------------------------- 1 | // +build linux 2 | 3 | package isatty 4 | 5 | import ( 6 | "syscall" 7 | "unsafe" 8 | ) 9 | 10 | const ioctlReadTermios = syscall.TCGETS 11 | 12 | // IsTerminal return true if the file descriptor is terminal. 13 | func IsTerminal(fd uintptr) bool { 14 | var termios syscall.Termios 15 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) 16 | return err == 0 17 | } 18 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/isatty_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | 3 | package isatty 4 | 5 | import ( 6 | "syscall" 7 | "unsafe" 8 | ) 9 | 10 | var kernel32 = syscall.NewLazyDLL("kernel32.dll") 11 | var procGetConsoleMode = kernel32.NewProc("GetConsoleMode") 12 | 13 | // IsTerminal return true if the file descriptor is terminal. 14 | func IsTerminal(fd uintptr) bool { 15 | var st uint32 16 | r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) 17 | return r != 0 && e == 0 18 | } 19 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Paul Borman 2 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009,2014 Google Inc. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/dce.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "encoding/binary" 9 | "fmt" 10 | "os" 11 | ) 12 | 13 | // A Domain represents a Version 2 domain 14 | type Domain byte 15 | 16 | // Domain constants for DCE Security (Version 2) UUIDs. 17 | const ( 18 | Person = Domain(0) 19 | Group = Domain(1) 20 | Org = Domain(2) 21 | ) 22 | 23 | // NewDCESecurity returns a DCE Security (Version 2) UUID. 24 | // 25 | // The domain should be one of Person, Group or Org. 26 | // On a POSIX system the id should be the users UID for the Person 27 | // domain and the users GID for the Group. The meaning of id for 28 | // the domain Org or on non-POSIX systems is site defined. 29 | // 30 | // For a given domain/id pair the same token may be returned for up to 31 | // 7 minutes and 10 seconds. 32 | func NewDCESecurity(domain Domain, id uint32) UUID { 33 | uuid := NewUUID() 34 | if uuid != nil { 35 | uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 36 | uuid[9] = byte(domain) 37 | binary.BigEndian.PutUint32(uuid[0:], id) 38 | } 39 | return uuid 40 | } 41 | 42 | // NewDCEPerson returns a DCE Security (Version 2) UUID in the person 43 | // domain with the id returned by os.Getuid. 44 | // 45 | // NewDCEPerson(Person, uint32(os.Getuid())) 46 | func NewDCEPerson() UUID { 47 | return NewDCESecurity(Person, uint32(os.Getuid())) 48 | } 49 | 50 | // NewDCEGroup returns a DCE Security (Version 2) UUID in the group 51 | // domain with the id returned by os.Getgid. 52 | // 53 | // NewDCEGroup(Group, uint32(os.Getgid())) 54 | func NewDCEGroup() UUID { 55 | return NewDCESecurity(Group, uint32(os.Getgid())) 56 | } 57 | 58 | // Domain returns the domain for a Version 2 UUID or false. 59 | func (uuid UUID) Domain() (Domain, bool) { 60 | if v, _ := uuid.Version(); v != 2 { 61 | return 0, false 62 | } 63 | return Domain(uuid[9]), true 64 | } 65 | 66 | // Id returns the id for a Version 2 UUID or false. 67 | func (uuid UUID) Id() (uint32, bool) { 68 | if v, _ := uuid.Version(); v != 2 { 69 | return 0, false 70 | } 71 | return binary.BigEndian.Uint32(uuid[0:4]), true 72 | } 73 | 74 | func (d Domain) String() string { 75 | switch d { 76 | case Person: 77 | return "Person" 78 | case Group: 79 | return "Group" 80 | case Org: 81 | return "Org" 82 | } 83 | return fmt.Sprintf("Domain%d", int(d)) 84 | } 85 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // The uuid package generates and inspects UUIDs. 6 | // 7 | // UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services. 8 | package uuid 9 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/hash.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "crypto/md5" 9 | "crypto/sha1" 10 | "hash" 11 | ) 12 | 13 | // Well known Name Space IDs and UUIDs 14 | var ( 15 | NameSpace_DNS = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 16 | NameSpace_URL = Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8") 17 | NameSpace_OID = Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8") 18 | NameSpace_X500 = Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8") 19 | NIL = Parse("00000000-0000-0000-0000-000000000000") 20 | ) 21 | 22 | // NewHash returns a new UUID dervied from the hash of space concatenated with 23 | // data generated by h. The hash should be at least 16 byte in length. The 24 | // first 16 bytes of the hash are used to form the UUID. The version of the 25 | // UUID will be the lower 4 bits of version. NewHash is used to implement 26 | // NewMD5 and NewSHA1. 27 | func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { 28 | h.Reset() 29 | h.Write(space) 30 | h.Write([]byte(data)) 31 | s := h.Sum(nil) 32 | uuid := make([]byte, 16) 33 | copy(uuid, s) 34 | uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) 35 | uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant 36 | return uuid 37 | } 38 | 39 | // NewMD5 returns a new MD5 (Version 3) UUID based on the 40 | // supplied name space and data. 41 | // 42 | // NewHash(md5.New(), space, data, 3) 43 | func NewMD5(space UUID, data []byte) UUID { 44 | return NewHash(md5.New(), space, data, 3) 45 | } 46 | 47 | // NewSHA1 returns a new SHA1 (Version 5) UUID based on the 48 | // supplied name space and data. 49 | // 50 | // NewHash(sha1.New(), space, data, 5) 51 | func NewSHA1(space UUID, data []byte) UUID { 52 | return NewHash(sha1.New(), space, data, 5) 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/json.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import "errors" 8 | 9 | func (u UUID) MarshalJSON() ([]byte, error) { 10 | if len(u) == 0 { 11 | return []byte(`""`), nil 12 | } 13 | return []byte(`"` + u.String() + `"`), nil 14 | } 15 | 16 | func (u *UUID) UnmarshalJSON(data []byte) error { 17 | if len(data) == 0 || string(data) == `""` { 18 | return nil 19 | } 20 | if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' { 21 | return errors.New("invalid UUID format") 22 | } 23 | data = data[1 : len(data)-1] 24 | uu := Parse(string(data)) 25 | if uu == nil { 26 | return errors.New("invalid UUID format") 27 | } 28 | *u = uu 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/node.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import "net" 8 | 9 | var ( 10 | interfaces []net.Interface // cached list of interfaces 11 | ifname string // name of interface being used 12 | nodeID []byte // hardware for version 1 UUIDs 13 | ) 14 | 15 | // NodeInterface returns the name of the interface from which the NodeID was 16 | // derived. The interface "user" is returned if the NodeID was set by 17 | // SetNodeID. 18 | func NodeInterface() string { 19 | return ifname 20 | } 21 | 22 | // SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. 23 | // If name is "" then the first usable interface found will be used or a random 24 | // Node ID will be generated. If a named interface cannot be found then false 25 | // is returned. 26 | // 27 | // SetNodeInterface never fails when name is "". 28 | func SetNodeInterface(name string) bool { 29 | if interfaces == nil { 30 | var err error 31 | interfaces, err = net.Interfaces() 32 | if err != nil && name != "" { 33 | return false 34 | } 35 | } 36 | 37 | for _, ifs := range interfaces { 38 | if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { 39 | if setNodeID(ifs.HardwareAddr) { 40 | ifname = ifs.Name 41 | return true 42 | } 43 | } 44 | } 45 | 46 | // We found no interfaces with a valid hardware address. If name 47 | // does not specify a specific interface generate a random Node ID 48 | // (section 4.1.6) 49 | if name == "" { 50 | if nodeID == nil { 51 | nodeID = make([]byte, 6) 52 | } 53 | randomBits(nodeID) 54 | return true 55 | } 56 | return false 57 | } 58 | 59 | // NodeID returns a slice of a copy of the current Node ID, setting the Node ID 60 | // if not already set. 61 | func NodeID() []byte { 62 | if nodeID == nil { 63 | SetNodeInterface("") 64 | } 65 | nid := make([]byte, 6) 66 | copy(nid, nodeID) 67 | return nid 68 | } 69 | 70 | // SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes 71 | // of id are used. If id is less than 6 bytes then false is returned and the 72 | // Node ID is not set. 73 | func SetNodeID(id []byte) bool { 74 | if setNodeID(id) { 75 | ifname = "user" 76 | return true 77 | } 78 | return false 79 | } 80 | 81 | func setNodeID(id []byte) bool { 82 | if len(id) < 6 { 83 | return false 84 | } 85 | if nodeID == nil { 86 | nodeID = make([]byte, 6) 87 | } 88 | copy(nodeID, id) 89 | return true 90 | } 91 | 92 | // NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is 93 | // not valid. The NodeID is only well defined for version 1 and 2 UUIDs. 94 | func (uuid UUID) NodeID() []byte { 95 | if len(uuid) != 16 { 96 | return nil 97 | } 98 | node := make([]byte, 6) 99 | copy(node, uuid[10:]) 100 | return node 101 | } 102 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/sql.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | ) 11 | 12 | // Scan implements sql.Scanner so UUIDs can be read from databases transparently 13 | // Currently, database types that map to string and []byte are supported. Please 14 | // consult database-specific driver documentation for matching types. 15 | func (uuid *UUID) Scan(src interface{}) error { 16 | switch src.(type) { 17 | case string: 18 | // see uuid.Parse for required string format 19 | parsed := Parse(src.(string)) 20 | 21 | if parsed == nil { 22 | return errors.New("Scan: invalid UUID format") 23 | } 24 | 25 | *uuid = parsed 26 | case []byte: 27 | // assumes a simple slice of bytes, just check validity and store 28 | u := UUID(src.([]byte)) 29 | 30 | if u.Variant() == Invalid { 31 | return errors.New("Scan: invalid UUID format") 32 | } 33 | 34 | *uuid = u 35 | default: 36 | return fmt.Errorf("Scan: unable to scan type %T into UUID", src) 37 | } 38 | 39 | return nil 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/time.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "encoding/binary" 9 | "sync" 10 | "time" 11 | ) 12 | 13 | // A Time represents a time as the number of 100's of nanoseconds since 15 Oct 14 | // 1582. 15 | type Time int64 16 | 17 | const ( 18 | lillian = 2299160 // Julian day of 15 Oct 1582 19 | unix = 2440587 // Julian day of 1 Jan 1970 20 | epoch = unix - lillian // Days between epochs 21 | g1582 = epoch * 86400 // seconds between epochs 22 | g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs 23 | ) 24 | 25 | var ( 26 | mu sync.Mutex 27 | lasttime uint64 // last time we returned 28 | clock_seq uint16 // clock sequence for this run 29 | 30 | timeNow = time.Now // for testing 31 | ) 32 | 33 | // UnixTime converts t the number of seconds and nanoseconds using the Unix 34 | // epoch of 1 Jan 1970. 35 | func (t Time) UnixTime() (sec, nsec int64) { 36 | sec = int64(t - g1582ns100) 37 | nsec = (sec % 10000000) * 100 38 | sec /= 10000000 39 | return sec, nsec 40 | } 41 | 42 | // GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and 43 | // clock sequence as well as adjusting the clock sequence as needed. An error 44 | // is returned if the current time cannot be determined. 45 | func GetTime() (Time, uint16, error) { 46 | defer mu.Unlock() 47 | mu.Lock() 48 | return getTime() 49 | } 50 | 51 | func getTime() (Time, uint16, error) { 52 | t := timeNow() 53 | 54 | // If we don't have a clock sequence already, set one. 55 | if clock_seq == 0 { 56 | setClockSequence(-1) 57 | } 58 | now := uint64(t.UnixNano()/100) + g1582ns100 59 | 60 | // If time has gone backwards with this clock sequence then we 61 | // increment the clock sequence 62 | if now <= lasttime { 63 | clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000 64 | } 65 | lasttime = now 66 | return Time(now), clock_seq, nil 67 | } 68 | 69 | // ClockSequence returns the current clock sequence, generating one if not 70 | // already set. The clock sequence is only used for Version 1 UUIDs. 71 | // 72 | // The uuid package does not use global static storage for the clock sequence or 73 | // the last time a UUID was generated. Unless SetClockSequence a new random 74 | // clock sequence is generated the first time a clock sequence is requested by 75 | // ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated 76 | // for 77 | func ClockSequence() int { 78 | defer mu.Unlock() 79 | mu.Lock() 80 | return clockSequence() 81 | } 82 | 83 | func clockSequence() int { 84 | if clock_seq == 0 { 85 | setClockSequence(-1) 86 | } 87 | return int(clock_seq & 0x3fff) 88 | } 89 | 90 | // SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to 91 | // -1 causes a new sequence to be generated. 92 | func SetClockSequence(seq int) { 93 | defer mu.Unlock() 94 | mu.Lock() 95 | setClockSequence(seq) 96 | } 97 | 98 | func setClockSequence(seq int) { 99 | if seq == -1 { 100 | var b [2]byte 101 | randomBits(b[:]) // clock sequence 102 | seq = int(b[0])<<8 | int(b[1]) 103 | } 104 | old_seq := clock_seq 105 | clock_seq = uint16(seq&0x3fff) | 0x8000 // Set our variant 106 | if old_seq != clock_seq { 107 | lasttime = 0 108 | } 109 | } 110 | 111 | // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in 112 | // uuid. It returns false if uuid is not valid. The time is only well defined 113 | // for version 1 and 2 UUIDs. 114 | func (uuid UUID) Time() (Time, bool) { 115 | if len(uuid) != 16 { 116 | return 0, false 117 | } 118 | time := int64(binary.BigEndian.Uint32(uuid[0:4])) 119 | time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 120 | time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 121 | return Time(time), true 122 | } 123 | 124 | // ClockSequence returns the clock sequence encoded in uuid. It returns false 125 | // if uuid is not valid. The clock sequence is only well defined for version 1 126 | // and 2 UUIDs. 127 | func (uuid UUID) ClockSequence() (int, bool) { 128 | if len(uuid) != 16 { 129 | return 0, false 130 | } 131 | return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff, true 132 | } 133 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "io" 9 | ) 10 | 11 | // randomBits completely fills slice b with random data. 12 | func randomBits(b []byte) { 13 | if _, err := io.ReadFull(rander, b); err != nil { 14 | panic(err.Error()) // rand should never fail 15 | } 16 | } 17 | 18 | // xvalues returns the value of a byte as a hexadecimal digit or 255. 19 | var xvalues = []byte{ 20 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 21 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 23 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 24 | 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 26 | 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 27 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 28 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 29 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 30 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 31 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 32 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 33 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 34 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 35 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 36 | } 37 | 38 | // xtob converts the the first two hex bytes of x into a byte. 39 | func xtob(x string) (byte, bool) { 40 | b1 := xvalues[x[0]] 41 | b2 := xvalues[x[1]] 42 | return (b1 << 4) | b2, b1 != 255 && b2 != 255 43 | } 44 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/uuid.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "fmt" 11 | "io" 12 | "strings" 13 | ) 14 | 15 | // A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC 16 | // 4122. 17 | type UUID []byte 18 | 19 | // A Version represents a UUIDs version. 20 | type Version byte 21 | 22 | // A Variant represents a UUIDs variant. 23 | type Variant byte 24 | 25 | // Constants returned by Variant. 26 | const ( 27 | Invalid = Variant(iota) // Invalid UUID 28 | RFC4122 // The variant specified in RFC4122 29 | Reserved // Reserved, NCS backward compatibility. 30 | Microsoft // Reserved, Microsoft Corporation backward compatibility. 31 | Future // Reserved for future definition. 32 | ) 33 | 34 | var rander = rand.Reader // random function 35 | 36 | // New returns a new random (version 4) UUID as a string. It is a convenience 37 | // function for NewRandom().String(). 38 | func New() string { 39 | return NewRandom().String() 40 | } 41 | 42 | // Parse decodes s into a UUID or returns nil. Both the UUID form of 43 | // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and 44 | // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded. 45 | func Parse(s string) UUID { 46 | if len(s) == 36+9 { 47 | if strings.ToLower(s[:9]) != "urn:uuid:" { 48 | return nil 49 | } 50 | s = s[9:] 51 | } else if len(s) != 36 { 52 | return nil 53 | } 54 | if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { 55 | return nil 56 | } 57 | uuid := make([]byte, 16) 58 | for i, x := range []int{ 59 | 0, 2, 4, 6, 60 | 9, 11, 61 | 14, 16, 62 | 19, 21, 63 | 24, 26, 28, 30, 32, 34} { 64 | if v, ok := xtob(s[x:]); !ok { 65 | return nil 66 | } else { 67 | uuid[i] = v 68 | } 69 | } 70 | return uuid 71 | } 72 | 73 | // Equal returns true if uuid1 and uuid2 are equal. 74 | func Equal(uuid1, uuid2 UUID) bool { 75 | return bytes.Equal(uuid1, uuid2) 76 | } 77 | 78 | // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 79 | // , or "" if uuid is invalid. 80 | func (uuid UUID) String() string { 81 | if uuid == nil || len(uuid) != 16 { 82 | return "" 83 | } 84 | b := []byte(uuid) 85 | return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", 86 | b[:4], b[4:6], b[6:8], b[8:10], b[10:]) 87 | } 88 | 89 | // URN returns the RFC 2141 URN form of uuid, 90 | // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. 91 | func (uuid UUID) URN() string { 92 | if uuid == nil || len(uuid) != 16 { 93 | return "" 94 | } 95 | b := []byte(uuid) 96 | return fmt.Sprintf("urn:uuid:%08x-%04x-%04x-%04x-%012x", 97 | b[:4], b[4:6], b[6:8], b[8:10], b[10:]) 98 | } 99 | 100 | // Variant returns the variant encoded in uuid. It returns Invalid if 101 | // uuid is invalid. 102 | func (uuid UUID) Variant() Variant { 103 | if len(uuid) != 16 { 104 | return Invalid 105 | } 106 | switch { 107 | case (uuid[8] & 0xc0) == 0x80: 108 | return RFC4122 109 | case (uuid[8] & 0xe0) == 0xc0: 110 | return Microsoft 111 | case (uuid[8] & 0xe0) == 0xe0: 112 | return Future 113 | default: 114 | return Reserved 115 | } 116 | panic("unreachable") 117 | } 118 | 119 | // Version returns the verison of uuid. It returns false if uuid is not 120 | // valid. 121 | func (uuid UUID) Version() (Version, bool) { 122 | if len(uuid) != 16 { 123 | return 0, false 124 | } 125 | return Version(uuid[6] >> 4), true 126 | } 127 | 128 | func (v Version) String() string { 129 | if v > 15 { 130 | return fmt.Sprintf("BAD_VERSION_%d", v) 131 | } 132 | return fmt.Sprintf("VERSION_%d", v) 133 | } 134 | 135 | func (v Variant) String() string { 136 | switch v { 137 | case RFC4122: 138 | return "RFC4122" 139 | case Reserved: 140 | return "Reserved" 141 | case Microsoft: 142 | return "Microsoft" 143 | case Future: 144 | return "Future" 145 | case Invalid: 146 | return "Invalid" 147 | } 148 | return fmt.Sprintf("BadVariant%d", int(v)) 149 | } 150 | 151 | // SetRand sets the random number generator to r, which implents io.Reader. 152 | // If r.Read returns an error when the package requests random data then 153 | // a panic will be issued. 154 | // 155 | // Calling SetRand with nil sets the random number generator to the default 156 | // generator. 157 | func SetRand(r io.Reader) { 158 | if r == nil { 159 | rander = rand.Reader 160 | return 161 | } 162 | rander = r 163 | } 164 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/version1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "encoding/binary" 9 | ) 10 | 11 | // NewUUID returns a Version 1 UUID based on the current NodeID and clock 12 | // sequence, and the current time. If the NodeID has not been set by SetNodeID 13 | // or SetNodeInterface then it will be set automatically. If the NodeID cannot 14 | // be set NewUUID returns nil. If clock sequence has not been set by 15 | // SetClockSequence then it will be set automatically. If GetTime fails to 16 | // return the current NewUUID returns nil. 17 | func NewUUID() UUID { 18 | if nodeID == nil { 19 | SetNodeInterface("") 20 | } 21 | 22 | now, seq, err := GetTime() 23 | if err != nil { 24 | return nil 25 | } 26 | 27 | uuid := make([]byte, 16) 28 | 29 | time_low := uint32(now & 0xffffffff) 30 | time_mid := uint16((now >> 32) & 0xffff) 31 | time_hi := uint16((now >> 48) & 0x0fff) 32 | time_hi |= 0x1000 // Version 1 33 | 34 | binary.BigEndian.PutUint32(uuid[0:], time_low) 35 | binary.BigEndian.PutUint16(uuid[4:], time_mid) 36 | binary.BigEndian.PutUint16(uuid[6:], time_hi) 37 | binary.BigEndian.PutUint16(uuid[8:], seq) 38 | copy(uuid[10:], nodeID) 39 | 40 | return uuid 41 | } 42 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/version4.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | // Random returns a Random (Version 4) UUID or panics. 8 | // 9 | // The strength of the UUIDs is based on the strength of the crypto/rand 10 | // package. 11 | // 12 | // A note about uniqueness derived from from the UUID Wikipedia entry: 13 | // 14 | // Randomly generated UUIDs have 122 random bits. One's annual risk of being 15 | // hit by a meteorite is estimated to be one chance in 17 billion, that 16 | // means the probability is about 0.00000000006 (6 × 10−11), 17 | // equivalent to the odds of creating a few tens of trillions of UUIDs in a 18 | // year and having one duplicate. 19 | func NewRandom() UUID { 20 | uuid := make([]byte, 16) 21 | randomBits([]byte(uuid)) 22 | uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 23 | uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 24 | return uuid 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/shiena/ansicolor/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) [2014] [shiena] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/shiena/ansicolor/README.md: -------------------------------------------------------------------------------- 1 | [![GoDoc](https://godoc.org/github.com/shiena/ansicolor?status.svg)](https://godoc.org/github.com/shiena/ansicolor) 2 | 3 | # ansicolor 4 | 5 | Ansicolor library provides color console in Windows as ANSICON for Golang. 6 | 7 | ## Features 8 | 9 | |Escape sequence|Text attributes| 10 | |---------------|----| 11 | |\x1b[0m|All attributes off(color at startup)| 12 | |\x1b[1m|Bold on(enable foreground intensity)| 13 | |\x1b[4m|Underline on| 14 | |\x1b[5m|Blink on(enable background intensity)| 15 | |\x1b[21m|Bold off(disable foreground intensity)| 16 | |\x1b[24m|Underline off| 17 | |\x1b[25m|Blink off(disable background intensity)| 18 | 19 | |Escape sequence|Foreground colors| 20 | |---------------|----| 21 | |\x1b[30m|Black| 22 | |\x1b[31m|Red| 23 | |\x1b[32m|Green| 24 | |\x1b[33m|Yellow| 25 | |\x1b[34m|Blue| 26 | |\x1b[35m|Magenta| 27 | |\x1b[36m|Cyan| 28 | |\x1b[37m|White| 29 | |\x1b[39m|Default(foreground color at startup)| 30 | |\x1b[90m|Light Gray| 31 | |\x1b[91m|Light Red| 32 | |\x1b[92m|Light Green| 33 | |\x1b[93m|Light Yellow| 34 | |\x1b[94m|Light Blue| 35 | |\x1b[95m|Light Magenta| 36 | |\x1b[96m|Light Cyan| 37 | |\x1b[97m|Light White| 38 | 39 | |Escape sequence|Background colors| 40 | |---------------|----| 41 | |\x1b[40m|Black| 42 | |\x1b[41m|Red| 43 | |\x1b[42m|Green| 44 | |\x1b[43m|Yellow| 45 | |\x1b[44m|Blue| 46 | |\x1b[45m|Magenta| 47 | |\x1b[46m|Cyan| 48 | |\x1b[47m|White| 49 | |\x1b[49m|Default(background color at startup)| 50 | |\x1b[100m|Light Gray| 51 | |\x1b[101m|Light Red| 52 | |\x1b[102m|Light Green| 53 | |\x1b[103m|Light Yellow| 54 | |\x1b[104m|Light Blue| 55 | |\x1b[105m|Light Magenta| 56 | |\x1b[106m|Light Cyan| 57 | |\x1b[107m|Light White| 58 | 59 | ## Example 60 | 61 | ```go 62 | package main 63 | 64 | import ( 65 | "fmt" 66 | "os" 67 | 68 | "github.com/shiena/ansicolor" 69 | ) 70 | 71 | func main() { 72 | w := ansicolor.NewAnsiColorWriter(os.Stdout) 73 | text := "%sforeground %sbold%s %sbackground%s\n" 74 | fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m") 75 | fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m") 76 | fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m") 77 | fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m") 78 | fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m") 79 | fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m") 80 | fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m") 81 | } 82 | ``` 83 | 84 | ![screenshot](https://gist.githubusercontent.com/shiena/a1bada24b525314a7d5e/raw/c763aa7cda6e4fefaccf831e2617adc40b6151c7/main.png) 85 | 86 | ## See also: 87 | 88 | - https://github.com/daviddengcn/go-colortext 89 | - https://github.com/adoxa/ansicon 90 | - https://github.com/aslakhellesoy/wac 91 | - https://github.com/wsxiaoys/terminal 92 | 93 | ## Contributing 94 | 95 | 1. Fork it 96 | 2. Create your feature branch (`git checkout -b my-new-feature`) 97 | 3. Commit your changes (`git commit -am 'Add some feature'`) 98 | 4. Push to the branch (`git push origin my-new-feature`) 99 | 5. Create new Pull Request 100 | 101 | -------------------------------------------------------------------------------- /vendor/github.com/shiena/ansicolor/ansicolor.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 shiena Authors. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package ansicolor provides color console in Windows as ANSICON. 6 | package ansicolor 7 | 8 | import "io" 9 | 10 | // NewAnsiColorWriter creates and initializes a new ansiColorWriter 11 | // using io.Writer w as its initial contents. 12 | // In the console of Windows, which change the foreground and background 13 | // colors of the text by the escape sequence. 14 | // In the console of other systems, which writes to w all text. 15 | func NewAnsiColorWriter(w io.Writer) io.Writer { 16 | if _, ok := w.(*ansiColorWriter); !ok { 17 | return &ansiColorWriter{w: w} 18 | } 19 | return w 20 | } 21 | -------------------------------------------------------------------------------- /vendor/github.com/shiena/ansicolor/ansicolor/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 shiena Authors. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | 7 | The ansicolor command colors a console text by ANSI escape sequence like wac. 8 | 9 | $ go get github.com/shiena/ansicolor/ansicolor 10 | 11 | See also: 12 | https://github.com/aslakhellesoy/wac 13 | 14 | */ 15 | package main 16 | 17 | import ( 18 | "io" 19 | "os" 20 | 21 | "github.com/shiena/ansicolor" 22 | ) 23 | 24 | func main() { 25 | w := ansicolor.NewAnsiColorWriter(os.Stdout) 26 | io.Copy(w, os.Stdin) 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/shiena/ansicolor/ansicolor_ansi.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 shiena Authors. All rights reserved. 2 | // Use of this source code is governed by a MIT-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !windows 6 | 7 | package ansicolor 8 | 9 | import "io" 10 | 11 | type ansiColorWriter struct { 12 | w io.Writer 13 | } 14 | 15 | func (cw *ansiColorWriter) Write(p []byte) (int, error) { 16 | return cw.w.Write(p) 17 | } 18 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/LICENSE.md: -------------------------------------------------------------------------------- 1 | objx - by Mat Ryer and Tyler Bunnell 2 | 3 | The MIT License (MIT) 4 | 5 | Copyright (c) 2014 Stretchr, Inc. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/README.md: -------------------------------------------------------------------------------- 1 | # objx 2 | 3 | * Jump into the [API Documentation](http://godoc.org/github.com/stretchr/objx) 4 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/constants.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | const ( 4 | // PathSeparator is the character used to separate the elements 5 | // of the keypath. 6 | // 7 | // For example, `location.address.city` 8 | PathSeparator string = "." 9 | 10 | // SignatureSeparator is the character that is used to 11 | // separate the Base64 string from the security signature. 12 | SignatureSeparator = "_" 13 | ) 14 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/conversions.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | import ( 4 | "bytes" 5 | "encoding/base64" 6 | "encoding/json" 7 | "errors" 8 | "fmt" 9 | "net/url" 10 | ) 11 | 12 | // JSON converts the contained object to a JSON string 13 | // representation 14 | func (m Map) JSON() (string, error) { 15 | 16 | result, err := json.Marshal(m) 17 | 18 | if err != nil { 19 | err = errors.New("objx: JSON encode failed with: " + err.Error()) 20 | } 21 | 22 | return string(result), err 23 | 24 | } 25 | 26 | // MustJSON converts the contained object to a JSON string 27 | // representation and panics if there is an error 28 | func (m Map) MustJSON() string { 29 | result, err := m.JSON() 30 | if err != nil { 31 | panic(err.Error()) 32 | } 33 | return result 34 | } 35 | 36 | // Base64 converts the contained object to a Base64 string 37 | // representation of the JSON string representation 38 | func (m Map) Base64() (string, error) { 39 | 40 | var buf bytes.Buffer 41 | 42 | jsonData, err := m.JSON() 43 | if err != nil { 44 | return "", err 45 | } 46 | 47 | encoder := base64.NewEncoder(base64.StdEncoding, &buf) 48 | encoder.Write([]byte(jsonData)) 49 | encoder.Close() 50 | 51 | return buf.String(), nil 52 | 53 | } 54 | 55 | // MustBase64 converts the contained object to a Base64 string 56 | // representation of the JSON string representation and panics 57 | // if there is an error 58 | func (m Map) MustBase64() string { 59 | result, err := m.Base64() 60 | if err != nil { 61 | panic(err.Error()) 62 | } 63 | return result 64 | } 65 | 66 | // SignedBase64 converts the contained object to a Base64 string 67 | // representation of the JSON string representation and signs it 68 | // using the provided key. 69 | func (m Map) SignedBase64(key string) (string, error) { 70 | 71 | base64, err := m.Base64() 72 | if err != nil { 73 | return "", err 74 | } 75 | 76 | sig := HashWithKey(base64, key) 77 | 78 | return base64 + SignatureSeparator + sig, nil 79 | 80 | } 81 | 82 | // MustSignedBase64 converts the contained object to a Base64 string 83 | // representation of the JSON string representation and signs it 84 | // using the provided key and panics if there is an error 85 | func (m Map) MustSignedBase64(key string) string { 86 | result, err := m.SignedBase64(key) 87 | if err != nil { 88 | panic(err.Error()) 89 | } 90 | return result 91 | } 92 | 93 | /* 94 | URL Query 95 | ------------------------------------------------ 96 | */ 97 | 98 | // URLValues creates a url.Values object from an Obj. This 99 | // function requires that the wrapped object be a map[string]interface{} 100 | func (m Map) URLValues() url.Values { 101 | 102 | vals := make(url.Values) 103 | 104 | for k, v := range m { 105 | //TODO: can this be done without sprintf? 106 | vals.Set(k, fmt.Sprintf("%v", v)) 107 | } 108 | 109 | return vals 110 | } 111 | 112 | // URLQuery gets an encoded URL query representing the given 113 | // Obj. This function requires that the wrapped object be a 114 | // map[string]interface{} 115 | func (m Map) URLQuery() (string, error) { 116 | return m.URLValues().Encode(), nil 117 | } 118 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/doc.go: -------------------------------------------------------------------------------- 1 | // objx - Go package for dealing with maps, slices, JSON and other data. 2 | // 3 | // Overview 4 | // 5 | // Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes 6 | // a powerful `Get` method (among others) that allows you to easily and quickly get 7 | // access to data within the map, without having to worry too much about type assertions, 8 | // missing data, default values etc. 9 | // 10 | // Pattern 11 | // 12 | // Objx uses a preditable pattern to make access data from within `map[string]interface{}'s 13 | // easy. 14 | // 15 | // Call one of the `objx.` functions to create your `objx.Map` to get going: 16 | // 17 | // m, err := objx.FromJSON(json) 18 | // 19 | // NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong, 20 | // the rest will be optimistic and try to figure things out without panicking. 21 | // 22 | // Use `Get` to access the value you're interested in. You can use dot and array 23 | // notation too: 24 | // 25 | // m.Get("places[0].latlng") 26 | // 27 | // Once you have saught the `Value` you're interested in, you can use the `Is*` methods 28 | // to determine its type. 29 | // 30 | // if m.Get("code").IsStr() { /* ... */ } 31 | // 32 | // Or you can just assume the type, and use one of the strong type methods to 33 | // extract the real value: 34 | // 35 | // m.Get("code").Int() 36 | // 37 | // If there's no value there (or if it's the wrong type) then a default value 38 | // will be returned, or you can be explicit about the default value. 39 | // 40 | // Get("code").Int(-1) 41 | // 42 | // If you're dealing with a slice of data as a value, Objx provides many useful 43 | // methods for iterating, manipulating and selecting that data. You can find out more 44 | // by exploring the index below. 45 | // 46 | // Reading data 47 | // 48 | // A simple example of how to use Objx: 49 | // 50 | // // use MustFromJSON to make an objx.Map from some JSON 51 | // m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) 52 | // 53 | // // get the details 54 | // name := m.Get("name").Str() 55 | // age := m.Get("age").Int() 56 | // 57 | // // get their nickname (or use their name if they 58 | // // don't have one) 59 | // nickname := m.Get("nickname").Str(name) 60 | // 61 | // Ranging 62 | // 63 | // Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For 64 | // example, to `range` the data, do what you would expect: 65 | // 66 | // m := objx.MustFromJSON(json) 67 | // for key, value := range m { 68 | // 69 | // /* ... do your magic ... */ 70 | // 71 | // } 72 | package objx 73 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/mutations.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | // Exclude returns a new Map with the keys in the specified []string 4 | // excluded. 5 | func (d Map) Exclude(exclude []string) Map { 6 | 7 | excluded := make(Map) 8 | for k, v := range d { 9 | var shouldInclude bool = true 10 | for _, toExclude := range exclude { 11 | if k == toExclude { 12 | shouldInclude = false 13 | break 14 | } 15 | } 16 | if shouldInclude { 17 | excluded[k] = v 18 | } 19 | } 20 | 21 | return excluded 22 | } 23 | 24 | // Copy creates a shallow copy of the Obj. 25 | func (m Map) Copy() Map { 26 | copied := make(map[string]interface{}) 27 | for k, v := range m { 28 | copied[k] = v 29 | } 30 | return New(copied) 31 | } 32 | 33 | // Merge blends the specified map with a copy of this map and returns the result. 34 | // 35 | // Keys that appear in both will be selected from the specified map. 36 | // This method requires that the wrapped object be a map[string]interface{} 37 | func (m Map) Merge(merge Map) Map { 38 | return m.Copy().MergeHere(merge) 39 | } 40 | 41 | // Merge blends the specified map with this map and returns the current map. 42 | // 43 | // Keys that appear in both will be selected from the specified map. The original map 44 | // will be modified. This method requires that 45 | // the wrapped object be a map[string]interface{} 46 | func (m Map) MergeHere(merge Map) Map { 47 | 48 | for k, v := range merge { 49 | m[k] = v 50 | } 51 | 52 | return m 53 | 54 | } 55 | 56 | // Transform builds a new Obj giving the transformer a chance 57 | // to change the keys and values as it goes. This method requires that 58 | // the wrapped object be a map[string]interface{} 59 | func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map { 60 | newMap := make(map[string]interface{}) 61 | for k, v := range m { 62 | modifiedKey, modifiedVal := transformer(k, v) 63 | newMap[modifiedKey] = modifiedVal 64 | } 65 | return New(newMap) 66 | } 67 | 68 | // TransformKeys builds a new map using the specified key mapping. 69 | // 70 | // Unspecified keys will be unaltered. 71 | // This method requires that the wrapped object be a map[string]interface{} 72 | func (m Map) TransformKeys(mapping map[string]string) Map { 73 | return m.Transform(func(key string, value interface{}) (string, interface{}) { 74 | 75 | if newKey, ok := mapping[key]; ok { 76 | return newKey, value 77 | } 78 | 79 | return key, value 80 | }) 81 | } 82 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/security.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | import ( 4 | "crypto/sha1" 5 | "encoding/hex" 6 | ) 7 | 8 | // HashWithKey hashes the specified string using the security 9 | // key. 10 | func HashWithKey(data, key string) string { 11 | hash := sha1.New() 12 | hash.Write([]byte(data + ":" + key)) 13 | return hex.EncodeToString(hash.Sum(nil)) 14 | } 15 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/tests.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | // Has gets whether there is something at the specified selector 4 | // or not. 5 | // 6 | // If m is nil, Has will always return false. 7 | func (m Map) Has(selector string) bool { 8 | if m == nil { 9 | return false 10 | } 11 | return !m.Get(selector).IsNil() 12 | } 13 | 14 | // IsNil gets whether the data is nil or not. 15 | func (v *Value) IsNil() bool { 16 | return v == nil || v.data == nil 17 | } 18 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/objx/value.go: -------------------------------------------------------------------------------- 1 | package objx 2 | 3 | // Value provides methods for extracting interface{} data in various 4 | // types. 5 | type Value struct { 6 | // data contains the raw data being managed by this Value 7 | data interface{} 8 | } 9 | 10 | // Data returns the raw data contained by this Value 11 | func (v *Value) Data() interface{} { 12 | return v.data 13 | } 14 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/doc.go: -------------------------------------------------------------------------------- 1 | // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. 2 | // 3 | // Example Usage 4 | // 5 | // The following is a complete example using assert in a standard test function: 6 | // import ( 7 | // "testing" 8 | // "github.com/stretchr/testify/assert" 9 | // ) 10 | // 11 | // func TestSomething(t *testing.T) { 12 | // 13 | // var a string = "Hello" 14 | // var b string = "Hello" 15 | // 16 | // assert.Equal(t, a, b, "The two words should be the same.") 17 | // 18 | // } 19 | // 20 | // if you assert many times, use the format below: 21 | // 22 | // import ( 23 | // "testing" 24 | // "github.com/stretchr/testify/assert" 25 | // ) 26 | // 27 | // func TestSomething(t *testing.T) { 28 | // assert := assert.New(t) 29 | // 30 | // var a string = "Hello" 31 | // var b string = "Hello" 32 | // 33 | // assert.Equal(a, b, "The two words should be the same.") 34 | // } 35 | // 36 | // Assertions 37 | // 38 | // Assertions allow you to easily write test code, and are global funcs in the `assert` package. 39 | // All assertion functions take, as the first argument, the `*testing.T` object provided by the 40 | // testing framework. This allows the assertion funcs to write the failings and other details to 41 | // the correct place. 42 | // 43 | // Every assertion function also takes an optional string message as the final argument, 44 | // allowing custom error messages to be appended to the message the assertion method outputs. 45 | package assert 46 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/assert/errors.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | // AnError is an error instance useful for testing. If the code does not care 8 | // about error specifics, and only needs to return the error for example, this 9 | // error should be used to make the test code more readable. 10 | var AnError = errors.New("assert.AnError general error for testing") 11 | -------------------------------------------------------------------------------- /vendor/github.com/stretchr/testify/mock/doc.go: -------------------------------------------------------------------------------- 1 | // Provides a system by which it is possible to mock your objects and verify calls are happening as expected. 2 | // 3 | // Example Usage 4 | // 5 | // The mock package provides an object, Mock, that tracks activity on another object. It is usually 6 | // embedded into a test object as shown below: 7 | // 8 | // type MyTestObject struct { 9 | // // add a Mock object instance 10 | // mock.Mock 11 | // 12 | // // other fields go here as normal 13 | // } 14 | // 15 | // When implementing the methods of an interface, you wire your functions up 16 | // to call the Mock.Called(args...) method, and return the appropriate values. 17 | // 18 | // For example, to mock a method that saves the name and age of a person and returns 19 | // the year of their birth or an error, you might write this: 20 | // 21 | // func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) { 22 | // args := o.Called(firstname, lastname, age) 23 | // return args.Int(0), args.Error(1) 24 | // } 25 | // 26 | // The Int, Error and Bool methods are examples of strongly typed getters that take the argument 27 | // index position. Given this argument list: 28 | // 29 | // (12, true, "Something") 30 | // 31 | // You could read them out strongly typed like this: 32 | // 33 | // args.Int(0) 34 | // args.Bool(1) 35 | // args.String(2) 36 | // 37 | // For objects of your own type, use the generic Arguments.Get(index) method and make a type assertion: 38 | // 39 | // return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine) 40 | // 41 | // This may cause a panic if the object you are getting is nil (the type assertion will fail), in those 42 | // cases you should check for nil first. 43 | package mock 44 | --------------------------------------------------------------------------------