Custom Plugin: access plugin configuration from `init_worker()`

Hi!

I would like to initialize some things in init_worker(), so that it is set up and verified when the requests arrive later with the other per-request callbacks.

But: It seems that the callback init_worker() is not getting the parameter conf with the plugin configuration.

How can I access the plugins own configuration in init_worker()?

Note: I have seen & read the GitHub Issue https://github.com/Kong/kong/issues/3001, but I was unable to get the point, how the bot-detection plugin manages/managed to serve as example.

All I want is to access the key/values read-only to react in the init_worker() phase which is setting up some maintenance and initialization stuff.

Thanks for any hints

Tino

1 Like

OK, after some more digging around I found some solution that seems to be working.


local function get_conf(self)
    -- for some reason init_worker does *not* get the plugins `conf` as parameter, see https://github.com/Kong/kong/issues/3001
    -- see also: https://discuss.konghq.com/t/custom-plugin-access-plugin-configuration-from-init-worker/4445
    local key = kong.db.plugins:cache_key(self._name, nil, nil, nil)
    local plugin, err = kong.cache:get(key, nil, function(key)
      local row, err = kong.db.plugins:select_by_cache_key(key)
      if err then
        return nil, tostring(err)
      end
      return row
    end, key)
    if err then
      ngx.log(ngx.ERR, "err in (pre-)fetching plugin ", self._name, " config:", err)
      return nil, err
    end
    return plugin.config, nil
end


function Plugin:init_worker()
    local conf, err = get_conf(self)
    ...
end

Is this the right way to go?

somebody else linked his question to this one, so I’ll give a late update on this:

There simply is no config in the init-worker phase. Why is there no config? because when a request comes in, based on it matching a specific route, service or consumer (or being global), the appropriate “instance” of a plugin configuration is loaded and executed.

Since in the init-worker phase there is no request, also the Kong router didn’t run to determine the route/service/consumer, so there also will be no “instance” of a plugin configuration.

A simple example explaining the problem:

  • assume a Kong node configured with 1 service, and 2 routes
  • both routes get the rate-limiting plugin, the first one gets 5 calls per second, the second one gets 10 calls per second.
  • the system now has two plugin configurations

Question: upon the init-worker phase; which of the 2 plugin configuration tables should be passed to the rate-limiting init-worker handler?

In the init-worker phase, there is no request, and hence we do not know which config table to pass.

Stated otherwise:

  • init and init-worker handlers are process-driven (when the Kong starts or a worker process is added)
  • the other phases are request-driven

hth

Thank you!

What do you propose then as best practice for configuration that is best looked at independantly of a request-driven event model? Some things are better set up process driven, per worker instance, as they for example create “singletons” in each nginx worker.

In our use case there are some of these things that we want to initialize non-request-driven.

Indeed the above mentioned workaround posted by myself (get_conf()) only partially worked, some plugins were able to use it, others not – so meanwhile we switched to “init-the plugin-on-first-request” - meaning the first request after a worker initialization is now special (and may take longer and may take other code paths) as it detects that such house keeping stuff is to be done first and sets that up.

Specifically for us these initialization steps are:

-> Database Connections to MS-SQL (hostname, port, username, credentials are stored in plugin config, so they are part of the conf parameter of the callbacks).

-> setting up ngx.every to check the health of these connections and potentially reconnect/resetup them.

-> reading of private key files whose file name locations are kept in the plugin config.

Hi again,

… reading your post several times and thinking about it I get the impression that

init_worker(static-conf)
access (per-request-or-per-route-conf)
...

might be a solution for my issue above (as the MS-SQL peer or the key file are indeed independant of concrete requests/routes).

From reading the documentation:


I obviously missed the point that the conf parameter might legitimately change from callback to callback invocation. So one plugin instance needs to be prepared to be called with different conf objects, changing from request to request, right?

Any chance to realize something like the static-conf? Sure we can use some hardcoded on-disk config file, but that seems “backward”?

here’s some old code that needs some updates, it was coded with a pre Kong 1.0.0 in mind. But after updating it could be useful. See https://github.com/Kong/kong-plugins-system

Make sure to read this: https://github.com/Kong/kong-plugins-system/blob/master/kong/plugins/system.lua#L1-L17

PR’s to update it are most welcome :smile: