Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into remove-geo-thresh…
Browse files Browse the repository at this point in the history
…old-alert
  • Loading branch information
Aaron Caldwell committed Jan 29, 2021
2 parents 9f66486 + a08895d commit c09755e
Show file tree
Hide file tree
Showing 216 changed files with 8,985 additions and 1,892 deletions.
4 changes: 2 additions & 2 deletions docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ It also provides a stateful version of it on the start contract.
Content is fetched from the remote (https://feeds.elastic.co and https://feeds-staging.elastic.co in dev mode) once a day, with periodic checks if the content needs to be refreshed. All newsfeed content is hosted remotely.
|{kib-repo}blob/{branch}/src/plugins/presentation_util/README.md[presentationUtil]
|Utilities and components used by the presentation-related plugins
|{kib-repo}blob/{branch}/src/plugins/presentation_util/README.mdx[presentationUtil]
|The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas).
|{kib-repo}blob/{branch}/src/plugins/region_map/README.md[regionMap]
Expand Down
9 changes: 4 additions & 5 deletions docs/setup/upgrade/upgrade-migrations.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,16 @@ Saved objects are stored in two indices:
* `.kibana_{kibana_version}_001`, or if the `kibana.index` configuration setting is set `.{kibana.index}_{kibana_version}_001`. E.g. for Kibana v7.12.0 `.kibana_7.12.0_001`.
* `.kibana_task_manager_{kibana_version}_001`, or if the `xpack.tasks.index` configuration setting is set `.{xpack.tasks.index}_{kibana_version}_001` E.g. for Kibana v7.12.0 `.kibana_task_manager_7.12.0_001`.

The index aliases `.kibana` and `.kibana_task_manager` will always point to the most up-to-date version indices.
The index aliases `.kibana` and `.kibana_task_manager` will always point to
the most up-to-date saved object indices.

The first time a newer {kib} starts, it will first perform an upgrade migration before starting plugins or serving HTTP traffic. To prevent losing acknowledged writes old nodes should be shutdown before starting the upgrade. To reduce the likelihood of old nodes losing acknowledged writes, {kib} 7.12.0 and later will add a write block to the outdated index. Table 1 lists the saved objects indices used by previous versions of {kib}.

.Saved object indices and aliases per {kib} version
[options="header"]
[cols="a,a,a"]
|=======================
|Upgrading from version | Outdated index (alias) | Upgraded index (alias)
| 6.0.0 through 6.4.x | `.kibana` 1.3+^.^| `.kibana_7.12.0_001`
(`.kibana` alias)
|Upgrading from version | Outdated index (alias)
| 6.0.0 through 6.4.x | `.kibana`

`.kibana_task_manager_7.12.0_001` (`.kibana_task_manager` alias)
| 6.5.0 through 7.3.x | `.kibana_N` (`.kibana` alias)
Expand Down
43 changes: 42 additions & 1 deletion docs/user/alerting/alert-types.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This section covers stack alerts. For domain-specific alert types, refer to the
Users will need `all` access to the *Stack Alerts* feature to be able to create and edit any of the alerts listed below.
See <<kibana-feature-privileges, feature privileges>> for more information on configuring roles that provide access to this feature.

Currently {kib} provides one stack alert: the <<alert-type-index-threshold>> type.
Currently {kib} provides two stack alerts: <<alert-type-index-threshold>> and <<alert-type-es-query>>.

[float]
[[alert-type-index-threshold]]
Expand Down Expand Up @@ -112,6 +112,47 @@ You can interactively change the time window and observe the effect it has on th
[role="screenshot"]
image::images/alert-types-index-threshold-example-comparison.png[Comparing two time windows]

[float]
[[alert-type-es-query]]
=== ES query

The ES query alert type is designed to run a user-configured {es} query over indices, compare the number of matches to a configured threshold, and schedule
actions to run when the threshold condition is met.

[float]
==== Creating the alert

An ES query alert can be created from the *Create* button in the <<alert-management, alert management UI>>. Fill in the <<defining-alerts-general-details, general alert details>>, then select *ES query*.

[role="screenshot"]
image::images/alert-types-es-query-select.png[Choosing an ES query alert type]

[float]
==== Defining the conditions

The ES query alert has 4 clauses that define the condition to detect.

[role="screenshot"]
image::images/alert-types-es-query-conditions.png[Four clauses define the condition to detect]

Index:: This clause requires an *index or index pattern* and a *time field* that will be used for the *time window*.
ES query:: This clause specifies the ES DSL query to execute. The number of documents that match this query will be evaulated against the threshold
condition. Aggregations are not supported at this time.
Threshold:: This clause defines a threshold value and a comparison operator (`is above`, `is above or equals`, `is below`, `is below or equals`, or `is between`). The number of documents that match the specified query is compared to this threshold.
Time window:: This clause determines how far back to search for documents, using the *time field* set in the *index* clause. Generally this value should be set to a value higher than the *check every* value in the <<defining-alerts-general-details, general alert details>>, to avoid gaps in detection.

[float]
==== Testing your query

Use the *Test query* feature to verify that your query DSL is valid.

When your query is valid:: Valid queries will be executed against the configured *index* using the configured *time window*. The number of documents that
match the query will be displayed.

[role="screenshot"]
image::images/alert-types-es-query-valid.png[Test ES query returns number of matches when valid]

When your query is invalid:: An error message is shown if the query is invalid.

[role="screenshot"]
image::images/alert-types-es-query-invalid.png[Test ES query shows error when invalid]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@
"@storybook/addon-essentials": "^6.0.26",
"@storybook/addon-knobs": "^6.0.26",
"@storybook/addon-storyshots": "^6.0.26",
"@storybook/addon-docs": "^6.0.26",
"@storybook/components": "^6.0.26",
"@storybook/core": "^6.0.26",
"@storybook/core-events": "^6.0.26",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function checkMatchingSchemasTask({ roots }: TaskContext, throwOnDiff: bo
root.esMappingDiffs = Object.keys(differences);
if (root.esMappingDiffs.length && throwOnDiff) {
throw Error(
`The following changes must be persisted in ${fullPath} file. Use '--fix' to update.\n${JSON.stringify(
`The following changes must be persisted in ${fullPath} file. Run 'node scripts/telemetry_check --fix' to update.\n${JSON.stringify(
differences,
null,
2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
* Public License, v 1.
*/

import pkg from '../../../../package.json';
import { getVersionInfo } from './version_info';
import { kibanaPackageJSON as pkg } from '@kbn/dev-utils';

jest.mock('./get_build_number');
import { getVersionInfo } from '../version_info';

jest.mock('../get_build_number');

describe('isRelease = true', () => {
it('returns unchanged package.version, build sha, and build number', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ function generator({
ubiImageFlavor,
architecture,
}: TemplateContext) {
const fileArchitecture = architecture === 'aarch64' ? 'arm64' : 'amd64';
return dedent(`
#!/usr/bin/env bash
#
Expand Down Expand Up @@ -56,9 +55,9 @@ function generator({
retry_docker_pull ${baseOSImage}
echo "Building: kibana${imageFlavor}${ubiImageFlavor}-docker"; \\
docker build -t ${imageTag}${imageFlavor}${ubiImageFlavor}:${version}-${fileArchitecture} -f Dockerfile . || exit 1;
docker build -t ${imageTag}${imageFlavor}${ubiImageFlavor}:${version} -f Dockerfile . || exit 1;
docker save ${imageTag}${imageFlavor}${ubiImageFlavor}:${version}-${fileArchitecture} | gzip -c > ${dockerTargetFilename}
docker save ${imageTag}${imageFlavor}${ubiImageFlavor}:${version} | gzip -c > ${dockerTargetFilename}
exit 0
`);
Expand Down
1 change: 1 addition & 0 deletions src/dev/storybook/aliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export const storybookAliases = {
security_solution: 'x-pack/plugins/security_solution/.storybook',
ui_actions_enhanced: 'x-pack/plugins/ui_actions_enhanced/.storybook',
observability: 'x-pack/plugins/observability/.storybook',
presentation: 'src/plugins/presentation_util/storybook',
};
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ function wrapQueryStringInputInContext(testProps: any, storage?: any) {
);
}

describe('QueryStringInput', () => {
// FAILING: https://github.com/elastic/kibana/issues/85715
// FAILING: https://github.com/elastic/kibana/issues/89603
// FAILING: https://github.com/elastic/kibana/issues/89641
describe.skip('QueryStringInput', () => {
beforeEach(() => {
jest.clearAllMocks();
});
Expand All @@ -102,7 +105,7 @@ describe('QueryStringInput', () => {
await waitFor(() => getByText('KQL'));
});

it.skip('Should pass the query language to the language switcher', () => {
it('Should pass the query language to the language switcher', () => {
const component = mount(
wrapQueryStringInputInContext({
query: luceneQuery,
Expand Down
3 changes: 0 additions & 3 deletions src/plugins/presentation_util/README.md

This file was deleted.

211 changes: 211 additions & 0 deletions src/plugins/presentation_util/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
---
id: presentationUtilPlugin
slug: /kibana-dev-docs/presentationPlugin
title: Presentation Utility Plugin
summary: Introduction to the Presentation Utility Plugin.
date: 2020-01-12
tags: ['kibana', 'presentation', 'services']
related: []
---

## Introduction

The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas).

## Plugin Services Toolkit

While Kibana provides a `useKibana` hook for use in a plugin, the number of services it provides is very large. This presents a set of difficulties:

- a direct dependency upon the Kibana environment;
- a requirement to mock the full Kibana environment when testing or using Storybook;
- a lack of knowledge as to what services are being consumed at any given time.

To mitigate these difficulties, the Presentation Team creates services within the plugin that then consume Kibana-provided (or other) services. This is a toolkit for creating simple services within a plugin.

### Overview

- A `PluginServiceFactory` is a function that will return a set of functions-- which comprise a `Service`-- given a set of parameters.
- A `PluginServiceProvider` is an object that use a factory to start, stop or provide a `Service`.
- A `PluginServiceRegistry` is a collection of providers for a given environment, (e.g. Kibana, Jest, Storybook, stub, etc).
- A `PluginServices` object uses a registry to provide services throughout the plugin.

### Defining Services

To start, a plugin should define a set of services it wants to provide to itself or other plugins.

<DocAccordion buttonContent="Service Definition Example" initialIsOpen>
```ts
export interface PresentationDashboardsService {
findDashboards: (
query: string,
fields: string[]
) => Promise<Array<SimpleSavedObject<DashboardSavedObject>>>;
findDashboardsByTitle: (title: string) => Promise<Array<SimpleSavedObject<DashboardSavedObject>>>;
}

export interface PresentationFooService {
getFoo: () => string;
setFoo: (bar: string) => void;
}

export interface PresentationUtilServices {
dashboards: PresentationDashboardsService;
foo: PresentationFooService;
}
```
</DocAccordion>

This definition will be used in the toolkit to ensure services are complete and as expected.

### Plugin Services

The `PluginServices` class hosts a registry of service providers from which a plugin can access its services. It uses the service definition as a generic.

```ts
export const pluginServices = new PluginServices<PresentationUtilServices>();
```

This can be placed in the `index.ts` file of a `services` directory within your plugin.

Once created, it simply requires a `PluginServiceRegistry` to be started and set.

### Service Provider Registry

Each environment in which components are used requires a `PluginServiceRegistry` to specify how the providers are started. For example, simple stubs of services require no parameters to start, (so the `StartParameters` generic remains unspecified)

<DocAccordion buttonContent="Stubbed Service Registry Example" initialIsOpen>
```ts
export const providers: PluginServiceProviders<PresentationUtilServices> = {
dashboards: new PluginServiceProvider(dashboardsServiceFactory),
foo: new PluginServiceProvider(fooServiceFactory),
};

export const serviceRegistry = new PluginServiceRegistry<PresentationUtilServices>(providers);
```
</DocAccordion>

By contrast, a registry that uses Kibana can provide `KibanaPluginServiceParams` to determine how to start its providers, so the `StartParameters` generic is given:

<DocAccordion buttonContent="Kibana Service Registry Example" initialIsOpen>
```ts
export const providers: PluginServiceProviders<
PresentationUtilServices,
KibanaPluginServiceParams<PresentationUtilPluginStart>
> = {
dashboards: new PluginServiceProvider(dashboardsServiceFactory),
foo: new PluginServiceProvider(fooServiceFactory),
};

export const serviceRegistry = new PluginServiceRegistry<
PresentationUtilServices,
KibanaPluginServiceParams<PresentationUtilPluginStart>
>(providers);
```
</DocAccordion>

### Service Provider

A `PluginServiceProvider` is a container for a Service Factory that is responsible for starting, stopping and providing a service implementation. A Service Provider doesn't change, rather the factory and the relevant `StartParameters` change.

### Service Factories

A Service Factory is nothing more than a function that uses `StartParameters` to return a set of functions that conforms to a portion of the `Services` specification. For each service, a factory is provided for each environment.

Given a service definition:

```ts
export interface PresentationFooService {
getFoo: () => string;
setFoo: (bar: string) => void;
}
```

a factory for a stubbed version might look like this:

```ts
type FooServiceFactory = PluginServiceFactory<PresentationFooService>;

export const fooServiceFactory: FooServiceFactory = () => ({
getFoo: () => 'bar',
setFoo: (bar) => { console.log(`${bar} set!`)},
});
```

and a factory for a Kibana version might look like this:

```ts
export type FooServiceFactory = KibanaPluginServiceFactory<
PresentationFooService,
PresentationUtilPluginStart
>;

export const fooServiceFactory: FooServiceFactory = ({
coreStart,
startPlugins,
}) => {
// ...do something with Kibana services...

return {
getFoo: //...
setFoo: //...
}
}
```

### Using Services

Once your services and providers are defined, and you have at least one set of factories, you can use `PluginServices` to provide the services to your React components:

<DocAccordion buttonContent="Services starting in a plugin" initialIsOpen>
```ts
// plugin.ts
import { pluginServices } from './services';
import { registry } from './services/kibana';

public async start(
coreStart: CoreStart,
startPlugins: StartDeps
): Promise<PresentationUtilPluginStart> {
pluginServices.setRegistry(registry.start({ coreStart, startPlugins }));
return {};
}
```
</DocAccordion>

and wrap your root React component with the `PluginServices` context:

<DocAccordion buttonContent="Providing services in a React context" initialIsOpen>
```ts
import { pluginServices } from './services';

const ContextProvider = pluginServices.getContextProvider(),

return(
<I18nContext>
<WhateverElse>
<ContextProvider>{application}</ContextProvider>
</WhateverElse>
</I18nContext>
)
```
</DocAccordion>

and then, consume your services using provided hooks in a component:

<DocAccordion buttonContent="Consuming services in a component" initialIsOpen>
```ts
// component.ts

import { pluginServices } from '../services';

export function MyComponent() {
// Retrieve all context hooks from `PluginServices`, destructuring for the one we're using
const { foo } = pluginServices.getHooks();

// Use the `useContext` hook to access the API.
const { getFoo } = foo.useService();

// ...
}
```
</DocAccordion>
Loading

0 comments on commit c09755e

Please sign in to comment.