Skip to content

Commit

Permalink
chore(admin-gui): Admin GUI CE/EE unification (#11355)
Browse files Browse the repository at this point in the history
Some changes to the admin GUI implementation in the CE gateway,
makes the CE -> EE merge more easily.

Most of the changes are re-position the code blocks, coupling them
with the EE code and making git 3-way merger happy, some tests were
also refactored

This fix KAG-2245

The coupled PR in the EE repo Kong/kong-ee#6199 has been merged
  • Loading branch information
nekolab authored Aug 29, 2023
1 parent 081039a commit e7efc1f
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 108 deletions.
1 change: 1 addition & 0 deletions kong-3.5.0-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ build = {
["kong.api.routes.upstreams"] = "kong/api/routes/upstreams.lua",

["kong.admin_gui"] = "kong/admin_gui/init.lua",
["kong.admin_gui.utils"] = "kong/admin_gui/utils.lua",

["kong.status"] = "kong/status/init.lua",
["kong.status.ready"] = "kong/status/ready.lua",
Expand Down
46 changes: 12 additions & 34 deletions kong/admin_gui/init.lua
Original file line number Diff line number Diff line change
@@ -1,45 +1,23 @@
local meta = require "kong.meta"
local meta = require "kong.meta"
local utils = require "kong.admin_gui.utils"

local _M = {}

-- return first listener matching filters
local function select_listener(listeners, filters)
for _, listener in ipairs(listeners) do
local match = true
for filter, value in pairs(filters) do
if listener[filter] ~= value then
match = false
end
end
if match then
return listener
end
end
end

local function prepare_variable(variable)
if variable == nil then
return ""
end

return tostring(variable)
end

function _M.generate_kconfig(kong_config)
local api_listen = select_listener(kong_config.admin_listeners, {ssl = false})
local api_listen = utils.select_listener(kong_config.admin_listeners, {ssl = false})
local api_port = api_listen and api_listen.port
local api_ssl_listen = select_listener(kong_config.admin_listeners, {ssl = true})
local api_ssl_listen = utils.select_listener(kong_config.admin_listeners, {ssl = true})
local api_ssl_port = api_ssl_listen and api_ssl_listen.port

local configs = {
ADMIN_GUI_URL = prepare_variable(kong_config.admin_gui_url),
ADMIN_GUI_PATH = prepare_variable(kong_config.admin_gui_path),
ADMIN_API_URL = prepare_variable(kong_config.admin_gui_api_url),
ADMIN_API_PORT = prepare_variable(api_port),
ADMIN_API_SSL_PORT = prepare_variable(api_ssl_port),
KONG_VERSION = prepare_variable(meta.version),
KONG_EDITION = "community",
ANONYMOUS_REPORTS = prepare_variable(kong_config.anonymous_reports),
ADMIN_GUI_URL = utils.prepare_variable(kong_config.admin_gui_url),
ADMIN_GUI_PATH = utils.prepare_variable(kong_config.admin_gui_path),
ADMIN_API_URL = utils.prepare_variable(kong_config.admin_gui_api_url),
ADMIN_API_PORT = utils.prepare_variable(api_port),
ADMIN_API_SSL_PORT = utils.prepare_variable(api_ssl_port),
KONG_VERSION = utils.prepare_variable(meta.version),
KONG_EDITION = meta._VERSION:match("enterprise") and "enterprise" or "community",
ANONYMOUS_REPORTS = utils.prepare_variable(kong_config.anonymous_reports),
}

local kconfig_str = "window.K_CONFIG = {\n"
Expand Down
26 changes: 26 additions & 0 deletions kong/admin_gui/utils.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
local _M = {}

-- return first listener matching filters
function _M.select_listener(listeners, filters)
for _, listener in ipairs(listeners) do
local match = true
for filter, value in pairs(filters) do
if listener[filter] ~= value then
match = false
end
end
if match then
return listener
end
end
end

function _M.prepare_variable(variable)
if variable == nil then
return ""
end

return tostring(variable)
end

return _M
34 changes: 17 additions & 17 deletions kong/conf_loader/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -289,15 +289,15 @@ local PREFIX_PATHS = {
admin_ssl_cert_default_ecdsa = {"ssl", "admin-kong-default-ecdsa.crt"},
admin_ssl_cert_key_default_ecdsa = {"ssl", "admin-kong-default-ecdsa.key"},

status_ssl_cert_default = {"ssl", "status-kong-default.crt"},
status_ssl_cert_key_default = {"ssl", "status-kong-default.key"},
status_ssl_cert_default_ecdsa = {"ssl", "status-kong-default-ecdsa.crt"},
status_ssl_cert_key_default_ecdsa = {"ssl", "status-kong-default-ecdsa.key"},

admin_gui_ssl_cert_default = {"ssl", "admin-gui-kong-default.crt"},
admin_gui_ssl_cert_key_default = {"ssl", "admin-gui-kong-default.key"},
admin_gui_ssl_cert_default_ecdsa = {"ssl", "admin-gui-kong-default-ecdsa.crt"},
admin_gui_ssl_cert_key_default_ecdsa = {"ssl", "admin-gui-kong-default-ecdsa.key"},

status_ssl_cert_default = {"ssl", "status-kong-default.crt"},
status_ssl_cert_key_default = {"ssl", "status-kong-default.key"},
status_ssl_cert_default_ecdsa = {"ssl", "status-kong-default-ecdsa.crt"},
status_ssl_cert_key_default_ecdsa = {"ssl", "status-kong-default-ecdsa.key"},
}


Expand Down Expand Up @@ -932,18 +932,6 @@ local function check_and_parse(conf, opts)
end
end

-- admin_gui_origin is a parameter for internal use only
-- it's not set directly by the user
-- if admin_gui_path is set to a path other than /, admin_gui_url may
-- contain a path component
-- to make it suitable to be used as an origin in headers, we need to
-- parse and reconstruct the admin_gui_url to ensure it only contains
-- the scheme, host, and port
if conf.admin_gui_url then
local parsed_url = socket_url.parse(conf.admin_gui_url)
conf.admin_gui_origin = parsed_url.scheme .. "://" .. parsed_url.authority
end

if conf.admin_gui_path then
if not conf.admin_gui_path:find("^/") then
errors[#errors + 1] = "admin_gui_path must start with a slash ('/')"
Expand Down Expand Up @@ -2192,6 +2180,18 @@ local function load(path, custom_conf, opts)
end
end

-- admin_gui_origin is a parameter for internal use only
-- it's not set directly by the user
-- if admin_gui_path is set to a path other than /, admin_gui_url may
-- contain a path component
-- to make it suitable to be used as an origin in headers, we need to
-- parse and reconstruct the admin_gui_url to ensure it only contains
-- the scheme, host, and port
if conf.admin_gui_url then
local parsed_url = socket_url.parse(conf.admin_gui_url)
conf.admin_gui_origin = parsed_url.scheme .. "://" .. parsed_url.authority
end

-- hybrid mode HTTP tunneling (CONNECT) proxy inside HTTPS
if conf.cluster_use_proxy then
-- throw err, assume it's already handled in check_and_parse
Expand Down
1 change: 0 additions & 1 deletion kong/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ local process = require "ngx.process"
local tablepool = require "tablepool"
local table_new = require "table.new"
local utils = require "kong.tools.utils"
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"
Expand Down
9 changes: 4 additions & 5 deletions kong/templates/kong_defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -185,18 +185,17 @@ untrusted_lua = sandbox
untrusted_lua_sandbox_requires =
untrusted_lua_sandbox_environment =
admin_gui_url =
admin_gui_path = /
admin_gui_api_url = NONE
openresty_path =
opentelemetry_tracing = off
opentelemetry_tracing_sampling_rate = 0.01
tracing_instrumentations = off
tracing_sampling_rate = 0.01
admin_gui_url =
admin_gui_origin = # for internal use only, can not be configured manually
admin_gui_path = /
admin_gui_api_url =
wasm = off
wasm_filters_path = NONE
wasm_dynamic_module = NONE
Expand Down
2 changes: 1 addition & 1 deletion spec/01-unit/03-conf_loader_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ describe("Configuration loader", function()
assert.is_not_nil(conf)
assert.is_nil(conf.admin_gui_origin)

local conf, _, errors = conf_loader(nil, {
conf, _, errors = conf_loader(nil, {
admin_gui_url = "http://localhost:8002",
})
assert.is_nil(errors)
Expand Down
16 changes: 8 additions & 8 deletions spec/01-unit/04-prefix_handler_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1155,8 +1155,8 @@ describe("NGINX conf compiler", function()
prefix = tmp_config.prefix,
proxy_listen = "127.0.0.1:8000 ssl",
admin_listen = "127.0.0.1:8001 ssl",
status_listen = "127.0.0.1:8002 ssl",
admin_gui_listen = "127.0.0.1:8003 ssl",
admin_gui_listen = "127.0.0.1:8002 ssl",
status_listen = "127.0.0.1:8003 ssl",
ssl_cipher_suite = "custom",
ssl_cert = "spec/fixtures/kong_spec.crt",
ssl_cert_key = "spec/fixtures/kong_spec.key",
Expand All @@ -1176,8 +1176,8 @@ describe("NGINX conf compiler", function()
prefix = tmp_config.prefix,
proxy_listen = "127.0.0.1:8000 ssl",
admin_listen = "127.0.0.1:8001 ssl",
status_listen = "127.0.0.1:8002 ssl",
admin_gui_listen = "127.0.0.1:8003 ssl",
admin_gui_listen = "127.0.0.1:8002 ssl",
status_listen = "127.0.0.1:8003 ssl",
})

assert(prefix_handler.prepare_prefix(conf))
Expand All @@ -1198,8 +1198,8 @@ describe("NGINX conf compiler", function()
prefix = tmp_config.prefix,
proxy_listen = "127.0.0.1:8000 ssl",
admin_listen = "127.0.0.1:8001 ssl",
status_listen = "127.0.0.1:8002 ssl",
admin_gui_listen = "127.0.0.1:8003 ssl",
admin_gui_listen = "127.0.0.1:8002 ssl",
status_listen = "127.0.0.1:8003 ssl",
})

assert(prefix_handler.prepare_prefix(conf))
Expand All @@ -1222,8 +1222,8 @@ describe("NGINX conf compiler", function()
prefix = tmp_config.prefix,
proxy_listen = "127.0.0.1:8000 ssl",
admin_listen = "127.0.0.1:8001 ssl",
status_listen = "127.0.0.1:8002 ssl",
admin_gui_listen = "127.0.0.1:8003 ssl",
admin_gui_listen = "127.0.0.1:8002 ssl",
status_listen = "127.0.0.1:8003 ssl",
stream_listen = "127.0.0.1:7000 ssl",
})

Expand Down
35 changes: 35 additions & 0 deletions spec/01-unit/29-admin_gui/01-admin_gui_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
local conf_loader = require "kong.conf_loader"
local prefix_handler = require "kong.cmd.utils.prefix_handler"

local helpers = require "spec.helpers"

describe("admin_gui", function()
local conf = assert(conf_loader(helpers.test_conf_path))

it("auto-generates SSL certificate and key", function()
assert(prefix_handler.gen_default_ssl_cert(conf, "admin_gui"))
assert(helpers.path.exists(conf.admin_gui_ssl_cert_default))
assert(helpers.path.exists(conf.admin_gui_ssl_cert_key_default))
end)

it("does not re-generate if they already exist", function()
assert(prefix_handler.gen_default_ssl_cert(conf, "admin_gui"))
local cer = helpers.file.read(conf.admin_gui_ssl_cert_default)
local key = helpers.file.read(conf.admin_gui_ssl_cert_key_default)
assert(prefix_handler.gen_default_ssl_cert(conf, "admin_gui"))
assert.equal(cer, helpers.file.read(conf.admin_gui_ssl_cert_default))
assert.equal(key, helpers.file.read(conf.admin_gui_ssl_cert_key_default))
end)

it("generates a different SSL certificate and key from the RESTful API", function()
assert(prefix_handler.gen_default_ssl_cert(conf, "admin_gui"))
local cer, key = {}, {}
cer[1] = helpers.file.read(conf.admin_gui_ssl_cert_default)
key[1] = helpers.file.read(conf.admin_gui_ssl_cert_key_default)
assert(prefix_handler.gen_default_ssl_cert(conf, "admin"))
cer[2] = helpers.file.read(conf.admin_ssl_cert_default)
key[2] = helpers.file.read(conf.admin_ssl_cert_key_default)
assert.not_equals(cer[1], cer[2])
assert.not_equals(key[1], key[2])
end)
end)
Loading

1 comment on commit e7efc1f

@khcp-gha-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bazel Build

Docker image available kong/kong:e7efc1fcfb583007597548b475c353d2b00f17df
Artifacts available https://github.com/Kong/kong/actions/runs/6010176474

Please sign in to comment.