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

[Backport release/3.4.x] fix(admin-gui): add basic kong manager statistics to phone home #11280

Merged
merged 1 commit into from
Jul 25, 2023
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
8 changes: 8 additions & 0 deletions kong/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ local constants = require "kong.constants"
local get_ctx_table = require("resty.core.ctx").get_ctx_table
local admin_gui = require "kong.admin_gui"
local wasm = require "kong.runloop.wasm"
local reports = require "kong.reports"


local kong = kong
Expand Down Expand Up @@ -221,6 +222,7 @@ do
"events:requests:ws",
"events:requests:wss",
"events:requests:go_plugins",
"events:km:visit",
"events:streams",
"events:streams:tcp",
"events:streams:tls",
Expand Down Expand Up @@ -1695,6 +1697,12 @@ function Kong.admin_gui_kconfig_content()
end
end

function Kong.admin_gui_log()
if kong.configuration.anonymous_reports then
reports.admin_gui_log(ngx.ctx)
end
end

function Kong.status_content()
return serve_content("kong.status")
end
Expand Down
13 changes: 13 additions & 0 deletions kong/reports.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ local TLS_STREAM_COUNT_KEY = "events:streams:tls"
local UDP_STREAM_COUNT_KEY = "events:streams:udp"


local KM_VISIT_COUNT_KEY = "events:km:visit"


local GO_PLUGINS_REQUEST_COUNT_KEY = "events:requests:go_plugins"


Expand Down Expand Up @@ -336,6 +339,7 @@ local function send_ping(host, port)
_ping_infos.grpcs_reqs = get_counter(GRPCS_REQUEST_COUNT_KEY)
_ping_infos.ws_reqs = get_counter(WS_REQUEST_COUNT_KEY)
_ping_infos.wss_reqs = get_counter(WSS_REQUEST_COUNT_KEY)
_ping_infos.km_visits = get_counter(KM_VISIT_COUNT_KEY)
_ping_infos.go_plugin_reqs = get_counter(GO_PLUGINS_REQUEST_COUNT_KEY)

_ping_infos.request_route_cache_hit_pos = get_counter(REQUEST_ROUTE_CACHE_HITS_KEY_POS)
Expand All @@ -352,6 +356,7 @@ local function send_ping(host, port)
reset_counter(GRPCS_REQUEST_COUNT_KEY, _ping_infos.grpcs_reqs)
reset_counter(WS_REQUEST_COUNT_KEY, _ping_infos.ws_reqs)
reset_counter(WSS_REQUEST_COUNT_KEY, _ping_infos.wss_reqs)
reset_counter(KM_VISIT_COUNT_KEY, _ping_infos.km_visits)
reset_counter(GO_PLUGINS_REQUEST_COUNT_KEY, _ping_infos.go_plugin_reqs)
reset_counter(REQUEST_ROUTE_CACHE_HITS_KEY_POS, _ping_infos.request_route_cache_hit_pos)
reset_counter(REQUEST_ROUTE_CACHE_HITS_KEY_NEG, _ping_infos.request_route_cache_hit_neg)
Expand Down Expand Up @@ -398,6 +403,7 @@ local function configure_ping(kong_conf)
add_immutable_value("role", kong_conf.role)
add_immutable_value("kic", kong_conf.kic)
add_immutable_value("_admin", #kong_conf.admin_listeners > 0 and 1 or 0)
add_immutable_value("_admin_gui", #kong_conf.admin_gui_listeners > 0 and 1 or 0)
add_immutable_value("_proxy", #kong_conf.proxy_listeners > 0 and 1 or 0)
add_immutable_value("_stream", #kong_conf.stream_listeners > 0 and 1 or 0)
end
Expand Down Expand Up @@ -485,6 +491,13 @@ return {
incr_counter(count_key .. ":" .. ROUTE_CACHE_HITS_KEY .. ":" .. route_match_cached)
end
end,
admin_gui_log = function(ctx)
if not _enabled then
return
end

incr_counter(KM_VISIT_COUNT_KEY)
end,

-- custom methods
toggle = function(enable)
Expand Down
4 changes: 4 additions & 0 deletions kong/templates/nginx_kong_gui_include.lua
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,9 @@ location ~* ^$(admin_gui_path_prefix)(?<path>/.*)?$ {
> end
sub_filter_once off;
sub_filter_types *;

log_by_lua_block {
Kong.admin_gui_log()
}
}
]]
28 changes: 28 additions & 0 deletions spec/01-unit/11-reports_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,34 @@ describe("reports", function()
end)
end)

describe("sends '_admin_gui' for 'admin_gui_listen'", function()
it("off", function()
local conf = assert(conf_loader(nil, {
admin_gui_listen = "off",
}))
reports.configure_ping(conf)

local thread = helpers.tcp_server(port, opts)
reports.send_ping("127.0.0.1", port)

local _, res = assert(thread:join())
assert.matches("_admin_gui=0", res, nil, true)
end)

it("on", function()
local conf = assert(conf_loader(nil, {
admin_gui_listen = "127.0.0.1:8001",
}))
reports.configure_ping(conf)

local thread = helpers.tcp_server(port, opts)
reports.send_ping("127.0.0.1", port)

local _, res = assert(thread:join())
assert.matches("_admin_gui=1", res, nil, true)
end)
end)

describe("sends '_proxy' for 'proxy_listen'", function()
it("off", function()
local conf = assert(conf_loader(nil, {
Expand Down
157 changes: 157 additions & 0 deletions spec/02-integration/17-admin_gui/03-reports_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
local cjson = require "cjson"
local lfs = require "lfs"
local pl_path = require "pl.path"

local helpers = require "spec.helpers"
local constants = require "kong.constants"

describe("anonymous reports for kong manager", function ()
local reports_send_ping = function()
ngx.sleep(0.2) -- hand over the CPU so other threads can do work (processing the sent data)
local admin_client = helpers.admin_client()
local res = admin_client:post("/reports/send-ping?port=" .. constants.REPORTS.STATS_TLS_PORT)
assert.response(res).has_status(200)
admin_client:close()
end

local assert_report = function (value)
local reports_server = helpers.tcp_server(constants.REPORTS.STATS_TLS_PORT, {tls=true})
reports_send_ping()
local _, reports_data = assert(reports_server:join())
reports_data = cjson.encode(reports_data)

assert.match(value, reports_data)
end

local prepare_gui_dir = function ()
local err, gui_dir_path
gui_dir_path = pl_path.join(helpers.test_conf.prefix, "gui")
os.execute("rm -rf " .. gui_dir_path)
err = select(2, lfs.mkdir(gui_dir_path))
assert.is_nil(err)
return gui_dir_path
end

local create_gui_file = function (path)
local fd = assert(io.open(path, "w"))
assert.is_not_nil(fd)
assert(fd:write("TEST"))
assert(fd:close())
end

local dns_hostsfile

lazy_setup(function ()
dns_hostsfile = assert(os.tmpname() .. ".hosts")
local fd = assert(io.open(dns_hostsfile, "w"))
assert(fd:write("127.0.0.1 " .. constants.REPORTS.ADDRESS))
assert(fd:close())

local bp = assert(helpers.get_db_utils(nil, {}, { "reports-api" }))

bp.plugins:insert({
name = "reports-api",
config = {}
})
end)

lazy_teardown(function ()
os.remove(dns_hostsfile)
end)

describe("availability status", function ()
it("should be correct when admin_gui_listen is set", function ()
assert(helpers.start_kong({
admin_gui_listen = "127.0.0.1:9012",
anonymous_reports = true,
plugins = "bundled,reports-api",
dns_hostsfile = dns_hostsfile,
}))

finally(function()
helpers.stop_kong()
end)

assert_report("_admin_gui=1")
end)

it("should be correct when admin_gui_listen is off", function ()
assert(helpers.start_kong({
admin_gui_listen = "off",
anonymous_reports = true,
plugins = "bundled,reports-api",
dns_hostsfile = dns_hostsfile,
}))

finally(function()
helpers.stop_kong()
end)

assert_report("_admin_gui=0")
end)
end)

describe("visit", function()
lazy_setup(function()
assert(helpers.start_kong({
admin_gui_listen = "127.0.0.1:9012",
anonymous_reports = true,
plugins = "bundled,reports-api",
dns_hostsfile = dns_hostsfile,
}))

local gui_dir_path = prepare_gui_dir()
create_gui_file(pl_path.join(gui_dir_path, "index.html"))
create_gui_file(pl_path.join(gui_dir_path, "robots.txt"))
create_gui_file(pl_path.join(gui_dir_path, "favicon.ico"))
create_gui_file(pl_path.join(gui_dir_path, "test.js"))
create_gui_file(pl_path.join(gui_dir_path, "test.css"))
create_gui_file(pl_path.join(gui_dir_path, "test.png"))
end)

lazy_teardown(function()
os.remove(dns_hostsfile)

helpers.stop_kong()
end)

it("should have value 0 when no kong mananger visit occurs", function ()
assert_report("km_visits=0")
end)

it("should increase counter by 1 for each kong mananger visit", function ()
local admin_gui_client = helpers.admin_gui_client(nil, 9012)
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/services" }))
admin_gui_client:close()
assert_report("km_visits=2")
end)

it("should reset the counter after report", function ()
local admin_gui_client = helpers.admin_gui_client(nil, 9012)
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/" }))
admin_gui_client:close()
assert_report("km_visits=1")

admin_gui_client = helpers.admin_gui_client(nil, 9012)
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/" }))
assert_report("km_visits=2")
admin_gui_client:close()
end)

it("should not increase the counter for GUI assets", function ()
local admin_gui_client = helpers.admin_gui_client(nil, 9012)
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/kconfig.js" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/robots.txt" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/favicon.ico" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/test.js" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/test.css" }))
assert.res_status(200, admin_gui_client:send({ method = "GET", path = "/test.png" }))
assert.res_status(404, admin_gui_client:send({ method = "GET", path = "/not-exist.png" }))
admin_gui_client:close()

assert_report("km_visits=0")
end)
end)
end)
4 changes: 4 additions & 0 deletions spec/fixtures/custom_nginx.template
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,10 @@ server {
> end
sub_filter_once off;
sub_filter_types *;

log_by_lua_block {
Kong.admin_gui_log()
}
}
}
> end -- of (role == "control_plane" or role == "traditional") and #admin_listen > 0 and #admin_gui_listeners > 0
Expand Down
4 changes: 4 additions & 0 deletions spec/fixtures/default_nginx.template
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,10 @@ server {
> end
sub_filter_once off;
sub_filter_types *;

log_by_lua_block {
Kong.admin_gui_log()
}
}
}
> end -- of (role == "control_plane" or role == "traditional") and #admin_listen > 0 and #admin_gui_listeners > 0
Expand Down
Loading