Skip to content

Commit 8621698

Browse files
authored
Merge pull request #4 from spigell/master
Docs
2 parents aed804d + d0b5649 commit 8621698

File tree

6 files changed

+205
-6
lines changed

6 files changed

+205
-6
lines changed

chef/README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
# chef [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/chef?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/chef)
22

3-
## Usage
3+
## Functions
4+
5+
- `client(client_name, path_to_file_with_key, chef_url, http_client_ud)` - returns chef client instance for further usage. Required [http](https://github.com/vadv/gopher-lua-libs/tree/master/http) client instance as `http_client_ud`. Please note that you must specify last slash in `chef_url`.
6+
7+
## Methods
8+
### client
9+
- `search(index, query, [partical_data], [params]` - make [search](https://docs.chef.io/api_chef_server.html#search) by given INDEX and query. Also possible use partical search and specify `offset`, `limit`, `order_by` in `params`.
10+
- `request(verb, url)` - make request to chef server.
11+
12+
13+
## Examples
414

515
```lua
616

717
local http = require("http")
818
local chef = require("chef")
19+
local inspect = require("inspect")
920

1021
local http_client = http.client({insecure_ssl=true})
1122
local client = chef.client(
@@ -18,7 +29,7 @@ local client = chef.client(
1829
-- list nodes
1930
local result, err = client:request("GET", "nodes")
2031
if err then error(err) end
21-
print(result[1][1]) -- { {node_name_1=url_node_name_1}, {node_name_2=url_node_name_2} }
32+
print(inspect(result)) -- { [node_name_1=url_node_name_1], [node_name_2=url_node_name_2] }
2233

2334
-- get node
2435
local result, err = client:request("GET", "nodes/node_name")

cmd/README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
# cmd [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/cmd?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/cmd)
22

3-
## Usage
3+
4+
## Functions
5+
`exec(command, [timeout=10])` - execute command via [exec.Start](https://golang.org/pkg/os/exec/#Cmd.Start). Will wait while command is executed.
6+
Returns table with values
7+
- `status`
8+
- `stdout`
9+
- `stderr`
10+
11+
The default timeout is 10 seconds after which the command will be terminated. The default timeout may be overriden with an optional timeout value (seconds).
12+
13+
## Examples
414

515
```lua
616
local cmd = require("cmd")
@@ -14,8 +24,6 @@ if err then error(err) end
1424
if not(result.status == 0) then error("status") end
1525
```
1626

17-
The default timeout is 10 seconds after which the command will be terminated. The default timeout may be overriden with an optional timeout value (seconds).
18-
1927
```lua
2028
local cmd = require("cmd")
2129
local runtime = require("runtime")

crypto/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# crypto [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/crypto?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/crypto)
22

3-
## Usage
3+
## Functions
4+
- `md5(string)` - return md5 checksum from string.
5+
- `sha256(string)` - return sha256 checksum from string.
6+
7+
## Examples
48

59
```lua
610
local crypto = require("crypto")
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Usage
2+
3+
Let's assume you have such configuration in alertmanager for slack.
4+
```
5+
slack_configs:
6+
- channel: "<you_channel>"
7+
api_url: "<you_apr_url>"
8+
callback_id: 'silence'
9+
title: "[ {{ .GroupLabels.alertname }}: {{ .CommonAnnotations.summary }} ]"
10+
text: '{{ range .Alerts }} {{ .Annotations.description }} {{ "\n" }} {{ end }}'
11+
12+
actions:
13+
- type: 'button'
14+
text: '{{ if eq .Status "firing" }} Silence for 24 hours {{ else }}{{ end }}'
15+
name: 'silence' # We used that value in bot
16+
style: '{{ if eq .Status "firing" }}danger{{ else }}good{{ end }}'
17+
value: '{{ if eq .Status "firing" }}{"labels": [ {{ range .GroupLabels.SortedPairs }} { "{{ .Name }}": "{{ .Value }}" }, {{ end }} { "alertname": "{{ .GroupLabels.alertname }}" } ], "duration": "24", "url": "{{ .ExternalURL }}" } {{end}}'
18+
19+
```
20+
21+
Alertmanager uses value as container for pass data to this bot. Field `duration` indicates silence time period in hours.
22+
23+
Start bot:
24+
```
25+
$ GLUA_LOG_SCRIPT_LEVEL=debug glua-libs ./bot.lua
26+
```
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
local http = require("http")
2+
local inspect = require("inspect")
3+
local json = require("json")
4+
local time = require("time")
5+
local cmd = require("cmd")
6+
local strings = require("strings")
7+
local filepath = require("filepath")
8+
9+
package.path = filepath.dir(debug.getinfo(1).source) .. './?.lua;' .. package.path
10+
functions = require("functions")
11+
12+
log_level = os.getenv("GLUA_SCRIPT_LOG_LEVEL") or 'info'
13+
local server, err = http.server("127.0.0.1:3001")
14+
if err then error(err) end
15+
16+
-- main block program
17+
while true do
18+
local req, resp = server:accept() -- lock and wait request
19+
20+
local raw_body, err = req.body()
21+
if err then error(err) end
22+
resp:code(200)
23+
resp:done()
24+
25+
if req.method == 'POST' then
26+
27+
body, err = json.decode(urldecode(raw_body:gsub("payload=", "")))
28+
if err then error(err) end
29+
30+
actions = body['actions']
31+
response_url = body['response_url']
32+
user = body['user']['name']
33+
34+
original_message = body['original_message']
35+
original_attach = original_message['attachments']
36+
original_fields = original_attach[1]['fields']
37+
38+
if log_level == 'debug' then
39+
print("[DEBUG] RAW BODY: \n"..inspect(body))
40+
print("[DEBUG] ACTIONS: \n"..inspect(actions))
41+
end
42+
43+
for _, v in pairs(actions) do --parce actions
44+
45+
if v['value'] ~= "" then
46+
j, err = json.decode(v['value'])
47+
duration = j['duration']
48+
alertmanager_url = j['url']
49+
if err then error(err) end
50+
51+
if j['labels'] then
52+
matchers = {}
53+
for n, v in pairs(j['labels']) do --making data for alertmanager
54+
for k, v in pairs(v) do
55+
matcher = {isRegex = false, name = k, value = v}
56+
table.insert(matchers, n, matcher)
57+
end
58+
end
59+
60+
else
61+
print("[INFO] No labels in value container")
62+
end
63+
64+
end_time = format_time_with_offset(duration)
65+
start_time = format_time_with_offset(0)
66+
silence = {comment = "Silenced by Slack!", createdBy = user, startsAt = start_time, endsAt = end_time, matchers = matchers}
67+
data, err = json.encode(silence)
68+
if err then error(err) end
69+
70+
client = http.client()
71+
url = alertmanager_url.."/api/v2/silences" -- Bot uses api v2
72+
request, err = http.request("POST", url, data)
73+
request:header_set("Content-Type", "application/json")
74+
75+
if err then error(err) end
76+
77+
local result, err = client:do_request(request)
78+
if err then
79+
error(err)
80+
elseif result.code ~= 200 then
81+
error(result.body)
82+
else
83+
-- We need to create new message for slack with changed field
84+
85+
silenced_text = ":thumbsup: successfully silenced by "..user.." for "..duration.." hours (ends "..end_time..")"
86+
for _, v in pairs(original_fields) do
87+
if v['title'] == 'Status' then
88+
v['value'] = silenced_text
89+
end
90+
end
91+
92+
new_actions = {}
93+
94+
for i, v in pairs(original_attach[1]['actions']) do
95+
if v['name'] and v['name'] == 'silence' then
96+
print('[INFO] Skiping action SILENCE because we have a new one')
97+
else
98+
table.insert(new_actions, v)
99+
end
100+
end
101+
new_attach = original_attach
102+
new_attach[1]['actions'] = new_actions
103+
104+
new_message = {}
105+
new_message['text'] = ""
106+
new_message['attachments'] = new_attach
107+
new_message['replace_original'] = true
108+
new_message['response_type'] = "in_channel"
109+
110+
if log_level == 'debug' then
111+
print("[DEBUG] NEW CREATED MESSAGE:\n"..inspect(new_message))
112+
end
113+
114+
message, err = json.encode(new_message)
115+
if err then error(err) end
116+
117+
request, err = http.request("POST", response_url, message)
118+
local result, err = client:do_request(request)
119+
120+
if err then error(err) end
121+
print("[DEBUG] Slack responce: \n"..result.body)
122+
end
123+
else
124+
print("[INFO] Skipping action because we do not value in action")
125+
end
126+
end
127+
end
128+
end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
strings = require("strings")
2+
cmd = require("cmd")
3+
4+
hex_to_char = function(x)
5+
return string.char(tonumber(x, 16))
6+
end
7+
8+
urldecode = function(url)
9+
if url == nil then
10+
return
11+
end
12+
url = url:gsub("+", " ")
13+
url = url:gsub("%%(%x%x)", hex_to_char)
14+
return url
15+
end
16+
17+
format_time_with_offset = function(i)
18+
command = ("date --iso-8601=seconds --date '+"..i.." hour'")
19+
encoded, err = cmd.exec(command)
20+
if err then error(err) end
21+
return strings.trim((encoded.stdout), "\n")
22+
end

0 commit comments

Comments
 (0)