Kibana Plugin API Changes in 7.3
Now using package root for root directory
New Platform plugins are now loaded relative to the Kibana installation rather than the current working directory of the process. This only affects new platform plugins. Legacy plugins are unchanged.
via #39619,
Removed vis
from aggTypeFieldFilters
If you register a filter via aggTypeFieldFilters.addFilter
, that filter won't get vis
passed in as the 4th argument anymore.
via #39880,
More dashboard migrations
Added dashboard saved object migrations.
- Removed uiStateJSON, properties have been migrated into the panelsJSON objects.
- Removed any remnants of
sort
andcolumns
properties that were once stored on panel objects. Moved them permanently into theembeddableConfig
. - Added migration step for old style angular react component that used
size_x
,size_y
,row
andcol
properties. Moved intogridData
. - Added migration step for the version where we added more rows and columns to the grid.
- URL migration is now using the same logic as migrations for the panels.
related to 35864
fixes 15204
via #39387,
Moved Chrome UI to Core
The ui/registry/chrome_nav_controls
registry that was no longer supported in 7.0 has been removed. To add items to the header bar, you should now use the ui/registry/chrome_header_nav_controls
or call the New Platform API directly:
import {
chromeHeaderNavControlsRegistry,
NavControlSide,
} from 'ui/registry/chrome_header_nav_controls';
chromeHeaderNavControlsRegistry.register(() => ({
name: 'myControl',
order: 1000,
side: NavControlSide.Left,
render(el) {
ReactDOM.render(<MyComponent />, el);
},
}));
import { npStart } from 'ui/new_platform';
npStart.core.chrome.navControls.registerLeft({
order: 1000,
mount(el) {
ReactDOM.render(<MyComponent />, el);
() => ReactDOM.unmountComponentAtNode(el);
}
});
via #39300,
d13n docTitle
ui/doc_title
now exports docTitle
instead of DocTitleProvider
. docTitle
has the same interface as DocTitleProvider
but does not rely on Private
.
via #39162,
Allow requestCert option to be set
This allows us to require an HTTP server created by Kibana to force a client to provide a certificate for authorization to the server instance. This enables PKI-based mutual TLS for client/server interactions
Creating a configuration as such:
const sslConfig = new SslConfig({
requestCert: true,
ca: [myCA],
key: privateKey,
cert: myCert
})
Would require a client to provide the same cert
and key
(and ca
if
it's a self-signed certificate) to the https request in order to the
server to respond:
const agent = new https.Agent({
key: privateKey,
cert: myCert
ca: myCa
})
https.request('https://kibana.local:3000/', { agent }).end()
// or
Wreck.defaults({
agent: {
https: agent
}
})
await wreck.get('https://kibana.local:3000')
Without the same certificate, key and ca, the Kibana server will reject the request as being unauthorized
via #38920,
Restrict access to hapi Request in registerAuth
In the previous release, we introduced experimental registerAuth
hook in New Platform that allows end users to define custom authentication logic.
We changed API of the AuthenticationHandler
function.
In 7.2:
export type AuthenticationHandler<T> = (
request: Request,
sessionStorage: SessionStorage<T>,
t: AuthToolkit
) => Promise<AuthResult>;
In 7.3
export type AuthenticationHandler = (
request: KibanaRequest,
t: AuthToolkit
) => AuthResult | Promise<AuthResult>;
We provide KibanaRequest
instead of hapi
Request object and remove sessionStorage from arguments. Now sessionStorageFactory
is returned as result of registerAuth
call.
Note: as API is experimental is still a subject for further changes.
via #38763,
Unify base path in HttpService
All requests to Kibana server should be concerned about server.basePath
option, which affects all routes when Kibana is run behind a proxy. To simplify URL manipulations to include/exclude server.basePath
part, New platform collocates under basePath
namespace a set of helpers as a part of CoreSetup.http contract:
// on client side
basePath: {
get: () => string;
prepend: (url: string) => string;
remove: (url: string) => string;
};
// on server side
basePath {
get: (request: KibanaRequest | Request) => string;
set: (request: KibanaRequest | Request, basePath: string) => void;
prepend: (url: string) => string;
remove: (url: string) => string;
};
via #38237,
Allow passing in a signal to abort a cluster client request
callWithRequest
now accepts a AbortController signal for aborting requests to Elasticsearch. Example usage:
const { callWithRequest } = server.plugins.elasticsearch.getCluster('data');
const controller = new AbortController();
req.events.once('disconnect', () => controller.abort());
return await callWithRequest(req, 'search', params, { signal: controller.signal });
via #37563,
Expose plugin contracts to Legacy platform
If you want to use a New Platform plugin in Legacy Platform you could access them
On the client
import { getNewPlatform } from 'ui/new_platform';
const plugins: Record<string, unknown> = getNewPlatform().setup.plugins
On the server
new kibana.Plugin({
init(server){
const plugins: Record<string, unknown> = server.newPlatform.setup.plugins;
}
})
via #37218,
ui/public
cleanup
Relocated modules
In preparation for Kibana's upcoming new platform, we are in the process of migrating away from the ui/public
directory. Over time, the contents of this directory will be either deprecated or housed inside a parent plugin. If your plugin imports from any of the following ui/public
modules, you will need to update your import statements as indicated below, so that you are pulling these modules from their new locations.
ui/filter_bar/query_filter
#37311
// deprecated
import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter';
const queryFilter = Private(FilterBarQueryFilterProvider);
queryFilter.addFilters(...);
// new location
import { FilterBarQueryFilterProvider } from 'ui/filter_manager/query_filter';
const queryFilter = Private(FilterBarQueryFilterProvider);
queryFilter.addFilters(...);
In addition, the following methods have been deprecated:
toggleFilter
- Change the filter'sdisabled
attribute instead.pinFilter
- UseFilterManager.setFiltersStore
to toggle filters between global & app state.pinAll
toggleAll
invertAll
ui/filter_manager/filter_manager
#37311
// deprecated
import { FilterManagerProvider } from 'ui/filter_manager';
const filterManager = Private(FilterManagerProvider);
// new location
import { getFilterGenerator } from 'ui/filter_manager';
const filterGen = getFilterGenerator(queryFilter);
ui/apply_filters
#36778
// deprecated
import 'ui/apply_filters';
// new location
import { data } from 'plugins/data/setup';
data.filter.loadLegacyDirectives();
...
<apply-filters-popover ...
// new location - react
import { data } from 'plugins/data/setup';
const { ApplyFiltersPopover } = data.filter.ui;
...
<ApplyFiltersPopover />
ui/utils/brush_event
#35625
// deprecated
import { onBrushEvent } from 'ui/utils/brush_event';
// new location
import { onBrushEvent } from 'ui/vis/vis_filters/brush_event';
ui/management
#39168
In the Management app, IndexPatternCreationConfigRegistry
registry has been replaced with the addIndexPatternType
function.
// deprecated
import { IndexPatternCreationConfigRegistry } from 'ui/management/index_pattern_creation';
IndexPatternCreationConfigRegistry.register(() => MyIndexPatternCreationConfig);
// new location
import { addIndexPatternType } from 'ui/management/index_pattern_creation';
addIndexPatternType(MyIndexPatternCreationConfig);
Angular Removal
Removed unused Angular items
In the process of removing Angular from the Kibana core, the following unused items have been deleted or relocated. If you have used any of those in your plugin and want to keep using them, please copy over the source from the previous Kibana version directly into your plugin code.
Directives
formDirective
,ui/fancy_forms
(via #39977)modal
,ui/angular-bootstrap
(via #39976)ngFormDirective
,ui/fancy_forms
(via #39977)ngModelDirective
,ui/fancy_forms
(via #39977)tableInfo
,ui/table_info
(via #39978)toolBarPagerButtons
,ui/pager_control
(via #39975)toolBarPagerText
,ui/pager_control
(via #39975)paginated_selectable_list
(via #39976)
Factories
via #37007,
Allow interception of http requests from browser http service
HTTP requests made via the new platform browser HTTP service can now be intercepted by registering interceptors:
http.intercept({
request(request: Request) {
// Modify or return a new request.
// Will be passed eventually to window.fetch(request)
return new Request(newPath, request);
},
requestError({ request, error }: HttpErrorRequest) {
// Handle errors that occur prior to the request being made.
if (error.message.test(/test/) {
// ...
}
// Modify or return a new request.
return new Request(newPath, request);
// Throw the existing error or throw a new one if necessary.
throw new Error('Unauthorized');
},
response(httpResponse: HttpResponse) {
// Modify the response or body and return as HttpResponse.
return {
...httpResponse,
body: 'hello',
};
// Throw if necessary.
throw new Error('Unauthorized');
},
responseError({ request, response, body, error }: HttpErrorResponse) {
// Handle errors that occur after the request has been made.
// Either return a new HttpResponse, throw a new error, or throw the existing error.
},
});
Any of these methods can be thrown from to trigger the interception flow. Interceptor handlers also expose an HttpInterceptController
to halt continuation of queued interceptions. This will cause the fetch operation to fail with a "HTTP Intercept Halt" error.
http.intercept({
request(request: Request, controller: HttpInterceptController) {
controller.halt();
// No more interceptors will be called,
// and the fetch will now reject with an HttpInterceptHaltError
},
response(httpResponse: HttpResponse, controller: HttpInterceptController) {
controller.halt();
// No more interceptors will be called, and even though the request was already made,
// the fetch will still reject with an HttpInterceptHaltError
},
});
A convenience method to remove all HTTP interceptors has also been added:
http.removeAllInterceptors();
via #36939,
Created additional http servers
New Platform plugins can now create additional HTTP servers on additional ports. Example:
class MyPlugin {
setup({ http }) {
this.additionalServer = http.createNewServer({ port: 3000 });
this.additionalServer.registerRouter(new Router());
}
async start() {
await this.additionalServer.start();
}
}
via #36804,
introduce pre-/post-auth request hooks for HttpServer
Kibana let define custom request interceptors for incoming requests:
http.registerAuth(handler, cookieOptions) => Promise<void>
To define custom authentication and/or authorization mechanism for incoming requests. A handler should return a state to associate with the incoming request. The state can be retrieved later via http.auth.get(..). Only one AuthenticationHandler can be registered.http.registerOnPreAuth(handler) => void
To define custom logic to perform for incoming requests. Runs the handler before Auth hook performs a check that user has access to requested resources, so it's the only place when you can forward a request to another URL right on the server. Can register any number of registerOnPostAuth, which are called in sequence (from the first registered to the last).http.registerOnPreAuth (handler) => void
To define custom logic to perform for incoming requests. Runs the handler after Auth hook did make sure a user has access to the requested resource. The auth state is available at stage via http.auth.get(..) Can register any number of registerOnPreAuth, which are called in sequence (from the first registered to the last).
via #36690,
Remove browser basePath service, move functionality into browser http service
The browser basePath
service is removed in favor of handling by the browser http
service. As the basePath
was used for controlling the route used to make fetch requests, it makes sense to colocate this functionality into the HTTP service.
via #36611,
[i18n] extract untracked translations and prettier logging
Running node scripts/i18n_check.js
now searches for labels in untracked files and throws an error if it finds any.
The i18n check tool now has an enhanced reporting experience with better error logging.
via #35171