1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
package internal
import (
"bytes"
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"os"
"reflect"
"strings"
"github.com/mitchellh/go-homedir"
)
// RemainingKeys will inspect a struct and compare it to a map. Any struct
// field that does not have a JSON tag that matches a key in the map or
// a matching lower-case field in the map will be returned as an extra.
//
// This is useful for determining the extra fields returned in response bodies
// for resources that can contain an arbitrary or dynamic number of fields.
func RemainingKeys(s interface{}, m map[string]interface{}) (extras map[string]interface{}) {
extras = make(map[string]interface{})
for k, v := range m {
extras[k] = v
}
valueOf := reflect.ValueOf(s)
typeOf := reflect.TypeOf(s)
for i := 0; i < valueOf.NumField(); i++ {
field := typeOf.Field(i)
lowerField := strings.ToLower(field.Name)
delete(extras, lowerField)
if tagValue := field.Tag.Get("json"); tagValue != "" && tagValue != "-" {
delete(extras, tagValue)
}
}
return
}
// PrepareTLSConfig generates TLS config based on the specifed parameters
func PrepareTLSConfig(caCertFile, clientCertFile, clientKeyFile string, insecure *bool) (*tls.Config, error) {
config := &tls.Config{}
if caCertFile != "" {
caCert, _, err := pathOrContents(caCertFile)
if err != nil {
return nil, fmt.Errorf("Error reading CA Cert: %s", err)
}
caCertPool := x509.NewCertPool()
if ok := caCertPool.AppendCertsFromPEM(bytes.TrimSpace(caCert)); !ok {
return nil, fmt.Errorf("Error parsing CA Cert from %s", caCertFile)
}
config.RootCAs = caCertPool
}
if insecure == nil {
config.InsecureSkipVerify = false
} else {
config.InsecureSkipVerify = *insecure
}
if clientCertFile != "" && clientKeyFile != "" {
clientCert, _, err := pathOrContents(clientCertFile)
if err != nil {
return nil, fmt.Errorf("Error reading Client Cert: %s", err)
}
clientKey, _, err := pathOrContents(clientKeyFile)
if err != nil {
return nil, fmt.Errorf("Error reading Client Key: %s", err)
}
cert, err := tls.X509KeyPair(clientCert, clientKey)
if err != nil {
return nil, err
}
config.Certificates = []tls.Certificate{cert}
config.BuildNameToCertificate()
}
return config, nil
}
func pathOrContents(poc string) ([]byte, bool, error) {
if len(poc) == 0 {
return nil, false, nil
}
path := poc
if path[0] == '~' {
var err error
path, err = homedir.Expand(path)
if err != nil {
return []byte(path), true, err
}
}
if _, err := os.Stat(path); err == nil {
contents, err := ioutil.ReadFile(path)
if err != nil {
return contents, true, err
}
return contents, true, nil
}
return []byte(poc), false, nil
}
|