Skip to content

Commit

Permalink
Merge branch 'task-manager/docs-monitoring' of github.com:gmmorris/ki…
Browse files Browse the repository at this point in the history
…bana into task-manager/docs-monitoring

* 'task-manager/docs-monitoring' of github.com:gmmorris/kibana:
  [ILM] Allow multiple searchable snapshot actions (#92789)
  Improve consistency for display of management items (#92694)
  skip flaky suite (#93152)
  skip flaky suite (#93152)
  [ILM] Refactor edit_policy client integration tests into separate feature files (#92826)
  Add developer documentation about the building blocks we offer plugin developers (#92743)
  [Security Solution] Case ui enhancement (#91863)
  [Security Solution] [Detections] Updates warning message when no indices match provided index patterns (#93094)
  Collect agent telemetry even when fleet server is disabled. (#93198)
  [Lens] Fix runtime validation error message (#93195)
  [Lens] Remove warning about ordinal x-domain (#93049)
  [Security Solution] Fixes the Customize Event Renderers modal by removing the EuiOverlayMask (#93150)
  Cleanup Security plugin imports (#93056)
  [Security Solution] - Bug fixes (#92294)
  Updated doc links (#92968)
  [ML] Transforms: Fixes chart histograms for runtime fields. (#93028)
  [chore] Enable core's eslint rule: `@ts-expect-error` (#93086)
  • Loading branch information
gmmorris committed Mar 2, 2021
2 parents e264533 + 96fd086 commit 0a85947
Show file tree
Hide file tree
Showing 615 changed files with 5,656 additions and 3,874 deletions.
10 changes: 9 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,7 @@ module.exports = {

{
files: [
// platform-team owned code
// core-team owned code
'src/core/**',
'x-pack/plugins/features/**',
'x-pack/plugins/licensing/**',
Expand All @@ -1325,6 +1325,14 @@ module.exports = {
'packages/kbn-config-schema',
'src/plugins/status_page/**',
'src/plugins/saved_objects_management/**',
'packages/kbn-analytics/**',
'packages/kbn-telemetry-tools/**',
'src/plugins/kibana_usage_collection/**',
'src/plugins/usage_collection/**',
'src/plugins/telemetry/**',
'src/plugins/telemetry_collection_manager/**',
'src/plugins/telemetry_management_section/**',
'x-pack/plugins/telemetry_collection_xpack/**',
],
rules: {
'@typescript-eslint/prefer-ts-expect-error': 'error',
Expand Down
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ x-pack/plugins/telemetry_collection_xpack/schema/ @elastic/kibana-core @elastic/
# Security
/src/core/server/csp/ @elastic/kibana-security @elastic/kibana-core
/src/plugins/security_oss/ @elastic/kibana-security
/src/plugins/spaces_oss/ @elastic/kibana-security
/test/security_functional/ @elastic/kibana-security
/x-pack/plugins/spaces/ @elastic/kibana-security
/x-pack/plugins/encrypted_saved_objects/ @elastic/kibana-security
Expand Down
138 changes: 138 additions & 0 deletions dev_docs/building_blocks.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
id: kibBuildingBlocks
slug: /kibana-dev-docs/building-blocks
title: Building blocks
summary: Consider these building blocks when developing your plugin.
date: 2021-02-24
tags: ['kibana','onboarding', 'dev', 'architecture']
---

When building a plugin in Kibana, there are a handful of architectural "building blocks" you can use. Some of these building blocks are "higher-level",
and some are "lower-level". High-level building blocks come
with many built-in capabilities, require less maintenance, and evolve new feature sets over time with little to no
impact on consumers. When developers use high-level building blocks, new features are exposed consistently, across all of Kibana, at the same time.
On the downside, they are not as flexible as our low-level building blocks.

Low-level building blocks
provide greater flexibility, but require more code to stitch them together into a meaningful UX. This results in higher maintenance cost for consumers and greater UI/UX variability
across Kibana.

For example, if an application is using <DocLink id="kibBuildingBlocks" section="index-patterns" text="Index Patterns"/> and
<DocLink id="kibBuildingBlocks" section="search-source" text="Search Source"/>,
their application would automatically support runtime fields. If the app is instead using the
lower-level <DocLink id="kibBuildingBlocks" section="search-strategy" text="Search Strategy"/>, additional work would be required.

Armed with this knowledge, you can choose what works best for your use case!

# Application building blocks

## UI components

The following high-level building blocks can be rendered directly into your application UI.

### Query Bar

The <DocLink id="kibDataPlugin" text="Data plugin"/> provides a high-level Query Bar component that comes with support for Lucene, KQL, Saved Queries,
and <DocLink id="kibBuildingBlocks" section="index-patterns" text="Index Patterns"/>.

If you would like to expose the ability to search and filter on Elasticsearch data, the Query Bar provided by the
<DocLink id="kibDataPlugin" text="Data plugin"/>
is your go-to building block.

**Github labels**: `Team:AppServices`, `Feature:QueryBar`

### Dashboard Embeddable

Add a Dashboard Embeddable directly inside your application to provide users with a set of visualizations and graphs that work seamlessly
with the <DocLink id="kibBuildingBlocks" section="query-bar" text="Query Bar"/>. Every feature that is added to a registered
<DocLink id="kibBuildingBlocks" section="embeddables" text="Embeddable"/>
(Lens, Maps, Saved Searches and more) will be available automatically, as well as any
<DocLink id="kibBuildingBlocks" section="ui-actions--triggers" text="UI Actions"/> that are
added to the Embeddable context menu panel (for example, drilldowns, custom panel time ranges, and "share to" features).

The Dashboard Embeddable is one of the highest-level UI components you can add to your application.

**Github labels**: `Team:Presentation`, `Feature:Dashboard`

### Lens Embeddable

Check out the Lens Embeddable if you wish to show users visualizations based on Elasticsearch data without worrying about query building and chart rendering. It's built on top of the
<DocLink id="kibBuildingBlocks" section="expressions" text="Expression language"/>, and integrates with
<DocLink id="kibBuildingBlocks" section="index-patterns" text="Index Patterns"/>
and <DocLink id="kibBuildingBlocks" section="ui-actions--triggers" text="UI Actions"/>. Using the same configuration, it's also possible to link to
a prefilled Lens editor, allowing the user to drill deeper and explore their data.

**Github labels**: `Team:KibanaApp`, `Feature:Lens`

### Map Embeddable

Check out the Map Embeddable if you wish to embed a map in your application.

**Github labels**: `Team:Geo`

## Searching

### Index Patterns

<DocLink id="kibDataPlugin" section="index-patterns-api" text="Index Patterns"/> are a high-level, space-aware abstraction layer that sits
above Data Streams and Elasticsearch indices. Index Patterns provide users the
ability to define and customize the data they wish to search and filter on, on a per-space basis. For example, users can specify a set of indices,
and they can customize the field list with runtime fields, formatting options and custom labels.

Index Patterns are used in many other high-level building blocks so we highly recommend you consider this building block for your search needs.

**Github labels**: `Team:AppServices`, `Feature:Index Patterns`

### Search Source

<DocLink id="kibDataPlugin" section="searchsource" text="Search Source"/> is a high-level search service offered by the
<DocLink id="kibDataPlugin" section="searchsource" text="Data plugin"/>. It requires an
<DocLink id="kibBuildingBlocks" section="index-patterns" text="Index Pattern"/>, and abstracts away the raw ES DSL and search endpoint. Internally
it uses the ES <DocLink id="kibBuildingBlocks" section="search-strategies" text="Search Strategy"/>. Use Search Source if you need to query data
from Elasticsearch, and you aren't already using one of the high-level UI Components that handles this internally.

**Github labels**: `Team:AppServices`, `Feature:Search`

### Search Strategies

Search Strategies are a low-level building block that abstracts away search details, like what REST endpoint is being called. The ES Search Strategy
is a very lightweight abstraction layer that sits just above querying ES with the elasticsearch-js client. Other search stragies are offered for other
languages, like EQL and SQL. These are very low-level building blocks so expect a lot of glue work to make these work with the higher-level abstractions.

**Github labels**: `Team:AppServices`, `Feature:Search`

### Expressions

Expressions are a low-level building block that can be used if you have advanced search needs that requiring piping results into additional functionality, like
joining and manipulating data. Lens and Canvas are built on top of Expressions. Most developers should be able to use
<DocLink id="kibBuildingBlocks" section="lens-embeddable" text="Lens"/> or
<DocLink id="kibBuildingBlocks" section="search-source" text="Search Source"/>, rather than need to access the Expression language directly.

**Github labels**: `Team:AppServices`, `Feature:ExpressionLanguage`

## Saved Objects

<DocLink id="kibDevDocsSavedObjectsIntro" text="Saved Objects" /> should be used if you need to persist application-level information. If you were building a TODO
application, each TODO item would be a `Saved Object`. Saved objects come pre-wired with support for bulk export/import, security features like space sharing and
space isolation, and tags.

**Github labels**: `Team:Core`, `Feature:Saved Objects`

# Integration building blocks

Use the following building blocks to create an inter-connected, cross-application, holistic Kibana experience. These building blocks allow you to expose functionality
that promotes your own application into other applications, as well as help developers of other applications integrate into your app.

## UI Actions & Triggers

Integrate custom actions into other applications by registering UI Actions attached to existing triggers. For example, the Maps
application could register a UI Action called "View in Maps" to appear any time the user clicked a geo field to filter on.

**Github labels**: `Team:AppServices`, `Feature:UIActions`

## Embeddables

Embeddables help you integrate your application with the Dashboard application. Register your custom UI Widget as an Embeddable and users will
be able to add it as a panel on a Dashboard. With a little extra work, it can also be exposed in Canvas workpads.

**Github labels**: `Team:AppServices`, `Feature:Embeddables`
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ interface ParsedError {
cause: string[];
}

const getCause = (obj: any = {}, causes: string[] = []): string[] => {
export const getEsCause = (obj: any = {}, causes: string[] = []): string[] => {
const updated = [...causes];

if (obj.caused_by) {
updated.push(obj.caused_by.reason);

// Recursively find all the "caused by" reasons
return getCause(obj.caused_by, updated);
return getEsCause(obj.caused_by, updated);
}

return updated.filter(Boolean);
Expand All @@ -27,7 +27,7 @@ const getCause = (obj: any = {}, causes: string[] = []): string[] => {
export const parseEsError = (err: string): ParsedError => {
try {
const { error } = JSON.parse(err);
const cause = getCause(error);
const cause = getEsCause(error);
return {
message: error.reason,
cause,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { ApiError } from '@elastic/elasticsearch';
import { ResponseError } from '@elastic/elasticsearch/lib/errors';
import { IKibanaResponse, KibanaResponseFactory } from 'kibana/server';
import { getEsCause } from './es_error_parser';

interface EsErrorHandlerParams {
error: ApiError;
Expand All @@ -34,7 +35,15 @@ export const handleEsError = ({
const { statusCode, body } = error as ResponseError;
return response.customError({
statusCode,
body: { message: body.error?.reason },
body: {
message: body.error?.reason,
attributes: {
// The full original ES error object
error: body.error,
// We assume that this is an ES error object with a nested caused by chain if we can see the "caused_by" field at the top-level
causes: body.error?.caused_by ? getEsCause(body.error) : undefined,
},
},
});
}
// Case: default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { getSavedObjectsCounts } from './get_saved_object_counts';
export function mockGetSavedObjectsCounts(params: any) {
const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser;
esClient.search.mockResolvedValue(
// @ts-ignore we only care about the response body
// @ts-expect-error we only care about the response body
{
body: { ...params },
}
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/security_oss/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"@typescript-eslint/consistent-type-imports": 1
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* Side Public License, v 1.
*/

import { coreMock } from '../../../../core/public/mocks';
import { coreMock } from 'src/core/public/mocks';

import { AppStateService } from './app_state_service';

describe('AppStateService', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
* Side Public License, v 1.
*/

import { CoreStart } from 'kibana/public';
import { AppState } from '../../common';
import type { CoreStart } from 'src/core/public';

import type { AppState } from '../../common';

const DEFAULT_APP_STATE = Object.freeze({
insecureClusterAlert: { displayAlert: false },
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/security_oss/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
* Side Public License, v 1.
*/

import { PluginInitializerContext } from 'kibana/public';
import type { PluginInitializerContext } from 'src/core/public';

import { SecurityOssPlugin } from './plugin';

export { SecurityOssPluginSetup, SecurityOssPluginStart } from './plugin';

export const plugin = (initializerContext: PluginInitializerContext) =>
new SecurityOssPlugin(initializerContext);
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import {
EuiSpacer,
EuiText,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { I18nProvider, FormattedMessage } from '@kbn/i18n/react';
import { MountPoint } from 'kibana/public';
import React, { useState } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';

import { i18n } from '@kbn/i18n';
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
import type { MountPoint } from 'src/core/public';

export const defaultAlertTitle = i18n.translate('security.checkup.insecureClusterTitle', {
defaultMessage: 'Your data is not secure',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import {
import type {
InsecureClusterServiceSetup,
InsecureClusterServiceStart,
} from './insecure_cluster_service';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
*/

import { nextTick } from '@kbn/test/jest';
import { coreMock } from '../../../../core/public/mocks';

import { coreMock } from 'src/core/public/mocks';

import { mockAppStateService } from '../app_state/app_state_service.mock';
import type { ConfigType } from '../config';
import { InsecureClusterService } from './insecure_cluster_service';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
* Side Public License, v 1.
*/

import { CoreSetup, CoreStart, MountPoint, Toast } from 'kibana/public';

import { BehaviorSubject, combineLatest, from } from 'rxjs';
import { distinctUntilChanged, map } from 'rxjs/operators';

import type { CoreSetup, CoreStart, MountPoint, Toast } from 'src/core/public';

import type { ConfigType } from '../config';
import type { AppStateServiceStart } from '../app_state';
import { defaultAlertText, defaultAlertTitle } from './components';
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/security_oss/public/plugin.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
*/

import type { DeeplyMockedKeys } from '@kbn/utility-types/jest';
import { InsecureClusterServiceStart } from './insecure_cluster_service';

import type { InsecureClusterServiceStart } from './insecure_cluster_service';
import { mockInsecureClusterService } from './insecure_cluster_service/insecure_cluster_service.mock';
import { SecurityOssPluginSetup, SecurityOssPluginStart } from './plugin';
import type { SecurityOssPluginSetup, SecurityOssPluginStart } from './plugin';

export const mockSecurityOssPlugin = {
createSetup: () => {
Expand Down
7 changes: 4 additions & 3 deletions src/plugins/security_oss/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import type {
Plugin,
PluginInitializerContext,
} from 'src/core/public';

import { AppStateService } from './app_state';
import type { ConfigType } from './config';
import {
InsecureClusterService,
import type {
InsecureClusterServiceSetup,
InsecureClusterServiceStart,
} from './insecure_cluster_service';
import { AppStateService } from './app_state';
import { InsecureClusterService } from './insecure_cluster_service';

export interface SecurityOssPluginSetup {
insecureCluster: InsecureClusterServiceSetup;
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/security_oss/server/check_cluster_data.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* Side Public License, v 1.
*/

import { elasticsearchServiceMock, loggingSystemMock } from '../../../core/server/mocks';
import { elasticsearchServiceMock, loggingSystemMock } from 'src/core/server/mocks';

import { createClusterDataCheck } from './check_cluster_data';

describe('checkClusterForUserData', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/security_oss/server/check_cluster_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import { ElasticsearchClient, Logger } from 'kibana/server';
import type { ElasticsearchClient, Logger } from 'src/core/server';

export const createClusterDataCheck = () => {
let clusterHasUserData = false;
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/security_oss/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* Side Public License, v 1.
*/

import { schema, TypeOf } from '@kbn/config-schema';
import type { TypeOf } from '@kbn/config-schema';
import { schema } from '@kbn/config-schema';

export type ConfigType = TypeOf<typeof ConfigSchema>;

Expand Down
4 changes: 2 additions & 2 deletions src/plugins/security_oss/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
* Side Public License, v 1.
*/

import { TypeOf } from '@kbn/config-schema';
import type { TypeOf } from '@kbn/config-schema';
import type { PluginConfigDescriptor, PluginInitializerContext } from 'src/core/server';

import { PluginConfigDescriptor, PluginInitializerContext } from 'kibana/server';
import { ConfigSchema } from './config';
import { SecurityOssPlugin } from './plugin';

Expand Down
Loading

0 comments on commit 0a85947

Please sign in to comment.