-
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(plugins): load wasm filter plugins before external plugins
In 4059a31 (#13843) we added a plugin-like interface for Wasm filters. We now have 3 sources for plugins: Lua, External, and Wasm Filters. When a plugin is enabled or configured, the plugin system follows a resolution order for looking up the plugin handler and schema: 1. Lua => `require kong.plugins.<name>.{handler,schema}` 2. External => `kong.runloop.plugin_servers.load_{handler,schema}(<name>)` 3. Wasm Filters => `kong.runloop.wasm.plugins.load_{handler,schema}(<name>)` When a user configures Kong with a "bad" entry in `pluginserver_names` (read: a plugin server that is not actually installed), step #2 of the plugin resolution process throws an exception, because the external plugin subsystem attempts to query a plugin server that does not exist. Importantly, *this exception is not encountered when the user has only configured/enabled Lua plugins,* because we never reach beyond step #1 of the plugin resolution process. A side effect of adding the Wasm filter plugin interface is that discovered Wasm filters are added to the global plugins table (`kong.configuration.loaded_plugins`) when Wasm is enabled. This means that, if Wasm is enabled, and any Wasm filters are installed, we _always_ step through step #2 of the plugin resolution process, triggering an exception if the user has any badly-configured plugin server. A future change will likely render this scenario unreachable by performing deeper validation of `pluginserver_names` at startup. For now, a simple fix is just to change the resolution order such that Wasm filters are loaded _before_ we query the external plugin subsystem: 1. Lua 2. Wasm Filters 3. External
- Loading branch information
Showing
3 changed files
with
102 additions
and
6 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
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,96 @@ | ||
local helpers = require "spec.helpers" | ||
|
||
for _, strategy in helpers.each_strategy() do | ||
|
||
describe("external plugins and wasm #" .. strategy, function() | ||
describe("wasm enabled in conjunction with unused pluginservers", function() | ||
it("does not prevent kong from starting", function() | ||
require("kong.runloop.wasm").enable({ | ||
{ name = "tests", | ||
path = helpers.test_conf.wasm_filters_path .. "/tests.wasm", | ||
}, | ||
}) | ||
|
||
local bp = assert(helpers.get_db_utils(strategy, { | ||
"services", | ||
"routes", | ||
"plugins", | ||
"filter_chains", | ||
}, { "response-transformer", "tests" })) | ||
|
||
local route = assert(bp.routes:insert({ | ||
protocols = { "http" }, | ||
paths = { "/" }, | ||
service = assert(bp.services:insert({})), | ||
})) | ||
|
||
-- configure a wasm filter plugin | ||
assert(bp.plugins:insert({ | ||
name = "tests", | ||
route = route, | ||
config = "", | ||
})) | ||
|
||
-- configure a lua plugin | ||
assert(bp.plugins:insert({ | ||
name = "response-transformer", | ||
route = route, | ||
config = { | ||
add = { | ||
headers = { | ||
"X-Lua-Plugin:hello from response-transformer", | ||
}, | ||
}, | ||
}, | ||
})) | ||
|
||
assert(helpers.start_kong({ | ||
nginx_conf = "spec/fixtures/custom_nginx.template", | ||
database = strategy, | ||
|
||
wasm = true, | ||
wasm_filters = "tests", | ||
|
||
plugins = "response-transformer", | ||
|
||
-- this pluginserver does not exist, but we will validate that kong can | ||
-- start so long as there are no configured/enabled plugins that will | ||
-- require us to invoke it in any way | ||
-- | ||
-- XXX: this configuration could be considered invalid, and future changes | ||
-- to plugin resolution/pluginserver code MAY opt to change this behavior | ||
pluginserver_names = "not-exists", | ||
pluginserver_not_exists_start_cmd = "/i/do/not/exist", | ||
pluginserver_not_exists_query_cmd = "/i/do/not/exist", | ||
})) | ||
|
||
local client | ||
|
||
finally(function() | ||
if client then | ||
client:close() | ||
end | ||
|
||
helpers.stop_kong() | ||
end) | ||
|
||
client = helpers.proxy_client() | ||
local res = client:get("/", { | ||
headers = { | ||
["X-PW-Test"] = "local_response", | ||
["X-PW-Input"] = "hello from wasm", | ||
}, | ||
}) | ||
|
||
-- verify that our wasm filter ran | ||
local body = assert.res_status(200, res) | ||
assert.equals("hello from wasm", body) | ||
|
||
-- verify that our lua plugin (response-transformer) ran | ||
local header = assert.response(res).has.header("X-Lua-Plugin") | ||
assert.equals("hello from response-transformer", header) | ||
end) | ||
end) | ||
end) | ||
|
||
end -- each strategy |