-
Notifications
You must be signed in to change notification settings - Fork 38
/
vault.lua
121 lines (107 loc) · 2.8 KB
/
vault.lua
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
local http = require "resty.http"
local cjson = require "cjson.safe"
local _M = {}
local mt = {__index = _M}
function _M.new(conf)
conf = conf or {}
local base_url = conf.https and "https://" or "http://"
base_url = base_url .. (conf.host or "127.0.0.1")
base_url = base_url .. ":" .. (conf.port or "8200")
local prefix = conf.kv_path
if not prefix then
prefix = "/acme"
elseif path:sub(1, 1) ~= "/" then
prefix = "/" .. prefix
end
local metadata_url = base_url .. "/v1/secret/metadata" .. prefix .. "/"
local data_url = base_url .. "/v1/secret/data" .. prefix .. "/"
local self =
setmetatable(
{
timeout = conf.timeout or 2000,
data_url = data_url,
metadata_url = metadata_url,
},
mt
)
self.headers = {
["X-Vault-Token"] = conf.token,
}
return self, nil
end
local function api(self, method, uri, payload)
local ok, err
-- vault don't keepalive, we create a new instance for every request
local client = http:new()
client:set_timeout(self.timeout)
local payload = payload and cjson.encode(payload)
local res, err = client:request_uri(uri, {
method = method,
headers = self.headers,
body = payload,
})
if err then
return nil, err
end
client:close()
-- return "soft error" for not found and successful delete
if res.status == 404 or res.status == 204 then
return nil, nil
end
-- "true" "false" is also valid through cjson
local decoded, err = cjson.decode(res.body)
if not decoded then
return nil, "unable to decode response body " .. (err or 'nil')
end
return decoded, err
end
function _M:set(k, v)
local res, err = api(self, "POST", self.data_url .. k, {
data = {
value = v,
note = "managed by lua-resty-acme",
}
})
if not res or err then
return err or "set key failed"
end
return nil
end
function _M:delete(k)
local res, err = api(self, "DELETE", self.metadata_url .. k)
if err then
return "delete key failed"
end
end
function _M:get(k)
local res, err = api(self, 'GET', self.data_url .. k)
if err then
return nil, err
elseif not res or not res["data"] or not res["data"]["data"]
or not res["data"]["data"]["value"] then
return nil, nil
end
return res["data"]["data"]["value"], err
end
local empty_table = {}
function _M:list(prefix)
local res, err = api(self, 'LIST', self.metadata_url)
if err then
return nil, err
elseif not res or not res['data'] or not res['data']['keys'] then
return empty_table, nil
end
local ret = {}
local prefix_length = #prefix
for _, key in ipairs(res['data']['keys']) do
local key, err = ngx.re.match(key, [[([^/]+)$]], "jo")
if key then
key = key[1]
if key:sub(1, prefix_length) == prefix then
table.insert(ret, key)
end
end
end
return ret
end
return _M