/
client.go
142 lines (121 loc) · 3.43 KB
/
client.go
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package salt
import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"io"
"io/ioutil"
"log"
"net/http"
"net/http/cookiejar"
"strings"
"time"
)
var _ Client = (*client)(nil)
type (
Client interface {
Login(ctx context.Context, username, password, eauth string) error
Logout(ctx context.Context) error
ListMinions(ctx context.Context) ([]Minion, error)
GetMinion(ctx context.Context, mid string) (*Minion, error)
LocalClient(ctx context.Context, tgt, fun string, arg []string, opts ...RunOption) (map[string]LocalClientReturn, error)
LocalClientAsync(ctx context.Context, tgt, fun string, arg []string, opts ...RunOption) (jid string, err error)
ListJobs(ctx context.Context) ([]Job, error)
GetJob(ctx context.Context, jid string) (*Job, error)
Hook(ctx context.Context, id string, payload interface{}) error
Stats(ctx context.Context) (*stats, error)
// Wheel Client Keys
ListKeys(ctx context.Context) (*ListKeysReturn, error)
GetKeyString(ctx context.Context, match string) (map[string]string, error)
GetKeyFinger(ctx context.Context, match string) (map[string]string, error)
AcceptKey(ctx context.Context, match string) ([]string, error)
RejectedKey(ctx context.Context, match string) ([]string, error)
DeleteKey(ctx context.Context, match string) ([]string, error)
// Runner Client
ManageStatus(ctx context.Context) (*ManageStatusReturn, error)
}
client struct {
httpClient *http.Client
baseAPI string
token string
}
clientOptions struct {
skipVerify bool
timeout time.Duration
}
ClientOption func(options *clientOptions)
)
func WithInsecure() ClientOption {
return func(options *clientOptions) {
options.skipVerify = true
}
}
func WithTimeout(timeout time.Duration) ClientOption {
return func(options *clientOptions) {
options.timeout = timeout
}
}
func NewClient(baseAPI string, opts ...ClientOption) *client {
options := clientOptions{
skipVerify: false,
timeout: 60,
}
for _, o := range opts {
o(&options)
}
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatalf("Got error while creating cookie jar %s", err.Error())
}
c := &client{
baseAPI: baseAPI,
}
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: options.skipVerify,
},
}
c.httpClient = &http.Client{Transport: tr, Jar: jar, Timeout: options.timeout * time.Second}
return c
}
func (c *client) doRequest(ctx context.Context, method, uri string, data interface{}) ([]byte, error) {
url := strings.Join([]string{c.baseAPI, uri}, "/")
var buf io.ReadWriter
if data != nil {
buf = &bytes.Buffer{}
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
err := enc.Encode(data)
if err != nil {
return nil, err
}
}
req, err := http.NewRequestWithContext(ctx, method, url, buf)
if err != nil {
return nil, err
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
if c.token != "" {
req.Header.Set("X-Auth-Token", c.token)
}
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return respBody, nil
}
func (c *client) get(ctx context.Context, uri string) ([]byte, error) {
return c.doRequest(ctx, "GET", uri, nil)
}
func (c *client) post(ctx context.Context, uri string, data interface{}) ([]byte, error) {
return c.doRequest(ctx, "POST", uri, data)
}