-
Notifications
You must be signed in to change notification settings - Fork 0
/
http.go
151 lines (127 loc) · 3.13 KB
/
http.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 secrets
import (
"bytes"
"context"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
MySecretKeeper = "127.0.0.1:10109" // available to apps running on the local host
)
// Http is a Keeper that interacts with the zostay-secrets keeper server to
// retrieve secrets.
type Http struct {
baseURL string
}
// NewHttp creates a new Http Keeper.
func NewHttp() *Http {
return &Http{
baseURL: MySecretKeeper,
}
}
// GetSecretResponse is the response expected from GET requests to the Keeper
// HTTP server.
type GetSecretResponse struct {
Err string
Secret string
}
// GetSecret contacts the HTTP server secret Keeper with the name of the secret
// to retrieve. If there is an error contacting the server, reading the response
// from the server, or the server returns an error in the response, an error is
// returned. Otherwise, the secret is returned.
func (h *Http) GetSecret(name string) (*Secret, error) {
res, err := http.Get("http://" + h.baseURL + "/secret?name=" + url.QueryEscape(name))
if err != nil {
return nil, err
}
bs, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
var gsr GetSecretResponse
err = json.Unmarshal(bs, &gsr)
if err != nil {
return nil, err
}
if gsr.Err != "" {
return nil, ErrNotFound
}
return &Secret{
Name: name,
Value: gsr.Secret,
}, nil
}
// SetSecretRequest is the structure of requests to the HTTP secret Keeper
// server.
type SetSecretRequest struct {
Name string
Secret string
}
// SetSecretResponse is the structure of responess from the HTTP secret Keeper
// server.
type SetSecretResponse struct {
Err string
}
// SetSecret sends the given name and secret value to the HTTP secret server for
// storage. If there is an error formatting the message, contacting the server,
// reading the response from the server, or the server returned an error in the
// response, an error will be returned.
//
// On success, this function returns nil.
func (h *Http) SetSecret(secret *Secret) error {
ssr := SetSecretRequest{secret.Name, secret.Value}
obs, err := json.Marshal(ssr)
if err != nil {
return err
}
br := bytes.NewReader(obs)
res, err := http.Post("http://"+h.baseURL+"/secret", "application/json", br)
if err != nil {
return err
}
bs, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}
var ssres SetSecretResponse
err = json.Unmarshal(bs, &ssres)
if err != nil {
return err
}
if ssres.Err != "" {
return errors.New(ssres.Err)
}
return nil
}
func (h *Http) RemoveSecret(name string) error {
return errors.New("not implemented")
}
// Ping performs a ping request on the server and confirms that the answer from
// the server is as expected. On success, returns nil. On failure, returns an
// error.
func (h *Http) Ping(ctx context.Context) error {
req, err := http.NewRequestWithContext(
ctx,
"GET",
"http://"+h.baseURL+"/ping",
nil,
)
if err != nil {
return err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
bs, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}
if string(bs) != "HELLO" {
return errors.New("invalid secret keeper server")
}
return nil
}