Merge pull request #3807 from ElvinEfendi/lua-plugin-system
Lua plugin system - MVP
This commit is contained in:
commit
acb36c0780
3 changed files with 83 additions and 3 deletions
48
rootfs/etc/nginx/lua/plugins.lua
Normal file
48
rootfs/etc/nginx/lua/plugins.lua
Normal 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
|
15
rootfs/etc/nginx/lua/plugins/hello_world/main.lua
Normal file
15
rootfs/etc/nginx/lua/plugins/hello_world/main.lua
Normal 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
|
|
@ -101,6 +101,15 @@ http {
|
||||||
certificate = res
|
certificate = res
|
||||||
end
|
end
|
||||||
{{ 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 {
|
init_worker_by_lua_block {
|
||||||
|
@ -109,6 +118,8 @@ http {
|
||||||
{{ if $all.EnableMetrics }}
|
{{ if $all.EnableMetrics }}
|
||||||
monitor.init_worker()
|
monitor.init_worker()
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
plugins.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
{{/* Enable the real_ip module only if we use either X-Forwarded headers or Proxy Protocol. */}}
|
{{/* 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 {
|
rewrite_by_lua_block {
|
||||||
lua_ingress.rewrite({{ locationConfigForLua $location $server $all }})
|
lua_ingress.rewrite({{ locationConfigForLua $location $server $all }})
|
||||||
balancer.rewrite()
|
balancer.rewrite()
|
||||||
|
plugins.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
{{ if shouldConfigureLuaRestyWAF $all.Cfg.DisableLuaRestyWAF $location.LuaRestyWAF.Mode }}
|
|
||||||
|
|
||||||
access_by_lua_block {
|
access_by_lua_block {
|
||||||
|
{{ if shouldConfigureLuaRestyWAF $all.Cfg.DisableLuaRestyWAF $location.LuaRestyWAF.Mode }}
|
||||||
local lua_resty_waf = require("resty.waf")
|
local lua_resty_waf = require("resty.waf")
|
||||||
local waf = lua_resty_waf:new()
|
local waf = lua_resty_waf:new()
|
||||||
|
|
||||||
|
@ -1021,15 +1032,19 @@ stream {
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
waf:exec()
|
waf:exec()
|
||||||
}
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
plugins.run()
|
||||||
|
}
|
||||||
|
|
||||||
header_filter_by_lua_block {
|
header_filter_by_lua_block {
|
||||||
{{ if shouldConfigureLuaRestyWAF $all.Cfg.DisableLuaRestyWAF $location.LuaRestyWAF.Mode }}
|
{{ if shouldConfigureLuaRestyWAF $all.Cfg.DisableLuaRestyWAF $location.LuaRestyWAF.Mode }}
|
||||||
local lua_resty_waf = require "resty.waf"
|
local lua_resty_waf = require "resty.waf"
|
||||||
local waf = lua_resty_waf:new()
|
local waf = lua_resty_waf:new()
|
||||||
waf:exec()
|
waf:exec()
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
plugins.run()
|
||||||
}
|
}
|
||||||
body_filter_by_lua_block {
|
body_filter_by_lua_block {
|
||||||
{{ if shouldConfigureLuaRestyWAF $all.Cfg.DisableLuaRestyWAF $location.LuaRestyWAF.Mode }}
|
{{ if shouldConfigureLuaRestyWAF $all.Cfg.DisableLuaRestyWAF $location.LuaRestyWAF.Mode }}
|
||||||
|
@ -1049,6 +1064,8 @@ stream {
|
||||||
{{ if $all.EnableMetrics }}
|
{{ if $all.EnableMetrics }}
|
||||||
monitor.call()
|
monitor.call()
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
plugins.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
{{ if (and (not (empty $server.SSLCert.PemFileName)) $all.Cfg.HSTS) }}
|
{{ if (and (not (empty $server.SSLCert.PemFileName)) $all.Cfg.HSTS) }}
|
||||||
|
|
Loading…
Reference in a new issue