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