lua plugin system

This commit is contained in:
Elvin Efendi 2019-02-24 21:32:17 -05:00
parent dcb1a04d53
commit 8f81538b0d
3 changed files with 83 additions and 3 deletions

View file

@ -0,0 +1,48 @@
local string_format = string.format
local new_tab = require "table.new"
local ngx_log = ngx.log
local INFO = ngx.INFO
local ERR = ngx.ERR
local _M = {}
local MAX_NUMBER_OF_PLUGINS = 10000
-- TODO: is this good for a dictionary?
local plugins = new_tab(MAX_NUMBER_OF_PLUGINS, 0)
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
plugins[name] = plugin
end
function _M.init(names)
for _, name in ipairs(names) do
load_plugin(name)
end
end
function _M.run()
local phase = ngx.get_phase()
for name, plugin in pairs(plugins) do
if plugin[phase] then
ngx_log(INFO, string_format("running plugin \"%s\" in phase \"%s\"", 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", name, phase, err))
end
end
end
end
return _M

View file

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

View file

@ -101,6 +101,15 @@ http {
certificate = res
end
{{ end }}
ok, res = pcall(require, "plugins")
if not ok then
error("require failed: " .. tostring(res))
else
plugins = res
end
-- load all plugins that'll be used here
plugins.init({})
}
init_worker_by_lua_block {
@ -109,6 +118,8 @@ http {
{{ if $all.EnableMetrics }}
monitor.init_worker()
{{ end }}
plugins.run()
}
{{/* Enable the real_ip module only if we use either X-Forwarded headers or Proxy Protocol. */}}
@ -976,11 +987,11 @@ stream {
rewrite_by_lua_block {
lua_ingress.rewrite({{ locationConfigForLua $location $server $all }})
balancer.rewrite()
plugins.run()
}
{{ if shouldConfigureLuaRestyWAF $all.Cfg.DisableLuaRestyWAF $location.LuaRestyWAF.Mode }}
access_by_lua_block {
{{ if shouldConfigureLuaRestyWAF $all.Cfg.DisableLuaRestyWAF $location.LuaRestyWAF.Mode }}
local lua_resty_waf = require("resty.waf")
local waf = lua_resty_waf:new()
@ -1021,8 +1032,10 @@ stream {
{{ end }}
waf:exec()
{{ end }}
plugins.run()
}
{{ end }}
header_filter_by_lua_block {
{{ if shouldConfigureLuaRestyWAF $all.Cfg.DisableLuaRestyWAF $location.LuaRestyWAF.Mode }}
@ -1030,6 +1043,8 @@ stream {
local waf = lua_resty_waf:new()
waf:exec()
{{ end }}
plugins.run()
}
body_filter_by_lua_block {
{{ if shouldConfigureLuaRestyWAF $all.Cfg.DisableLuaRestyWAF $location.LuaRestyWAF.Mode }}
@ -1049,6 +1064,8 @@ stream {
{{ if $all.EnableMetrics }}
monitor.call()
{{ end }}
plugins.run()
}
{{ if (and (not (empty $server.SSLCert.PemFileName)) $all.Cfg.HSTS) }}