106 lines
3.6 KiB
Lua
106 lines
3.6 KiB
Lua
local proc_mgmt = require "kong.runloop.plugin_servers.process"
|
|
local plugin = require "kong.runloop.plugin_servers.plugin"
|
|
|
|
local pairs = pairs
|
|
local kong = kong
|
|
|
|
-- module cache of loaded external plugins
|
|
-- XXX historically, this list of plugins has not been invalidated;
|
|
-- however, as plugin servers can be managed externally, users may also
|
|
-- change and restart the plugin server, potentially with new configurations
|
|
-- this needs to be improved -- docs and code hardening
|
|
local loaded_plugins
|
|
|
|
local function load_external_plugins()
|
|
if loaded_plugins then
|
|
return true
|
|
end
|
|
|
|
loaded_plugins = {}
|
|
|
|
local kong_config = kong.configuration
|
|
|
|
local plugins_info, err = proc_mgmt.load_external_plugins_info(kong_config)
|
|
if not plugins_info then
|
|
return nil, "failed loading external plugins: " .. err
|
|
end
|
|
|
|
for plugin_name, plugin_info in pairs(plugins_info) do
|
|
local plugin = plugin.new(plugin_info)
|
|
loaded_plugins[plugin_name] = plugin
|
|
end
|
|
|
|
return loaded_plugins
|
|
end
|
|
|
|
local function get_plugin(plugin_name)
|
|
assert(load_external_plugins())
|
|
|
|
return loaded_plugins[plugin_name]
|
|
end
|
|
|
|
local function load_plugin(plugin_name)
|
|
local plugin = get_plugin(plugin_name)
|
|
if plugin and plugin.PRIORITY then
|
|
return true, plugin
|
|
end
|
|
|
|
return false, "no plugin found"
|
|
end
|
|
|
|
local function load_schema(plugin_name)
|
|
local plugin = get_plugin(plugin_name)
|
|
if plugin and plugin.PRIORITY then
|
|
return true, plugin.schema
|
|
end
|
|
|
|
return false, "no plugin found"
|
|
end
|
|
|
|
local function start()
|
|
-- in case plugin server restarts, all workers need to update their defs
|
|
kong.worker_events.register(function (data)
|
|
plugin.reset_instances_for_plugin(data.plugin_name)
|
|
end, "plugin_server", "reset_instances")
|
|
|
|
return proc_mgmt.start_pluginservers()
|
|
end
|
|
|
|
local function stop()
|
|
return proc_mgmt.stop_pluginservers()
|
|
end
|
|
|
|
|
|
--
|
|
-- This modules sole responsibility is to
|
|
-- manage external plugins: starting/stopping plugins servers,
|
|
-- and return plugins info (such as schema and their loaded representations)
|
|
--
|
|
-- The general initialization flow is:
|
|
-- - kong.init: calls start and stop to start/stop external plugins servers
|
|
-- - kong.db.schema.plugin_loader: calls load_schema to get an external plugin schema
|
|
-- - kong.db.dao.plugins: calls load_plugin to get the expected representation of a plugin
|
|
-- (phase handlers, priority, etc)
|
|
--
|
|
-- Internal flow:
|
|
-- .plugin_servers.init: loads all external plugins, by calling .plugin_servers.process and .plugin_servers.plugin
|
|
-- .plugin_servers.process: queries external plugins info with the command specified in _query_cmd properties
|
|
-- .plugin_servers.plugin: with info obtained as described above, .plugin:new returns a kong-compatible representation
|
|
-- of an external plugin, with phase handlers, PRIORITY, and wrappers to the PDK. Calls
|
|
-- .plugin_servers.rpc to create an RPC through which Kong communicates with the plugin process
|
|
-- .plugin_servers.rpc: based on info contained in the plugin (protocol field), creates the correct RPC for the
|
|
-- given external plugin
|
|
-- .plugin_servers.rpc.pb_rpc: protobuf rpc implementation - used by Golang
|
|
-- .plugin_servers.rpc.mp.rpc: messagepack rpc implementation - used by JS and Python
|
|
-- .plugin_servers.init: calls .plugin_servers.process to start external plugin servers
|
|
-- .plugin_servers.process: optionally starts all external plugin servers (if a _start_cmd is found)
|
|
-- uses the resty pipe API to manage the external plugin process
|
|
--
|
|
|
|
return {
|
|
start = start,
|
|
stop = stop,
|
|
load_schema = load_schema,
|
|
load_plugin = load_plugin,
|
|
}
|