-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(cmd):
kong vault get
doesn't work in dbless mode (#11127)
* fix(cmd): `kong vault get` doesn't work in dbless mode The cli `kong vault get <reference>` doesn't work in DBless mode if <reference> uses vaults entity. It doesn't affect the normal use of vault in kong instance though. The reason is in DBless mode the vaults entity is stored in LMDB which is implemented by a Nginx C module. However Everytime `resty` cli (which is relied on by `kong` cli) runs it creates a temporary `nginx.conf` which doesn't contain the lmdb-related directives. This PR is fixing this by starting another `resty` call with lmdb-related directives inserted via the `--main-conf` option. Note we only try this after detecting the `no LMDB environment defined` error in order to avoid infinite loop. And because `resty` will create a temmporary nginx instance so we need to convert the relative paths in the nginx.conf to the absolute path under kong instance prefix. [FTI-4937](https://konghq.atlassian.net/browse/FTI-4937) * add CHANGELOG * make it more robust * update comment * update comment * test the existence of LMDB rather than Kong instance * fixup * make the fix more generic * fix and add tests in 04-prefix_handler_spec * add lua_ssl_protocols and fix tests * rename the new configuration files to avoid conflict with the prefix of injected directives * add and fix tests of 14-vault_spec * fix test * rename template files to consistent with configuration file names * add unit tests for inject_directives.lua * change to absolute path * fixup * fix path * Update CHANGELOG.md Co-authored-by: Hans Hübner <[email protected]> * use return (...) syntax instead * don't expose the option and use a better name * pass paths instead of patterns and use better names * correctly handle the stdout/stderr/exit code * preserve original cli args for reusing * use env variable to terminate recursion * resty isn't necessarily in the position -1, so add it explicitly * update the lmdb_map_size to 2048m * fix(cmd): lack of necessary nginx directives in kong cli nginx.conf This is an alternative of (#10675)[#10675]. The primary logic keeps the same. The inject logic is further moved forward from `kong/cmd/init.lua` to `bin/kong` so that the execution flow won't enter `kong/cmd/init.lua` twice. We still keep the `bin/kong` a resty script because many files such as `kong.conf_loader`, `kong.cmd.utils.process_secrets` rely on `ngx`. If we change `bin/kong` into a pure lua or other language script, we need to rewrite the conf_loader and compile part logic. [FTI-4937](https://konghq.atlassian.net/browse/FTI-4937) * fix lint * fix test * fix test * use xpcall to catch exceptions and handle error message * add health to skip_inject_cmds * fix tests in 11-config_spec.lua * add hybrid into skip_inject_cmds * fix typo * remove CHANGELOG entry to the right place ("Unreleased") * extend load() to a subset of fields and these fields can't reference vault * add field `database` to CONF_NO_VAULT * fix test * fix test * keep `conf.nginx_http_lua_ssl_protocols` and `conf.nginx_stream_lua_ssl_protocols` so that we don't change the previous behavior * fixup * fix test * fix test * fix test * update CHANGELOG * Update CHANGELOG.md Co-authored-by: Qirui(Keery) Nie <[email protected]> * always call prepare_prefix as the prefix directory may not existed and the lua_ssl_trusted_certificate config may be updated --------- Co-authored-by: Hans Hübner <[email protected]> Co-authored-by: Qirui(Keery) Nie <[email protected]>
- Loading branch information
1 parent
e025bbd
commit 8a1ebba
Showing
18 changed files
with
765 additions
and
240 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,148 @@ | ||
#!/usr/bin/env resty | ||
|
||
setmetatable(_G, nil) | ||
pcall(require, "luarocks.loader") | ||
package.path = (os.getenv("KONG_LUA_PATH_OVERRIDE") or "") .. "./?.lua;./?/init.lua;" .. package.path | ||
|
||
local pl_app = require "pl.lapp" | ||
local pl_utils = require "pl.utils" | ||
local pl_tablex = require "pl.tablex" | ||
local inject_confs = require "kong.cmd.utils.inject_confs" | ||
|
||
local options = [[ | ||
--v verbose | ||
--vv debug | ||
]] | ||
|
||
local cmds_arr = {} | ||
local cmds = { | ||
start = true, | ||
stop = true, | ||
quit = true, | ||
restart = true, | ||
reload = true, | ||
health = true, | ||
check = true, | ||
prepare = true, | ||
migrations = true, | ||
version = true, | ||
config = true, | ||
roar = true, | ||
hybrid = true, | ||
vault = true, | ||
} | ||
|
||
-- unnecessary to inject nginx directives for these simple cmds | ||
local skip_inject_cmds = { | ||
version = true, | ||
roar = true, | ||
check = true, | ||
stop = true, | ||
quit = true, | ||
health = true, | ||
hybrid = true, | ||
} | ||
|
||
for k in pairs(cmds) do | ||
cmds_arr[#cmds_arr+1] = k | ||
end | ||
|
||
table.sort(cmds_arr) | ||
|
||
local help = string.format([[ | ||
Usage: kong COMMAND [OPTIONS] | ||
The available commands are: | ||
%s | ||
Options: | ||
%s]], table.concat(cmds_arr, "\n "), options) | ||
|
||
local cmd_name = table.remove(arg, 1) | ||
if not cmd_name then | ||
pl_app(help) | ||
pl_app.quit() | ||
elseif not cmds[cmd_name] then | ||
pl_app(help) | ||
pl_app.quit("No such command: " .. cmd_name) | ||
end | ||
|
||
local cmd = require("kong.cmd." .. cmd_name) | ||
local cmd_lapp = cmd.lapp | ||
|
||
if cmd_lapp then | ||
cmd_lapp = cmd_lapp .. options -- append universal options | ||
arg = pl_app(cmd_lapp) | ||
end | ||
|
||
-- check sub-commands | ||
if cmd.sub_commands then | ||
local sub_cmd = table.remove(arg, 1) | ||
if not sub_cmd then | ||
pl_app.quit() | ||
elseif not cmd.sub_commands[sub_cmd] then | ||
pl_app.quit("No such command for " .. cmd_name .. ": " .. sub_cmd) | ||
else | ||
arg.command = sub_cmd | ||
end | ||
end | ||
|
||
-- inject necessary nginx directives (e.g. lmdb_*, lua_ssl_*) | ||
-- into the temporary nginx.conf that `resty` will create | ||
local main_conf = "" | ||
local http_conf = "" | ||
local stream_conf = "" | ||
|
||
if not skip_inject_cmds[cmd_name] then | ||
local pok, confs = xpcall(inject_confs.compile_confs, function(err) | ||
if not (arg.v or arg.vv) then | ||
err = err:match "^.-:.-:.(.*)$" | ||
io.stderr:write("Error: " .. err .. "\n") | ||
io.stderr:write("\n Run with --v (verbose) or --vv (debug) for more details\n") | ||
else | ||
local trace = debug.traceback(err, 2) | ||
io.stderr:write("Error: \n") | ||
io.stderr:write(trace .. "\n") | ||
end | ||
|
||
pl_app.quit(nil, true) | ||
end, arg) | ||
|
||
main_conf = confs.main_conf | ||
http_conf = confs.http_conf | ||
stream_conf = confs.stream_conf | ||
end | ||
|
||
-- construct the args table | ||
local args_table = { "{" } | ||
for k, v in pairs(arg) do | ||
if type(k) == "string" then | ||
k = "\"" .. k .. "\"" | ||
end | ||
if type(v) == "string" then | ||
v = "\"" .. v .. "\"" | ||
end | ||
|
||
table.insert(args_table, string.format("[%s] = %s,", k, v)) | ||
end | ||
table.insert(args_table, "}") | ||
|
||
local args_str = table.concat(args_table, " ") | ||
|
||
local inline_code = string.format([[ | ||
setmetatable(_G, nil) | ||
pcall(require, "luarocks.loader") | ||
package.path = (os.getenv("KONG_LUA_PATH_OVERRIDE") or "") .. "./?.lua;./?/init.lua;" .. package.path | ||
require("kong.cmd.init")(arg) | ||
require("kong.cmd.init")("%s", %s) | ||
]], cmd_name, args_str) | ||
|
||
local resty_cmd = string.format( | ||
"resty --main-conf \"%s\" --http-conf \"%s\" --stream-conf \"%s\" -e '%s'", | ||
main_conf, http_conf, stream_conf, inline_code) | ||
|
||
local _, code = pl_utils.execute(resty_cmd) | ||
os.exit(code) | ||
-- vim: set ft=lua ts=2 sw=2 sts=2 et : |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
local conf_loader = require "kong.conf_loader" | ||
local pl_path = require "pl.path" | ||
local pl_stringx = require "pl.stringx" | ||
local prefix_handler = require "kong.cmd.utils.prefix_handler" | ||
local log = require "kong.cmd.utils.log" | ||
local fmt = string.format | ||
|
||
local compile_nginx_main_inject_conf = prefix_handler.compile_nginx_main_inject_conf | ||
local compile_nginx_http_inject_conf = prefix_handler.compile_nginx_http_inject_conf | ||
local compile_nginx_stream_inject_conf = prefix_handler.compile_nginx_stream_inject_conf | ||
local prepare_prefix = prefix_handler.prepare_prefix | ||
|
||
local function load_conf(args) | ||
-- retrieve default prefix or use given one | ||
log.disable() | ||
local conf = assert(conf_loader(args.conf, { | ||
prefix = args.prefix | ||
}, { pre_cmd = true })) | ||
log.enable() | ||
|
||
if pl_path.exists(conf.kong_env) then | ||
-- load <PREFIX>/kong.conf containing running node's config | ||
conf = assert(conf_loader(conf.kong_env)) | ||
end | ||
|
||
-- make sure necessary files like `.ca_combined` exist | ||
-- but skip_write to avoid overwriting the existing nginx configurations | ||
assert(prepare_prefix(conf, nil, true)) | ||
|
||
return conf | ||
end | ||
|
||
-- convert relative path to absolute path | ||
-- as resty will run a temporary nginx instance | ||
local function convert_directive_path_to_absolute(prefix, nginx_conf, paths) | ||
local new_conf = nginx_conf | ||
|
||
for _, path in ipairs(paths) do | ||
local pattern = fmt("(%s) (.+);", path) | ||
local m, err = ngx.re.match(new_conf, pattern) | ||
if err then | ||
return nil, err | ||
|
||
elseif m then | ||
local path = pl_stringx.strip(m[2]) | ||
|
||
if path:sub(1, 1) ~= '/' then | ||
local absolute_path = prefix .. "/" .. path | ||
local replace = "$1 " .. absolute_path .. ";" | ||
local _, err | ||
new_conf, _, err = ngx.re.sub(new_conf, pattern, replace) | ||
|
||
if not new_conf then | ||
return nil, err | ||
end | ||
end | ||
end | ||
end | ||
|
||
return new_conf, nil | ||
end | ||
|
||
local function compile_main_inject(conf) | ||
local nginx_main_inject_conf, err = compile_nginx_main_inject_conf(conf) | ||
if not nginx_main_inject_conf then | ||
return nil, err | ||
end | ||
|
||
-- path directives that needs to be converted | ||
local paths = { | ||
"lmdb_environment_path", | ||
} | ||
return convert_directive_path_to_absolute(conf.prefix, nginx_main_inject_conf, paths) | ||
end | ||
|
||
local function compile_http_inject(conf) | ||
return compile_nginx_http_inject_conf(conf) | ||
end | ||
|
||
local function compile_stream_inject(conf) | ||
return compile_nginx_stream_inject_conf(conf) | ||
end | ||
|
||
local function compile_confs(args) | ||
local conf = load_conf(args) | ||
local main_conf = assert(compile_main_inject(conf)) | ||
local http_conf = assert(compile_http_inject(conf)) | ||
local stream_conf = assert(compile_stream_inject(conf)) | ||
|
||
return { main_conf = main_conf, http_conf = http_conf, stream_conf = stream_conf, } | ||
end | ||
|
||
return { | ||
compile_confs = compile_confs, | ||
} |
Oops, something went wrong.
8a1ebba
There was a problem hiding this comment.
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:8a1ebba055d28f940cc19774cf5edf35f71dd149
Artifacts available https://github.com/Kong/kong/actions/runs/5643379141