Breaking changes in 7.10edit

This page discusses the breaking changes that you need to be aware of when migrating your application to Kibana 7.10.

Breaking changes for usersedit

Legacy plugins support removededit

The legacy plugin system and the legacy plugin API have been removed. Legacy plugin owners should migrate their plugins to the Kibana Platform plugin API.

via #77599

Support added for Kibana Platform pluginsedit

The bin/kibana-plugin CLI has been updated to work with the new Kibana Platform plugin format instead of the legacy plugin format.

via #74604

Vega visualizations without $schema property no longer supportededit

Previously, if you did not provide the $schema property, the default value was set and hardcoded in the Vega code. The visualization was then rendered with a warning message. This introduced difficulties when updating the version of the Vega library.

Now all Vega specs must contain the $schema param. In no $schema param exists, an error message is returned. Refer to the Vega docs for more information about this property.

via #73805

Breaking changes for plugin developersedit

Config moved from xpack.ingestManager to xpack.fleet

To rename the Ingest Manger plugin to Fleet:

  • The Kibana config for Ingest Manager moved from xpack.ingestManager.* to xpack.fleet.*.
  • The config options specific to agents moved to xpack.ingestManager.fleet.* and xpack.fleet.agents.*.

via #79406

Plugins server code no longer transpiled with Babel

Kibana plugins can no longer rely on their server code being automatically transpiled with Babel. The @kbn/plugin-helpers provide a build task that will transform a plugin’s server code to plain JS via Babel, but plugin authors can use a tool of their choosing to accomplish the same result.

via #79176 and #79379*

Ingest Manager APIs moved to Fleet

The following Ingest Manager API routes changed:

  • All API routes moved from /api/ingest_manager/* to /api/fleet/*
  • All previous Fleet routes moved from /api/ingest_manager/fleet/* to /api/fleet/*. This includes:

    • /api/ingest_manager/fleet/agents/api/fleet/agents
    • /api/ingest_manager/fleet/enrollment-api-keys/api/fleet/enrollment-api-keys
  • The Fleet setup API moved from /api/ingest_manager/fleet/setup to /api/fleet/agents/setup

via #79193

SearchSource is now exposed on the server

The high-level search API SearchSource is now available on the server:

function async myRouteHandler(context, request, response) {
  const searchSource = await data.search.searchSource.asScoped(request);
  searchSource.createEmpty(); // API after calling `asScoped` matches the client-side service
}

via #78383

Response status helpers added

This release introduces the following search helpers:

  • isCompleteResponse
  • isErrorResponse
  • isPartialResponse

via #78006

The index pattern factory and crud methods refactored

The refactoring includes the following changes:

  • Create new indexPattern instance (unsaved) - indexPatternService.make() => indexPatternService.create(indexPatternSpec, skipFetchFields)
  • Save new index pattern - indexPattern.create() => indexPatternService.createSavedObject(indexPattern)
  • Setting the default index pattern is done as part of indexPatternService.createSavedObject, but can also be called individually- uiSettings.set('defaultIndex', id) => indexPatternService.setDefault(indexPatternId, force)
  • Update index pattern - indexPattern.save() => indexPatternService.updateSavedObject(indexPattern)
  • Additional changes:

    • indexPatternService.get(); no longer returns a new IndexPattern instance
    • indexPattern.fieldsFetcher is replaced by indexPatternService.getFieldsForWildcard and indexPatternService.getFieldsForIndexPattern
    • indexPattern.originalBodyindexPattern.originalSavedObjectBody updates via indexPattern.resetOriginalSavedObjectBody
    • indexPattern.refreshFields => indexPatternService.refreshFields(indexPattern)
    • indexPatternService.createAndSave(indexPatternSpec) convenience method added
    • indexPatternService.getFieldsForWildcard can be called directly. Previously a temp index pattern had to be created.

via #77791

Error notifications now aligned

The data.search service now includes these explicit error types:

  • AbortError if the request was canceled by the application or by calling cancelPending.
  • SearchTimeoutError if the request has timed out on the client or on the server.
  • PainlessError if there’s an painless script error inside the response
  • If the error is unidentified, it throws the error as is.

The new showError function can be used with these errors to show customized toast messages. Applications may choose to handle errors differently. However, the SearchTimeoutError error notification is shown regardless.

data.search.search(...)
   .catchError((e: Error) => {
       data.search.showError(e);
   }

via #77788

className prop added to QueryStringInput component

A className prop was added to the main container of the QueryStringInput component.

via #76848

KibanaRequest now has a uuid property

KibanaRequest now has a uuid property, which is a UUID that uniquely identifies the request.

via #76822

Index pattern save moved to index pattern service

IndexPattern.save has been replaced with IndexPatternsService.save.

via #76706

FetchOptions replaced with ISearchOptions

The FetchOptions type was removed—use the ISearchOptions type instead. The ISearchOptions signal option was renamed to abortSignal.

via #76538

Legacy Elasticsearch client APIs removed

The __LEGACY APIs have been removed from the data plugin’s client-side search service. Specifically, data.search.__LEGACY.esClient is no longer exposed, and the legacy elasticsearch-browser package has been removed from the repo. If you rely on this client in your plugin, we recommend migrating to the new elasticsearch-js client.

via #75943

Plugin status API added

Kibana Platform plugins can now read the status of their dependencies, their plugin’s default status, and manually override that status as reported to the end user and on the /api/status endpoint.

class MyPlugin {
  setup(core) {
    // Override default behavior and only elevate severity when elasticsearch is not available
    core.status.set(
      core.status.core$.pipe(core => core.elasticsearch);
    );
  }
}

via #75819

New advanced setting searchTimeout added

The behavior of how search requests timeout changed:

  • The Kibana server uses the new Elasticsearch client. The client already uses all timeout configurations such as requestTimeout, shardTimeout, and maxRetries. Because the client can’t override those settings, in OSS, we removed the code governing the Elasticsearch timeout on the client. Instead, this change adds handling for a timeout error response. A nice side effect is being able to remove injectDefaultVars from the legacy core plugin.
  • With Basic+ licenses, users can control the maximum time for a search session (for example, a single re-load of a dashboard), per space. Aa new Advanced Setting can be set to a positive value, or to 0, allowing queries to run without a timeout, as long as a user stays on screen.

via #75728

IndexPattern class no longer uses getConfig or uiSettingsValues

The IndexPattern class now takes shortDotsEnable (boolean) and metaFields (string[]) as arguments. These were formerly provided by uiSettings

via #75717

The expressions plugin has removed its __LEGACY APIs

The expressions plugin has removed its __LEGACY APIs, which were designed for internal use in Canvas. In the unlikely event that you rely on the expressions.__LEGACY namespace, you will need to copy the relevant code into your plugin before updating.

Also removed is the createKibanaUtilsCore helper from the kibana_utils plugin, which was only used in the legacy Expressions APIs.

via #75517

The search service’s getParamsFromSearchRequest helper changed

The getParamsFromSearchRequest helper changed to prepare for exposing SearchSource on the server. If your plugin relies on this helper, update the dependencies passed to it as follows:

       import { getSearchParamsFromRequest } from '../../../src/plugins/data/public';

       const params = getSearchParamsFromRequest(request, {
-          injectedMetadata: core.injectedMetadata,
-          uiSettings: core.uiSettings,
+          esShardTimeout: core.injectedMetadata.getInjectedVar('esShardTimeout') as number,
+          getConfig: core.uiSettings.get.bind(core.uiSettings),
       });

via #75368

Dependencies removed from index pattern list and field list

The index pattern fields class has the following changes:

  • The class is no longer created using a constructor. This produced odd side effects when array methods were used. In particular, removing the IndexPattern argument revealed that the FieldList constructor was being called when filter and similar were called, producing an error. Now, it’s only created once by IndexPattern.
  • The IndexPattern object and onNotification are no longer provided to the creation function.

The index pattern field class has the following changes:

  • The IndexPattern object and onNotification are no longer provided to the constructor.
  • The format attribute no longer exists. Use IndexPattern.getFormatterForField instead.
  • A callback is no longer used when an unknown field type is encountered. Instead it throws FieldTypeUnknownError.
  • toSpec now takes an optional argument, { getFormatterForField }. This argument takes the field as an argument and returns a formatter.

via #75185

Agent and package configs renamed to agent and package policies

The following Fleet (previously Ingest Manager) API routes changed:

  • /api/ingest_manager/agent_configs/* renamed to /api/fleet/agent_policies/*
  • /api/ingest_manager/package_configs/* renamed to /api/fleet/package_policies/*

All Ingest Manager routes with payload fields that were previously in reference to agent configs or package configs have been renamed to agent policies and package policies. For example configIdpolicyId, package_configspackage_policies.

The following Ingest Manager app routes changed:

  • /app/ingestManager#/configs renamed to /app/ingestManager#/policies

The following Ingest Manager settings changed:

  • xpack.ingestManager.fleet.agentConfigRolloutRateLimitIntervalMs renamed to xpack.fleet.agents.agentPolicyRolloutRateLimitIntervalMs
  • xpack.fleet.agents.agentConfigRolloutRateLimitRequestPerInterval renamed to xpack.fleet.agents.agentPolicyRolloutRateLimitRequestPerInterval

via #74914

SearchSource dependencies moved to the server

The getSearchErrorType and the SearchError class have been removed from the static exports of the data plugin’s contract. If you rely on these, copy the code directly into your plugin. The SearchError interface is still exposed.

via #74607

data.search.aggs available on the server

The search.aggs service in the data plugin is now available on the server. The usage is the same as on the client, except that a scoped saved objects client must be provided on the server to retrieve the start contract:

const savedObjectsClient = savedObjects.getScopedClient(kibanaRequest);
// `aggs.asScopedToClient` will return the same contract as is available in the browser
const aggs = await data.search.aggs.asScopedToClient(savedObjectsClient);
const allAggTypes = aggs.types.getAll();

The calculateAutoTimeExpression method was removed from the setup contract, and now only exists on the data plugin’s start contract. The method was was not used in setup elsewhere in Kibana, so it was removed for simplicity.

In addition, the agg types registry changed and now accepts a provider function, which is used to inject dependencies. This might be needed in the agg type definition, specifically a getConfig function used to retrieve uiSettings:

const getMyAgg = ({ getConfig }) =>
  new MetricAggType({
    name: 'myAgg',
    expressionName: 'myAggFunction',
    getSerializedFormat: (agg) => ({ id: 'number' }),
    params: [
      {
        name: 'someParam',
        write: (agg, output, aggs) => ({
          const queryLanguage = getConfig('search:queryLanguage');
          ...etc
        })
      }
    ],
  });

// register the agg type provider
dataSetup.search.aggs.registerMetric('myAgg', getMyAgg);

via #74472

Routes can specify the idle socket timeout

Route definitions can now specify the idleSocket timeout in addition to the payload timeout.

Resolves #73557.

via #73730

New Elasticsearch client exposed

Kibana provides the new Elasticsearch client as a part of the Elasticsearch service on the server-side. The legacy client is deprecated on and subject for removal in 7.x. Reference the migration guide to refactor your code

via #73651

Query input string manager added

This PR allows gracefully extracting of the query string state, to be consumed by other services. You can now use the data.query.state$ observable and receive all state updates in one place.

data.query.state$.subscribe((queryState: QueryState) => {...})

This PR also adds the data.query.queryString service, allowing to you set the query string programmatically.

data.query.queryString.setQuery({query: 'abc', language: 'kuery'});

via #72093

Role-based access control added to the Alerting & Action plugins

This PR allows you to assign privileges to the Alerting framework when defining your feature in Kibana. When registering your feature, you can add a list of AlertTypes under your read and all keys of the privileges object, as such:

features.registerFeature({
      id: 'alertsExample',
      name: 'alertsExample',
      app: [],
      privileges: {
        all: {
          alerting: {
            all: ['example.always-firing', 'example.people-in-space'],
          },
        },
        read: {
          alerting: {
            read: ['example.always-firing', 'example.people-in-space'],
          },
        },
      },
    });

This specifies:

  • If users AbortError granted the all privilege to the alertsExample feature, then they are also granted all privileges to the example.always-firing and example.people-in-space AlertTypes under the alertsExample consumer.
  • If users are granted the read privilege to the alertsExample feature, then they are also granted read privileges to the example.always-firing and example.people-in-space AlertTypes under the alertsExample consumer.

For example, an all user will be able to create an example.always-firing alert with the alertsExample as consumer. This will also automatically grant the user the right to create an example.always-firing alert from within Alerts management, where alerts is the consumer. This does not grant the user the ability to create an example.always-firing alert under any other consumer. For that, the specific consumer will have to grant the user explicit rights through their privilege system.

For example, if Uptime wanted to allow users to create an example.people-in-space alert inside of the Uptime solution, then they will have to do the following:

features.registerFeature({
      id: 'uptime',
      name: 'Uptime',
      app: [],
      privileges: {
        all: {
          alerting: {
            all: ['xpack.uptime.alerts.actionGroups.tls', 'example.people-in-space'],
          },
        },
        read: {
          alerting: {
            read: ['xpack.uptime.alerts.actionGroups.tls', 'example.people-in-space'],
          },
        },
      },
    });

This, assuming it’s added by Uptime, would grant uptime users the privilege to create both their own xpack.uptime.alerts.actionGroups.tls alert and the example.people-in-space alert with uptime as the consumer.

This does not allow any Uptime user with all privileges to create an example.people-in-space alert. To create an example.people-in-space alert, the Uptime user needs both all in Uptime and in AlertsExample, as we always check whether the user is privileged to execute an operation (create/enable/delete etc.) in both the alert’s consumer and its producer.

The one exception to this is when the producer is alerts, which represents a built-in AlertType, in which case we only check for consumer privileges as all users are privileged to create built-in types by definition.

via #67157

The EventLog Setup contract now exposes a registerSavedObjectProvider

The EventLog Setup contract now exposes a registerSavedObjectProvider method which can be used to register a Saved Object provider.

export interface IEventLogService {
   isEnabled(): boolean;
   isLoggingEntries(): boolean;
   isIndexingEntries(): boolean;
   registerProviderActions(provider: string, actions: string[]): void;
   isProviderActionRegistered(provider: string, action: string): boolean;
   getProviderActions(): Map<string, Set<string>>;
   registerSavedObjectProvider(type: string, provider: SavedObjectProvider): void;
   getLogger(properties: IEvent): IEventLogger;
 }

This API specifies the Saved Object type and a "provider" callback that is called whenever a new request asks for that type of Saved Object.

This example shows a provider for the alert SavedObject type, which creates a new AlertsClient for the request and returns a getter that attempts to get the SavedObject by its id.

via #73257

eventLogService.registerSavedObjectProvider('alert', (request: KibanaRequest) => {
    const client = getAlertsClientWithRequest(request);
    return (type: string, id: string) => client.get({ id });
});

The EventLog maintains a registry of each provider, and creates a getter on demand when the user actually requests an object of a certain type. An AlertsClient is only instantiated if the user requests to the events reference an Alert. Once a getter is created for a specific request, it is cached for the remainder of the lifecycle of that request. This means a single provider is used for multiple gets made by the request.

New Elasticsearch client in SO service

The SO service was refactored to use elasticsearch-js under the hood. This change might affect plugins reading the response status field from the SO error bubbled to the Solutions code because the Elasticsearch error no longer provides the status field (statusCode is still provided).

Several plugins were adjusted to check SO errors with SavedObjectsErrorHelpers. Plugins must use this because we are going to stop wrapping errors in the Boom object.

via #72289

Alerts Management now controlled via Feature Controls and privileges

If you want your plugin to grant a user access to Alerts Management, you must specify it under Management in your feature configuration:

management: {
    insightsAndAlerting: ['triggersActions'],
},

You can specify it in three places:

  • Directly on the feature. When security is disabled, this grants access to every role granted access to the Feature via Feature Controls. When security is enabled, this specifies that the feature has access to this management section and is required before you can grant this to a specific role.
  • Under the all privilege. When security is enabled, this grants access to every role granted the all privilege to the Feature via Feature Controls.
  • Under the read privilege. When security is enabled, this grants access to every role granted the read privilege to the Feature via Feature Controls.

You’re likely to have to specify this in 3 places in your plugin to cover all 3 scenarios. Although this is more verbose than before, it aligns with the rest of Kibana. It also means that the Triggers and Actions plugin no longer needs to know about each plugin that wants to gain access (which means Kibana can more easily support future alerting usage).

via #72029

API changed for creating a Jira connector

casesConfiguration was renamed to incidentConfiguration. Added optional attributeisCaseOwned.

via #73778

API changed for creating an IBM Resilient connector

casesConfiguration was renamed to incidentConfiguration. Added optional attributeisCaseOwned.

via #74357

Settings per case per connector
  • To create a case (POST <kibana host>:<port>/api/cases), you must provide a connector. Requests without a connector get a 400 Bad Request.
  • To update the connector of a case (PATCH <kibana host>:<port>/api/cases), you must provide the connector. The connector_id attribute has been removed in favor of the connector attribute.
  • To set the default connector (POST <kibana host>:<port>/api/cases/configure), you must provide a connector. The connector_id and connector_name attributes have been removed in favor of the connector attribute.
  • To update the connector’s case closure settings (PATCH <kibana host>:<port>/api/cases/configure), you must provide a connector. The connector_id and connector_name attributes have been removed in favor of the connector attribute.

via #77327