-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclient.go
151 lines (140 loc) · 3.78 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
143
144
145
146
147
148
149
150
151
package infoblox
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"sync"
)
// Config - Configuration details for connecting to infoblox
type Config struct {
Host string
Port string
Version string
Username string
Password string
DisableTLSVerification bool
}
// Client - base client for infoblox interactions
type Client struct {
client *http.Client
config Config
baseURL string
cookies []*http.Cookie
eaDefinitions []EADefinition
OrchestratorEAs *ExtensibleAttribute
SequentialLock sync.Mutex
}
// New - creates a new infoblox client
func New(config Config) Client {
var client *http.Client
if config.DisableTLSVerification {
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client = &http.Client{Transport: transport}
} else {
client = http.DefaultClient
}
return Client{
client: client,
config: config,
baseURL: fmt.Sprintf("https://%s:%s/wapi/v%s", config.Host, config.Port, config.Version),
}
}
// BuildQuery creates query string
func (c *Client) BuildQuery(params map[string]string) string {
q := url.Values{}
for k, v := range params {
q.Add(k, v)
}
return q.Encode()
}
// CreateJSONRequest - helper function for creating json based http requests
func (c *Client) CreateJSONRequest(method string, path string, params interface{}) (*http.Request, error) {
var request *http.Request
var buf bytes.Buffer
err := json.NewEncoder(&buf).Encode(¶ms)
if err != nil {
return request, err
}
combinedPath := fmt.Sprintf("%s/%s", c.baseURL, path)
request, err = http.NewRequest(method, combinedPath, &buf)
if err != nil {
return request, err
}
if buf.Len() == 0 {
request.Body = http.NoBody
}
request.Header.Set("Content-Type", "application/json")
return request, nil
}
// Call - function for handling http requests
func (c *Client) Call(request *http.Request, result interface{}) *ResponseError {
request.SetBasicAuth(c.config.Username, c.config.Password)
// Use cookies for auth if set
if len(c.cookies) > 0 {
for i := range c.cookies {
request.AddCookie(c.cookies[i])
}
}
response, err := c.client.Do(request)
if err != nil {
return &ResponseError{
StatusCode: 0,
Request: fmt.Sprintf("%+v", request),
ResponseBody: "",
ErrorMessage: fmt.Sprint(err),
}
}
defer response.Body.Close()
if !(response.StatusCode >= 200 && response.StatusCode <= 299) {
var rawBodyBuffer bytes.Buffer
// Decode raw response, usually contains
// additional error details
body := io.TeeReader(response.Body, &rawBodyBuffer)
var responseBody interface{}
json.NewDecoder(body).Decode(&responseBody)
return &ResponseError{
StatusCode: response.StatusCode,
Request: fmt.Sprintf("%+v", request),
ResponseBody: fmt.Sprintf("%+v", responseBody),
ErrorMessage: fmt.Sprintf("Request %+v\n failed with status code %d\n response %+v", request,
response.StatusCode, responseBody),
}
}
// Add cookies if none exist
if len(c.cookies) == 0 {
c.cookies = response.Request.Cookies()
}
// If no result is expected, don't attempt to decode a potentially
// empty response stream and avoid incurring EOF errors
if result == nil {
return nil
}
err = json.NewDecoder(response.Body).Decode(&result)
if err != nil {
return &ResponseError{
StatusCode: 0,
Request: fmt.Sprintf("%+v", request),
ResponseBody: "",
ErrorMessage: fmt.Sprint(err),
}
}
return nil
}
// Logout clears auth cookie
func (c *Client) Logout() error {
request, err := c.CreateJSONRequest(http.MethodPost, "logout", nil)
if err != nil {
return err
}
response := c.Call(request, nil)
if response != nil {
return fmt.Errorf(response.ErrorMessage)
}
return nil
}