Skip to content

Commit

Permalink
feat(gui): added a new feature to support multiple domains for gui.
Browse files Browse the repository at this point in the history
  • Loading branch information
raoxiaoyan committed Sep 19, 2024
1 parent 71e7cb6 commit 9dea7d9
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 30 deletions.
4 changes: 4 additions & 0 deletions changelog/unreleased/kong/add_multiple_domain_for_gui.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
message: |
Added a new feature for Kong Manager that supports multiple domains, enabling dynamic cross-origin access for Admin API requests.
type: feature
scope: "Core"
15 changes: 5 additions & 10 deletions kong.conf.default
Original file line number Diff line number Diff line change
Expand Up @@ -1994,28 +1994,23 @@

#admin_gui_url = # Kong Manager URL
#
# The lookup, or balancer, address for Kong Manager.
# Comma-separated list of addresses(the lookup or balancer) for Kong Manager.
#
# Accepted format (items in parentheses are optional):
# Accepted format (items in square brackets are optional):
#
# `<scheme>://<IP / HOSTNAME>(:<PORT>)`
# `<scheme>://<IP / HOSTNAME>:[PORT][, <scheme>://<IP / HOSTNAME>:PORT]`
#
# Examples:
#
# - `http://127.0.0.1:8003`
# - `https://kong-admin.test`
# - `http://dev-machine`
#
# By default, Kong Manager will use the window request
# host and append the resolved listener port depending
# on the requested protocol.
# - `http://127.0.0.1:8003, https://exmple.com`

#admin_gui_path = / # Kong Manager base path
#
# This configuration parameter allows the user to customize
# the path prefix where Kong Manager is served. When updating
# this parameter, it's recommended to update the path in `admin_gui_url`
# as well.
# the path prefix where Kong Manager is served.
#
# Accepted format:
#
Expand Down
1 change: 0 additions & 1 deletion kong/admin_gui/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ function _M.generate_kconfig(kong_config)
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),
Expand Down
23 changes: 19 additions & 4 deletions kong/api/api_helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,28 @@ function _M.before_filter(self)
end

function _M.cors_filter(self)
local origin = self.req.headers["Origin"]
local allowed_origins = kong.configuration.admin_gui_origin

if kong.configuration.admin_gui_origin then
origin = kong.configuration.admin_gui_origin
local function is_origin_allowed(req_origin)
for _, allowed_origin in ipairs(allowed_origins) do
if req_origin == allowed_origin then
return true
end
end
return false
end

local req_origin = self.req.headers["Origin"]

if allowed_origins and #allowed_origins > 0 then
if not is_origin_allowed(req_origin) then
req_origin = allowed_origins[1]
end
else
req_origin = req_origin or "*"
end

ngx.header["Access-Control-Allow-Origin"] = origin or "*"
ngx.header["Access-Control-Allow-Origin"] = req_origin
ngx.header["Access-Control-Allow-Credentials"] = "true"

if ngx.req.get_method() == "OPTIONS" then
Expand Down
6 changes: 3 additions & 3 deletions kong/conf_loader/constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -562,9 +562,9 @@ local CONF_PARSERS = {
error_template_xml = { typ = "string" },
error_template_plain = { typ = "string" },

admin_gui_url = {typ = "string"},
admin_gui_path = {typ = "string"},
admin_gui_api_url = {typ = "string"},
admin_gui_url = { typ = "array" },
admin_gui_path = { typ = "string" },
admin_gui_api_url = { typ = "string" },

request_debug = { typ = "boolean" },
request_debug_token = { typ = "string" },
Expand Down
10 changes: 7 additions & 3 deletions kong/conf_loader/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -935,9 +935,13 @@ local function load(path, custom_conf, opts)
-- 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
if conf.admin_gui_url and #conf.admin_gui_url > 0 then
local admin_gui_origin = {}
for _, url in ipairs(conf.admin_gui_url) do
local parsed_url = socket_url.parse(url)
table.insert(admin_gui_origin, parsed_url.scheme .. "://" .. parsed_url.authority)
end
conf.admin_gui_origin = admin_gui_origin
end

-- hybrid mode HTTP tunneling (CONNECT) proxy inside HTTPS
Expand Down
15 changes: 12 additions & 3 deletions spec/01-unit/03-conf_loader_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -323,23 +323,32 @@ describe("Configuration loader", function()
assert.is_nil(errors)
assert.is_not_nil(conf)
assert.is_not_nil(conf.admin_gui_origin)
assert.equal("http://localhost:8002", conf.admin_gui_origin)
assert.same({ "http://localhost:8002" }, conf.admin_gui_origin)

conf, _, errors = conf_loader(nil, {
admin_gui_url = "https://localhost:8002",
})
assert.is_nil(errors)
assert.is_not_nil(conf)
assert.is_not_nil(conf.admin_gui_origin)
assert.equal("https://localhost:8002", conf.admin_gui_origin)
assert.same({ "https://localhost:8002" }, conf.admin_gui_origin)

conf, _, errors = conf_loader(nil, {
admin_gui_url = "http://localhost:8002/manager",
})
assert.is_nil(errors)
assert.is_not_nil(conf)
assert.is_not_nil(conf.admin_gui_origin)
assert.equal("http://localhost:8002", conf.admin_gui_origin)
assert.same({ "http://localhost:8002" }, conf.admin_gui_origin)

conf, _, errors = conf_loader(nil, {
admin_gui_url = "http://localhost:8002/manager, https://localhost:8445/manager",
})
assert.is_nil(errors)
assert.is_not_nil(conf)
assert.is_not_nil(conf.admin_gui_origin)
assert.is_table(conf.admin_gui_origin)
assert.same({ "http://localhost:8002", "https://localhost:8445" }, conf.admin_gui_origin)
end)
it("strips comments ending settings", function()
local _os_getenv = os.getenv
Expand Down
4 changes: 0 additions & 4 deletions spec/01-unit/29-admin_gui/02-admin_gui_template_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ describe("admin_gui template", function()
it("should generates the appropriate kconfig", function()
local kconfig_content = admin_gui.generate_kconfig(conf)

assert.matches("'ADMIN_GUI_URL': 'http://0.0.0.0:8002'", kconfig_content, nil, true)
assert.matches("'ADMIN_GUI_PATH': '/manager'", kconfig_content, nil, true)
assert.matches("'ADMIN_API_URL': 'https://admin-reference.kong-cloud.test'", kconfig_content, nil, true)
assert.matches("'ADMIN_API_PORT': '8001'", kconfig_content, nil, true)
Expand All @@ -83,7 +82,6 @@ describe("admin_gui template", function()
local new_content = admin_gui.generate_kconfig(new_conf)

-- test configuration values against template
assert.matches("'ADMIN_GUI_URL': 'http://admin-test.example.com'", new_content, nil, true)
assert.matches("'ADMIN_GUI_PATH': '/manager'", new_content, nil, true)
assert.matches("'ADMIN_API_URL': 'http://localhost:8001'", new_content, nil, true)
assert.matches("'ADMIN_API_PORT': '8001'", new_content, nil, true)
Expand Down Expand Up @@ -146,7 +144,6 @@ describe("admin_gui template", function()
it("should generates the appropriate kconfig", function()
local kconfig_content = admin_gui.generate_kconfig(conf)

assert.matches("'ADMIN_GUI_URL': 'http://0.0.0.0:8002'", kconfig_content, nil, true)
assert.matches("'ADMIN_API_URL': '0.0.0.0:8001'", kconfig_content, nil, true)
assert.matches("'ADMIN_API_PORT': '8001'", kconfig_content, nil, true)
assert.matches("'ADMIN_API_SSL_PORT': '8444'", kconfig_content, nil, true)
Expand All @@ -164,7 +161,6 @@ describe("admin_gui template", function()
local new_content = admin_gui.generate_kconfig(new_conf)

-- test configuration values against template
assert.matches("'ADMIN_GUI_URL': 'http://admin-test.example.com'", new_content, nil, true)
assert.matches("'ADMIN_API_URL': '0.0.0.0:8001'", new_content, nil, true)
assert.matches("'ADMIN_API_PORT': '8001'", new_content, nil, true)
assert.matches("'ADMIN_API_SSL_PORT': '8444'", new_content, nil, true)
Expand Down
4 changes: 2 additions & 2 deletions spec/02-integration/02-cmd/03-reload_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ describe("Admin GUI config", function ()
path = "/kconfig.js",
})
res = assert.res_status(200, res)
assert.matches("'ADMIN_GUI_URL': 'http://test1.example.com'", res, nil, true)
assert.matches("'ADMIN_GUI_PATH': '/'", res, nil, true)

client:close()

Expand All @@ -764,7 +764,7 @@ describe("Admin GUI config", function ()
path = "/manager/kconfig.js",
})
res = assert.res_status(200, res)
assert.matches("'ADMIN_GUI_URL': 'http://test2.example.com'", res, nil, true)
assert.matches("'ADMIN_GUI_PATH': '/manager'", res, nil, true)
client:close()
end)
end)

0 comments on commit 9dea7d9

Please sign in to comment.