656 lines
21 KiB
Lua
656 lines
21 KiB
Lua
local helpers = require("spec.helpers")
|
|
local cjson = require("cjson")
|
|
local fmt = string.format
|
|
|
|
local strategies = {}
|
|
for _, strategy in helpers.each_strategy() do
|
|
table.insert(strategies, strategy)
|
|
end
|
|
table.insert(strategies, "off")
|
|
for _, strategy in pairs(strategies) do
|
|
describe("Admin API - Kong debug route with strategy #" .. strategy, function()
|
|
local https_server
|
|
lazy_setup(function()
|
|
local bp = helpers.get_db_utils(nil, {}) -- runs migrations
|
|
|
|
local mock_https_server_port = helpers.get_available_port()
|
|
|
|
local service_mockbin = assert(bp.services:insert {
|
|
name = "service-mockbin",
|
|
url = fmt("https://127.0.0.1:%s/request", mock_https_server_port)
|
|
})
|
|
|
|
assert(bp.routes:insert {
|
|
protocols = { "http" },
|
|
hosts = { "mockbin.test" },
|
|
paths = { "/" },
|
|
service = service_mockbin,
|
|
})
|
|
assert(bp.plugins:insert {
|
|
name = "datadog",
|
|
service = service_mockbin,
|
|
})
|
|
|
|
https_server = helpers.https_server.new(mock_https_server_port, nil, "https")
|
|
https_server:start()
|
|
|
|
assert(helpers.start_kong {
|
|
database = strategy,
|
|
trusted_ips = "127.0.0.1",
|
|
nginx_http_proxy_ssl_verify = "on",
|
|
-- Mocking https_server is using kong_spec key/cert pairs but the pairs does not
|
|
-- have domain defined, so ssl verify will still fail with domain mismatch
|
|
nginx_http_proxy_ssl_trusted_certificate = "../spec/fixtures/kong_spec.crt",
|
|
nginx_http_proxy_ssl_verify_depth = "5",
|
|
})
|
|
assert(helpers.start_kong{
|
|
database = strategy,
|
|
prefix = "node2",
|
|
admin_listen = "127.0.0.1:9110",
|
|
admin_gui_listen = "off",
|
|
proxy_listen = "off",
|
|
log_level = "debug",
|
|
})
|
|
|
|
if strategy ~= "off" then
|
|
assert(helpers.start_kong({
|
|
role = "control_plane",
|
|
cluster_cert = "spec/fixtures/kong_clustering.crt",
|
|
cluster_cert_key = "spec/fixtures/kong_clustering.key",
|
|
database = strategy,
|
|
db_update_frequency = 0.1,
|
|
admin_listen = "127.0.0.1:9113",
|
|
cluster_listen = "127.0.0.1:9005",
|
|
admin_gui_listen = "off",
|
|
prefix = "cp",
|
|
log_level = "debug",
|
|
}))
|
|
assert(helpers.start_kong({
|
|
role = "control_plane",
|
|
cluster_cert = "spec/fixtures/kong_clustering.crt",
|
|
cluster_cert_key = "spec/fixtures/kong_clustering.key",
|
|
database = strategy,
|
|
db_update_frequency = 0.1,
|
|
admin_listen = "127.0.0.1:9114",
|
|
cluster_listen = "127.0.0.1:9006",
|
|
admin_gui_listen = "off",
|
|
prefix = "cp2",
|
|
cluster_telemetry_listen = "localhost:9008",
|
|
log_level = "debug",
|
|
}))
|
|
end
|
|
end)
|
|
|
|
lazy_teardown(function()
|
|
https_server:shutdown()
|
|
helpers.stop_kong()
|
|
helpers.stop_kong("node2")
|
|
|
|
if strategy ~= "off" then
|
|
helpers.stop_kong("cp")
|
|
helpers.stop_kong("cp2")
|
|
end
|
|
end)
|
|
|
|
describe("/debug/{node, cluster}/log-level", function()
|
|
it("gets current log level for traditional and dbless", function()
|
|
local res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
local message = "log level: debug"
|
|
assert(json.message == message)
|
|
end)
|
|
|
|
if strategy == "off" then
|
|
it("cannot change the log level for dbless", function()
|
|
local res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/notice",
|
|
})
|
|
local body = assert.res_status(405, res)
|
|
local json = cjson.decode(body)
|
|
local message = "cannot change log level when not using a database"
|
|
assert(json.message == message)
|
|
end)
|
|
return
|
|
end
|
|
|
|
it("e2e test - check if dynamic set log level works", function()
|
|
local res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/alert",
|
|
})
|
|
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
local message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to alert
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: alert"
|
|
return json.message == message
|
|
end, 30)
|
|
|
|
-- e2e test: we are not printing lower than alert
|
|
helpers.clean_logfile()
|
|
res = assert(helpers.proxy_client():send {
|
|
method = "GET",
|
|
path = "/",
|
|
headers = {
|
|
Host = "mockbin.test",
|
|
},
|
|
})
|
|
body = assert.res_status(502, res)
|
|
assert.matches("An invalid response was received from the upstream server", body)
|
|
assert.logfile().has.no.line([[upstream SSL certificate does not match]] ..
|
|
[[ "127.0.0.1" while SSL handshaking to upstream]], true, 2)
|
|
|
|
-- e2e test: we are not printing lower than alert
|
|
helpers.clean_logfile()
|
|
res = assert(helpers.proxy_client():send {
|
|
method = "GET",
|
|
path = "/",
|
|
headers = {
|
|
Host = "mockbin.test",
|
|
},
|
|
})
|
|
assert.res_status(502, res)
|
|
-- from timers pre-created by timer-ng (datadog plugin)
|
|
assert.logfile().has.no.line("failed to send data to", true, 2)
|
|
|
|
-- go back to default (debug)
|
|
res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/debug",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to debug
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: debug"
|
|
return json.message == message
|
|
end, 30)
|
|
|
|
assert.logfile().has.line(fmt("log level changed to %s", ngx.DEBUG), true, 2)
|
|
|
|
-- e2e test: we are printing higher than debug
|
|
helpers.clean_logfile()
|
|
res = assert(helpers.proxy_client():send {
|
|
method = "GET",
|
|
path = "/",
|
|
headers = {
|
|
Host = "mockbin.test",
|
|
},
|
|
})
|
|
body = assert.res_status(502, res)
|
|
assert.matches("An invalid response was received from the upstream server", body)
|
|
assert.logfile().has.line([[upstream SSL certificate does not match]] ..
|
|
[[ "127.0.0.1" while SSL handshaking to upstream]], true, 2)
|
|
|
|
-- e2e test: we are printing higher than debug
|
|
helpers.clean_logfile()
|
|
res = assert(helpers.proxy_client():send {
|
|
method = "GET",
|
|
path = "/",
|
|
headers = {
|
|
Host = "mockbin.test",
|
|
},
|
|
})
|
|
assert.res_status(502, res)
|
|
-- from timers pre-created by timer-ng (datadog plugin)
|
|
assert.logfile().has.line("failed to send data to", true, 30)
|
|
end)
|
|
|
|
it("changes log level for traditional mode", function()
|
|
local res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/notice",
|
|
})
|
|
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
local message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to notice
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: notice"
|
|
return json.message == message
|
|
end, 30)
|
|
|
|
-- go back to default (debug)
|
|
res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/debug",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to debug
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: debug"
|
|
return json.message == message
|
|
end, 30)
|
|
end)
|
|
|
|
it("handles unknown log level for traditional mode", function()
|
|
local res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/stderr",
|
|
})
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
local message = "unknown log level: stderr"
|
|
assert(json.message == message)
|
|
end)
|
|
|
|
it("current log level is equal to configured log level", function()
|
|
local res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/debug",
|
|
})
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
local message = "log level is already debug"
|
|
assert(json.message == message)
|
|
end)
|
|
|
|
it("broadcasts to all traditional nodes", function()
|
|
local res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/cluster/log-level/emerg"
|
|
})
|
|
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
local message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to emerg on NODE 1
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: emerg"
|
|
return json.message == message
|
|
end, 30)
|
|
|
|
-- make sure we changed to emerg on NODE 2
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client(nil, 9110):send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: emerg"
|
|
return json.message == message
|
|
end, 30)
|
|
|
|
-- decrease log level to debug on both NODE 1 and NODE 2
|
|
res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/cluster/log-level/debug"
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to debug on NODE 1
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: debug"
|
|
return json.message == message
|
|
end, 30)
|
|
|
|
-- make sure we changed to debug on NODE 2
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client(nil, 9110):send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: debug"
|
|
return json.message == message
|
|
end, 30)
|
|
end)
|
|
|
|
it("gets current log level for CP", function()
|
|
local res = assert(helpers.admin_client(nil, 9113):send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
local message = "log level: debug"
|
|
assert(json.message == message)
|
|
end)
|
|
|
|
it("changes CP log level", function()
|
|
local res = assert(helpers.admin_client(nil, 9113):send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/notice",
|
|
})
|
|
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
local message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to notice
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client(nil, 9113):send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: notice"
|
|
return json.message == message
|
|
end, 30)
|
|
|
|
-- go back to default (debug)
|
|
res = assert(helpers.admin_client(nil, 9113):send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/debug",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to debug
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client(nil, 9113):send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: debug"
|
|
return json.message == message
|
|
end, 30)
|
|
end)
|
|
|
|
it("broadcasts to all CP nodes", function()
|
|
local res = assert(helpers.admin_client(nil, 9113):send {
|
|
method = "PUT",
|
|
path = "/debug/cluster/control-planes-nodes/log-level/emerg"
|
|
})
|
|
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
local message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to emerg on CP 1
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client(nil, 9113):send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: emerg"
|
|
return json.message == message
|
|
end, 30)
|
|
|
|
-- make sure we changed to emerg on CP 2
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client(nil, 9114):send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: emerg"
|
|
return json.message == message
|
|
end, 30)
|
|
|
|
-- decrease log level to debug on both CP 1 and CP 2
|
|
res = assert(helpers.admin_client(nil, 9113):send {
|
|
method = "PUT",
|
|
path = "/debug/cluster/control-planes-nodes/log-level/debug"
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to debug on CP 1
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client(nil, 9113):send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: debug"
|
|
return json.message == message
|
|
end, 30)
|
|
|
|
-- Wait for CP 2 to check for cluster events
|
|
helpers.wait_until(function()
|
|
-- make sure we changed to debug on CP 2
|
|
res = assert(helpers.admin_client(nil, 9114):send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: debug"
|
|
return json.message == message
|
|
end, 30)
|
|
end)
|
|
|
|
it("common cluster endpoint not accepted in hybrid mode", function()
|
|
local res = assert(helpers.admin_client(nil, 9113):send {
|
|
method = "PUT",
|
|
path = "/debug/cluster/log-level/notice"
|
|
})
|
|
assert.res_status(404, res)
|
|
end)
|
|
|
|
it("newly spawned workers can update their log levels", function()
|
|
local res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/crit?timeout=10",
|
|
})
|
|
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
local message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to crit
|
|
helpers.pwait_until(function()
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: crit"
|
|
assert.same(message, json.message)
|
|
end, 3)
|
|
|
|
local prefix = helpers.test_conf.prefix
|
|
assert(helpers.reload_kong("reload --prefix " .. prefix))
|
|
|
|
-- Wait for new workers to spawn
|
|
helpers.pwait_until(function()
|
|
-- make sure new workers' log level is crit
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
|
|
message = "log level: crit"
|
|
assert.same(message, json.message)
|
|
end, 7)
|
|
|
|
-- wait for the expriration of the previous log level changes
|
|
helpers.pwait_until(function()
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: debug"
|
|
assert.same(message, json.message)
|
|
end, 16)
|
|
end)
|
|
|
|
it("change log_level with timeout", function()
|
|
local res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/alert?timeout=5",
|
|
})
|
|
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
local message = "log level changed"
|
|
assert(json.message == message)
|
|
|
|
-- make sure we changed to alert
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: alert"
|
|
return json.message == message
|
|
end, 3)
|
|
|
|
-- e2e test: we are not printing lower than alert
|
|
helpers.clean_logfile()
|
|
res = assert(helpers.proxy_client():send {
|
|
method = "GET",
|
|
path = "/",
|
|
headers = {
|
|
Host = "mockbin.test",
|
|
},
|
|
})
|
|
body = assert.res_status(502, res)
|
|
assert.matches("An invalid response was received from the upstream server", body)
|
|
assert.logfile().has.no.line([[upstream SSL certificate does not match]] ..
|
|
[[ "127.0.0.1" while SSL handshaking to upstream]], true, 2)
|
|
|
|
-- e2e test: we are not printing lower than alert
|
|
helpers.clean_logfile()
|
|
res = assert(helpers.proxy_client():send {
|
|
method = "GET",
|
|
path = "/",
|
|
headers = {
|
|
Host = "mockbin.test",
|
|
},
|
|
})
|
|
assert.res_status(502, res)
|
|
-- from timers pre-created by timer-ng (datadog plugin)
|
|
assert.logfile().has.no.line("failed to send data to", true, 2)
|
|
|
|
-- wait for the dynamic log level timeout
|
|
helpers.wait_until(function()
|
|
res = assert(helpers.admin_client():send {
|
|
method = "GET",
|
|
path = "/debug/node/log-level",
|
|
})
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
message = "log level: debug"
|
|
return json.message == message
|
|
end, 6)
|
|
|
|
-- e2e test: we are printing higher than debug
|
|
helpers.clean_logfile()
|
|
res = assert(helpers.proxy_client():send {
|
|
method = "GET",
|
|
path = "/",
|
|
headers = {
|
|
Host = "mockbin.test",
|
|
},
|
|
})
|
|
body = assert.res_status(502, res)
|
|
assert.matches("An invalid response was received from the upstream server", body)
|
|
assert.logfile().has.line([[upstream SSL certificate does not match]] ..
|
|
[[ "127.0.0.1" while SSL handshaking to upstream]], true, 2)
|
|
|
|
-- e2e test: we are printing higher than debug
|
|
helpers.clean_logfile()
|
|
res = assert(helpers.proxy_client():send {
|
|
method = "GET",
|
|
path = "/",
|
|
headers = {
|
|
Host = "mockbin.test",
|
|
},
|
|
})
|
|
assert.res_status(502, res)
|
|
-- from timers pre-created by timer-ng (datadog plugin)
|
|
assert.logfile().has.line("failed to send data to", true, 30)
|
|
end)
|
|
|
|
it("should refuse invalid timeout", function()
|
|
local res = assert(helpers.admin_client():send {
|
|
method = "PUT",
|
|
path = "/debug/node/log-level/notice?timeout=-1",
|
|
})
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
assert.same("timeout must be greater than or equal to 0", json.message)
|
|
end)
|
|
end)
|
|
|
|
end)
|
|
end
|