-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathkong.go
127 lines (98 loc) · 2.72 KB
/
kong.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
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/gojektech/heimdall/httpclient"
)
type kongClient struct {
httpClient *httpclient.Client
kongAdminURL string
}
func newKongClient(kongHost, kongAdminPort string, timeout time.Duration) *kongClient {
if timeout == 0 {
timeout = 1000 * time.Millisecond
}
return &kongClient{
kongAdminURL: fmt.Sprintf("%s:%s", kongHost, kongAdminPort),
httpClient: httpclient.NewClient(httpclient.WithHTTPTimeout(timeout)),
}
}
type upstreamResponse struct {
Data []upstream `json:"data"`
}
type upstream struct {
ID string `json:"id"`
Name string `json:"name"`
}
func (kc *kongClient) upstreams() ([]upstream, error) {
upstreams := []upstream{}
respBytes, err := kc.doRequest(http.MethodGet, "upstreams", nil)
if err != nil {
return upstreams, err
}
upstreamResponse := &upstreamResponse{}
err = json.Unmarshal(respBytes, upstreamResponse)
if err != nil {
return upstreams, err
}
return upstreamResponse.Data, nil
}
type target struct {
ID string `json:"id,omitempty"`
URL string `json:"target"`
Weight int `json:"weight"`
UpstreamID string `json:"upstream_id,omitempty"`
}
type targetResponse struct {
Data []target `json:"data"`
}
func (kc *kongClient) targetsFor(upstreamID string) ([]target, error) {
targets := []target{}
respBytes, err := kc.doRequest(http.MethodGet, fmt.Sprintf("upstreams/%s/targets", upstreamID), nil)
if err != nil {
return targets, err
}
targetResponse := &targetResponse{}
err = json.Unmarshal(respBytes, targetResponse)
if err != nil {
return targets, err
}
return targetResponse.Data, nil
}
func (kc *kongClient) setTargetWeightFor(upstreamID, targetURL string, weight int) error {
target := target{URL: targetURL, Weight: weight}
requestBody, err := json.Marshal(target)
if err != nil {
return err
}
_, err = kc.doRequest(http.MethodPost, fmt.Sprintf("upstreams/%s/targets", upstreamID), requestBody)
if err != nil {
return err
}
return nil
}
func (kc *kongClient) doRequest(method, path string, body []byte) ([]byte, error) {
var respBytes []byte
req, err := http.NewRequest(method, fmt.Sprintf("%s/%s", kc.kongAdminURL, path), bytes.NewBuffer(body))
if err != nil {
return respBytes, fmt.Errorf("failed to create request: %s", err)
}
req.Header.Set("Content-Type", "application/json")
response, err := kc.httpClient.Do(req)
if err != nil {
return respBytes, err
}
defer response.Body.Close()
respBytes, err = ioutil.ReadAll(response.Body)
if err != nil {
return respBytes, err
}
if response.StatusCode >= http.StatusBadRequest {
return respBytes, fmt.Errorf("failed with status: %d", response.StatusCode)
}
return respBytes, nil
}