Remove 3rd party lua plugin support (#11821)

This commit is contained in:
Ricardo Katz 2024-08-21 10:54:29 -03:00 committed by GitHub
parent bfd65d6c59
commit 3bec99ecfc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 2 additions and 258 deletions

View file

@ -1,61 +0,0 @@
local require = require
local ngx = ngx
local ipairs = ipairs
local string_format = string.format
local ngx_log = ngx.log
local INFO = ngx.INFO
local ERR = ngx.ERR
local pcall = pcall
local _M = {}
local MAX_NUMBER_OF_PLUGINS = 20
local plugins = {}
local function load_plugin(name)
local path = string_format("plugins.%s.main", name)
local ok, plugin = pcall(require, path)
if not ok then
ngx_log(ERR, string_format("error loading plugin \"%s\": %s", path, plugin))
return
end
local index = #plugins
if (plugin.name == nil or plugin.name == '') then
plugin.name = name
end
plugins[index + 1] = plugin
end
function _M.init(names)
local count = 0
for _, name in ipairs(names) do
if count >= MAX_NUMBER_OF_PLUGINS then
ngx_log(ERR, "the total number of plugins exceed the maximum number: ", MAX_NUMBER_OF_PLUGINS)
break
end
load_plugin(name)
count = count + 1 -- ignore loading failure, just count the total
end
end
function _M.run()
local phase = ngx.get_phase()
for _, plugin in ipairs(plugins) do
if plugin[phase] then
ngx_log(INFO, string_format("running plugin \"%s\" in phase \"%s\"", plugin.name, phase))
-- TODO: consider sandboxing this, should we?
-- probably yes, at least prohibit plugin from accessing env vars etc
-- but since the plugins are going to be installed by ingress-nginx
-- operator they can be assumed to be safe also
local ok, err = pcall(plugin[phase])
if not ok then
ngx_log(ERR, string_format("error while running plugin \"%s\" in phase \"%s\": %s",
plugin.name, phase, err))
end
end
end
end
return _M

View file

@ -1,36 +0,0 @@
# Custom Lua plugins
ingress-nginx uses [https://github.com/openresty/lua-nginx-module](https://github.com/openresty/lua-nginx-module) to run custom Lua code
within Nginx workers. It is recommended to familiarize yourself with that ecosystem before deploying your custom Lua based ingress-nginx plugin.
### Writing a plugin
Every ingress-nginx Lua plugin is expected to have `main.lua` file and all of its dependencies.
`main.lua` is the entry point of the plugin. The plugin manager uses convention over configuration
strategy and automatically runs functions defined in `main.lua` in the corresponding Nginx phase based on their name.
Nginx has different [request processing phases](https://nginx.org/en/docs/dev/development_guide.html#http_phases).
By defining functions with the following names, you can run your custom Lua code in the corresponding Nginx phase:
- `init_worker`: useful for initializing some data per Nginx worker process
- `rewrite`: useful for modifying request, changing headers, redirection, dropping request, doing authentication etc
- `header_filter`: this is called when backend response header is received, it is useful for modifying response headers
- `body_filter`: this is called when response body is received, it is useful for logging response body
- `log`: this is called when request processing is completed and a response is delivered to the client
Check this [`hello_world`](https://github.com/kubernetes/ingress-nginx/tree/main/rootfs/etc/nginx/lua/plugins/hello_world) plugin as a simple example or refer to [OpenID Connect integration](https://github.com/ElvinEfendi/ingress-nginx-openidc/tree/master/rootfs/etc/nginx/lua/plugins/openidc) for more advanced usage.
Do not forget to write tests for your plugin.
### Installing a plugin
There are two options:
- mount your plugin into `/etc/nginx/lua/plugins/<your plugin name>` in the ingress-nginx pod
- build your own ingress-nginx image like it is done in the [example](https://github.com/ElvinEfendi/ingress-nginx-openidc/tree/master/rootfs/etc/nginx/lua/plugins/openidc) and install your plugin during image build
Mounting is the quickest option.
### Enabling plugins
Once your plugin is ready you need to use [`plugins` configuration setting](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#plugins) to activate it. Let's say you want to activate `hello_world` and `open_idc` plugins, then you set `plugins` setting to `"hello_world, open_idc"`. _Note_ that the plugins will be executed in the given order.

View file

@ -1,13 +0,0 @@
local ngx = ngx
local _M = {}
function _M.rewrite()
local ua = ngx.var.http_user_agent
if ua == "hello" then
ngx.req.set_header("x-hello-world", "1")
end
end
return _M

View file

@ -1,24 +0,0 @@
local main = require("plugins.hello_world.main")
-- The unit tests are run within a timer phase in a headless Nginx process.
-- Since `set_header` and `ngx.var.http_` API are disabled in this phase we have to stub it
-- to avoid `API disabled in the current context` error.
describe("main", function()
describe("rewrite", function()
it("sets x-hello-world header to 1 when user agent is hello", function()
ngx.var = { http_user_agent = "hello" }
stub(ngx.req, "set_header")
main.rewrite()
assert.stub(ngx.req.set_header).was_called_with("x-hello-world", "1")
end)
it("does not set x-hello-world header to 1 when user agent is not hello", function()
ngx.var = { http_user_agent = "not-hello" }
stub(ngx.req, "set_header")
main.rewrite()
assert.stub(ngx.req.set_header).was_not_called_with("x-hello-world", "1")
end)
end)
end)

View file

@ -1,23 +0,0 @@
describe("plugins", function()
describe("#run", function()
it("runs the plugins in the given order", function()
ngx.get_phase = function() return "rewrite" end
local plugins = require("plugins")
local called_plugins = {}
local plugins_to_mock = {"plugins.pluginfirst.main", "plugins.pluginsecond.main", "plugins.pluginthird.main"}
for i=1, 3, 1
do
package.loaded[plugins_to_mock[i]] = {
rewrite = function()
called_plugins[#called_plugins + 1] = plugins_to_mock[i]
end
}
end
assert.has_no.errors(function()
plugins.init({"pluginfirst", "pluginsecond", "pluginthird"})
end)
assert.has_no.errors(plugins.run)
assert.are.same(plugins_to_mock, called_plugins)
end)
end)
end)