Kibana plugin - read configuration from kibana.yml

Hello,
I code own plugin for kibana, but am unable to read plugin-related configuration from kibana.yml

kibana.yml - custom attributes part

cleanup tool

kibanaVersion format: [major].[minor]

cleanup_tool.kibanaVersion: 4.6
cleanup_tool.enabled: true
cleanup_tool.debug: true

auditlog settings

cleanup_tool.auditlogRecordsPerPage: 20
cleanup_tool.auditlogDefaultSortField: timestamp
cleanup_tool.auditlogDefaultSortDirection: desc

scrollTime used in Scroll API on searching for documents for bulk processing

cleanup_tool.scrollTime: 3m

settings for scheduler connection to ES - prevents all Kibana features from using high priviledges needed for scheduler

cleanup_tool.schedulerESHost: 10.88.13.204
cleanup_tool.schedulerESPort: 9200
cleanup_tool.schedulerESUser: superClean
cleanup_tool.schedulerESPassword: password
cleanup_tool.schedulerESRequestTimeout: 30000
cleanup_tool.schedulerESPingTimeout: 3000
cleanup_tool.schedulerESKeepAlive: true

ms to wait before recall ES on failure

cleanup_tool.checkESTimeout: 30000

index.js (config(Joi) part)

config(Joi) {
const { array, boolean, number, object, string } = Joi;

  return Joi.object({
    kibanaVersion: Joi.string().default('4.6'),
    enabled: Joi.boolean().default(true),
    debug: Joi.boolean().default(true),
    auditlogRecordsPerPage: Joi.number().integer().default(20),
    auditlogDefaultSortField: Joi.string().default('timestamp'),
    auditlogDefaultSortDirection: Joi.string().default('desc'),
    scrollTime: Joi.string().default('3m'),
    schedulerESHost: Joi.string().default('127.0.0.1'),
    schedulerESPort: Joi.number().integer().default(9200),
    schedulerESUser: Joi.string().default('elastic'),
    schedulerESPassword: Joi.string().default('changeme'),
    schedulerESRequestTimeout: Joi.number().integer().default(30000),
    schedulerESPingTimeout: Joi.number().integer().default(3000),
    schedulerESKeepAlive: Joi.boolean().default(true),
    checkESTimeout: Joi.number().default(30000)
  }).default();
}

I believe, configuration is read from here, when plugin starts ?

index.js (injectVars part)

injectVars: function(server, options) {
const config = server.config();
return {
kbnIndex: config.get('kibana.index'), // unused
elasticsearchUrl: config.get('elasticsearch.url'), // new
enabled: options.enabled,
debug: options.debug,
auditlogRecordsPerPage: options.auditlogRecordsPerPage,
auditlogDefaultSortField: options.auditlogDefaultSortField,
auditlogDefaultSortDirection: options.auditlogDefaultSortDirection,
scrollTime: options.scrollTime,
schedulerESHost: options.schedulerESHost,
schedulerESPort: options.schedulerESPort,
schedulerESUser: options.schedulerESUser,
schedulerESPassword: options.schedulerESPassword,
schedulerESRequestTimeout: options.schedulerESRequestTimeout,
schedulerESPingTimeout: options.schedulerESPingTimeout,
schedulerESKeepAlive: options.schedulerESKeepAlive
};

But when I later access

options.schedulerESUser

, it has default value 'elastic' rather than what I have specified in kibana.yml.

Does anybody know how to solve this ?
Thanks in advance.

P.S. - note that I am completely new to kibana plugin development.

Assuming you are talking about reading a config value from the server side, you can use the server.config service.

  server.route({
    method: 'GET',
    path: '/api/myplugin/v1/coolstuff',
    async handler: (req, reply) => {

      const config = req.server.config();
      const schedulerESUser = config.get('myplugin.stuff.schedulerESUser');
      const usefulData = await helperModule(schedulerESUser);

      reply(usefulData);
    }
  });

Hey, thanks for reply, it was helpful for me to get oriented in plugin's code,
but mistake was actually in field

name
in package.json.

This has to be set to the same value, as the configuration prefix in kibana.yml.

One more question though.

I read about callWithRequest and found out that "normal usage" is to forward "req" from client request.

I need to ping elasticsearch at the start up of my plugin, to test if it is available;
but not with callWithInternalUser, because it has no rights to certain operations plugin requires. I need to use custom user defined in by fields in kibana.yml.

Is it possible to create "req" object manually ?
Is it possible to modify authentication of incoming request ?

I tried following:

const reqAuthorizationString = options.schedulerESUser + ':' + options.schedulerESPassword;
const reqAllIn = { 'headers': { 'authorization': { 'credentials': reqAuthorizationString } } };
callWithRequest(reqAllIn, 'ping', {}).then(function (response) { //some code here }
but this throws 401 with following message:

Authentication Exception :: {"path":"/","query":{},"statusCode":401,"response":"","wwwAuthenticateDirective":"Basic realm=\"security\" charset=\"UTF-8\""}"}

Is it possible to manually create "req" parameter ?

There's a relatively standard way to do this. In your plugin's init method:

init(plugin, server) {
  const esPlugin = server.plugins.elasticsearch;
  plugin.status.yellow('Waiting for Elasticsearch');

  esPlugin.status.once('green', () => {
    // kibana has a solid connection to elasticsearch, now initialize my plugin
    // more init code ...
    plugin.status.green('Plugin ready'));
  });
}

Yes, these things are possible, but I would avoid them if you can for now.

Shay announced the opening of X-Pack at the Elasticon Keynote recently, and once the code is open, it'll be easier to find references on how to do these kinds of things.

Hey,
thanks very much, I managed to make it work somehow ! :slight_smile:

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.