Move to vendor
Signed-off-by: Olivier Gambier <olivier@docker.com>
This commit is contained in:
parent
c8d8e7e357
commit
77e69b9cf3
1268 changed files with 34 additions and 24 deletions
76
vendor/github.com/denverdino/aliyungo/util/attempt.go
generated
vendored
Normal file
76
vendor/github.com/denverdino/aliyungo/util/attempt.go
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// AttemptStrategy is reused from the goamz package
|
||||
|
||||
// AttemptStrategy represents a strategy for waiting for an action
|
||||
// to complete successfully. This is an internal type used by the
|
||||
// implementation of other packages.
|
||||
type AttemptStrategy struct {
|
||||
Total time.Duration // total duration of attempt.
|
||||
Delay time.Duration // interval between each try in the burst.
|
||||
Min int // minimum number of retries; overrides Total
|
||||
}
|
||||
|
||||
type Attempt struct {
|
||||
strategy AttemptStrategy
|
||||
last time.Time
|
||||
end time.Time
|
||||
force bool
|
||||
count int
|
||||
}
|
||||
|
||||
// Start begins a new sequence of attempts for the given strategy.
|
||||
func (s AttemptStrategy) Start() *Attempt {
|
||||
now := time.Now()
|
||||
return &Attempt{
|
||||
strategy: s,
|
||||
last: now,
|
||||
end: now.Add(s.Total),
|
||||
force: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Next waits until it is time to perform the next attempt or returns
|
||||
// false if it is time to stop trying.
|
||||
func (a *Attempt) Next() bool {
|
||||
now := time.Now()
|
||||
sleep := a.nextSleep(now)
|
||||
if !a.force && !now.Add(sleep).Before(a.end) && a.strategy.Min <= a.count {
|
||||
return false
|
||||
}
|
||||
a.force = false
|
||||
if sleep > 0 && a.count > 0 {
|
||||
time.Sleep(sleep)
|
||||
now = time.Now()
|
||||
}
|
||||
a.count++
|
||||
a.last = now
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *Attempt) nextSleep(now time.Time) time.Duration {
|
||||
sleep := a.strategy.Delay - now.Sub(a.last)
|
||||
if sleep < 0 {
|
||||
return 0
|
||||
}
|
||||
return sleep
|
||||
}
|
||||
|
||||
// HasNext returns whether another attempt will be made if the current
|
||||
// one fails. If it returns true, the following call to Next is
|
||||
// guaranteed to return true.
|
||||
func (a *Attempt) HasNext() bool {
|
||||
if a.force || a.strategy.Min > a.count {
|
||||
return true
|
||||
}
|
||||
now := time.Now()
|
||||
if now.Add(a.nextSleep(now)).Before(a.end) {
|
||||
a.force = true
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
152
vendor/github.com/denverdino/aliyungo/util/encoding.go
generated
vendored
Normal file
152
vendor/github.com/denverdino/aliyungo/util/encoding.go
generated
vendored
Normal file
|
@ -0,0 +1,152 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
//ConvertToQueryValues converts the struct to url.Values
|
||||
func ConvertToQueryValues(ifc interface{}) url.Values {
|
||||
values := url.Values{}
|
||||
SetQueryValues(ifc, &values)
|
||||
return values
|
||||
}
|
||||
|
||||
//SetQueryValues sets the struct to existing url.Values following ECS encoding rules
|
||||
func SetQueryValues(ifc interface{}, values *url.Values) {
|
||||
setQueryValues(ifc, values, "")
|
||||
}
|
||||
|
||||
func setQueryValues(i interface{}, values *url.Values, prefix string) {
|
||||
// add to support url.Values
|
||||
mapValues, ok := i.(url.Values)
|
||||
if ok {
|
||||
for k, _ := range mapValues {
|
||||
values.Set(k, mapValues.Get(k))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
elem := reflect.ValueOf(i)
|
||||
if elem.Kind() == reflect.Ptr {
|
||||
elem = elem.Elem()
|
||||
}
|
||||
elemType := elem.Type()
|
||||
|
||||
for i := 0; i < elem.NumField(); i++ {
|
||||
fieldName := elemType.Field(i).Name
|
||||
anonymous := elemType.Field(i).Anonymous
|
||||
field := elem.Field(i)
|
||||
// TODO Use Tag for validation
|
||||
// tag := typ.Field(i).Tag.Get("tagname")
|
||||
kind := field.Kind()
|
||||
if (kind == reflect.Ptr || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map || kind == reflect.Chan) && field.IsNil() {
|
||||
continue
|
||||
}
|
||||
if kind == reflect.Ptr {
|
||||
field = field.Elem()
|
||||
kind = field.Kind()
|
||||
}
|
||||
var value string
|
||||
//switch field.Interface().(type) {
|
||||
switch kind {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
i := field.Int()
|
||||
if i != 0 {
|
||||
value = strconv.FormatInt(i, 10)
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
i := field.Uint()
|
||||
if i != 0 {
|
||||
value = strconv.FormatUint(i, 10)
|
||||
}
|
||||
case reflect.Float32:
|
||||
value = strconv.FormatFloat(field.Float(), 'f', 4, 32)
|
||||
case reflect.Float64:
|
||||
value = strconv.FormatFloat(field.Float(), 'f', 4, 64)
|
||||
case reflect.Bool:
|
||||
value = strconv.FormatBool(field.Bool())
|
||||
case reflect.String:
|
||||
value = field.String()
|
||||
case reflect.Map:
|
||||
ifc := field.Interface()
|
||||
m := ifc.(map[string]string)
|
||||
if m != nil {
|
||||
j := 0
|
||||
for k, v := range m {
|
||||
j++
|
||||
keyName := fmt.Sprintf("%s.%d.Key", fieldName, j)
|
||||
values.Set(keyName, k)
|
||||
valueName := fmt.Sprintf("%s.%d.Value", fieldName, j)
|
||||
values.Set(valueName, v)
|
||||
}
|
||||
}
|
||||
case reflect.Slice:
|
||||
switch field.Type().Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
value = string(field.Bytes())
|
||||
case reflect.String:
|
||||
l := field.Len()
|
||||
if l > 0 {
|
||||
strArray := make([]string, l)
|
||||
for i := 0; i < l; i++ {
|
||||
strArray[i] = field.Index(i).String()
|
||||
}
|
||||
bytes, err := json.Marshal(strArray)
|
||||
if err == nil {
|
||||
value = string(bytes)
|
||||
} else {
|
||||
log.Printf("Failed to convert JSON: %v", err)
|
||||
}
|
||||
}
|
||||
default:
|
||||
l := field.Len()
|
||||
for j := 0; j < l; j++ {
|
||||
prefixName := fmt.Sprintf("%s.%d.", fieldName, (j + 1))
|
||||
ifc := field.Index(j).Interface()
|
||||
//log.Printf("%s : %v", prefixName, ifc)
|
||||
if ifc != nil {
|
||||
setQueryValues(ifc, values, prefixName)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
default:
|
||||
switch field.Interface().(type) {
|
||||
case ISO6801Time:
|
||||
t := field.Interface().(ISO6801Time)
|
||||
value = t.String()
|
||||
case time.Time:
|
||||
t := field.Interface().(time.Time)
|
||||
value = GetISO8601TimeStamp(t)
|
||||
default:
|
||||
ifc := field.Interface()
|
||||
if ifc != nil {
|
||||
if anonymous {
|
||||
SetQueryValues(ifc, values)
|
||||
} else {
|
||||
prefixName := fieldName + "."
|
||||
setQueryValues(ifc, values, prefixName)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if value != "" {
|
||||
name := elemType.Field(i).Tag.Get("ArgName")
|
||||
if name == "" {
|
||||
name = fieldName
|
||||
}
|
||||
if prefix != "" {
|
||||
name = prefix + name
|
||||
}
|
||||
values.Set(name, value)
|
||||
}
|
||||
}
|
||||
}
|
80
vendor/github.com/denverdino/aliyungo/util/iso6801.go
generated
vendored
Normal file
80
vendor/github.com/denverdino/aliyungo/util/iso6801.go
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GetISO8601TimeStamp gets timestamp string in ISO8601 format
|
||||
func GetISO8601TimeStamp(ts time.Time) string {
|
||||
t := ts.UTC()
|
||||
return fmt.Sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
|
||||
}
|
||||
|
||||
const formatISO8601 = "2006-01-02T15:04:05Z"
|
||||
const jsonFormatISO8601 = `"` + formatISO8601 + `"`
|
||||
const formatISO8601withoutSeconds = "2006-01-02T15:04Z"
|
||||
const jsonFormatISO8601withoutSeconds = `"` + formatISO8601withoutSeconds + `"`
|
||||
|
||||
// A ISO6801Time represents a time in ISO8601 format
|
||||
type ISO6801Time time.Time
|
||||
|
||||
// New constructs a new iso8601.Time instance from an existing
|
||||
// time.Time instance. This causes the nanosecond field to be set to
|
||||
// 0, and its time zone set to a fixed zone with no offset from UTC
|
||||
// (but it is *not* UTC itself).
|
||||
func NewISO6801Time(t time.Time) ISO6801Time {
|
||||
return ISO6801Time(time.Date(
|
||||
t.Year(),
|
||||
t.Month(),
|
||||
t.Day(),
|
||||
t.Hour(),
|
||||
t.Minute(),
|
||||
t.Second(),
|
||||
0,
|
||||
time.UTC,
|
||||
))
|
||||
}
|
||||
|
||||
// IsDefault checks if the time is default
|
||||
func (it *ISO6801Time) IsDefault() bool {
|
||||
return *it == ISO6801Time{}
|
||||
}
|
||||
|
||||
// MarshalJSON serializes the ISO6801Time into JSON string
|
||||
func (it ISO6801Time) MarshalJSON() ([]byte, error) {
|
||||
return []byte(time.Time(it).Format(jsonFormatISO8601)), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON deserializes the ISO6801Time from JSON string
|
||||
func (it *ISO6801Time) UnmarshalJSON(data []byte) error {
|
||||
str := string(data)
|
||||
|
||||
if str == "\"\"" || len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
var t time.Time
|
||||
var err error
|
||||
if str[0] == '"' {
|
||||
t, err = time.ParseInLocation(jsonFormatISO8601, str, time.UTC)
|
||||
if err != nil {
|
||||
t, err = time.ParseInLocation(jsonFormatISO8601withoutSeconds, str, time.UTC)
|
||||
}
|
||||
} else {
|
||||
var i int64
|
||||
i, err = strconv.ParseInt(str, 10, 64)
|
||||
if err == nil {
|
||||
t = time.Unix(i/1000, i%1000)
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
*it = ISO6801Time(t)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// String returns the time in ISO6801Time format
|
||||
func (it ISO6801Time) String() string {
|
||||
return time.Time(it).Format(formatISO8601)
|
||||
}
|
40
vendor/github.com/denverdino/aliyungo/util/signature.go
generated
vendored
Normal file
40
vendor/github.com/denverdino/aliyungo/util/signature.go
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//CreateSignature creates signature for string following Aliyun rules
|
||||
func CreateSignature(stringToSignature, accessKeySecret string) string {
|
||||
// Crypto by HMAC-SHA1
|
||||
hmacSha1 := hmac.New(sha1.New, []byte(accessKeySecret))
|
||||
hmacSha1.Write([]byte(stringToSignature))
|
||||
sign := hmacSha1.Sum(nil)
|
||||
|
||||
// Encode to Base64
|
||||
base64Sign := base64.StdEncoding.EncodeToString(sign)
|
||||
|
||||
return base64Sign
|
||||
}
|
||||
|
||||
func percentReplace(str string) string {
|
||||
str = strings.Replace(str, "+", "%20", -1)
|
||||
str = strings.Replace(str, "*", "%2A", -1)
|
||||
str = strings.Replace(str, "%7E", "~", -1)
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// CreateSignatureForRequest creates signature for query string values
|
||||
func CreateSignatureForRequest(method string, values *url.Values, accessKeySecret string) string {
|
||||
|
||||
canonicalizedQueryString := percentReplace(values.Encode())
|
||||
|
||||
stringToSign := method + "&%2F&" + url.QueryEscape(canonicalizedQueryString)
|
||||
|
||||
return CreateSignature(stringToSign, accessKeySecret)
|
||||
}
|
147
vendor/github.com/denverdino/aliyungo/util/util.go
generated
vendored
Normal file
147
vendor/github.com/denverdino/aliyungo/util/util.go
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
srand "crypto/rand"
|
||||
"encoding/binary"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
const dictionary = "_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
//CreateRandomString create random string
|
||||
func CreateRandomString() string {
|
||||
b := make([]byte, 32)
|
||||
l := len(dictionary)
|
||||
|
||||
_, err := srand.Read(b)
|
||||
|
||||
if err != nil {
|
||||
// fail back to insecure rand
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
for i := range b {
|
||||
b[i] = dictionary[rand.Int()%l]
|
||||
}
|
||||
} else {
|
||||
for i, v := range b {
|
||||
b[i] = dictionary[v%byte(l)]
|
||||
}
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// Encode encodes the values into ``URL encoded'' form
|
||||
// ("acl&bar=baz&foo=quux") sorted by key.
|
||||
func Encode(v url.Values) string {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
keys := make([]string, 0, len(v))
|
||||
for k := range v {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
vs := v[k]
|
||||
prefix := url.QueryEscape(k)
|
||||
for _, v := range vs {
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteByte('&')
|
||||
}
|
||||
buf.WriteString(prefix)
|
||||
if v != "" {
|
||||
buf.WriteString("=")
|
||||
buf.WriteString(url.QueryEscape(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func GetGMTime() string {
|
||||
return time.Now().UTC().Format(http.TimeFormat)
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
func randUint32() uint32 {
|
||||
return randUint32Slice(1)[0]
|
||||
}
|
||||
|
||||
func randUint32Slice(c int) []uint32 {
|
||||
b := make([]byte, c*4)
|
||||
|
||||
_, err := srand.Read(b)
|
||||
|
||||
if err != nil {
|
||||
// fail back to insecure rand
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
for i := range b {
|
||||
b[i] = byte(rand.Int())
|
||||
}
|
||||
}
|
||||
|
||||
n := make([]uint32, c)
|
||||
|
||||
for i := range n {
|
||||
n[i] = binary.BigEndian.Uint32(b[i*4 : i*4+4])
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func toByte(n uint32, st, ed byte) byte {
|
||||
return byte(n%uint32(ed-st+1) + uint32(st))
|
||||
}
|
||||
|
||||
func toDigit(n uint32) byte {
|
||||
return toByte(n, '0', '9')
|
||||
}
|
||||
|
||||
func toLowerLetter(n uint32) byte {
|
||||
return toByte(n, 'a', 'z')
|
||||
}
|
||||
|
||||
func toUpperLetter(n uint32) byte {
|
||||
return toByte(n, 'A', 'Z')
|
||||
}
|
||||
|
||||
type convFunc func(uint32) byte
|
||||
|
||||
var convFuncs = []convFunc{toDigit, toLowerLetter, toUpperLetter}
|
||||
|
||||
// tools for generating a random ECS instance password
|
||||
// from 8 to 30 char MUST contain digit upper, case letter and upper case letter
|
||||
// http://docs.aliyun.com/#/pub/ecs/open-api/instance&createinstance
|
||||
func GenerateRandomECSPassword() string {
|
||||
|
||||
// [8, 30]
|
||||
l := int(randUint32()%23 + 8)
|
||||
|
||||
n := randUint32Slice(l)
|
||||
|
||||
b := make([]byte, l)
|
||||
|
||||
b[0] = toDigit(n[0])
|
||||
b[1] = toLowerLetter(n[1])
|
||||
b[2] = toUpperLetter(n[2])
|
||||
|
||||
for i := 3; i < l; i++ {
|
||||
b[i] = convFuncs[n[i]%3](n[i])
|
||||
}
|
||||
|
||||
s := make([]byte, l)
|
||||
perm := rand.Perm(l)
|
||||
for i, v := range perm {
|
||||
s[v] = b[i]
|
||||
}
|
||||
|
||||
return string(s)
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue