diff --git a/changelog/unreleased/kong/add_multiple_domain_for_gui.yml b/changelog/unreleased/kong/add_multiple_domain_for_gui.yml new file mode 100644 index 000000000000..dd4793830ea1 --- /dev/null +++ b/changelog/unreleased/kong/add_multiple_domain_for_gui.yml @@ -0,0 +1,4 @@ +message: | + Added a new feature to support multiple domains for Gui. +type: feature +scope: "Core" \ No newline at end of file diff --git a/kong/api/api_helpers.lua b/kong/api/api_helpers.lua index 69e9822a8ede..079a4214f3ba 100644 --- a/kong/api/api_helpers.lua +++ b/kong/api/api_helpers.lua @@ -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 req_origin and 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 diff --git a/kong/conf_loader/constants.lua b/kong/conf_loader/constants.lua index 4e416d4da361..21326a588e3e 100644 --- a/kong/conf_loader/constants.lua +++ b/kong/conf_loader/constants.lua @@ -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" }, diff --git a/kong/conf_loader/init.lua b/kong/conf_loader/init.lua index f1deaf9ef21d..96ff04522ac2 100644 --- a/kong/conf_loader/init.lua +++ b/kong/conf_loader/init.lua @@ -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 diff --git a/spec/01-unit/03-conf_loader_spec.lua b/spec/01-unit/03-conf_loader_spec.lua index 9827fcef10e2..be5ca97e17ee 100644 --- a/spec/01-unit/03-conf_loader_spec.lua +++ b/spec/01-unit/03-conf_loader_spec.lua @@ -323,7 +323,7 @@ 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", @@ -331,7 +331,7 @@ describe("Configuration loader", function() 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", @@ -339,7 +339,16 @@ 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 = "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