Change kibana settings at runtime from Plugin

(Simone Scarduzio) #1

Hello guys, can you please comment if the following is total Sci-Fi or can be done?


Serve each user their own dashboards and kibana settings.

Implementation idea

Write a plugin that dynamically changes kibana.index at runtime depending on some external parameters (i.e. request headers).

  • A reverse proxy Authenticates a user (i.e. "user1")
  • The reverse proxy Injects an identity header in the incoming request.
  • The request hits Kibana daemon, where a plugin changes on the fly the value of kibana.index to ".kibana_user1"
  • The browser loads the Kibana webapp that thinks all settings are stored in ".kibana_user1" index

Thank you!

(Joe Fleming) #2

Interesting question. I'm not aware of anyone trying to do this before, but it might work. Let me think in text here a moment...

As you note, the index is stored in the config service, which is available on the server instance, and I think might be writable. Because Kibana is based on Hapi, you could potentially write a hook that would update that setting, which would apply it on every request the server saw.

The question is, would doing so require the server to restart? Because if it does, then pending requests would fail, which would make the system basically unusable.

If the server doesn't have to restart, the next problem is the client/browser. Because queries happen directly to the kibana index through the es_admin endpoint (eg. http://localhost:5601/es_admin/.kibana/visualization/_search?size=100), the client needs to know which index to use, so the server is pushing it up when the app first loads. You should be able to send the correct value after your routing hook, but I can't guarantee that it would work reliably.

There's probably other parts I'm not considering here, but I guess the short answer is "maybe, but it would require a fair bit of experimentation to find out."

The easier way to do this would be to host a Kibana instance for each group/index you need to expose.

(Simone Scarduzio) #3

Hey @Joe_Fleming thanks for the response!

Thanks, the server side is done.
But on the client side - as you say - is more complicated.
In the kibana code, the kbnIndex value is injected via angular as a string value in a lot of constructors. And I think those constructors are executed before the uiRouters.addSetupWork.

So It does not help if I do this:

uiRoutes.addSetupWork(['$http', '$location', 'kbnUrl', 'esAdmin', '$rootScope', function ($http, $location, kbnUrl, esAdmin, $rootScope) {

    // patch the getInjected function, to around the cloning.. 
    const orig = $
    $ = function (name, def) {
      if (name == 'kbnIndex') return '.kibana_simone'
      if (name == null) {
        var map = orig()
        map.kbnIndex = '.kibana_simone'
        return map;
      return $, def)

Examples of constructors with reference tokbnIndex as a value:

export function IndexPatternProvider(Private, $http, config, kbnIndex, Promise, confirmModalPromise) {

Not sure where to go from here.
Is there a way to abort the whole kibana from bootstrapping and start over with a mutated root scope?

(Joe Fleming) #4

Ah, right, kbnIndex is defined using injectDefaultVars, which is a custom hook that, if I recall correctly, creates an Angular constant on the fly. It's just an easy way to expose server-side values on the client, but it was never intended to handle values that would change. If you hunt around the code, particularly around the stuff that bootstraps apps, you'll find the injected vars stuff. I would provide some guidance, but I'm really not sure how it all works myself.

Is there a way to abort the whole kibana from bootstrapping and start over with a mutated root scope?

Not that I know of, and that's certainly more Angular than I know, or will ever know...

If there's a way to override Angular constants, or maybe put a proxy in front of an existing definition, you could change it on the fly that way. But again, I have no idea how to do that, or if it's even possible. Sorry.

(system) #5

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