traefik/vendor/github.com/oracle/oci-go-sdk/common/helpers.go
2019-03-14 11:04:04 +01:00

245 lines
5.6 KiB
Go

// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
package common
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"reflect"
"strconv"
"strings"
"time"
)
// String returns a pointer to the provided string
func String(value string) *string {
return &value
}
// Int returns a pointer to the provided int
func Int(value int) *int {
return &value
}
// Int64 returns a pointer to the provided int64
func Int64(value int64) *int64 {
return &value
}
// Uint returns a pointer to the provided uint
func Uint(value uint) *uint {
return &value
}
//Float32 returns a pointer to the provided float32
func Float32(value float32) *float32 {
return &value
}
//Float64 returns a pointer to the provided float64
func Float64(value float64) *float64 {
return &value
}
//Bool returns a pointer to the provided bool
func Bool(value bool) *bool {
return &value
}
//PointerString prints the values of pointers in a struct
//Producing a human friendly string for an struct with pointers.
//useful when debugging the values of a struct
func PointerString(datastruct interface{}) (representation string) {
val := reflect.ValueOf(datastruct)
typ := reflect.TypeOf(datastruct)
all := make([]string, 2)
all = append(all, "{")
for i := 0; i < typ.NumField(); i++ {
sf := typ.Field(i)
//unexported
if sf.PkgPath != "" && !sf.Anonymous {
continue
}
sv := val.Field(i)
stringValue := ""
if isNil(sv) {
stringValue = fmt.Sprintf("%s=<nil>", sf.Name)
} else {
if sv.Type().Kind() == reflect.Ptr {
sv = sv.Elem()
}
stringValue = fmt.Sprintf("%s=%v", sf.Name, sv)
}
all = append(all, stringValue)
}
all = append(all, "}")
representation = strings.TrimSpace(strings.Join(all, " "))
return
}
// SDKTime a struct that parses/renders to/from json using RFC339 date-time information
type SDKTime struct {
time.Time
}
// SDKDate a struct that parses/renders to/from json using only date information
type SDKDate struct {
//Date date information
Date time.Time
}
func sdkTimeFromTime(t time.Time) SDKTime {
return SDKTime{t}
}
func sdkDateFromTime(t time.Time) SDKDate {
return SDKDate{Date: t}
}
func formatTime(t SDKTime) string {
return t.Format(sdkTimeFormat)
}
func formatDate(t SDKDate) string {
return t.Date.Format(sdkDateFormat)
}
func now() *SDKTime {
t := SDKTime{time.Now()}
return &t
}
var timeType = reflect.TypeOf(SDKTime{})
var timeTypePtr = reflect.TypeOf(&SDKTime{})
var sdkDateType = reflect.TypeOf(SDKDate{})
var sdkDateTypePtr = reflect.TypeOf(&SDKDate{})
//Formats for sdk supported time representations
const sdkTimeFormat = time.RFC3339Nano
const rfc1123OptionalLeadingDigitsInDay = "Mon, _2 Jan 2006 15:04:05 MST"
const sdkDateFormat = "2006-01-02"
func tryParsingTimeWithValidFormatsForHeaders(data []byte, headerName string) (t time.Time, err error) {
header := strings.ToLower(headerName)
switch header {
case "lastmodified", "date":
t, err = tryParsing(data, time.RFC3339Nano, time.RFC3339, time.RFC1123, rfc1123OptionalLeadingDigitsInDay, time.RFC850, time.ANSIC)
return
default: //By default we parse with RFC3339
t, err = time.Parse(sdkTimeFormat, string(data))
return
}
}
func tryParsing(data []byte, layouts ...string) (tm time.Time, err error) {
datestring := string(data)
for _, l := range layouts {
tm, err = time.Parse(l, datestring)
if err == nil {
return
}
}
err = fmt.Errorf("Could not parse time: %s with formats: %s", datestring, layouts[:])
return
}
// String returns string representation of SDKDate
func (t *SDKDate) String() string {
return t.Date.Format(sdkDateFormat)
}
// NewSDKDateFromString parses the dateString into SDKDate
func NewSDKDateFromString(dateString string) (*SDKDate, error) {
parsedTime, err := time.Parse(sdkDateFormat, dateString)
if err != nil {
return nil, err
}
return &SDKDate{Date: parsedTime}, nil
}
// UnmarshalJSON unmarshals from json
func (t *SDKTime) UnmarshalJSON(data []byte) (e error) {
s := string(data)
if s == "null" {
t.Time = time.Time{}
} else {
//Try parsing with RFC3339
t.Time, e = time.Parse(`"`+sdkTimeFormat+`"`, string(data))
}
return
}
// MarshalJSON marshals to JSON
func (t *SDKTime) MarshalJSON() (buff []byte, e error) {
s := t.Format(sdkTimeFormat)
buff = []byte(`"` + s + `"`)
return
}
// UnmarshalJSON unmarshals from json
func (t *SDKDate) UnmarshalJSON(data []byte) (e error) {
if string(data) == `"null"` {
t.Date = time.Time{}
return
}
t.Date, e = tryParsing(data,
strconv.Quote(sdkDateFormat),
)
return
}
// MarshalJSON marshals to JSON
func (t *SDKDate) MarshalJSON() (buff []byte, e error) {
s := t.Date.Format(sdkDateFormat)
buff = []byte(strconv.Quote(s))
return
}
// PrivateKeyFromBytes is a helper function that will produce a RSA private
// key from bytes.
func PrivateKeyFromBytes(pemData []byte, password *string) (key *rsa.PrivateKey, e error) {
if pemBlock, _ := pem.Decode(pemData); pemBlock != nil {
decrypted := pemBlock.Bytes
if x509.IsEncryptedPEMBlock(pemBlock) {
if password == nil {
e = fmt.Errorf("private_key_password is required for encrypted private keys")
return
}
if decrypted, e = x509.DecryptPEMBlock(pemBlock, []byte(*password)); e != nil {
return
}
}
key, e = x509.ParsePKCS1PrivateKey(decrypted)
} else {
e = fmt.Errorf("PEM data was not found in buffer")
return
}
return
}
func generateRandUUID() (string, error) {
b := make([]byte, 16)
_, err := rand.Read(b)
if err != nil {
return "", err
}
uuid := fmt.Sprintf("%x%x%x%x%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
return uuid, nil
}
func makeACopy(original []string) []string {
tmp := make([]string, len(original))
copy(tmp, original)
return tmp
}