Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a status version field, and header support #54

Merged
merged 2 commits into from
Sep 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ Versioning is strictly based on [Semantic Versioning](https://semver.org/)
* fix: properly log line numbers by using tail calls [#29](https://github.com/Kong/lua-resty-healthcheck/pull/29)
* fix: when not providing a hostname, use IP [#48](https://github.com/Kong/lua-resty-healthcheck/pull/48)
* fix: makefile; make install
* feature: added a status version field [#54](https://github.com/Kong/lua-resty-healthcheck/pull/54)
* feature: add headers for probe request [#54](https://github.com/Kong/lua-resty-healthcheck/pull/54)

### 1.3.0 (17-Jun-2020)

Expand Down
28 changes: 22 additions & 6 deletions lib/resty/healthcheck.lua
Original file line number Diff line number Diff line change
Expand Up @@ -850,8 +850,15 @@ function checker:run_single_check(ip, port, hostname, hostheader)

end

local req_headers = self.checks.active.headers
local headers = table.concat(req_headers, "\r\n")
if #headers > 0 then
headers = headers .. "\r\n"
end

local path = self.checks.active.http_path
local request = ("GET %s HTTP/1.0\r\nHost: %s\r\n\r\n"):format(path, hostheader or hostname)
local request = ("GET %s HTTP/1.0\r\n%sHost: %s\r\n\r\n"):format(path, headers, hostheader or hostname or ip)
self:log(DEBUG, "request head: ", request)

local bytes
bytes, err = sock:send(request)
Expand Down Expand Up @@ -1076,11 +1083,17 @@ function checker:event_handler(event_name, ip, port, hostname)
self:log(DEBUG, "event: target added '", hostname or "", "(", ip, ":", port, ")'")
end
do
local from = target_found.internal_health
local to = event_name
self:log(DEBUG, "event: target status '", hostname or "", "(", ip, ":", port,
")' from '", from == "healthy" or from == "mostly_healthy",
"' to '", to == "healthy" or to == "mostly_healthy", "'")
local from_status = target_found.internal_health
local to_status = event_name
local from = from_status == "healthy" or from_status == "mostly_healthy"
local to = to_status == "healthy" or to_status == "mostly_healthy"

if from ~= to then
self.status_ver = self.status_ver + 1
end

self:log(DEBUG, "event: target status '", hostname or "", "(", ip, ":",
port, ")' from '", from, "' to '", to, "', ver: ", self.status_ver)
end
target_found.internal_health = event_name

Expand Down Expand Up @@ -1214,6 +1227,7 @@ local defaults = {
name = NO_DEFAULT,
shm_name = NO_DEFAULT,
type = NO_DEFAULT,
status_ver = 0,
checks = {
active = {
type = "http",
Expand All @@ -1222,6 +1236,7 @@ local defaults = {
http_path = "/",
https_sni = NO_DEFAULT,
https_verify_certificate = true,
headers = {""},
healthy = {
interval = 0, -- 0 = disabled by default
http_statuses = { 200, 302 },
Expand Down Expand Up @@ -1294,6 +1309,7 @@ end
-- * `checks.active.http_path`: path to use in `GET` HTTP request to run on active checks
-- * `checks.active.https_sni`: SNI server name incase of HTTPS
-- * `checks.active.https_verify_certificate`: boolean indicating whether to verify the HTTPS certificate
-- * `checks.active.hheaders`: an array of headers (no hash-table! must be pre-formatted)
-- * `checks.active.healthy.interval`: interval between checks for healthy targets (in seconds)
-- * `checks.active.healthy.http_statuses`: which HTTP statuses to consider a success
-- * `checks.active.healthy.successes`: number of successes to consider a target healthy
Expand Down
62 changes: 62 additions & 0 deletions t/19-status-ver.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use Test::Nginx::Socket::Lua 'no_plan';
use Cwd qw(cwd);

workers(2);
master_on();

my $pwd = cwd();

our $HttpConfig = qq{
lua_package_path "$pwd/lib/?.lua;;";
lua_shared_dict test_shm 8m;
lua_shared_dict my_worker_events 8m;

init_worker_by_lua_block {
local we = require "resty.worker.events"
assert(we.configure{ shm = "my_worker_events", interval = 0.1 })
ngx.timer.at(0, function()
local healthcheck = require("resty.healthcheck")
local checker = healthcheck.new({
name = "testing",
shm_name = "test_shm",
checks = {
active = {
healthy = {
interval = 0.1
},
unhealthy = {
interval = 0.1
}
}
}
})
local ok, err = checker:add_target("127.0.0.1", 11111)
if not ok then
error(err)
end
end)
}
};

run_tests();

__DATA__

=== TEST 1: add_target() adds an unhealthy target
--- http_config eval: $::HttpConfig
--- config
location = /t {
content_by_lua_block {
ngx.say(true)
ngx.sleep(0.3) -- wait twice the interval
}
}
--- request
GET /t
--- response_body
true
--- error_log
checking unhealthy targets: nothing to do
checking unhealthy targets: #1
from 'true' to 'false', ver: 2
from 'true' to 'false', ver: 1
114 changes: 114 additions & 0 deletions t/20-req-headers.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use Test::Nginx::Socket::Lua 'no_plan';
use Cwd qw(cwd);

workers(1);

my $pwd = cwd();

our $HttpConfig = qq{
lua_package_path "$pwd/lib/?.lua;;";
lua_shared_dict test_shm 8m;
lua_shared_dict my_worker_events 8m;
};

run_tests();

__DATA__

=== TEST 1: headers: {"User-Agent", "curl/7.29.0"}
--- http_config eval
qq{
$::HttpConfig

server {
listen 2112;
location = /status {
return 200;
}
}
}
--- config
location = /t {
content_by_lua_block {
local we = require "resty.worker.events"
assert(we.configure{ shm = "my_worker_events", interval = 0.1 })
local healthcheck = require("resty.healthcheck")
local checker = healthcheck.new({
name = "testing",
shm_name = "test_shm",
checks = {
active = {
http_path = "/status",
healthy = {
interval = 0.1
},
headers = {"User-Agent: curl/7.29.0"}
}
}
})
ngx.sleep(0.2) -- wait twice the interval
local ok, err = checker:add_target("127.0.0.1", 2112, nil, true)
ngx.say(ok)
ngx.sleep(0.2) -- wait twice the interval
}
}
--- request
GET /t
--- response_body
true
--- error_log
checking healthy targets: nothing to do
checking healthy targets: #1
GET /status HTTP/1.0
User-Agent: curl/7.29.0
Host: 127.0.0.1



=== TEST 2: headers: {"User-Agent", "curl"}
--- http_config eval
qq{
$::HttpConfig

server {
listen 2112;
location = /status {
return 200;
}
}
}
--- config
location = /t {
content_by_lua_block {
local we = require "resty.worker.events"
assert(we.configure{ shm = "my_worker_events", interval = 0.1 })
local healthcheck = require("resty.healthcheck")
local checker = healthcheck.new({
name = "testing",
shm_name = "test_shm",
checks = {
active = {
http_path = "/status",
healthy = {
interval = 0.1
},
headers = {"User-Agent: curl"}
}
}
})
ngx.sleep(0.2) -- wait twice the interval
local ok, err = checker:add_target("127.0.0.1", 2112, nil, true)
ngx.say(ok)
ngx.sleep(0.2) -- wait twice the interval
}
}
--- request
GET /t
--- response_body
true
--- error_log
checking healthy targets: nothing to do
checking healthy targets: #1
GET /status HTTP/1.0
User-Agent: curl
Host: 127.0.0.1