From 2c4196270abc540f841ab5492061d29fb5184ad5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ester=20Mart=C3=AD=20Vilaseca?=
Date: Mon, 29 Nov 2021 17:06:25 +0100
Subject: [PATCH 001/236] [Unified Observability] Add feature flag for the new
overview page (#119193)
* Add feature flag to display a blank overview page when enabled
* Add tests for overview page feature flag
* Fix types
* Fix more types
* Remove duplicated BucketSize type
* fix linter
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../public/application/application.test.tsx | 8 +-
.../components/app/section/apm/index.test.tsx | 8 +-
.../components/app/section/ux/index.test.tsx | 8 +-
.../public/hooks/use_time_range.test.ts | 16 ++-
x-pack/plugins/observability/public/index.ts | 6 +-
.../public/pages/overview/index.test.tsx | 51 +++++++
.../public/pages/overview/index.tsx | 131 ++---------------
.../pages/overview/old_overview_page.tsx | 136 ++++++++++++++++++
.../pages/overview/overview.stories.tsx | 6 +-
.../public/pages/overview/overview_page.tsx | 82 +++++++++++
.../public/utils/test_helper.tsx | 8 +-
x-pack/plugins/observability/server/index.ts | 1 +
12 files changed, 333 insertions(+), 128 deletions(-)
create mode 100644 x-pack/plugins/observability/public/pages/overview/index.test.tsx
create mode 100644 x-pack/plugins/observability/public/pages/overview/old_overview_page.tsx
create mode 100644 x-pack/plugins/observability/public/pages/overview/overview_page.tsx
diff --git a/x-pack/plugins/observability/public/application/application.test.tsx b/x-pack/plugins/observability/public/application/application.test.tsx
index 6b5863c8b122a..dddc44c3c26ea 100644
--- a/x-pack/plugins/observability/public/application/application.test.tsx
+++ b/x-pack/plugins/observability/public/application/application.test.tsx
@@ -46,7 +46,13 @@ describe('renderApp', () => {
uiSettings: { get: () => false },
http: { basePath: { prepend: (path: string) => path } },
} as unknown as CoreStart;
- const config = { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } };
+ const config = {
+ unsafe: {
+ alertingExperience: { enabled: true },
+ cases: { enabled: true },
+ overviewNext: { enabled: false },
+ },
+ };
const params = {
element: window.document.createElement('div'),
history: createMemoryHistory(),
diff --git a/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx b/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx
index c9c2ed549a1c3..35835cd0bc8e6 100644
--- a/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx
+++ b/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx
@@ -42,7 +42,13 @@ describe('APMSection', () => {
http: { basePath: { prepend: jest.fn() } },
} as unknown as CoreStart,
appMountParameters: {} as AppMountParameters,
- config: { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } },
+ config: {
+ unsafe: {
+ alertingExperience: { enabled: true },
+ cases: { enabled: true },
+ overviewNext: { enabled: false },
+ },
+ },
observabilityRuleTypeRegistry: createObservabilityRuleTypeRegistryMock(),
plugins: {
data: {
diff --git a/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx b/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx
index 8a99b6a53cf06..b4dda3ed3559e 100644
--- a/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx
+++ b/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx
@@ -42,7 +42,13 @@ describe('UXSection', () => {
http: { basePath: { prepend: jest.fn() } },
} as unknown as CoreStart,
appMountParameters: {} as AppMountParameters,
- config: { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } },
+ config: {
+ unsafe: {
+ alertingExperience: { enabled: true },
+ cases: { enabled: true },
+ overviewNext: { enabled: false },
+ },
+ },
plugins: {
data: {
query: {
diff --git a/x-pack/plugins/observability/public/hooks/use_time_range.test.ts b/x-pack/plugins/observability/public/hooks/use_time_range.test.ts
index bf513d8a1a99a..bbf3096e55107 100644
--- a/x-pack/plugins/observability/public/hooks/use_time_range.test.ts
+++ b/x-pack/plugins/observability/public/hooks/use_time_range.test.ts
@@ -24,7 +24,13 @@ describe('useTimeRange', () => {
jest.spyOn(pluginContext, 'usePluginContext').mockImplementation(() => ({
core: {} as CoreStart,
appMountParameters: {} as AppMountParameters,
- config: { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } },
+ config: {
+ unsafe: {
+ alertingExperience: { enabled: true },
+ cases: { enabled: true },
+ overviewNext: { enabled: false },
+ },
+ },
plugins: {
data: {
query: {
@@ -67,7 +73,13 @@ describe('useTimeRange', () => {
jest.spyOn(pluginContext, 'usePluginContext').mockImplementation(() => ({
core: {} as CoreStart,
appMountParameters: {} as AppMountParameters,
- config: { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } },
+ config: {
+ unsafe: {
+ alertingExperience: { enabled: true },
+ cases: { enabled: true },
+ overviewNext: { enabled: false },
+ },
+ },
plugins: {
data: {
query: {
diff --git a/x-pack/plugins/observability/public/index.ts b/x-pack/plugins/observability/public/index.ts
index 0dab3e5135717..7646ac9bec9bb 100644
--- a/x-pack/plugins/observability/public/index.ts
+++ b/x-pack/plugins/observability/public/index.ts
@@ -26,7 +26,11 @@ export type {
export { enableInspectEsQueries } from '../common/ui_settings_keys';
export interface ConfigSchema {
- unsafe: { alertingExperience: { enabled: boolean }; cases: { enabled: boolean } };
+ unsafe: {
+ alertingExperience: { enabled: boolean };
+ cases: { enabled: boolean };
+ overviewNext: { enabled: boolean };
+ };
}
export const plugin: PluginInitializer<
diff --git a/x-pack/plugins/observability/public/pages/overview/index.test.tsx b/x-pack/plugins/observability/public/pages/overview/index.test.tsx
new file mode 100644
index 0000000000000..b37ed1d873ba7
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/overview/index.test.tsx
@@ -0,0 +1,51 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import React from 'react';
+import { shallow } from 'enzyme';
+import * as PluginContext from '../../hooks/use_plugin_context';
+import { PluginContextValue } from '../../context/plugin_context';
+import { OverviewPage } from './';
+import { OverviewPage as OldOverviewPage } from './old_overview_page';
+import { OverviewPage as NewOverviewPage } from './overview_page';
+
+describe('Overview page', () => {
+ it('should render the old overview page when feature flag is disabled', () => {
+ const pluginContext = {
+ config: {
+ unsafe: {
+ overviewNext: { enabled: false },
+ },
+ },
+ };
+
+ jest
+ .spyOn(PluginContext, 'usePluginContext')
+ .mockReturnValue(pluginContext as PluginContextValue);
+
+ const component = shallow();
+ expect(component.find(OldOverviewPage)).toHaveLength(1);
+ expect(component.find(NewOverviewPage)).toHaveLength(0);
+ });
+
+ it('should render the new overview page when feature flag is enabled', () => {
+ const pluginContext = {
+ config: {
+ unsafe: {
+ overviewNext: { enabled: true },
+ },
+ },
+ };
+
+ jest
+ .spyOn(PluginContext, 'usePluginContext')
+ .mockReturnValue(pluginContext as PluginContextValue);
+
+ const component = shallow();
+ expect(component.find(OldOverviewPage)).toHaveLength(0);
+ expect(component.find(NewOverviewPage)).toHaveLength(1);
+ });
+});
diff --git a/x-pack/plugins/observability/public/pages/overview/index.tsx b/x-pack/plugins/observability/public/pages/overview/index.tsx
index 7100a0552876d..cc38445e3a0f2 100644
--- a/x-pack/plugins/observability/public/pages/overview/index.tsx
+++ b/x-pack/plugins/observability/public/pages/overview/index.tsx
@@ -4,133 +4,24 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-
-import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiPanel } from '@elastic/eui';
-import { i18n } from '@kbn/i18n';
import React from 'react';
-import { useTrackPageview } from '../..';
-import { EmptySections } from '../../components/app/empty_sections';
-import { ObservabilityHeaderMenu } from '../../components/app/header';
-import { NewsFeed } from '../../components/app/news_feed';
-import { Resources } from '../../components/app/resources';
-import { AlertsSection } from '../../components/app/section/alerts';
-import { DatePicker } from '../../components/shared/date_picker';
-import { useBreadcrumbs } from '../../hooks/use_breadcrumbs';
-import { useFetcher } from '../../hooks/use_fetcher';
-import { useHasData } from '../../hooks/use_has_data';
-import { usePluginContext } from '../../hooks/use_plugin_context';
-import { useTimeRange } from '../../hooks/use_time_range';
import { RouteParams } from '../../routes';
-import { getNewsFeed } from '../../services/get_news_feed';
-import { getBucketSize } from '../../utils/get_bucket_size';
-import { getNoDataConfig } from '../../utils/no_data_config';
-import { DataSections } from './data_sections';
-import { LoadingObservability } from './loading_observability';
+import { usePluginContext } from '../../hooks/use_plugin_context';
+import { OverviewPage as OldOverviewPage } from './old_overview_page';
+import { OverviewPage as NewOverviewPage } from './overview_page';
+
+export type { BucketSize } from './old_overview_page';
interface Props {
routeParams: RouteParams<'/overview'>;
}
-export type BucketSize = ReturnType;
-function calculateBucketSize({ start, end }: { start?: number; end?: number }) {
- if (start && end) {
- return getBucketSize({ start, end, minInterval: '60s' });
- }
-}
-
-export function OverviewPage({ routeParams }: Props) {
- useTrackPageview({ app: 'observability-overview', path: 'overview' });
- useTrackPageview({ app: 'observability-overview', path: 'overview', delay: 15000 });
- useBreadcrumbs([
- {
- text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', {
- defaultMessage: 'Overview',
- }),
- },
- ]);
-
- const { core, ObservabilityPageTemplate } = usePluginContext();
-
- const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange();
- const relativeTime = { start: relativeStart, end: relativeEnd };
- const absoluteTime = { start: absoluteStart, end: absoluteEnd };
+export function OverviewPage(props: Props) {
+ const { config } = usePluginContext();
- const { data: newsFeed } = useFetcher(() => getNewsFeed({ core }), [core]);
-
- const { hasDataMap, hasAnyData, isAllRequestsComplete } = useHasData();
-
- if (hasAnyData === undefined) {
- return ;
+ if (config.unsafe.overviewNext.enabled) {
+ return ;
+ } else {
+ return ;
}
-
- const hasData = hasAnyData === true || (isAllRequestsComplete === false ? undefined : false);
-
- const noDataConfig = getNoDataConfig({
- hasData,
- basePath: core.http.basePath,
- docsLink: core.docLinks.links.observability.guide,
- });
-
- const { refreshInterval = 10000, refreshPaused = true } = routeParams.query;
-
- const bucketSize = calculateBucketSize({
- start: absoluteTime.start,
- end: absoluteTime.end,
- });
-
- return (
- ,
- ],
- }
- : undefined
- }
- >
- {hasData && (
- <>
-
-
-
- {/* Data sections */}
- {hasAnyData && }
-
-
-
-
- {/* Resources / What's New sections */}
-
-
-
- {!!newsFeed?.items?.length && }
-
-
- {hasDataMap?.alert?.hasData && (
-
-
-
-
-
- )}
-
-
-
- >
- )}
-
- );
}
-
-const overviewPageTitle = i18n.translate('xpack.observability.overview.pageTitle', {
- defaultMessage: 'Overview',
-});
diff --git a/x-pack/plugins/observability/public/pages/overview/old_overview_page.tsx b/x-pack/plugins/observability/public/pages/overview/old_overview_page.tsx
new file mode 100644
index 0000000000000..7100a0552876d
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/overview/old_overview_page.tsx
@@ -0,0 +1,136 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiPanel } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import React from 'react';
+import { useTrackPageview } from '../..';
+import { EmptySections } from '../../components/app/empty_sections';
+import { ObservabilityHeaderMenu } from '../../components/app/header';
+import { NewsFeed } from '../../components/app/news_feed';
+import { Resources } from '../../components/app/resources';
+import { AlertsSection } from '../../components/app/section/alerts';
+import { DatePicker } from '../../components/shared/date_picker';
+import { useBreadcrumbs } from '../../hooks/use_breadcrumbs';
+import { useFetcher } from '../../hooks/use_fetcher';
+import { useHasData } from '../../hooks/use_has_data';
+import { usePluginContext } from '../../hooks/use_plugin_context';
+import { useTimeRange } from '../../hooks/use_time_range';
+import { RouteParams } from '../../routes';
+import { getNewsFeed } from '../../services/get_news_feed';
+import { getBucketSize } from '../../utils/get_bucket_size';
+import { getNoDataConfig } from '../../utils/no_data_config';
+import { DataSections } from './data_sections';
+import { LoadingObservability } from './loading_observability';
+
+interface Props {
+ routeParams: RouteParams<'/overview'>;
+}
+export type BucketSize = ReturnType;
+function calculateBucketSize({ start, end }: { start?: number; end?: number }) {
+ if (start && end) {
+ return getBucketSize({ start, end, minInterval: '60s' });
+ }
+}
+
+export function OverviewPage({ routeParams }: Props) {
+ useTrackPageview({ app: 'observability-overview', path: 'overview' });
+ useTrackPageview({ app: 'observability-overview', path: 'overview', delay: 15000 });
+ useBreadcrumbs([
+ {
+ text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', {
+ defaultMessage: 'Overview',
+ }),
+ },
+ ]);
+
+ const { core, ObservabilityPageTemplate } = usePluginContext();
+
+ const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange();
+
+ const relativeTime = { start: relativeStart, end: relativeEnd };
+ const absoluteTime = { start: absoluteStart, end: absoluteEnd };
+
+ const { data: newsFeed } = useFetcher(() => getNewsFeed({ core }), [core]);
+
+ const { hasDataMap, hasAnyData, isAllRequestsComplete } = useHasData();
+
+ if (hasAnyData === undefined) {
+ return ;
+ }
+
+ const hasData = hasAnyData === true || (isAllRequestsComplete === false ? undefined : false);
+
+ const noDataConfig = getNoDataConfig({
+ hasData,
+ basePath: core.http.basePath,
+ docsLink: core.docLinks.links.observability.guide,
+ });
+
+ const { refreshInterval = 10000, refreshPaused = true } = routeParams.query;
+
+ const bucketSize = calculateBucketSize({
+ start: absoluteTime.start,
+ end: absoluteTime.end,
+ });
+
+ return (
+ ,
+ ],
+ }
+ : undefined
+ }
+ >
+ {hasData && (
+ <>
+
+
+
+ {/* Data sections */}
+ {hasAnyData && }
+
+
+
+
+ {/* Resources / What's New sections */}
+
+
+
+ {!!newsFeed?.items?.length && }
+
+
+ {hasDataMap?.alert?.hasData && (
+
+
+
+
+
+ )}
+
+
+
+ >
+ )}
+
+ );
+}
+
+const overviewPageTitle = i18n.translate('xpack.observability.overview.pageTitle', {
+ defaultMessage: 'Overview',
+});
diff --git a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx
index 6549e892cab12..6213ea3e66d40 100644
--- a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx
+++ b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx
@@ -66,7 +66,11 @@ const withCore = makeDecorator({
setHeaderActionMenu: () => {},
} as unknown as AppMountParameters,
config: {
- unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } },
+ unsafe: {
+ alertingExperience: { enabled: true },
+ cases: { enabled: true },
+ overviewNext: { enabled: false },
+ },
},
core: options as CoreStart,
plugins: {
diff --git a/x-pack/plugins/observability/public/pages/overview/overview_page.tsx b/x-pack/plugins/observability/public/pages/overview/overview_page.tsx
new file mode 100644
index 0000000000000..f4cdec680af94
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/overview/overview_page.tsx
@@ -0,0 +1,82 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { i18n } from '@kbn/i18n';
+import React from 'react';
+import { useTrackPageview } from '../..';
+import { DatePicker } from '../../components/shared/date_picker';
+import { useBreadcrumbs } from '../../hooks/use_breadcrumbs';
+import { useHasData } from '../../hooks/use_has_data';
+import { usePluginContext } from '../../hooks/use_plugin_context';
+import { useTimeRange } from '../../hooks/use_time_range';
+import { RouteParams } from '../../routes';
+import { getNoDataConfig } from '../../utils/no_data_config';
+import { LoadingObservability } from './loading_observability';
+
+interface Props {
+ routeParams: RouteParams<'/overview'>;
+}
+
+export function OverviewPage({ routeParams }: Props) {
+ useTrackPageview({ app: 'observability-overview', path: 'overview' });
+ useTrackPageview({ app: 'observability-overview', path: 'overview', delay: 15000 });
+ useBreadcrumbs([
+ {
+ text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', {
+ defaultMessage: 'Overview',
+ }),
+ },
+ ]);
+
+ const { core, ObservabilityPageTemplate } = usePluginContext();
+
+ const { relativeStart, relativeEnd } = useTimeRange();
+
+ const relativeTime = { start: relativeStart, end: relativeEnd };
+
+ const { hasAnyData, isAllRequestsComplete } = useHasData();
+
+ if (hasAnyData === undefined) {
+ return ;
+ }
+
+ const hasData = hasAnyData === true || (isAllRequestsComplete === false ? undefined : false);
+
+ const noDataConfig = getNoDataConfig({
+ hasData,
+ basePath: core.http.basePath,
+ docsLink: core.docLinks.links.observability.guide,
+ });
+
+ const { refreshInterval = 10000, refreshPaused = true } = routeParams.query;
+
+ return (
+ ,
+ ],
+ }
+ : undefined
+ }
+ >
+ {hasData && New observability content goes here
}
+
+ );
+}
+
+const overviewPageTitle = i18n.translate('xpack.observability.overview.pageTitle', {
+ defaultMessage: 'Overview',
+});
diff --git a/x-pack/plugins/observability/public/utils/test_helper.tsx b/x-pack/plugins/observability/public/utils/test_helper.tsx
index 544f3feecb2bb..a3ec446e5c307 100644
--- a/x-pack/plugins/observability/public/utils/test_helper.tsx
+++ b/x-pack/plugins/observability/public/utils/test_helper.tsx
@@ -34,7 +34,13 @@ export const core = {
},
} as unknown as CoreStart;
-const config = { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } };
+const config = {
+ unsafe: {
+ alertingExperience: { enabled: true },
+ cases: { enabled: true },
+ overviewNext: { enabled: false },
+ },
+};
const plugins = {
data: { query: { timefilter: { timefilter: { setTime: jest.fn() } } } },
diff --git a/x-pack/plugins/observability/server/index.ts b/x-pack/plugins/observability/server/index.ts
index d99cf0865c0dd..51204c7512a3d 100644
--- a/x-pack/plugins/observability/server/index.ts
+++ b/x-pack/plugins/observability/server/index.ts
@@ -34,6 +34,7 @@ export const config: PluginConfigDescriptor = {
unsafe: schema.object({
alertingExperience: schema.object({ enabled: schema.boolean({ defaultValue: true }) }),
cases: schema.object({ enabled: schema.boolean({ defaultValue: true }) }),
+ overviewNext: schema.object({ enabled: schema.boolean({ defaultValue: false }) }),
}),
}),
};
From 75fcfe1c80ff78f2c3ef1f8065b531d171a3a273 Mon Sep 17 00:00:00 2001
From: "Christiane (Tina) Heiligers"
Date: Mon, 29 Nov 2021 09:17:15 -0700
Subject: [PATCH 002/236] Docs/kibana logging links (#119680)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
docs/migration/migrate_8_0.asciidoc | 8 ++++----
docs/settings/logging-settings.asciidoc | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/docs/migration/migrate_8_0.asciidoc b/docs/migration/migrate_8_0.asciidoc
index 59dd36a4fa5ef..8936e41762c69 100644
--- a/docs/migration/migrate_8_0.asciidoc
+++ b/docs/migration/migrate_8_0.asciidoc
@@ -65,7 +65,7 @@ If you are currently using one of these settings in your Kibana config, please r
==== Default logging timezone is now the system's timezone
*Details:* In prior releases the timezone used in logs defaulted to UTC. We now use the host machine's timezone by default.
-*Impact:* To restore the previous behavior, in kibana.yml use the pattern layout, with a date modifier:
+*Impact:* To restore the previous behavior, in kibana.yml use the pattern layout, with a {kibana-ref}/logging-configuration.html#date-format[date modifier]:
[source,yaml]
-------------------
logging:
@@ -100,7 +100,7 @@ See https://github.com/elastic/kibana/pull/87939 for more details.
[float]
==== Logging destination is specified by the appender
-*Details:* Previously log destination would be `stdout` and could be changed to `file` using `logging.dest`. With the new logging configuration, you can specify the destination using appenders.
+*Details:* Previously log destination would be `stdout` and could be changed to `file` using `logging.dest`. With the new logging configuration, you can specify the destination using {kibana-ref}/logging-configuration.html#logging-appenders[appenders].
*Impact:* To restore the previous behavior and log records to *stdout*, in `kibana.yml` use an appender with `type: console`.
[source,yaml]
@@ -131,7 +131,7 @@ logging:
[float]
==== Set log verbosity with root
-*Details:* Previously logging output would be specified by `logging.silent` (none), `logging.quiet` (error messages only) and `logging.verbose` (all). With the new logging configuration, set the minimum required log level.
+*Details:* Previously logging output would be specified by `logging.silent` (none), `logging.quiet` (error messages only) and `logging.verbose` (all). With the new logging configuration, set the minimum required {kibana-ref}/logging-configuration.html#log-level[log level].
*Impact:* To restore the previous behavior, in `kibana.yml` specify `logging.root.level`:
[source,yaml]
@@ -188,7 +188,7 @@ logging:
==== Configure log rotation with the rolling-file appender
*Details:* Previously log rotation would be enabled when `logging.rotate.enabled` was true.
-*Impact:* To restore the previous behavior, in `kibana.yml` use the `rolling-file` appender.
+*Impact:* To restore the previous behavior, in `kibana.yml` use the {kibana-ref}/logging-configuration.html#rolling-file-appender[`rolling-file`] appender.
[source,yaml]
-------------------
diff --git a/docs/settings/logging-settings.asciidoc b/docs/settings/logging-settings.asciidoc
index cb8237c5aa384..a9053b90ce722 100644
--- a/docs/settings/logging-settings.asciidoc
+++ b/docs/settings/logging-settings.asciidoc
@@ -30,7 +30,7 @@ The following table serves as a quick reference for different logging configurat
| Allows you to specify a fileName to write log records to disk. To write <>, add the file appender to `root.appenders`. If configured, you also need to specify <>.
| `logging.appenders[].rolling-file:`
-| Similar to Log4j's `RollingFileAppender`, this appender will log to a file and rotate if following a rolling strategy when the configured policy triggers. There are currently two policies supported: `size-limit` and `time-interval`.
+| Similar to https://logging.apache.org/log4j/2.x/[Log4j's] `RollingFileAppender`, this appender will log to a file and rotate if following a rolling strategy when the configured policy triggers. There are currently two policies supported: <> and <>.
| `logging.appenders[]..type`
| The appender type determines where the log messages are sent. Options are `console`, `file`, `rewrite`, `rolling-file`. Required.
From 095247f8574fa9c93521fcddd490bc1bdc1b5d9c Mon Sep 17 00:00:00 2001
From: Shahzad
Date: Mon, 29 Nov 2021 18:29:30 +0100
Subject: [PATCH 003/236] [Uptime] Monitor management stub crud routes
(#119800)
* fix uptime config key
* crud routes
* prefix
* test wip
* add tests
* revert
* fixed path
---
x-pack/plugins/uptime/common/config.ts | 2 +-
.../uptime/common/constants/rest_api.ts | 3 +-
.../framework/kibana_framework_adapter.ts | 7 +++
.../plugins/uptime/server/rest_api/index.ts | 12 +++++
.../synthetics_service/add_monitor.ts | 26 ++++++++++
.../synthetics_service/delete_monitor.ts | 34 +++++++++++++
.../synthetics_service/edit_monitor.ts | 31 +++++++++++
.../synthetics_service/get_monitors.ts | 40 +++++++++++++++
.../apis/uptime/rest/add_monitor.ts | 29 +++++++++++
.../apis/uptime/rest/delete_monitor.ts | 36 +++++++++++++
.../apis/uptime/rest/edit_monitor.ts | 37 ++++++++++++++
.../apis/uptime/rest/get_monitor.ts | 51 +++++++++++++++++++
.../api_integration/apis/uptime/rest/index.ts | 7 +++
x-pack/test/api_integration/config.ts | 4 ++
14 files changed, 317 insertions(+), 2 deletions(-)
create mode 100644 x-pack/plugins/uptime/server/rest_api/synthetics_service/add_monitor.ts
create mode 100644 x-pack/plugins/uptime/server/rest_api/synthetics_service/delete_monitor.ts
create mode 100644 x-pack/plugins/uptime/server/rest_api/synthetics_service/edit_monitor.ts
create mode 100644 x-pack/plugins/uptime/server/rest_api/synthetics_service/get_monitors.ts
create mode 100644 x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts
create mode 100644 x-pack/test/api_integration/apis/uptime/rest/delete_monitor.ts
create mode 100644 x-pack/test/api_integration/apis/uptime/rest/edit_monitor.ts
create mode 100644 x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts
diff --git a/x-pack/plugins/uptime/common/config.ts b/x-pack/plugins/uptime/common/config.ts
index ccd5e7b5a2cc6..8b70869645649 100644
--- a/x-pack/plugins/uptime/common/config.ts
+++ b/x-pack/plugins/uptime/common/config.ts
@@ -36,7 +36,7 @@ export const config: PluginConfigDescriptor = {
username: schema.string(),
password: schema.string(),
manifestUrl: schema.string(),
- hosts: schema.arrayOf(schema.string()),
+ hosts: schema.maybe(schema.arrayOf(schema.string())),
})
),
})
diff --git a/x-pack/plugins/uptime/common/constants/rest_api.ts b/x-pack/plugins/uptime/common/constants/rest_api.ts
index bef84c41796d9..9c8098390d129 100644
--- a/x-pack/plugins/uptime/common/constants/rest_api.ts
+++ b/x-pack/plugins/uptime/common/constants/rest_api.ts
@@ -37,5 +37,6 @@ export enum API_URLS {
CONNECTOR_TYPES = '/api/actions/connector_types',
// Service end points
- INDEX_TEMPLATES = '/api/uptime/service/index_templates',
+ INDEX_TEMPLATES = '/internal/uptime/service/index_templates',
+ SYNTHETICS_MONITORS = '/internal/uptime/service/monitors',
}
diff --git a/x-pack/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts
index eae9dd5e73cae..d51496d6efaf1 100644
--- a/x-pack/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts
+++ b/x-pack/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts
@@ -20,6 +20,7 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte
validate,
options,
};
+
switch (method) {
case 'GET':
this.server.router.get(routeDefinition, handler);
@@ -27,6 +28,12 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte
case 'POST':
this.server.router.post(routeDefinition, handler);
break;
+ case 'PUT':
+ this.server.router.put(routeDefinition, handler);
+ break;
+ case 'DELETE':
+ this.server.router.delete(routeDefinition, handler);
+ break;
default:
throw new Error(`Handler for method ${method} is not defined`);
}
diff --git a/x-pack/plugins/uptime/server/rest_api/index.ts b/x-pack/plugins/uptime/server/rest_api/index.ts
index 344dd4d203d8d..4eb6ae3071256 100644
--- a/x-pack/plugins/uptime/server/rest_api/index.ts
+++ b/x-pack/plugins/uptime/server/rest_api/index.ts
@@ -28,6 +28,13 @@ import { createNetworkEventsRoute } from './network_events';
import { createJourneyFailedStepsRoute } from './pings/journeys';
import { createLastSuccessfulStepRoute } from './synthetics/last_successful_step';
import { installIndexTemplatesRoute } from './synthetics_service/install_index_templates';
+import {
+ getAllSyntheticsMonitorRoute,
+ getSyntheticsMonitorRoute,
+} from './synthetics_service/get_monitors';
+import { addSyntheticsMonitorRoute } from './synthetics_service/add_monitor';
+import { editSyntheticsMonitorRoute } from './synthetics_service/edit_monitor';
+import { deleteSyntheticsMonitorRoute } from './synthetics_service/delete_monitor';
export * from './types';
export { createRouteWithAuth } from './create_route_with_auth';
@@ -53,4 +60,9 @@ export const restApiRoutes: UMRestApiRouteFactory[] = [
createLastSuccessfulStepRoute,
createJourneyScreenshotBlocksRoute,
installIndexTemplatesRoute,
+ getSyntheticsMonitorRoute,
+ getAllSyntheticsMonitorRoute,
+ addSyntheticsMonitorRoute,
+ editSyntheticsMonitorRoute,
+ deleteSyntheticsMonitorRoute,
];
diff --git a/x-pack/plugins/uptime/server/rest_api/synthetics_service/add_monitor.ts b/x-pack/plugins/uptime/server/rest_api/synthetics_service/add_monitor.ts
new file mode 100644
index 0000000000000..11d7dcedcaa34
--- /dev/null
+++ b/x-pack/plugins/uptime/server/rest_api/synthetics_service/add_monitor.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { schema } from '@kbn/config-schema';
+import { UMRestApiRouteFactory } from '../types';
+import { API_URLS } from '../../../common/constants';
+import { SyntheticsMonitorSavedObject } from '../../../common/types';
+import { syntheticsMonitorType } from '../../lib/saved_objects/synthetics_monitor';
+
+export const addSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({
+ method: 'POST',
+ path: API_URLS.SYNTHETICS_MONITORS,
+ validate: {
+ body: schema.any(),
+ },
+ handler: async ({ request, savedObjectsClient }): Promise => {
+ const monitor = request.body as SyntheticsMonitorSavedObject;
+
+ const newMonitor = await savedObjectsClient.create(syntheticsMonitorType, monitor);
+ // TODO: call to service sync
+ return newMonitor;
+ },
+});
diff --git a/x-pack/plugins/uptime/server/rest_api/synthetics_service/delete_monitor.ts b/x-pack/plugins/uptime/server/rest_api/synthetics_service/delete_monitor.ts
new file mode 100644
index 0000000000000..68eb8aa130d2e
--- /dev/null
+++ b/x-pack/plugins/uptime/server/rest_api/synthetics_service/delete_monitor.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { schema } from '@kbn/config-schema';
+import { SavedObjectsErrorHelpers } from '../../../../../../src/core/server';
+import { UMRestApiRouteFactory } from '../types';
+import { API_URLS } from '../../../common/constants';
+import { syntheticsMonitorType } from '../../lib/saved_objects/synthetics_monitor';
+
+export const deleteSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({
+ method: 'DELETE',
+ path: API_URLS.SYNTHETICS_MONITORS + '/{monitorId}',
+ validate: {
+ params: schema.object({
+ monitorId: schema.string(),
+ }),
+ },
+ handler: async ({ request, savedObjectsClient }): Promise => {
+ const { monitorId } = request.params;
+
+ try {
+ await savedObjectsClient.delete(syntheticsMonitorType, monitorId);
+ // TODO: call to service sync
+ return monitorId;
+ } catch (getErr) {
+ if (SavedObjectsErrorHelpers.isNotFoundError(getErr)) {
+ return 'Not found';
+ }
+ }
+ },
+});
diff --git a/x-pack/plugins/uptime/server/rest_api/synthetics_service/edit_monitor.ts b/x-pack/plugins/uptime/server/rest_api/synthetics_service/edit_monitor.ts
new file mode 100644
index 0000000000000..46a91738c380d
--- /dev/null
+++ b/x-pack/plugins/uptime/server/rest_api/synthetics_service/edit_monitor.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { schema } from '@kbn/config-schema';
+import { UMRestApiRouteFactory } from '../types';
+import { API_URLS } from '../../../common/constants';
+import { SyntheticsMonitorSavedObject } from '../../../common/types';
+import { syntheticsMonitorType } from '../../lib/saved_objects/synthetics_monitor';
+
+export const editSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({
+ method: 'PUT',
+ path: API_URLS.SYNTHETICS_MONITORS + '/{monitorId}',
+ validate: {
+ params: schema.object({
+ monitorId: schema.string(),
+ }),
+ body: schema.any(),
+ },
+ handler: async ({ request, savedObjectsClient }): Promise => {
+ const monitor = request.body as SyntheticsMonitorSavedObject['attributes'];
+
+ const { monitorId } = request.params;
+
+ const editMonitor = await savedObjectsClient.update(syntheticsMonitorType, monitorId, monitor);
+ // TODO: call to service sync
+ return editMonitor;
+ },
+});
diff --git a/x-pack/plugins/uptime/server/rest_api/synthetics_service/get_monitors.ts b/x-pack/plugins/uptime/server/rest_api/synthetics_service/get_monitors.ts
new file mode 100644
index 0000000000000..537d6c77195ca
--- /dev/null
+++ b/x-pack/plugins/uptime/server/rest_api/synthetics_service/get_monitors.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { schema } from '@kbn/config-schema';
+import { UMRestApiRouteFactory } from '../types';
+import { API_URLS } from '../../../common/constants';
+import { syntheticsMonitorType } from '../../lib/saved_objects/synthetics_monitor';
+
+export const getSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({
+ method: 'GET',
+ path: API_URLS.SYNTHETICS_MONITORS + '/{monitorId}',
+ validate: {
+ params: schema.object({
+ monitorId: schema.string(),
+ }),
+ },
+ handler: async ({ request, savedObjectsClient }): Promise => {
+ const { monitorId } = request.params;
+ return await savedObjectsClient.get(syntheticsMonitorType, monitorId);
+ },
+});
+
+export const getAllSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({
+ method: 'GET',
+ path: API_URLS.SYNTHETICS_MONITORS,
+ validate: {
+ query: schema.object({
+ page: schema.maybe(schema.number()),
+ perPage: schema.maybe(schema.number()),
+ }),
+ },
+ handler: async ({ request, savedObjectsClient }): Promise => {
+ const { perPage = 50, page } = request.query;
+ // TODO: add query/filtering params
+ return await savedObjectsClient.find({ type: syntheticsMonitorType, perPage, page });
+ },
+});
diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts
new file mode 100644
index 0000000000000..a57a03fd3a1f5
--- /dev/null
+++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+import { API_URLS } from '../../../../../plugins/uptime/common/constants';
+
+export default function ({ getService }: FtrProviderContext) {
+ describe('add synthetics monitor', () => {
+ const supertest = getService('supertest');
+ const newMonitor = {
+ type: 'http',
+ name: 'Test monitor',
+ urls: 'https://www.elastic.co',
+ };
+
+ it('returns the newly added monitor', async () => {
+ const apiResponse = await supertest
+ .post(API_URLS.SYNTHETICS_MONITORS)
+ .set('kbn-xsrf', 'true')
+ .send(newMonitor);
+
+ expect(apiResponse.body.attributes).eql(newMonitor);
+ });
+ });
+}
diff --git a/x-pack/test/api_integration/apis/uptime/rest/delete_monitor.ts b/x-pack/test/api_integration/apis/uptime/rest/delete_monitor.ts
new file mode 100644
index 0000000000000..bc49587fab872
--- /dev/null
+++ b/x-pack/test/api_integration/apis/uptime/rest/delete_monitor.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+import { API_URLS } from '../../../../../plugins/uptime/common/constants';
+
+export default function ({ getService }: FtrProviderContext) {
+ describe('delete synthetics monitor', () => {
+ const supertest = getService('supertest');
+ const newMonitor = {
+ type: 'http',
+ name: 'Test monitor',
+ urls: 'https://www.elastic.co',
+ };
+
+ it('deleted monitor by id', async () => {
+ const apiResponse = await supertest
+ .post(API_URLS.SYNTHETICS_MONITORS)
+ .set('kbn-xsrf', 'true')
+ .send(newMonitor);
+
+ const monitorId = apiResponse.body.id;
+
+ const deleteResponse = await supertest
+ .delete(API_URLS.SYNTHETICS_MONITORS + '/' + monitorId)
+ .set('kbn-xsrf', 'true');
+ //
+ expect(deleteResponse.body).eql(monitorId);
+ });
+ });
+}
diff --git a/x-pack/test/api_integration/apis/uptime/rest/edit_monitor.ts b/x-pack/test/api_integration/apis/uptime/rest/edit_monitor.ts
new file mode 100644
index 0000000000000..f5d54c40a8646
--- /dev/null
+++ b/x-pack/test/api_integration/apis/uptime/rest/edit_monitor.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+import { API_URLS } from '../../../../../plugins/uptime/common/constants';
+export default function ({ getService }: FtrProviderContext) {
+ describe('edit synthetics monitor', () => {
+ const supertest = getService('supertest');
+ const newMonitor = {
+ type: 'http',
+ name: 'Test monitor',
+ urls: 'https://www.elastic.co',
+ };
+
+ it('edits the monitor', async () => {
+ const apiResponse = await supertest
+ .post(API_URLS.SYNTHETICS_MONITORS)
+ .set('kbn-xsrf', 'true')
+ .send(newMonitor);
+
+ const monitorId = apiResponse.body.id;
+
+ expect(apiResponse.body.attributes).eql(newMonitor);
+
+ const editResponse = await supertest
+ .put(API_URLS.SYNTHETICS_MONITORS + '/' + monitorId)
+ .set('kbn-xsrf', 'true')
+ .send({ ...newMonitor, name: 'New name' });
+
+ expect(editResponse.body.attributes.name).eql('New name');
+ });
+ });
+}
diff --git a/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts b/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts
new file mode 100644
index 0000000000000..76d27ff8a9d1d
--- /dev/null
+++ b/x-pack/test/api_integration/apis/uptime/rest/get_monitor.ts
@@ -0,0 +1,51 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+import { API_URLS } from '../../../../../plugins/uptime/common/constants';
+
+export default function ({ getService }: FtrProviderContext) {
+ describe('get synthetics monitor', () => {
+ const newMonitor = {
+ type: 'http',
+ name: 'Test monitor',
+ urls: 'https://www.elastic.co',
+ };
+
+ const addMonitor = async () => {
+ const res = await supertest
+ .post(API_URLS.SYNTHETICS_MONITORS)
+ .set('kbn-xsrf', 'true')
+ .send(newMonitor);
+ return res.body.id;
+ };
+
+ const supertest = getService('supertest');
+
+ it('get all monitors', async () => {
+ const id1 = await addMonitor();
+ const id2 = await addMonitor();
+
+ const apiResponse = await supertest.get(API_URLS.SYNTHETICS_MONITORS);
+
+ const monitor1 = apiResponse.body.saved_objects.find((obj: any) => obj.id === id1);
+ const monitor2 = apiResponse.body.saved_objects.find((obj: any) => obj.id === id2);
+
+ expect(monitor1.id).eql(id1);
+ expect(monitor2.id).eql(id2);
+ });
+
+ it('get monitor by id', async () => {
+ const monitorId = await addMonitor();
+
+ const apiResponse = await supertest.get(API_URLS.SYNTHETICS_MONITORS + '/' + monitorId);
+
+ expect(apiResponse.body.id).eql(monitorId);
+ });
+ });
+}
diff --git a/x-pack/test/api_integration/apis/uptime/rest/index.ts b/x-pack/test/api_integration/apis/uptime/rest/index.ts
index dc3c00b03f712..f674879552d6a 100644
--- a/x-pack/test/api_integration/apis/uptime/rest/index.ts
+++ b/x-pack/test/api_integration/apis/uptime/rest/index.ts
@@ -71,5 +71,12 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./index_status'));
loadTestFile(require.resolve('./monitor_states_real_data'));
});
+
+ describe('uptime CRUD routes', () => {
+ loadTestFile(require.resolve('./get_monitor'));
+ loadTestFile(require.resolve('./add_monitor'));
+ loadTestFile(require.resolve('./edit_monitor'));
+ loadTestFile(require.resolve('./delete_monitor'));
+ });
});
}
diff --git a/x-pack/test/api_integration/config.ts b/x-pack/test/api_integration/config.ts
index e2c2e0b52dfdc..bf42a5b0865a2 100644
--- a/x-pack/test/api_integration/config.ts
+++ b/x-pack/test/api_integration/config.ts
@@ -35,6 +35,10 @@ export async function getApiIntegrationConfig({ readConfigFile }: FtrConfigProvi
'--xpack.ruleRegistry.write.enabled=true',
'--xpack.ruleRegistry.write.enabled=true',
'--xpack.ruleRegistry.write.cache.enabled=false',
+ '--xpack.uptime.unsafe.service.enabled=true',
+ '--xpack.uptime.unsafe.service.password=test',
+ '--xpack.uptime.unsafe.service.manifestUrl=http://test.com',
+ '--xpack.uptime.unsafe.service.username=user',
`--xpack.securitySolution.enableExperimental=${JSON.stringify(['ruleRegistryEnabled'])}`,
],
},
From 8915c90a3127e14bf2b778bd1daa7310a96ce31f Mon Sep 17 00:00:00 2001
From: Jean-Louis Leysens
Date: Mon, 29 Nov 2021 19:03:29 +0100
Subject: [PATCH 004/236] [es-query] Fix logic for detecting scripted phrase
fields (#119511)
* WIP, started updating functions for detecting scripted phrase filters
* replace script.script with query.script.script
* added test to verify detection of scripted and phrase filters
* with elastic@ email
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../build_filters/phrase_filter.test.ts | 25 ++++++++++++++++++-
.../filters/build_filters/phrase_filter.ts | 10 +++++---
.../filter_manager/lib/generate_filters.ts | 4 ++-
.../filter_manager/lib/mappers/map_phrase.ts | 2 +-
.../filter_manager/phrase_filter_manager.ts | 4 +--
5 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/packages/kbn-es-query/src/filters/build_filters/phrase_filter.test.ts b/packages/kbn-es-query/src/filters/build_filters/phrase_filter.test.ts
index 87a7812165a66..7c7f7dd28f6ca 100644
--- a/packages/kbn-es-query/src/filters/build_filters/phrase_filter.test.ts
+++ b/packages/kbn-es-query/src/filters/build_filters/phrase_filter.test.ts
@@ -5,16 +5,19 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
-
+import { set } from 'lodash';
import {
buildInlineScriptForPhraseFilter,
buildPhraseFilter,
getPhraseFilterField,
PhraseFilter,
+ isPhraseFilter,
+ isScriptedPhraseFilter,
} from './phrase_filter';
import { fields, getField } from '../stubs';
import { DataViewBase } from '../../es_query';
import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
+import { Filter } from './types';
describe('Phrase filter builder', () => {
let indexPattern: DataViewBase;
@@ -164,3 +167,23 @@ describe('getPhraseFilterField', function () {
expect(result).toBe('extension');
});
});
+
+describe('isPhraseFilter', () => {
+ it('should return true if the filter is a phrases filter false otherwise', () => {
+ const filter: Filter = set({ meta: {} }, 'query.match_phrase', {}) as Filter;
+ const unknownFilter = {} as Filter;
+
+ expect(isPhraseFilter(filter)).toBe(true);
+ expect(isPhraseFilter(unknownFilter)).toBe(false);
+ });
+});
+
+describe('isScriptedPhraseFilter', () => {
+ it('should return true if the filter is a phrases filter false otherwise', () => {
+ const filter: Filter = set({ meta: {} }, 'query.script.script.params.value', {}) as Filter;
+ const unknownFilter = {} as Filter;
+
+ expect(isScriptedPhraseFilter(filter)).toBe(true);
+ expect(isPhraseFilter(unknownFilter)).toBe(false);
+ });
+});
diff --git a/packages/kbn-es-query/src/filters/build_filters/phrase_filter.ts b/packages/kbn-es-query/src/filters/build_filters/phrase_filter.ts
index 4c1827dc58c04..525463c9de246 100644
--- a/packages/kbn-es-query/src/filters/build_filters/phrase_filter.ts
+++ b/packages/kbn-es-query/src/filters/build_filters/phrase_filter.ts
@@ -31,8 +31,10 @@ export type PhraseFilter = Filter & {
export type ScriptedPhraseFilter = Filter & {
meta: PhraseFilterMeta;
- script: {
- script: estypes.InlineScript;
+ query: {
+ script: {
+ script: estypes.InlineScript;
+ };
};
};
@@ -58,7 +60,7 @@ export const isPhraseFilter = (filter: Filter): filter is PhraseFilter => {
* @public
*/
export const isScriptedPhraseFilter = (filter: Filter): filter is ScriptedPhraseFilter =>
- has(filter, 'script.script.params.value');
+ has(filter, 'query.script.script.params.value');
/** @internal */
export const getPhraseFilterField = (filter: PhraseFilter) => {
@@ -77,7 +79,7 @@ export const getPhraseFilterValue = (
const queryValue = Object.values(queryConfig)[0];
return isPlainObject(queryValue) ? queryValue.query : queryValue;
} else {
- return filter.script.script.params?.value;
+ return filter.query?.script?.script?.params?.value;
}
};
diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts b/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts
index cfc3ddabe0751..58f5cf8e52c91 100644
--- a/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts
+++ b/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts
@@ -40,7 +40,9 @@ function getExistingFilter(
}
if (isScriptedPhraseFilter(filter)) {
- return filter.meta.field === fieldName && filter.script.script.params?.value === value;
+ return (
+ filter.meta.field === fieldName && filter.query?.script?.script?.params?.value === value
+ );
}
}) as any;
}
diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts
index 64576d4978c99..23cae0ee852ca 100644
--- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts
+++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_phrase.ts
@@ -20,7 +20,7 @@ import {
import { FilterValueFormatter } from '../../../../../common';
const getScriptedPhraseValue = (filter: PhraseFilter) =>
- get(filter, ['script', 'script', 'params', 'value']);
+ get(filter, ['query', 'script', 'script', 'params', 'value']);
const getFormattedValueFn = (value: any) => {
return (formatter?: FilterValueFormatter) => {
diff --git a/src/plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.ts b/src/plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.ts
index 8ffeefefd0cc3..98ba8b4fbcda8 100644
--- a/src/plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.ts
+++ b/src/plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.ts
@@ -97,8 +97,8 @@ export class PhraseFilterManager extends FilterManager {
}
// scripted field filter
- if (_.has(kbnFilter, 'script')) {
- return _.get(kbnFilter, 'script.script.params.value');
+ if (_.has(kbnFilter, 'query.script')) {
+ return _.get(kbnFilter, 'query.script.script.params.value');
}
// single phrase filter
From c6db25a3ef5663cc71dce348036601707fac930d Mon Sep 17 00:00:00 2001
From: Tiago Costa
Date: Mon, 29 Nov 2021 18:15:06 +0000
Subject: [PATCH 005/236] chore(NA): splits types from code on @kbn/alerts
(#119855)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
package.json | 1 +
packages/BUILD.bazel | 1 +
packages/kbn-alerts/BUILD.bazel | 27 ++++++++++++++++++++++-----
packages/kbn-alerts/package.json | 1 -
yarn.lock | 4 ++++
5 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index 5e8a77f2c55f4..b0c7e4659a559 100644
--- a/package.json
+++ b/package.json
@@ -556,6 +556,7 @@
"@types/json-stable-stringify": "^1.0.32",
"@types/json5": "^0.0.30",
"@types/kbn__ace": "link:bazel-bin/packages/kbn-ace/npm_module_types",
+ "@types/kbn__alerts": "link:bazel-bin/packages/kbn-alerts/npm_module_types",
"@types/kbn__i18n": "link:bazel-bin/packages/kbn-i18n/npm_module_types",
"@types/kbn__i18n-react": "link:bazel-bin/packages/kbn-i18n-react/npm_module_types",
"@types/license-checker": "15.0.0",
diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel
index 07513ac94c85d..c9a0f6a759b2a 100644
--- a/packages/BUILD.bazel
+++ b/packages/BUILD.bazel
@@ -78,6 +78,7 @@ filegroup(
"//packages/elastic-apm-synthtrace:build_types",
"//packages/elastic-datemath:build_types",
"//packages/kbn-ace:build_types",
+ "//packages/kbn-alerts:build_types",
"//packages/kbn-i18n:build_types",
"//packages/kbn-i18n-react:build_types",
],
diff --git a/packages/kbn-alerts/BUILD.bazel b/packages/kbn-alerts/BUILD.bazel
index e567c18807dfc..15dbc163cd288 100644
--- a/packages/kbn-alerts/BUILD.bazel
+++ b/packages/kbn-alerts/BUILD.bazel
@@ -1,10 +1,10 @@
-load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project")
-load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm")
-load("//src/dev/bazel:index.bzl", "jsts_transpiler")
+load("@npm//@bazel/typescript:index.bzl", "ts_config")
+load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
+load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
PKG_BASE_NAME = "kbn-alerts"
-
PKG_REQUIRE_NAME = "@kbn/alerts"
+TYPES_PKG_REQUIRE_NAME = "@types/kbn__alerts"
SOURCE_FILES = glob(
[
@@ -87,7 +87,7 @@ ts_project(
js_library(
name = PKG_BASE_NAME,
srcs = NPM_MODULE_EXTRA_FILES,
- deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"],
+ deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
visibility = ["//visibility:public"],
)
@@ -106,3 +106,20 @@ filegroup(
],
visibility = ["//visibility:public"],
)
+
+pkg_npm_types(
+ name = "npm_module_types",
+ srcs = SRCS,
+ deps = [":tsc_types"],
+ package_name = TYPES_PKG_REQUIRE_NAME,
+ tsconfig = ":tsconfig",
+ visibility = ["//visibility:public"],
+)
+
+filegroup(
+ name = "build_types",
+ srcs = [
+ ":npm_module_types",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/packages/kbn-alerts/package.json b/packages/kbn-alerts/package.json
index b52a6efc35139..13b60ad9fa072 100644
--- a/packages/kbn-alerts/package.json
+++ b/packages/kbn-alerts/package.json
@@ -5,6 +5,5 @@
"license": "SSPL-1.0 OR Elastic License 2.0",
"browser": "./target_web/index.js",
"main": "./target_node/index.js",
- "types": "./target_types/index.d.ts",
"private": true
}
diff --git a/yarn.lock b/yarn.lock
index 821b788bc7c8f..71b82ffdf5af6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5809,6 +5809,10 @@
version "0.0.0"
uid ""
+"@types/kbn__alerts@link:bazel-bin/packages/kbn-alerts/npm_module_types":
+ version "0.0.0"
+ uid ""
+
"@types/kbn__i18n-react@link:bazel-bin/packages/kbn-i18n-react/npm_module_types":
version "0.0.0"
uid ""
From b2f54829d853db84a9aa4829ae664716aaacc9cd Mon Sep 17 00:00:00 2001
From: Spencer
Date: Mon, 29 Nov 2021 10:29:45 -0800
Subject: [PATCH 006/236] [babel] ensure TS preset runs before anything else
(#119107)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
packages/kbn-babel-preset/common_preset.js | 85 ++++++------
..._babel_runtime_helpers_in_entry_bundles.ts | 4 +-
.../src/worker/emit_stats_plugin.ts | 2 +-
packages/kbn-storybook/src/webpack.config.ts | 125 +++++++++++++++---
.../console/public/services/history.ts | 6 +-
.../viewport/dashboard_viewport.tsx | 2 +-
.../roles/roles_management_app.test.tsx | 6 +-
7 files changed, 168 insertions(+), 62 deletions(-)
diff --git a/packages/kbn-babel-preset/common_preset.js b/packages/kbn-babel-preset/common_preset.js
index 3a3763693db9a..824a73f9b2611 100644
--- a/packages/kbn-babel-preset/common_preset.js
+++ b/packages/kbn-babel-preset/common_preset.js
@@ -6,46 +6,57 @@
* Side Public License, v 1.
*/
-const plugins = [
- require.resolve('babel-plugin-add-module-exports'),
-
- // The class properties proposal was merged with the private fields proposal
- // into the "class fields" proposal. Babel doesn't support this combined
- // proposal yet, which includes private field, so this transform is
- // TECHNICALLY stage 2, but for all intents and purposes it's stage 3
- //
- // See https://github.com/babel/proposals/issues/12 for progress
- require.resolve('@babel/plugin-proposal-class-properties'),
-
- // Optional Chaining proposal is stage 4 (https://github.com/tc39/proposal-optional-chaining)
- // Need this since we are using TypeScript 3.7+
- require.resolve('@babel/plugin-proposal-optional-chaining'),
-
- // Nullish coalescing proposal is stage 4 (https://github.com/tc39/proposal-nullish-coalescing)
- // Need this since we are using TypeScript 3.7+
- require.resolve('@babel/plugin-proposal-nullish-coalescing-operator'),
-
- // Proposal is on stage 4, and included in ECMA-262 (https://github.com/tc39/proposal-export-ns-from)
- // Need this since we are using TypeScript 3.8+
- require.resolve('@babel/plugin-proposal-export-namespace-from'),
-
- // Proposal is on stage 4, and included in ECMA-262 (https://github.com/tc39/proposal-export-ns-from)
- // Need this since we are using TypeScript 3.9+
- require.resolve('@babel/plugin-proposal-private-methods'),
-
- // It enables the @babel/runtime so we can decrease the bundle sizes of the produced outputs
- [
- require.resolve('@babel/plugin-transform-runtime'),
+module.exports = {
+ presets: [
+ // plugins always run before presets, but in this case we need the
+ // @babel/preset-typescript preset to run first so we have to move
+ // our explicit plugin configs to a sub-preset
{
- version: '^7.12.5',
+ plugins: [
+ require.resolve('babel-plugin-add-module-exports'),
+
+ // The class properties proposal was merged with the private fields proposal
+ // into the "class fields" proposal. Babel doesn't support this combined
+ // proposal yet, which includes private field, so this transform is
+ // TECHNICALLY stage 2, but for all intents and purposes it's stage 3
+ //
+ // See https://github.com/babel/proposals/issues/12 for progress
+ require.resolve('@babel/plugin-proposal-class-properties'),
+
+ // Optional Chaining proposal is stage 4 (https://github.com/tc39/proposal-optional-chaining)
+ // Need this since we are using TypeScript 3.7+
+ require.resolve('@babel/plugin-proposal-optional-chaining'),
+
+ // Nullish coalescing proposal is stage 4 (https://github.com/tc39/proposal-nullish-coalescing)
+ // Need this since we are using TypeScript 3.7+
+ require.resolve('@babel/plugin-proposal-nullish-coalescing-operator'),
+
+ // Proposal is on stage 4, and included in ECMA-262 (https://github.com/tc39/proposal-export-ns-from)
+ // Need this since we are using TypeScript 3.8+
+ require.resolve('@babel/plugin-proposal-export-namespace-from'),
+
+ // Proposal is on stage 4, and included in ECMA-262 (https://github.com/tc39/proposal-export-ns-from)
+ // Need this since we are using TypeScript 3.9+
+ require.resolve('@babel/plugin-proposal-private-methods'),
+
+ // It enables the @babel/runtime so we can decrease the bundle sizes of the produced outputs
+ [
+ require.resolve('@babel/plugin-transform-runtime'),
+ {
+ version: '^7.12.5',
+ },
+ ],
+ ],
},
- ],
-];
-module.exports = {
- presets: [
- [require.resolve('@babel/preset-typescript'), { allowNamespaces: true }],
require.resolve('@babel/preset-react'),
+
+ [
+ require.resolve('@babel/preset-typescript'),
+ {
+ allowNamespaces: true,
+ allowDeclareFields: true,
+ },
+ ],
],
- plugins,
};
diff --git a/packages/kbn-optimizer/src/babel_runtime_helpers/find_babel_runtime_helpers_in_entry_bundles.ts b/packages/kbn-optimizer/src/babel_runtime_helpers/find_babel_runtime_helpers_in_entry_bundles.ts
index beff36023343d..f00905f3f4920 100644
--- a/packages/kbn-optimizer/src/babel_runtime_helpers/find_babel_runtime_helpers_in_entry_bundles.ts
+++ b/packages/kbn-optimizer/src/babel_runtime_helpers/find_babel_runtime_helpers_in_entry_bundles.ts
@@ -35,14 +35,14 @@ export async function runFindBabelHelpersInEntryBundlesCli() {
}
for (const { userRequest } of module.reasons) {
- if (userRequest.startsWith('@babel/runtime/')) {
+ if (userRequest.startsWith('@babel/runtime')) {
imports.add(userRequest);
}
}
}
}
- log.success('found', imports.size, '@babel/register imports in entry bundles');
+ log.success('found', imports.size, '@babel/runtime* imports in entry bundles');
log.write(
Array.from(imports, (i) => `'${i}',`)
.sort()
diff --git a/packages/kbn-optimizer/src/worker/emit_stats_plugin.ts b/packages/kbn-optimizer/src/worker/emit_stats_plugin.ts
index c964219e1fed6..5cb60344037fc 100644
--- a/packages/kbn-optimizer/src/worker/emit_stats_plugin.ts
+++ b/packages/kbn-optimizer/src/worker/emit_stats_plugin.ts
@@ -26,7 +26,7 @@ export class EmitStatsPlugin {
(stats) => {
Fs.writeFileSync(
Path.resolve(this.bundle.outputDir, 'stats.json'),
- JSON.stringify(stats.toJson())
+ JSON.stringify(stats.toJson(), null, 2)
);
}
);
diff --git a/packages/kbn-storybook/src/webpack.config.ts b/packages/kbn-storybook/src/webpack.config.ts
index 27e887eda65ce..53f9c82b86815 100644
--- a/packages/kbn-storybook/src/webpack.config.ts
+++ b/packages/kbn-storybook/src/webpack.config.ts
@@ -9,11 +9,13 @@
import { externals } from '@kbn/ui-shared-deps-src';
import { stringifyRequest } from 'loader-utils';
import { resolve } from 'path';
-import { Configuration, Stats } from 'webpack';
+import webpack, { Configuration, Stats } from 'webpack';
import webpackMerge from 'webpack-merge';
import { REPO_ROOT } from './lib/constants';
import { IgnoreNotFoundExportPlugin } from './ignore_not_found_export_plugin';
+type Preset = string | [string, Record] | Record;
+
const stats = {
...Stats.presetToOptions('minimal'),
colors: true,
@@ -22,6 +24,46 @@ const stats = {
moduleTrace: true,
};
+function isProgressPlugin(plugin: any) {
+ return 'handler' in plugin && plugin.showActiveModules && plugin.showModules;
+}
+
+function isHtmlPlugin(plugin: any): plugin is { options: { template: string } } {
+ return !!(typeof plugin.options?.template === 'string');
+}
+
+function isBabelLoaderRule(rule: webpack.RuleSetRule): rule is webpack.RuleSetRule & {
+ use: webpack.RuleSetLoader[];
+} {
+ return !!(
+ rule.use &&
+ Array.isArray(rule.use) &&
+ rule.use.some(
+ (l) =>
+ typeof l === 'object' && typeof l.loader === 'string' && l.loader.includes('babel-loader')
+ )
+ );
+}
+
+function getPresetPath(preset: Preset) {
+ if (typeof preset === 'string') return preset;
+ if (Array.isArray(preset)) return preset[0];
+ return undefined;
+}
+
+function getTsPreset(preset: Preset) {
+ if (getPresetPath(preset)?.includes('preset-typescript')) {
+ if (typeof preset === 'string') return [preset, {}];
+ if (Array.isArray(preset)) return preset;
+
+ throw new Error('unsupported preset-typescript format');
+ }
+}
+
+function isDesiredPreset(preset: Preset) {
+ return !getPresetPath(preset)?.includes('preset-flow');
+}
+
// Extend the Storybook Webpack config with some customizations
/* eslint-disable import/no-default-export */
export default function ({ config: storybookConfig }: { config: Configuration }) {
@@ -83,21 +125,72 @@ export default function ({ config: storybookConfig }: { config: Configuration })
stats,
};
- // Disable the progress plugin
- const progressPlugin: any = (storybookConfig.plugins || []).find((plugin: any) => {
- return 'handler' in plugin && plugin.showActiveModules && plugin.showModules;
- });
- progressPlugin.handler = () => {};
-
- // This is the hacky part. We find something that looks like the
- // HtmlWebpackPlugin and mutate its `options.template` to point at our
- // revised template.
- const htmlWebpackPlugin: any = (storybookConfig.plugins || []).find((plugin: any) => {
- return plugin.options && typeof plugin.options.template === 'string';
- });
- if (htmlWebpackPlugin) {
- htmlWebpackPlugin.options.template = require.resolve('../templates/index.ejs');
+ const updatedModuleRules = [];
+ // clone and modify the module.rules config provided by storybook so that the default babel plugins run after the typescript preset
+ for (const originalRule of storybookConfig.module?.rules ?? []) {
+ const rule = { ...originalRule };
+ updatedModuleRules.push(rule);
+
+ if (isBabelLoaderRule(rule)) {
+ rule.use = [...rule.use];
+ const loader = (rule.use[0] = { ...rule.use[0] });
+ const options = (loader.options = { ...(loader.options as Record) });
+
+ // capture the plugins defined at the root level
+ const plugins: string[] = options.plugins;
+ options.plugins = [];
+
+ // move the plugins to the top of the preset array so they will run after the typescript preset
+ options.presets = [
+ {
+ plugins,
+ },
+ ...(options.presets as Preset[]).filter(isDesiredPreset).map((preset) => {
+ const tsPreset = getTsPreset(preset);
+ if (!tsPreset) {
+ return preset;
+ }
+
+ return [
+ tsPreset[0],
+ {
+ ...tsPreset[1],
+ allowNamespaces: true,
+ allowDeclareFields: true,
+ },
+ ];
+ }),
+ ];
+ }
}
- return webpackMerge(storybookConfig, config);
+ // copy and modify the webpack plugins added by storybook
+ const filteredStorybookPlugins = [];
+ for (const plugin of storybookConfig.plugins ?? []) {
+ // Remove the progress plugin
+ if (isProgressPlugin(plugin)) {
+ continue;
+ }
+
+ // This is the hacky part. We find something that looks like the
+ // HtmlWebpackPlugin and mutate its `options.template` to point at our
+ // revised template.
+ if (isHtmlPlugin(plugin)) {
+ plugin.options.template = require.resolve('../templates/index.ejs');
+ }
+
+ filteredStorybookPlugins.push(plugin);
+ }
+
+ return webpackMerge(
+ {
+ ...storybookConfig,
+ plugins: filteredStorybookPlugins,
+ module: {
+ ...storybookConfig.module,
+ rules: updatedModuleRules,
+ },
+ },
+ config
+ );
}
diff --git a/src/plugins/console/public/services/history.ts b/src/plugins/console/public/services/history.ts
index ee1e97ceb386e..972e5283274de 100644
--- a/src/plugins/console/public/services/history.ts
+++ b/src/plugins/console/public/services/history.ts
@@ -14,9 +14,11 @@ const MAX_NUMBER_OF_HISTORY_ITEMS = 100;
export const isQuotaExceededError = (e: Error): boolean => e.name === 'QuotaExceededError';
export class History {
- constructor(private readonly storage: Storage) {}
+ private changeEmitter: BehaviorSubject;
- private changeEmitter = new BehaviorSubject(this.getHistory() || []);
+ constructor(private readonly storage: Storage) {
+ this.changeEmitter = new BehaviorSubject(this.getHistory() || []);
+ }
getHistoryKeys() {
return this.storage
diff --git a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx
index 611a426dd4d71..1e19e495585fe 100644
--- a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx
+++ b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx
@@ -32,7 +32,7 @@ interface State {
export class DashboardViewport extends React.Component {
static contextType = context;
- public readonly context!: DashboardReactContextValue;
+ public declare readonly context: DashboardReactContextValue;
private controlsRoot: React.RefObject;
diff --git a/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx b/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx
index 007c3e306372e..1601ea481cf2d 100644
--- a/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx
+++ b/x-pack/plugins/security/public/management/roles/roles_management_app.test.tsx
@@ -104,7 +104,7 @@ describe('rolesManagementApp', () => {
expect(docTitle.reset).not.toHaveBeenCalled();
expect(container).toMatchInlineSnapshot(`
- Role Edit Page: {"action":"edit","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"fieldCache":{}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit","search":"","hash":""}}}
+ Role Edit Page: {"action":"edit","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"fieldCache":{},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit","search":"","hash":""}}}
`);
@@ -129,7 +129,7 @@ describe('rolesManagementApp', () => {
expect(docTitle.reset).not.toHaveBeenCalled();
expect(container).toMatchInlineSnapshot(`
- Role Edit Page: {"action":"edit","roleName":"role@name","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"fieldCache":{}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/role@name","search":"","hash":""}}}
+ Role Edit Page: {"action":"edit","roleName":"role@name","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"fieldCache":{},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/edit/role@name","search":"","hash":""}}}
`);
@@ -154,7 +154,7 @@ describe('rolesManagementApp', () => {
expect(docTitle.reset).not.toHaveBeenCalled();
expect(container).toMatchInlineSnapshot(`
- Role Edit Page: {"action":"clone","roleName":"someRoleName","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"fieldCache":{}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/clone/someRoleName","search":"","hash":""}}}
+ Role Edit Page: {"action":"clone","roleName":"someRoleName","rolesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"userAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"indicesAPIClient":{"fieldCache":{},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"privilegesAPIClient":{"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}}},"http":{"basePath":{"basePath":"","serverBasePath":""},"anonymousPaths":{},"externalUrl":{}},"notifications":{"toasts":{}},"fatalErrors":{},"license":{"features$":{"_isScalar":false}},"docLinks":{},"uiCapabilities":{"catalogue":{},"management":{},"navLinks":{}},"history":{"action":"PUSH","length":1,"location":{"pathname":"/clone/someRoleName","search":"","hash":""}}}
`);
From 57ae8db66a53a87c976e67d82a297baf3857f1c1 Mon Sep 17 00:00:00 2001
From: Ryland Herrick
Date: Mon, 29 Nov 2021 12:39:55 -0600
Subject: [PATCH 007/236] [RAC,Security Solution]Update alerts mappings to ECS
1.12 (#118812)
* Update output directory for generative script
These files were moved in #98935 but the script has become out of date.
* Update ECS fieldmap with ECS 1.12
This fieldmap was missing fields from ECS 1.11+. Notable ommissions were
the threat.indicator and threat.enrichments fieldsets.
* Remove non-additive mappings changes
These are incompatible with the current alerts framework.
* Add only necessary threat fields for CTI features
This could probably be pared down further, as most of these fields are
not critical for CTI features. Additionally, these additions now exceed
the limit of 1000 fields and is causing an error in the ruleRegistry
bootstrapping.
* Remove file.pe threat fields
* Remove geo threat indicator fields
* Remove all threat.indicator mappings
These are not relevant for alerts, which will only have enrichments.
* increments index mappings total fields limit to 1200
Co-authored-by: Ece Ozalp
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../common/assets/field_maps/ecs_field_map.ts | 420 ++++++++++++++++++
.../scripts/generate_ecs_fieldmap/index.js | 2 +-
.../resource_installer.ts | 2 +-
3 files changed, 422 insertions(+), 2 deletions(-)
diff --git a/x-pack/plugins/rule_registry/common/assets/field_maps/ecs_field_map.ts b/x-pack/plugins/rule_registry/common/assets/field_maps/ecs_field_map.ts
index 859070bd498e3..1ea85e5a5434e 100644
--- a/x-pack/plugins/rule_registry/common/assets/field_maps/ecs_field_map.ts
+++ b/x-pack/plugins/rule_registry/common/assets/field_maps/ecs_field_map.ts
@@ -2550,6 +2550,426 @@ export const ecsFieldMap = {
array: false,
required: false,
},
+ 'threat.enrichments': {
+ type: 'nested',
+ array: true,
+ required: false,
+ },
+ 'threat.enrichments.indicator': {
+ type: 'object',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.as.number': {
+ type: 'long',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.as.organization.name': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.confidence': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.description': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.email.address': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.accessed': {
+ type: 'date',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.attributes': {
+ type: 'keyword',
+ array: true,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.code_signature.digest_algorithm': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.code_signature.exists': {
+ type: 'boolean',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.code_signature.signing_id': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.code_signature.status': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.code_signature.subject_name': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.code_signature.team_id': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.code_signature.timestamp': {
+ type: 'date',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.code_signature.trusted': {
+ type: 'boolean',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.code_signature.valid': {
+ type: 'boolean',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.created': {
+ type: 'date',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.ctime': {
+ type: 'date',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.device': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.directory': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.drive_letter': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.extension': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.fork_name': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.gid': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.group': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.hash.md5': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.hash.sha1': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.hash.sha256': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.hash.sha512': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.hash.ssdeep': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.inode': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.mime_type': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.mode': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.mtime': {
+ type: 'date',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.name': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.owner': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.path': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.size': {
+ type: 'long',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.target_path': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.type': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.file.uid': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.first_seen': {
+ type: 'date',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.ip': {
+ type: 'ip',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.last_seen': {
+ type: 'date',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.marking.tlp': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.modified_at': {
+ type: 'date',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.port': {
+ type: 'long',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.provider': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.reference': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.registry.data.bytes': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.registry.data.strings': {
+ type: 'wildcard',
+ array: true,
+ required: false,
+ },
+ 'threat.enrichments.indicator.registry.data.type': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.registry.hive': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.registry.key': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.registry.path': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.registry.value': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.scanner_stats': {
+ type: 'long',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.sightings': {
+ type: 'long',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.type': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.domain': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.extension': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.fragment': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.full': {
+ type: 'wildcard',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.original': {
+ type: 'wildcard',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.password': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.path': {
+ type: 'wildcard',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.port': {
+ type: 'long',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.query': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.registered_domain': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.scheme': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.subdomain': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.top_level_domain': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.indicator.url.username': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.matched.atomic': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.matched.field': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.matched.id': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.matched.index': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.enrichments.matched.type': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.group.alias': {
+ type: 'keyword',
+ array: true,
+ required: false,
+ },
+ 'threat.group.id': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.group.name': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
+ 'threat.group.reference': {
+ type: 'keyword',
+ array: false,
+ required: false,
+ },
'threat.tactic.id': {
type: 'keyword',
array: true,
diff --git a/x-pack/plugins/rule_registry/scripts/generate_ecs_fieldmap/index.js b/x-pack/plugins/rule_registry/scripts/generate_ecs_fieldmap/index.js
index 6b10ca5f837d5..bbcf651bd6d69 100644
--- a/x-pack/plugins/rule_registry/scripts/generate_ecs_fieldmap/index.js
+++ b/x-pack/plugins/rule_registry/scripts/generate_ecs_fieldmap/index.js
@@ -19,7 +19,7 @@ const exec = util.promisify(execCb);
const ecsDir = path.resolve(__dirname, '../../../../../../ecs');
const ecsYamlFilename = path.join(ecsDir, 'generated/ecs/ecs_flat.yml');
-const outputDir = path.join(__dirname, '../../common/field_map');
+const outputDir = path.join(__dirname, '../../common/assets/field_maps');
const outputFieldMapFilename = path.join(outputDir, 'ecs_field_map.ts');
diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts
index bfdec28a50987..bbfa17c5694f1 100644
--- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts
+++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts
@@ -316,7 +316,7 @@ export class ResourceInstaller {
// @ts-expect-error
rollover_alias: primaryNamespacedAlias,
},
- 'index.mapping.total_fields.limit': 1100,
+ 'index.mapping.total_fields.limit': 1200,
},
mappings: {
dynamic: false,
From 2a0312cd48704c2bf76fa0ca3289211e7d57f263 Mon Sep 17 00:00:00 2001
From: Ersin Erdal <92688503+ersin-erdal@users.noreply.github.com>
Date: Mon, 29 Nov 2021 19:44:17 +0100
Subject: [PATCH 008/236] 119061 refactor observability (#119211)
* group containers and components, create index files
---
x-pack/plugins/observability/public/index.ts | 4 +-
.../{ => components}/alerts_disclaimer.tsx | 0
.../alerts_flyout/alerts_flyout.stories.tsx | 10 ++---
.../alerts_flyout/alerts_flyout.test.tsx | 10 ++---
.../alerts_flyout/alerts_flyout.tsx} | 14 +++----
.../alerts_flyout}/example_data.ts | 0
.../alerts/components/alerts_flyout/index.ts | 8 ++++
.../{ => components}/alerts_search_bar.tsx | 4 +-
.../{ => components}/alerts_status_filter.tsx | 4 +-
.../{ => components}/default_cell_actions.tsx | 6 +--
.../{ => components}/filter_for_value.tsx | 0
.../public/pages/alerts/components/index.ts | 17 +++++++++
.../alerts/{ => components}/parse_alert.ts | 8 ++--
.../components/render_cell_value/index.ts | 8 ++++
.../render_cell_value.test.tsx | 8 ++--
.../render_cell_value}/render_cell_value.tsx | 16 ++++----
.../alerts/components/severity_badge/index.ts | 8 ++++
.../severity_badge.stories.tsx | 0
.../severity_badge}/severity_badge.tsx | 0
.../workflow_status_filter/index.ts | 8 ++++
.../workflow_status_filter.stories.tsx | 2 +-
.../workflow_status_filter.test.tsx | 2 +-
.../workflow_status_filter.tsx | 2 +-
.../alerts_page/alerts_page.tsx} | 38 +++++++++----------
.../alerts/containers/alerts_page/index.ts | 9 +++++
.../{ => containers/alerts_page}/styles.scss | 0
.../alerts_table_t_grid.tsx | 28 +++++++-------
.../containers/alerts_table_t_grid/index.ts | 8 ++++
.../public/pages/alerts/containers/index.ts | 10 +++++
.../state_container/index.tsx | 0
.../state_container/state_container.tsx | 4 +-
.../use_alerts_page_state_container.tsx | 6 +--
.../public/pages/alerts/index.ts | 9 +++++
.../public/pages/cases/helpers.ts | 4 +-
.../observability/public/routes/index.tsx | 2 +-
35 files changed, 171 insertions(+), 86 deletions(-)
rename x-pack/plugins/observability/public/pages/alerts/{ => components}/alerts_disclaimer.tsx (100%)
rename x-pack/plugins/observability/public/pages/alerts/{ => components}/alerts_flyout/alerts_flyout.stories.tsx (85%)
rename x-pack/plugins/observability/public/pages/alerts/{ => components}/alerts_flyout/alerts_flyout.test.tsx (91%)
rename x-pack/plugins/observability/public/pages/alerts/{alerts_flyout/index.tsx => components/alerts_flyout/alerts_flyout.tsx} (89%)
rename x-pack/plugins/observability/public/pages/alerts/{ => components/alerts_flyout}/example_data.ts (100%)
create mode 100644 x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/index.ts
rename x-pack/plugins/observability/public/pages/alerts/{ => components}/alerts_search_bar.tsx (92%)
rename x-pack/plugins/observability/public/pages/alerts/{ => components}/alerts_status_filter.tsx (94%)
rename x-pack/plugins/observability/public/pages/alerts/{ => components}/default_cell_actions.tsx (85%)
rename x-pack/plugins/observability/public/pages/alerts/{ => components}/filter_for_value.tsx (100%)
create mode 100644 x-pack/plugins/observability/public/pages/alerts/components/index.ts
rename x-pack/plugins/observability/public/pages/alerts/{ => components}/parse_alert.ts (78%)
create mode 100644 x-pack/plugins/observability/public/pages/alerts/components/render_cell_value/index.ts
rename x-pack/plugins/observability/public/pages/alerts/{ => components/render_cell_value}/render_cell_value.test.tsx (87%)
rename x-pack/plugins/observability/public/pages/alerts/{ => components/render_cell_value}/render_cell_value.tsx (86%)
create mode 100644 x-pack/plugins/observability/public/pages/alerts/components/severity_badge/index.ts
rename x-pack/plugins/observability/public/pages/alerts/{ => components/severity_badge}/severity_badge.stories.tsx (100%)
rename x-pack/plugins/observability/public/pages/alerts/{ => components/severity_badge}/severity_badge.tsx (100%)
create mode 100644 x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/index.ts
rename x-pack/plugins/observability/public/pages/alerts/{ => components/workflow_status_filter}/workflow_status_filter.stories.tsx (92%)
rename x-pack/plugins/observability/public/pages/alerts/{ => components/workflow_status_filter}/workflow_status_filter.test.tsx (95%)
rename x-pack/plugins/observability/public/pages/alerts/{ => components/workflow_status_filter}/workflow_status_filter.tsx (95%)
rename x-pack/plugins/observability/public/pages/alerts/{index.tsx => containers/alerts_page/alerts_page.tsx} (87%)
create mode 100644 x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/index.ts
rename x-pack/plugins/observability/public/pages/alerts/{ => containers/alerts_page}/styles.scss (100%)
rename x-pack/plugins/observability/public/pages/alerts/{ => containers/alerts_table_t_grid}/alerts_table_t_grid.tsx (94%)
create mode 100644 x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/index.ts
create mode 100644 x-pack/plugins/observability/public/pages/alerts/containers/index.ts
rename x-pack/plugins/observability/public/pages/alerts/{ => containers}/state_container/index.tsx (100%)
rename x-pack/plugins/observability/public/pages/alerts/{ => containers}/state_container/state_container.tsx (92%)
rename x-pack/plugins/observability/public/pages/alerts/{ => containers}/state_container/use_alerts_page_state_container.tsx (92%)
create mode 100644 x-pack/plugins/observability/public/pages/alerts/index.ts
diff --git a/x-pack/plugins/observability/public/index.ts b/x-pack/plugins/observability/public/index.ts
index 7646ac9bec9bb..2383044bc14c2 100644
--- a/x-pack/plugins/observability/public/index.ts
+++ b/x-pack/plugins/observability/public/index.ts
@@ -64,7 +64,9 @@ export {
METRIC_TYPE,
} from './hooks/use_track_metric';
-export const LazyAlertsFlyout = lazy(() => import('./pages/alerts/alerts_flyout'));
+export const LazyAlertsFlyout = lazy(
+ () => import('./pages/alerts/components/alerts_flyout/alerts_flyout')
+);
export { useFetcher, FETCH_STATUS } from './hooks/use_fetcher';
export { useEsSearch, createEsParams } from './hooks/use_es_search';
diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_disclaimer.tsx b/x-pack/plugins/observability/public/pages/alerts/components/alerts_disclaimer.tsx
similarity index 100%
rename from x-pack/plugins/observability/public/pages/alerts/alerts_disclaimer.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/alerts_disclaimer.tsx
diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_flyout/alerts_flyout.stories.tsx b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.stories.tsx
similarity index 85%
rename from x-pack/plugins/observability/public/pages/alerts/alerts_flyout/alerts_flyout.stories.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.stories.tsx
index 64d495dbbc798..36b1fc2f2b6e2 100644
--- a/x-pack/plugins/observability/public/pages/alerts/alerts_flyout/alerts_flyout.stories.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.stories.tsx
@@ -7,11 +7,11 @@
import { ALERT_UUID } from '@kbn/rule-data-utils/technical_field_names';
import React, { ComponentType } from 'react';
-import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public';
-import { PluginContext, PluginContextValue } from '../../../context/plugin_context';
-import { createObservabilityRuleTypeRegistryMock } from '../../../rules/observability_rule_type_registry_mock';
-import { apmAlertResponseExample } from '../example_data';
-import { AlertsFlyout } from './';
+import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public';
+import { PluginContext, PluginContextValue } from '../../../../context/plugin_context';
+import { createObservabilityRuleTypeRegistryMock } from '../../../../rules/observability_rule_type_registry_mock';
+import { apmAlertResponseExample } from './example_data';
+import { AlertsFlyout } from '..';
interface Args {
alerts: Array>;
diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_flyout/alerts_flyout.test.tsx b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.test.tsx
similarity index 91%
rename from x-pack/plugins/observability/public/pages/alerts/alerts_flyout/alerts_flyout.test.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.test.tsx
index 4fdc8d245799a..13fb5d805fb81 100644
--- a/x-pack/plugins/observability/public/pages/alerts/alerts_flyout/alerts_flyout.test.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.test.tsx
@@ -6,11 +6,11 @@
*/
import React from 'react';
-import * as useUiSettingHook from '../../../../../../../src/plugins/kibana_react/public/ui_settings/use_ui_setting';
-import { createObservabilityRuleTypeRegistryMock } from '../../../rules/observability_rule_type_registry_mock';
-import { render } from '../../../utils/test_helper';
-import type { TopAlert } from '../';
-import { AlertsFlyout } from './';
+import * as useUiSettingHook from '../../../../../../../../src/plugins/kibana_react/public/ui_settings/use_ui_setting';
+import { createObservabilityRuleTypeRegistryMock } from '../../../../rules/observability_rule_type_registry_mock';
+import { render } from '../../../../utils/test_helper';
+import type { TopAlert } from '../../containers/alerts_page';
+import { AlertsFlyout } from '..';
describe('AlertsFlyout', () => {
jest
diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_flyout/index.tsx b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.tsx
similarity index 89%
rename from x-pack/plugins/observability/public/pages/alerts/alerts_flyout/index.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.tsx
index c5cad5f3b1c8c..ced4896c5f31d 100644
--- a/x-pack/plugins/observability/public/pages/alerts/alerts_flyout/index.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.tsx
@@ -35,14 +35,14 @@ import {
} from '@kbn/rule-data-utils/alerts_as_data_status';
import moment from 'moment-timezone';
import React, { useMemo } from 'react';
-import type { TopAlert } from '../';
-import { useKibana, useUiSetting } from '../../../../../../../src/plugins/kibana_react/public';
-import { asDuration } from '../../../../common/utils/formatters';
-import type { ObservabilityRuleTypeRegistry } from '../../../rules/create_observability_rule_type_registry';
+import type { TopAlert } from '../../containers';
+import { useKibana, useUiSetting } from '../../../../../../../../src/plugins/kibana_react/public';
+import { asDuration } from '../../../../../common/utils/formatters';
+import type { ObservabilityRuleTypeRegistry } from '../../../../rules/create_observability_rule_type_registry';
import { parseAlert } from '../parse_alert';
-import { AlertStatusIndicator } from '../../../components/shared/alert_status_indicator';
-import { ExperimentalBadge } from '../../../components/shared/experimental_badge';
-import { translations, paths } from '../../../config';
+import { AlertStatusIndicator } from '../../../../components/shared/alert_status_indicator';
+import { ExperimentalBadge } from '../../../../components/shared/experimental_badge';
+import { translations, paths } from '../../../../config';
type AlertsFlyoutProps = {
alert?: TopAlert;
diff --git a/x-pack/plugins/observability/public/pages/alerts/example_data.ts b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/example_data.ts
similarity index 100%
rename from x-pack/plugins/observability/public/pages/alerts/example_data.ts
rename to x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/example_data.ts
diff --git a/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/index.ts b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/index.ts
new file mode 100644
index 0000000000000..4153ab6e5b596
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { AlertsFlyout } from './alerts_flyout';
diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_search_bar.tsx b/x-pack/plugins/observability/public/pages/alerts/components/alerts_search_bar.tsx
similarity index 92%
rename from x-pack/plugins/observability/public/pages/alerts/alerts_search_bar.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/alerts_search_bar.tsx
index 926f03acf01d8..14d47d1e7e9d3 100644
--- a/x-pack/plugins/observability/public/pages/alerts/alerts_search_bar.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/alerts_search_bar.tsx
@@ -8,8 +8,8 @@
import { IndexPatternBase } from '@kbn/es-query';
import { i18n } from '@kbn/i18n';
import React, { useMemo, useState } from 'react';
-import { SearchBar, TimeHistory } from '../../../../../../src/plugins/data/public';
-import { Storage } from '../../../../../../src/plugins/kibana_utils/public';
+import { SearchBar, TimeHistory } from '../../../../../../../src/plugins/data/public';
+import { Storage } from '../../../../../../../src/plugins/kibana_utils/public';
export function AlertsSearchBar({
dynamicIndexPatterns,
diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_status_filter.tsx b/x-pack/plugins/observability/public/pages/alerts/components/alerts_status_filter.tsx
similarity index 94%
rename from x-pack/plugins/observability/public/pages/alerts/alerts_status_filter.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/alerts_status_filter.tsx
index 38c753bbebf3b..d717e916de2c6 100644
--- a/x-pack/plugins/observability/public/pages/alerts/alerts_status_filter.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/alerts_status_filter.tsx
@@ -13,8 +13,8 @@ import {
ALERT_STATUS_RECOVERED,
} from '@kbn/rule-data-utils/alerts_as_data_status';
import { ALERT_STATUS } from '@kbn/rule-data-utils/technical_field_names';
-import { AlertStatusFilterButton } from '../../../common/typings';
-import { AlertStatusFilter } from '../../../common/typings';
+import { AlertStatusFilterButton } from '../../../../common/typings';
+import { AlertStatusFilter } from '../../../../common/typings';
export interface AlertStatusFilterProps {
status: AlertStatusFilterButton;
diff --git a/x-pack/plugins/observability/public/pages/alerts/default_cell_actions.tsx b/x-pack/plugins/observability/public/pages/alerts/components/default_cell_actions.tsx
similarity index 85%
rename from x-pack/plugins/observability/public/pages/alerts/default_cell_actions.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/default_cell_actions.tsx
index 3adfb0a1d9c89..5126647161fa5 100644
--- a/x-pack/plugins/observability/public/pages/alerts/default_cell_actions.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/default_cell_actions.tsx
@@ -9,9 +9,9 @@ import React from 'react';
import { i18n } from '@kbn/i18n';
import { getMappedNonEcsValue } from './render_cell_value';
import FilterForValueButton from './filter_for_value';
-import { TimelineNonEcsData } from '../../../../timelines/common/search_strategy';
-import { TGridCellAction } from '../../../../timelines/common/types/timeline';
-import { getPageRowIndex } from '../../../../timelines/public';
+import { TimelineNonEcsData } from '../../../../../timelines/common/search_strategy';
+import { TGridCellAction } from '../../../../../timelines/common/types/timeline';
+import { getPageRowIndex } from '../../../../../timelines/public';
export const FILTER_FOR_VALUE = i18n.translate('xpack.observability.hoverActions.filterForValue', {
defaultMessage: 'Filter for value',
diff --git a/x-pack/plugins/observability/public/pages/alerts/filter_for_value.tsx b/x-pack/plugins/observability/public/pages/alerts/components/filter_for_value.tsx
similarity index 100%
rename from x-pack/plugins/observability/public/pages/alerts/filter_for_value.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/filter_for_value.tsx
diff --git a/x-pack/plugins/observability/public/pages/alerts/components/index.ts b/x-pack/plugins/observability/public/pages/alerts/components/index.ts
new file mode 100644
index 0000000000000..57ad311f65d1c
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/alerts/components/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './alerts_flyout';
+export * from './render_cell_value';
+export * from './severity_badge';
+export * from './workflow_status_filter';
+export * from './alerts_search_bar';
+export * from './alerts_disclaimer';
+export * from './default_cell_actions';
+export * from './filter_for_value';
+export * from './parse_alert';
+export * from './alerts_status_filter';
diff --git a/x-pack/plugins/observability/public/pages/alerts/parse_alert.ts b/x-pack/plugins/observability/public/pages/alerts/components/parse_alert.ts
similarity index 78%
rename from x-pack/plugins/observability/public/pages/alerts/parse_alert.ts
rename to x-pack/plugins/observability/public/pages/alerts/components/parse_alert.ts
index 7b28803084067..680798811e9ab 100644
--- a/x-pack/plugins/observability/public/pages/alerts/parse_alert.ts
+++ b/x-pack/plugins/observability/public/pages/alerts/components/parse_alert.ts
@@ -12,10 +12,10 @@ import {
ALERT_RULE_NAME,
} from '@kbn/rule-data-utils/technical_field_names';
import { ALERT_STATUS_ACTIVE } from '@kbn/rule-data-utils/alerts_as_data_status';
-import type { TopAlert } from '.';
-import { parseTechnicalFields } from '../../../../rule_registry/common/parse_technical_fields';
-import { asDuration, asPercent } from '../../../common/utils/formatters';
-import { ObservabilityRuleTypeRegistry } from '../../rules/create_observability_rule_type_registry';
+import type { TopAlert } from '../';
+import { parseTechnicalFields } from '../../../../../rule_registry/common/parse_technical_fields';
+import { asDuration, asPercent } from '../../../../common/utils/formatters';
+import { ObservabilityRuleTypeRegistry } from '../../../rules/create_observability_rule_type_registry';
export const parseAlert =
(observabilityRuleTypeRegistry: ObservabilityRuleTypeRegistry) =>
diff --git a/x-pack/plugins/observability/public/pages/alerts/components/render_cell_value/index.ts b/x-pack/plugins/observability/public/pages/alerts/components/render_cell_value/index.ts
new file mode 100644
index 0000000000000..b6df77f075888
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/alerts/components/render_cell_value/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { getRenderCellValue, getMappedNonEcsValue } from './render_cell_value';
diff --git a/x-pack/plugins/observability/public/pages/alerts/render_cell_value.test.tsx b/x-pack/plugins/observability/public/pages/alerts/components/render_cell_value/render_cell_value.test.tsx
similarity index 87%
rename from x-pack/plugins/observability/public/pages/alerts/render_cell_value.test.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/render_cell_value/render_cell_value.test.tsx
index 79a27faa96c69..25de2e36b08c3 100644
--- a/x-pack/plugins/observability/public/pages/alerts/render_cell_value.test.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/render_cell_value/render_cell_value.test.tsx
@@ -10,10 +10,10 @@ import {
ALERT_STATUS_RECOVERED,
} from '@kbn/rule-data-utils/alerts_as_data_status';
import { ALERT_STATUS } from '@kbn/rule-data-utils/technical_field_names';
-import type { CellValueElementProps } from '../../../../timelines/common';
-import { createObservabilityRuleTypeRegistryMock } from '../../rules/observability_rule_type_registry_mock';
-import * as PluginHook from '../../hooks/use_plugin_context';
-import { render } from '../../utils/test_helper';
+import type { CellValueElementProps } from '../../../../../../timelines/common';
+import { createObservabilityRuleTypeRegistryMock } from '../../../../rules/observability_rule_type_registry_mock';
+import * as PluginHook from '../../../../hooks/use_plugin_context';
+import { render } from '../../../../utils/test_helper';
import { getRenderCellValue } from './render_cell_value';
interface AlertsTableRow {
diff --git a/x-pack/plugins/observability/public/pages/alerts/render_cell_value.tsx b/x-pack/plugins/observability/public/pages/alerts/components/render_cell_value/render_cell_value.tsx
similarity index 86%
rename from x-pack/plugins/observability/public/pages/alerts/render_cell_value.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/render_cell_value/render_cell_value.tsx
index 80ccd4a69b281..d9fa6c6e2221b 100644
--- a/x-pack/plugins/observability/public/pages/alerts/render_cell_value.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/render_cell_value/render_cell_value.tsx
@@ -17,14 +17,14 @@ import {
ALERT_STATUS_ACTIVE,
ALERT_STATUS_RECOVERED,
} from '@kbn/rule-data-utils/alerts_as_data_status';
-import type { CellValueElementProps, TimelineNonEcsData } from '../../../../timelines/common';
-import { AlertStatusIndicator } from '../../components/shared/alert_status_indicator';
-import { TimestampTooltip } from '../../components/shared/timestamp_tooltip';
-import { asDuration } from '../../../common/utils/formatters';
-import { SeverityBadge } from './severity_badge';
-import { TopAlert } from '.';
-import { parseAlert } from './parse_alert';
-import { usePluginContext } from '../../hooks/use_plugin_context';
+import type { CellValueElementProps, TimelineNonEcsData } from '../../../../../../timelines/common';
+import { AlertStatusIndicator } from '../../../../components/shared/alert_status_indicator';
+import { TimestampTooltip } from '../../../../components/shared/timestamp_tooltip';
+import { asDuration } from '../../../../../common/utils/formatters';
+import { SeverityBadge } from '../severity_badge';
+import { TopAlert } from '../../';
+import { parseAlert } from '../parse_alert';
+import { usePluginContext } from '../../../../hooks/use_plugin_context';
export const getMappedNonEcsValue = ({
data,
diff --git a/x-pack/plugins/observability/public/pages/alerts/components/severity_badge/index.ts b/x-pack/plugins/observability/public/pages/alerts/components/severity_badge/index.ts
new file mode 100644
index 0000000000000..7974156327085
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/alerts/components/severity_badge/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { SeverityBadge } from './severity_badge';
diff --git a/x-pack/plugins/observability/public/pages/alerts/severity_badge.stories.tsx b/x-pack/plugins/observability/public/pages/alerts/components/severity_badge/severity_badge.stories.tsx
similarity index 100%
rename from x-pack/plugins/observability/public/pages/alerts/severity_badge.stories.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/severity_badge/severity_badge.stories.tsx
diff --git a/x-pack/plugins/observability/public/pages/alerts/severity_badge.tsx b/x-pack/plugins/observability/public/pages/alerts/components/severity_badge/severity_badge.tsx
similarity index 100%
rename from x-pack/plugins/observability/public/pages/alerts/severity_badge.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/severity_badge/severity_badge.tsx
diff --git a/x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/index.ts b/x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/index.ts
new file mode 100644
index 0000000000000..84badecd29dcd
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { WorkflowStatusFilter } from './workflow_status_filter';
diff --git a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.stories.tsx b/x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/workflow_status_filter.stories.tsx
similarity index 92%
rename from x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.stories.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/workflow_status_filter.stories.tsx
index e06b5d333a9a6..4dce3ee80b833 100644
--- a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.stories.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/workflow_status_filter.stories.tsx
@@ -6,7 +6,7 @@
*/
import React, { ComponentProps, useState } from 'react';
-import type { AlertWorkflowStatus } from '../../../common/typings';
+import type { AlertWorkflowStatus } from '../../../../../common/typings';
import { WorkflowStatusFilter } from './workflow_status_filter';
type Args = ComponentProps;
diff --git a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.test.tsx b/x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/workflow_status_filter.test.tsx
similarity index 95%
rename from x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.test.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/workflow_status_filter.test.tsx
index 29c5e88788a89..a9819a6619dc5 100644
--- a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.test.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/workflow_status_filter.test.tsx
@@ -8,7 +8,7 @@
import { render } from '@testing-library/react';
import { Simulate } from 'react-dom/test-utils';
import React from 'react';
-import type { AlertWorkflowStatus } from '../../../common/typings';
+import type { AlertWorkflowStatus } from '../../../../../common/typings';
import { WorkflowStatusFilter } from './workflow_status_filter';
describe('StatusFilter', () => {
diff --git a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx b/x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/workflow_status_filter.tsx
similarity index 95%
rename from x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx
rename to x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/workflow_status_filter.tsx
index d857b9d6bd650..86116fb969682 100644
--- a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/workflow_status_filter/workflow_status_filter.tsx
@@ -8,7 +8,7 @@
import { EuiButtonGroup, EuiButtonGroupOptionProps } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
-import type { AlertWorkflowStatus } from '../../../common/typings';
+import type { AlertWorkflowStatus } from '../../../../../common/typings';
export interface WorkflowStatusFilterProps {
status: AlertWorkflowStatus;
diff --git a/x-pack/plugins/observability/public/pages/alerts/index.tsx b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx
similarity index 87%
rename from x-pack/plugins/observability/public/pages/alerts/index.tsx
rename to x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx
index 2636463bcfd7a..b19a1dbe86fe1 100644
--- a/x-pack/plugins/observability/public/pages/alerts/index.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx
@@ -14,23 +14,25 @@ import useAsync from 'react-use/lib/useAsync';
import { AlertStatus } from '@kbn/rule-data-utils/alerts_as_data_status';
import { ALERT_STATUS } from '@kbn/rule-data-utils/technical_field_names';
-import { AlertStatusFilterButton } from '../../../common/typings';
-import { ParsedTechnicalFields } from '../../../../rule_registry/common/parse_technical_fields';
-import { ExperimentalBadge } from '../../components/shared/experimental_badge';
-import { useBreadcrumbs } from '../../hooks/use_breadcrumbs';
-import { useFetcher } from '../../hooks/use_fetcher';
-import { useHasData } from '../../hooks/use_has_data';
-import { usePluginContext } from '../../hooks/use_plugin_context';
-import { useTimefilterService } from '../../hooks/use_timefilter_service';
-import { callObservabilityApi } from '../../services/call_observability_api';
-import { getNoDataConfig } from '../../utils/no_data_config';
-import { LoadingObservability } from '../overview/loading_observability';
-import { AlertsSearchBar } from './alerts_search_bar';
-import { AlertsTableTGrid } from './alerts_table_t_grid';
-import { Provider, alertsPageStateContainer, useAlertsPageStateContainer } from './state_container';
+import { AlertStatusFilterButton } from '../../../../../common/typings';
+import { ParsedTechnicalFields } from '../../../../../../rule_registry/common/parse_technical_fields';
+import { ExperimentalBadge } from '../../../../components/shared/experimental_badge';
+import { useBreadcrumbs } from '../../../../hooks/use_breadcrumbs';
+import { useFetcher } from '../../../../hooks/use_fetcher';
+import { useHasData } from '../../../../hooks/use_has_data';
+import { usePluginContext } from '../../../../hooks/use_plugin_context';
+import { useTimefilterService } from '../../../../hooks/use_timefilter_service';
+import { callObservabilityApi } from '../../../../services/call_observability_api';
+import { getNoDataConfig } from '../../../../utils/no_data_config';
+import { LoadingObservability } from '../../../overview/loading_observability';
+import { AlertsTableTGrid } from '../alerts_table_t_grid';
+import {
+ Provider,
+ alertsPageStateContainer,
+ useAlertsPageStateContainer,
+} from '../state_container';
import './styles.scss';
-import { AlertsStatusFilter } from './alerts_status_filter';
-import { AlertsDisclaimer } from './alerts_disclaimer';
+import { AlertsStatusFilter, AlertsDisclaimer, AlertsSearchBar } from '../../components';
export interface TopAlert {
fields: ParsedTechnicalFields;
@@ -243,12 +245,10 @@ function AlertsPage() {
);
}
-function WrappedAlertsPage() {
+export function WrappedAlertsPage() {
return (
);
}
-
-export { WrappedAlertsPage as AlertsPage };
diff --git a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/index.ts b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/index.ts
new file mode 100644
index 0000000000000..e3509e04b2f2b
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { WrappedAlertsPage as AlertsPage } from './alerts_page';
+export type { TopAlert } from './alerts_page';
diff --git a/x-pack/plugins/observability/public/pages/alerts/styles.scss b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/styles.scss
similarity index 100%
rename from x-pack/plugins/observability/public/pages/alerts/styles.scss
rename to x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/styles.scss
diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/alerts_table_t_grid.tsx
similarity index 94%
rename from x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx
rename to x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/alerts_table_t_grid.tsx
index 4b64ae07ddf06..bf99bcedc16be 100644
--- a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/alerts_table_t_grid.tsx
@@ -33,33 +33,33 @@ import styled from 'styled-components';
import React, { Suspense, useMemo, useState, useCallback, useEffect } from 'react';
import usePrevious from 'react-use/lib/usePrevious';
import { pick } from 'lodash';
-import { getAlertsPermissions } from '../../hooks/use_alert_permission';
+import { getAlertsPermissions } from '../../../../hooks/use_alert_permission';
import type {
TimelinesUIStart,
TGridType,
TGridState,
TGridModel,
SortDirection,
-} from '../../../../timelines/public';
+} from '../../../../../../timelines/public';
-import type { TopAlert } from './';
-import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
+import type { TopAlert } from '../alerts_page/alerts_page';
+import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
import type {
ActionProps,
AlertWorkflowStatus,
ColumnHeaderOptions,
ControlColumnProps,
RowRenderer,
-} from '../../../../timelines/common';
-
-import { getRenderCellValue } from './render_cell_value';
-import { observabilityAppId, observabilityFeatureId } from '../../../common';
-import { useGetUserCasesPermissions } from '../../hooks/use_get_user_cases_permissions';
-import { usePluginContext } from '../../hooks/use_plugin_context';
-import { LazyAlertsFlyout } from '../..';
-import { parseAlert } from './parse_alert';
-import { CoreStart } from '../../../../../../src/core/public';
-import { translations, paths } from '../../config';
+} from '../../../../../../timelines/common';
+
+import { getRenderCellValue } from '../../components/render_cell_value';
+import { observabilityAppId, observabilityFeatureId } from '../../../../../common';
+import { useGetUserCasesPermissions } from '../../../../hooks/use_get_user_cases_permissions';
+import { usePluginContext } from '../../../../hooks/use_plugin_context';
+import { LazyAlertsFlyout } from '../../../..';
+import { parseAlert } from '../../components/parse_alert';
+import { CoreStart } from '../../../../../../../../src/core/public';
+import { translations, paths } from '../../../../config';
const ALERT_TABLE_STATE_STORAGE_KEY = 'xpack.observability.alert.tableState';
diff --git a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/index.ts b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/index.ts
new file mode 100644
index 0000000000000..7bbcc43230a44
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_table_t_grid/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { AlertsTableTGrid } from './alerts_table_t_grid';
diff --git a/x-pack/plugins/observability/public/pages/alerts/containers/index.ts b/x-pack/plugins/observability/public/pages/alerts/containers/index.ts
new file mode 100644
index 0000000000000..074f48f426640
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/alerts/containers/index.ts
@@ -0,0 +1,10 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './alerts_page';
+export * from './alerts_table_t_grid';
+export * from './state_container';
diff --git a/x-pack/plugins/observability/public/pages/alerts/state_container/index.tsx b/x-pack/plugins/observability/public/pages/alerts/containers/state_container/index.tsx
similarity index 100%
rename from x-pack/plugins/observability/public/pages/alerts/state_container/index.tsx
rename to x-pack/plugins/observability/public/pages/alerts/containers/state_container/index.tsx
diff --git a/x-pack/plugins/observability/public/pages/alerts/state_container/state_container.tsx b/x-pack/plugins/observability/public/pages/alerts/containers/state_container/state_container.tsx
similarity index 92%
rename from x-pack/plugins/observability/public/pages/alerts/state_container/state_container.tsx
rename to x-pack/plugins/observability/public/pages/alerts/containers/state_container/state_container.tsx
index 3e0a801fedbe2..d00109cc5d63f 100644
--- a/x-pack/plugins/observability/public/pages/alerts/state_container/state_container.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/containers/state_container/state_container.tsx
@@ -8,8 +8,8 @@
import {
createStateContainer,
createStateContainerReactHelpers,
-} from '../../../../../../../src/plugins/kibana_utils/public';
-import type { AlertWorkflowStatus } from '../../../../common/typings';
+} from '../../../../../../../../src/plugins/kibana_utils/public';
+import type { AlertWorkflowStatus } from '../../../../../common/typings';
interface AlertsPageContainerState {
rangeFrom: string;
diff --git a/x-pack/plugins/observability/public/pages/alerts/state_container/use_alerts_page_state_container.tsx b/x-pack/plugins/observability/public/pages/alerts/containers/state_container/use_alerts_page_state_container.tsx
similarity index 92%
rename from x-pack/plugins/observability/public/pages/alerts/state_container/use_alerts_page_state_container.tsx
rename to x-pack/plugins/observability/public/pages/alerts/containers/state_container/use_alerts_page_state_container.tsx
index dfa4afcd939cc..5e81286affba7 100644
--- a/x-pack/plugins/observability/public/pages/alerts/state_container/use_alerts_page_state_container.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/containers/state_container/use_alerts_page_state_container.tsx
@@ -8,14 +8,14 @@
import { useEffect } from 'react';
import { useHistory } from 'react-router-dom';
-import { TimefilterContract } from '../../../../../../../src/plugins/data/public';
+import { TimefilterContract } from '../../../../../../../../src/plugins/data/public';
import {
createKbnUrlStateStorage,
syncState,
IKbnUrlStateStorage,
useContainerSelector,
-} from '../../../../../../../src/plugins/kibana_utils/public';
-import { useTimefilterService } from '../../../hooks/use_timefilter_service';
+} from '../../../../../../../../src/plugins/kibana_utils/public';
+import { useTimefilterService } from '../../../../hooks/use_timefilter_service';
import {
useContainer,
diff --git a/x-pack/plugins/observability/public/pages/alerts/index.ts b/x-pack/plugins/observability/public/pages/alerts/index.ts
new file mode 100644
index 0000000000000..525f3441c4470
--- /dev/null
+++ b/x-pack/plugins/observability/public/pages/alerts/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export * from './components';
+export * from './containers';
diff --git a/x-pack/plugins/observability/public/pages/cases/helpers.ts b/x-pack/plugins/observability/public/pages/cases/helpers.ts
index 91f45c711d6a6..f4bc5af7f604d 100644
--- a/x-pack/plugins/observability/public/pages/cases/helpers.ts
+++ b/x-pack/plugins/observability/public/pages/cases/helpers.ts
@@ -6,10 +6,8 @@
*/
import { useEffect, useState } from 'react';
import { isEmpty } from 'lodash';
-
import { usePluginContext } from '../../hooks/use_plugin_context';
-import { parseAlert } from '../../pages/alerts/parse_alert';
-import { TopAlert } from '../../pages/alerts/';
+import { TopAlert, parseAlert } from '../../pages/alerts/';
import { useKibana } from '../../utils/kibana_react';
import { Ecs } from '../../../../cases/common';
diff --git a/x-pack/plugins/observability/public/routes/index.tsx b/x-pack/plugins/observability/public/routes/index.tsx
index 169f4b5254c04..6f38a66cdb643 100644
--- a/x-pack/plugins/observability/public/routes/index.tsx
+++ b/x-pack/plugins/observability/public/routes/index.tsx
@@ -8,8 +8,8 @@
import * as t from 'io-ts';
import React from 'react';
import { casesPath } from '../../common';
-import { AlertsPage } from '../pages/alerts';
import { CasesPage } from '../pages/cases';
+import { AlertsPage } from '../pages/alerts/containers/alerts_page';
import { HomePage } from '../pages/home';
import { LandingPage } from '../pages/landing';
import { OverviewPage } from '../pages/overview';
From 7e9b1bce092ae22ffb6ee081e43267b9da6ba9e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ece=20=C3=96zalp?=
Date: Mon, 29 Nov 2021 13:44:39 -0500
Subject: [PATCH 009/236] [Security Solution] updates host risk score decimal
count (UI) (#119228)
* updates host risk score decimal count
* fix function
* changes isNaN to Number.isNaN
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Ece Ozalp
---
.../overview_risky_host_links/risky_hosts_panel_view.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_panel_view.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_panel_view.tsx
index eb4e226940c5f..87a5710ab0372 100644
--- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_panel_view.tsx
+++ b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_panel_view.tsx
@@ -30,6 +30,8 @@ const columns: Array> = [
align: 'right',
field: 'count',
name: 'Risk Score',
+ render: (riskScore) =>
+ Number.isNaN(riskScore) ? riskScore : Number.parseFloat(riskScore).toFixed(2),
sortable: true,
truncateText: true,
width: '15%',
From a0ca3d90bceff111cb48b3cb4973f273b58a1499 Mon Sep 17 00:00:00 2001
From: Kate Patticha
Date: Mon, 29 Nov 2021 19:51:06 +0100
Subject: [PATCH 010/236] [APM] Add service icon for the originating service in
traces table (#119421)
* [APM] Add service icon for the originating service in traces table
* Fix api test
* Fix agentName type
---
.../app/trace_overview/trace_list.tsx | 17 +++-
.../__snapshots__/queries.test.ts.snap | 6 ++
.../server/lib/transaction_groups/fetcher.ts | 5 +-
.../get_transaction_group_stats.ts | 13 ++-
.../traces/__snapshots__/top_traces.spec.snap | 81 +++++++++++++++++++
.../tests/traces/top_traces.spec.ts | 2 +
6 files changed, 120 insertions(+), 4 deletions(-)
diff --git a/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx b/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx
index 0fc25b28b60e8..58179366fa42d 100644
--- a/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx
+++ b/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx
@@ -5,7 +5,13 @@
* 2.0.
*/
-import { EuiIcon, EuiToolTip, RIGHT_ALIGNMENT } from '@elastic/eui';
+import {
+ EuiIcon,
+ EuiToolTip,
+ EuiFlexGroup,
+ EuiFlexItem,
+ RIGHT_ALIGNMENT,
+} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common';
@@ -19,6 +25,7 @@ import { EmptyMessage } from '../../shared/EmptyMessage';
import { ImpactBar } from '../../shared/ImpactBar';
import { TransactionDetailLink } from '../../shared/Links/apm/transaction_detail_link';
import { ITableColumn, ManagedTable } from '../../shared/managed_table';
+import { AgentIcon } from '../../shared/agent_icon';
type TraceGroup = APIReturnType<'GET /internal/apm/traces'>['items'][0];
@@ -65,6 +72,14 @@ const traceListColumns: Array> = [
}
),
sortable: true,
+ render: (_: string, { serviceName, agentName }) => (
+
+
+
+
+ {serviceName}
+
+ ),
},
{
field: 'averageResponseTime',
diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap
index 17c43e36e5cc3..00440b2b51853 100644
--- a/x-pack/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap
+++ b/x-pack/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap
@@ -18,6 +18,9 @@ Array [
Object {
"field": "transaction.type",
},
+ Object {
+ "field": "agent.name",
+ },
],
"sort": Object {
"@timestamp": "desc",
@@ -228,6 +231,9 @@ Array [
Object {
"field": "transaction.type",
},
+ Object {
+ "field": "agent.name",
+ },
],
"sort": Object {
"@timestamp": "desc",
diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts b/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts
index aea92d06b7589..bca71ed71b1f6 100644
--- a/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts
+++ b/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts
@@ -31,7 +31,7 @@ import {
} from '../helpers/transactions';
import { Setup } from '../helpers/setup_request';
import { getAverages, getCounts, getSums } from './get_transaction_group_stats';
-
+import { AgentName } from '../../../typings/es_schemas/ui/fields/agent';
export interface TopTraceOptions {
environment: string;
kuery: string;
@@ -51,6 +51,7 @@ export interface TransactionGroup {
averageResponseTime: number | null | undefined;
transactionsPerMinute: number;
impact: number;
+ agentName: AgentName;
}
export type ESResponse = Promise<{ items: TransactionGroup[] }>;
@@ -142,6 +143,7 @@ function getItemsWithRelativeImpact(
avg?: number | null;
count?: number | null;
transactionType?: string;
+ agentName?: AgentName;
}>,
start: number,
end: number
@@ -166,6 +168,7 @@ function getItemsWithRelativeImpact(
item.sum !== null && item.sum !== undefined
? ((item.sum - min) / (max - min)) * 100 || 0
: 0,
+ agentName: item.agentName as AgentName,
};
});
diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_group_stats.ts b/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_group_stats.ts
index c79dde721d138..fd638a6731c63 100644
--- a/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_group_stats.ts
+++ b/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_group_stats.ts
@@ -7,11 +7,14 @@
import { merge } from 'lodash';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
-import { TRANSACTION_TYPE } from '../../../common/elasticsearch_fieldnames';
+import {
+ TRANSACTION_TYPE,
+ AGENT_NAME,
+} from '../../../common/elasticsearch_fieldnames';
import { arrayUnionToCallable } from '../../../common/utils/array_union_to_callable';
import { TransactionGroupRequestBase, TransactionGroupSetup } from './fetcher';
import { getTransactionDurationFieldForTransactions } from '../helpers/transactions';
-
+import { AgentName } from '../../../typings/es_schemas/ui/fields/agent';
interface MetricParams {
request: TransactionGroupRequestBase;
setup: TransactionGroupSetup;
@@ -79,6 +82,9 @@ export async function getCounts({ request, setup }: MetricParams) {
{
field: TRANSACTION_TYPE,
} as const,
+ {
+ field: AGENT_NAME,
+ } as const,
],
},
},
@@ -98,6 +104,9 @@ export async function getCounts({ request, setup }: MetricParams) {
transactionType: bucket.transaction_type.top[0].metrics[
TRANSACTION_TYPE
] as string,
+ agentName: bucket.transaction_type.top[0].metrics[
+ AGENT_NAME
+ ] as AgentName,
};
});
}
diff --git a/x-pack/test/apm_api_integration/tests/traces/__snapshots__/top_traces.spec.snap b/x-pack/test/apm_api_integration/tests/traces/__snapshots__/top_traces.spec.snap
index 604348355f38c..528963709712d 100644
--- a/x-pack/test/apm_api_integration/tests/traces/__snapshots__/top_traces.spec.snap
+++ b/x-pack/test/apm_api_integration/tests/traces/__snapshots__/top_traces.spec.snap
@@ -3,6 +3,7 @@
exports[`APM API tests basic apm_8.0.0 Top traces when data is loaded returns the correct buckets 1`] = `
Array [
Object {
+ "agentName": "java",
"averageResponseTime": 1639,
"impact": 0,
"key": Object {
@@ -15,6 +16,7 @@ Array [
"transactionsPerMinute": 0.0333333333333333,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 3279,
"impact": 0.00144735571024101,
"key": Object {
@@ -27,6 +29,7 @@ Array [
"transactionsPerMinute": 0.0333333333333333,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 6175,
"impact": 0.00400317408637392,
"key": Object {
@@ -39,6 +42,7 @@ Array [
"transactionsPerMinute": 0.0333333333333333,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 3495,
"impact": 0.00472243927164613,
"key": Object {
@@ -51,6 +55,7 @@ Array [
"transactionsPerMinute": 0.0666666666666667,
},
Object {
+ "agentName": "python",
"averageResponseTime": 7039,
"impact": 0.00476568343615943,
"key": Object {
@@ -63,6 +68,7 @@ Array [
"transactionsPerMinute": 0.0333333333333333,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 6303,
"impact": 0.00967875004525193,
"key": Object {
@@ -75,6 +81,7 @@ Array [
"transactionsPerMinute": 0.0666666666666667,
},
Object {
+ "agentName": "java",
"averageResponseTime": 7209.66666666667,
"impact": 0.0176418540534865,
"key": Object {
@@ -87,6 +94,7 @@ Array [
"transactionsPerMinute": 0.1,
},
Object {
+ "agentName": "java",
"averageResponseTime": 4511,
"impact": 0.0224401912465233,
"key": Object {
@@ -99,6 +107,7 @@ Array [
"transactionsPerMinute": 0.2,
},
Object {
+ "agentName": "python",
"averageResponseTime": 7607,
"impact": 0.0254072704525173,
"key": Object {
@@ -111,6 +120,7 @@ Array [
"transactionsPerMinute": 0.133333333333333,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 10143,
"impact": 0.025408152986487,
"key": Object {
@@ -123,6 +133,7 @@ Array [
"transactionsPerMinute": 0.1,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 6105.66666666667,
"impact": 0.0308842762682221,
"key": Object {
@@ -135,6 +146,7 @@ Array [
"transactionsPerMinute": 0.2,
},
Object {
+ "agentName": "java",
"averageResponseTime": 6116.33333333333,
"impact": 0.0309407584422802,
"key": Object {
@@ -147,6 +159,7 @@ Array [
"transactionsPerMinute": 0.2,
},
Object {
+ "agentName": "java",
"averageResponseTime": 12543,
"impact": 0.0317623975680329,
"key": Object {
@@ -159,6 +172,7 @@ Array [
"transactionsPerMinute": 0.1,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 5551,
"impact": 0.0328461492827744,
"key": Object {
@@ -171,6 +185,7 @@ Array [
"transactionsPerMinute": 0.233333333333333,
},
Object {
+ "agentName": "java",
"averageResponseTime": 13183,
"impact": 0.0334568627897785,
"key": Object {
@@ -183,6 +198,7 @@ Array [
"transactionsPerMinute": 0.1,
},
Object {
+ "agentName": "go",
"averageResponseTime": 8050.2,
"impact": 0.0340764016364792,
"key": Object {
@@ -195,6 +211,7 @@ Array [
"transactionsPerMinute": 0.166666666666667,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 10079,
"impact": 0.0341337663445071,
"key": Object {
@@ -207,6 +224,7 @@ Array [
"transactionsPerMinute": 0.133333333333333,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 8463,
"impact": 0.0358979517498557,
"key": Object {
@@ -219,6 +237,7 @@ Array [
"transactionsPerMinute": 0.166666666666667,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 10799,
"impact": 0.0366754641771254,
"key": Object {
@@ -231,6 +250,7 @@ Array [
"transactionsPerMinute": 0.133333333333333,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 7428.33333333333,
"impact": 0.0378880658514371,
"key": Object {
@@ -243,6 +263,7 @@ Array [
"transactionsPerMinute": 0.2,
},
Object {
+ "agentName": "java",
"averageResponseTime": 3105.13333333333,
"impact": 0.039659311528543,
"key": Object {
@@ -255,6 +276,7 @@ Array [
"transactionsPerMinute": 0.5,
},
Object {
+ "agentName": "java",
"averageResponseTime": 6883.57142857143,
"impact": 0.0410784261517549,
"key": Object {
@@ -267,6 +289,7 @@ Array [
"transactionsPerMinute": 0.233333333333333,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 3505,
"impact": 0.0480460318422139,
"key": Object {
@@ -279,6 +302,7 @@ Array [
"transactionsPerMinute": 0.533333333333333,
},
Object {
+ "agentName": "java",
"averageResponseTime": 5621.4,
"impact": 0.0481642913941483,
"key": Object {
@@ -291,6 +315,7 @@ Array [
"transactionsPerMinute": 0.333333333333333,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 8428.71428571429,
"impact": 0.0506239135675883,
"key": Object {
@@ -303,6 +328,7 @@ Array [
"transactionsPerMinute": 0.233333333333333,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 8520.14285714286,
"impact": 0.0511887353081702,
"key": Object {
@@ -315,6 +341,7 @@ Array [
"transactionsPerMinute": 0.233333333333333,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 6683.44444444444,
"impact": 0.0516388276326964,
"key": Object {
@@ -327,6 +354,7 @@ Array [
"transactionsPerMinute": 0.3,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 3482.78947368421,
"impact": 0.0569534471979838,
"key": Object {
@@ -339,6 +367,7 @@ Array [
"transactionsPerMinute": 0.633333333333333,
},
Object {
+ "agentName": "python",
"averageResponseTime": 16703,
"impact": 0.057517386404596,
"key": Object {
@@ -351,6 +380,7 @@ Array [
"transactionsPerMinute": 0.133333333333333,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 4943,
"impact": 0.0596266425920813,
"key": Object {
@@ -363,6 +393,7 @@ Array [
"transactionsPerMinute": 0.466666666666667,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 7892.33333333333,
"impact": 0.0612407972225879,
"key": Object {
@@ -375,6 +406,7 @@ Array [
"transactionsPerMinute": 0.3,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 6346.42857142857,
"impact": 0.0769666700279444,
"key": Object {
@@ -387,6 +419,7 @@ Array [
"transactionsPerMinute": 0.466666666666667,
},
Object {
+ "agentName": "go",
"averageResponseTime": 7052.84615384615,
"impact": 0.0794704188998674,
"key": Object {
@@ -399,6 +432,7 @@ Array [
"transactionsPerMinute": 0.433333333333333,
},
Object {
+ "agentName": "java",
"averageResponseTime": 10484.3333333333,
"impact": 0.0818285496667966,
"key": Object {
@@ -411,6 +445,7 @@ Array [
"transactionsPerMinute": 0.3,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 23711,
"impact": 0.0822565786420813,
"key": Object {
@@ -423,6 +458,7 @@ Array [
"transactionsPerMinute": 0.133333333333333,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 4491.36363636364,
"impact": 0.0857567083657495,
"key": Object {
@@ -435,6 +471,7 @@ Array [
"transactionsPerMinute": 0.733333333333333,
},
Object {
+ "agentName": "python",
"averageResponseTime": 20715.8,
"impact": 0.089965512867054,
"key": Object {
@@ -447,6 +484,7 @@ Array [
"transactionsPerMinute": 0.166666666666667,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 9036.33333333333,
"impact": 0.0942519803576885,
"key": Object {
@@ -459,6 +497,7 @@ Array [
"transactionsPerMinute": 0.4,
},
Object {
+ "agentName": "java",
"averageResponseTime": 7504.06666666667,
"impact": 0.0978924329825326,
"key": Object {
@@ -471,6 +510,7 @@ Array [
"transactionsPerMinute": 0.5,
},
Object {
+ "agentName": "go",
"averageResponseTime": 4250.55555555556,
"impact": 0.0998375378516613,
"key": Object {
@@ -483,6 +523,7 @@ Array [
"transactionsPerMinute": 0.9,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 21343,
"impact": 0.11156906191034,
"key": Object {
@@ -495,6 +536,7 @@ Array [
"transactionsPerMinute": 0.2,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 16655,
"impact": 0.116142352941114,
"key": Object {
@@ -507,6 +549,7 @@ Array [
"transactionsPerMinute": 0.266666666666667,
},
Object {
+ "agentName": "go",
"averageResponseTime": 5749,
"impact": 0.12032203382142,
"key": Object {
@@ -519,6 +562,7 @@ Array [
"transactionsPerMinute": 0.8,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 9951,
"impact": 0.121502864272824,
"key": Object {
@@ -531,6 +575,7 @@ Array [
"transactionsPerMinute": 0.466666666666667,
},
Object {
+ "agentName": "go",
"averageResponseTime": 14040.6,
"impact": 0.122466591367692,
"key": Object {
@@ -543,6 +588,7 @@ Array [
"transactionsPerMinute": 0.333333333333333,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 20963.5714285714,
"impact": 0.128060974201361,
"key": Object {
@@ -555,6 +601,7 @@ Array [
"transactionsPerMinute": 0.233333333333333,
},
Object {
+ "agentName": "python",
"averageResponseTime": 22874.4285714286,
"impact": 0.139865748579522,
"key": Object {
@@ -567,6 +614,7 @@ Array [
"transactionsPerMinute": 0.233333333333333,
},
Object {
+ "agentName": "python",
"averageResponseTime": 32203.8,
"impact": 0.140658264084276,
"key": Object {
@@ -579,6 +627,7 @@ Array [
"transactionsPerMinute": 0.166666666666667,
},
Object {
+ "agentName": "go",
"averageResponseTime": 4482.11111111111,
"impact": 0.140955678032051,
"key": Object {
@@ -591,6 +640,7 @@ Array [
"transactionsPerMinute": 1.2,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 12582.3846153846,
"impact": 0.142910490774846,
"key": Object {
@@ -603,6 +653,7 @@ Array [
"transactionsPerMinute": 0.433333333333333,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 10009.9473684211,
"impact": 0.166401779979233,
"key": Object {
@@ -615,6 +666,7 @@ Array [
"transactionsPerMinute": 0.633333333333333,
},
Object {
+ "agentName": "python",
"averageResponseTime": 27825.2857142857,
"impact": 0.170450845832029,
"key": Object {
@@ -627,6 +679,7 @@ Array [
"transactionsPerMinute": 0.233333333333333,
},
Object {
+ "agentName": "python",
"averageResponseTime": 20562.2,
"impact": 0.180021926732983,
"key": Object {
@@ -639,6 +692,7 @@ Array [
"transactionsPerMinute": 0.333333333333333,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 7106.76470588235,
"impact": 0.21180020991247,
"key": Object {
@@ -651,6 +705,7 @@ Array [
"transactionsPerMinute": 1.13333333333333,
},
Object {
+ "agentName": "go",
"averageResponseTime": 8612.51724137931,
"impact": 0.218977858687708,
"key": Object {
@@ -663,6 +718,7 @@ Array [
"transactionsPerMinute": 0.966666666666667,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 11295,
"impact": 0.277663720068132,
"key": Object {
@@ -675,6 +731,7 @@ Array [
"transactionsPerMinute": 0.933333333333333,
},
Object {
+ "agentName": "python",
"averageResponseTime": 65035.8,
"impact": 0.285535040543522,
"key": Object {
@@ -687,6 +744,7 @@ Array [
"transactionsPerMinute": 0.166666666666667,
},
Object {
+ "agentName": "go",
"averageResponseTime": 30999.4705882353,
"impact": 0.463640986028375,
"key": Object {
@@ -699,6 +757,7 @@ Array [
"transactionsPerMinute": 0.566666666666667,
},
Object {
+ "agentName": "go",
"averageResponseTime": 20197.4,
"impact": 0.622424732781511,
"key": Object {
@@ -711,6 +770,7 @@ Array [
"transactionsPerMinute": 1.16666666666667,
},
Object {
+ "agentName": "python",
"averageResponseTime": 64681.6666666667,
"impact": 0.68355874339377,
"key": Object {
@@ -723,6 +783,7 @@ Array [
"transactionsPerMinute": 0.4,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 41416.1428571429,
"impact": 0.766127739061111,
"key": Object {
@@ -735,6 +796,7 @@ Array [
"transactionsPerMinute": 0.7,
},
Object {
+ "agentName": "go",
"averageResponseTime": 19429,
"impact": 0.821597646656097,
"key": Object {
@@ -747,6 +809,7 @@ Array [
"transactionsPerMinute": 1.6,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 62390.652173913,
"impact": 1.26497653527507,
"key": Object {
@@ -759,6 +822,7 @@ Array [
"transactionsPerMinute": 0.766666666666667,
},
Object {
+ "agentName": "python",
"averageResponseTime": 33266.2,
"impact": 1.76006661931225,
"key": Object {
@@ -771,6 +835,7 @@ Array [
"transactionsPerMinute": 2,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 38491.4444444444,
"impact": 1.83293391905112,
"key": Object {
@@ -783,6 +848,7 @@ Array [
"transactionsPerMinute": 1.8,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 118488.6,
"impact": 2.08995781717084,
"key": Object {
@@ -795,6 +861,7 @@ Array [
"transactionsPerMinute": 0.666666666666667,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 250440.142857143,
"impact": 4.64001412901584,
"key": Object {
@@ -807,6 +874,7 @@ Array [
"transactionsPerMinute": 0.7,
},
Object {
+ "agentName": "java",
"averageResponseTime": 312096.523809524,
"impact": 5.782704992387,
"key": Object {
@@ -819,6 +887,7 @@ Array [
"transactionsPerMinute": 0.7,
},
Object {
+ "agentName": "ruby",
"averageResponseTime": 91519.7032967033,
"impact": 7.34855500859826,
"key": Object {
@@ -831,6 +900,7 @@ Array [
"transactionsPerMinute": 3.03333333333333,
},
Object {
+ "agentName": "rum-js",
"averageResponseTime": 648269.769230769,
"impact": 7.43611473386403,
"key": Object {
@@ -843,6 +913,7 @@ Array [
"transactionsPerMinute": 0.433333333333333,
},
Object {
+ "agentName": "python",
"averageResponseTime": 1398919.72727273,
"impact": 13.5790895084132,
"key": Object {
@@ -855,6 +926,7 @@ Array [
"transactionsPerMinute": 0.366666666666667,
},
Object {
+ "agentName": "rum-js",
"averageResponseTime": 1199907.57142857,
"impact": 14.8239822181408,
"key": Object {
@@ -867,6 +939,7 @@ Array [
"transactionsPerMinute": 0.466666666666667,
},
Object {
+ "agentName": "rum-js",
"averageResponseTime": 955876.052631579,
"impact": 16.026822184214,
"key": Object {
@@ -879,6 +952,7 @@ Array [
"transactionsPerMinute": 0.633333333333333,
},
Object {
+ "agentName": "go",
"averageResponseTime": 965009.526315789,
"impact": 16.1799735991728,
"key": Object {
@@ -891,6 +965,7 @@ Array [
"transactionsPerMinute": 0.633333333333333,
},
Object {
+ "agentName": "rum-js",
"averageResponseTime": 1213675.30769231,
"impact": 27.8474053933734,
"key": Object {
@@ -903,6 +978,7 @@ Array [
"transactionsPerMinute": 0.866666666666667,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 924019.363636364,
"impact": 35.8796065162284,
"key": Object {
@@ -915,6 +991,7 @@ Array [
"transactionsPerMinute": 1.46666666666667,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 1060469.15384615,
"impact": 36.498655556576,
"key": Object {
@@ -927,6 +1004,7 @@ Array [
"transactionsPerMinute": 1.3,
},
Object {
+ "agentName": "python",
"averageResponseTime": 118686.822222222,
"impact": 37.7068083771466,
"key": Object {
@@ -939,6 +1017,7 @@ Array [
"transactionsPerMinute": 12,
},
Object {
+ "agentName": "nodejs",
"averageResponseTime": 1039228.27659574,
"impact": 43.1048035741496,
"key": Object {
@@ -951,6 +1030,7 @@ Array [
"transactionsPerMinute": 1.56666666666667,
},
Object {
+ "agentName": "python",
"averageResponseTime": 1949922.55555556,
"impact": 61.9499776921889,
"key": Object {
@@ -963,6 +1043,7 @@ Array [
"transactionsPerMinute": 1.2,
},
Object {
+ "agentName": "dotnet",
"averageResponseTime": 5963775,
"impact": 100,
"key": Object {
diff --git a/x-pack/test/apm_api_integration/tests/traces/top_traces.spec.ts b/x-pack/test/apm_api_integration/tests/traces/top_traces.spec.ts
index 51b14809982d8..06a24cbd34a4b 100644
--- a/x-pack/test/apm_api_integration/tests/traces/top_traces.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/traces/top_traces.spec.ts
@@ -63,6 +63,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
expectSnapshot(firstItem).toMatchInline(`
Object {
+ "agentName": "java",
"averageResponseTime": 1639,
"impact": 0,
"key": Object {
@@ -78,6 +79,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
expectSnapshot(lastItem).toMatchInline(`
Object {
+ "agentName": "dotnet",
"averageResponseTime": 5963775,
"impact": 100,
"key": Object {
From 9f47e386c98056a3eb07cb44b78b5822f3f1d2e0 Mon Sep 17 00:00:00 2001
From: Nicolas Chaulet
Date: Mon, 29 Nov 2021 14:13:06 -0500
Subject: [PATCH 011/236] [Fleet] Fix preconfiguration variable values
(#119749)
---
.../server/services/package_policy.test.ts | 786 +++++++++++++++++-
.../fleet/server/services/package_policy.ts | 157 +++-
.../fleet/server/services/preconfiguration.ts | 4 +-
3 files changed, 909 insertions(+), 38 deletions(-)
diff --git a/x-pack/plugins/fleet/server/services/package_policy.test.ts b/x-pack/plugins/fleet/server/services/package_policy.test.ts
index 36976bea4a970..ac88204f082b7 100644
--- a/x-pack/plugins/fleet/server/services/package_policy.test.ts
+++ b/x-pack/plugins/fleet/server/services/package_policy.test.ts
@@ -39,7 +39,8 @@ import type {
import { IngestManagerError } from '../errors';
import {
- overridePackageInputs,
+ preconfigurePackageInputs,
+ updatePackageInputs,
packagePolicyService,
_applyIndexPrivileges,
} from './package_policy';
@@ -1170,7 +1171,776 @@ describe('Package policy service', () => {
});
});
- describe('overridePackageInputs', () => {
+ describe('preconfigurePackageInputs', () => {
+ describe('when variable is already defined', () => {
+ it('override original variable value', () => {
+ const basePackagePolicy: NewPackagePolicy = {
+ name: 'base-package-policy',
+ description: 'Base Package Policy',
+ namespace: 'default',
+ enabled: true,
+ policy_id: 'xxxx',
+ output_id: 'xxxx',
+ package: {
+ name: 'test-package',
+ title: 'Test Package',
+ version: '0.0.1',
+ },
+ inputs: [
+ {
+ type: 'logs',
+ policy_template: 'template_1',
+ enabled: true,
+ vars: {
+ path: {
+ type: 'text',
+ value: ['/var/log/logfile.log'],
+ },
+ },
+ streams: [],
+ },
+ ],
+ };
+
+ const packageInfo: PackageInfo = {
+ name: 'test-package',
+ description: 'Test Package',
+ title: 'Test Package',
+ version: '0.0.1',
+ latestVersion: '0.0.1',
+ release: 'experimental',
+ format_version: '1.0.0',
+ owner: { github: 'elastic/fleet' },
+ policy_templates: [
+ {
+ name: 'template_1',
+ title: 'Template 1',
+ description: 'Template 1',
+ inputs: [
+ {
+ type: 'logs',
+ title: 'Log',
+ description: 'Log Input',
+ vars: [
+ {
+ name: 'path',
+ type: 'text',
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ // @ts-ignore
+ assets: {},
+ };
+
+ const inputsOverride: NewPackagePolicyInput[] = [
+ {
+ type: 'logs',
+ enabled: true,
+ streams: [],
+ vars: {
+ path: {
+ type: 'text',
+ value: '/var/log/new-logfile.log',
+ },
+ },
+ },
+ ];
+
+ const result = preconfigurePackageInputs(
+ basePackagePolicy,
+ packageInfo,
+ // TODO: Update this type assertion when the `InputsOverride` type is updated such
+ // that it no longer causes unresolvable type errors when used directly
+ inputsOverride as InputsOverride[]
+ );
+ expect(result.inputs[0]?.vars?.path.value).toEqual('/var/log/new-logfile.log');
+ });
+ });
+
+ describe('when variable is undefined in original object', () => {
+ it('adds the variable definition to the resulting object', () => {
+ const basePackagePolicy: NewPackagePolicy = {
+ name: 'base-package-policy',
+ description: 'Base Package Policy',
+ namespace: 'default',
+ enabled: true,
+ policy_id: 'xxxx',
+ output_id: 'xxxx',
+ package: {
+ name: 'test-package',
+ title: 'Test Package',
+ version: '0.0.1',
+ },
+ inputs: [
+ {
+ type: 'logs',
+ policy_template: 'template_1',
+ enabled: true,
+ vars: {
+ path: {
+ type: 'text',
+ value: ['/var/log/logfile.log'],
+ },
+ },
+ streams: [],
+ },
+ ],
+ };
+
+ const packageInfo: PackageInfo = {
+ name: 'test-package',
+ description: 'Test Package',
+ title: 'Test Package',
+ version: '0.0.1',
+ latestVersion: '0.0.1',
+ release: 'experimental',
+ format_version: '1.0.0',
+ owner: { github: 'elastic/fleet' },
+ policy_templates: [
+ {
+ name: 'template_1',
+ title: 'Template 1',
+ description: 'Template 1',
+ inputs: [
+ {
+ type: 'logs',
+ title: 'Log',
+ description: 'Log Input',
+ vars: [
+ {
+ name: 'path',
+ type: 'text',
+ },
+ {
+ name: 'path_2',
+ type: 'text',
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ // @ts-ignore
+ assets: {},
+ };
+
+ const inputsOverride: NewPackagePolicyInput[] = [
+ {
+ type: 'logs',
+ enabled: true,
+ streams: [],
+ policy_template: 'template_1',
+ vars: {
+ path: {
+ type: 'text',
+ value: '/var/log/new-logfile.log',
+ },
+ path_2: {
+ type: 'text',
+ value: '/var/log/custom.log',
+ },
+ },
+ },
+ ];
+
+ const result = preconfigurePackageInputs(
+ basePackagePolicy,
+ packageInfo,
+ // TODO: Update this type assertion when the `InputsOverride` type is updated such
+ // that it no longer causes unresolvable type errors when used directly
+ inputsOverride as InputsOverride[]
+ );
+
+ expect(result.inputs[0]?.vars?.path_2.value).toEqual('/var/log/custom.log');
+ });
+ });
+
+ describe('when variable is undefined in original object and policy_template is undefined', () => {
+ it('adds the variable definition to the resulting object', () => {
+ const basePackagePolicy: NewPackagePolicy = {
+ name: 'base-package-policy',
+ description: 'Base Package Policy',
+ namespace: 'default',
+ enabled: true,
+ policy_id: 'xxxx',
+ output_id: 'xxxx',
+ package: {
+ name: 'test-package',
+ title: 'Test Package',
+ version: '0.0.1',
+ },
+ inputs: [
+ {
+ type: 'logs',
+ policy_template: 'template_1',
+ enabled: true,
+ vars: {
+ path: {
+ type: 'text',
+ value: ['/var/log/logfile.log'],
+ },
+ },
+ streams: [],
+ },
+ ],
+ };
+
+ const packageInfo: PackageInfo = {
+ name: 'test-package',
+ description: 'Test Package',
+ title: 'Test Package',
+ version: '0.0.1',
+ latestVersion: '0.0.1',
+ release: 'experimental',
+ format_version: '1.0.0',
+ owner: { github: 'elastic/fleet' },
+ policy_templates: [
+ {
+ name: 'template_1',
+ title: 'Template 1',
+ description: 'Template 1',
+ inputs: [
+ {
+ type: 'logs',
+ title: 'Log',
+ description: 'Log Input',
+ vars: [
+ {
+ name: 'path',
+ type: 'text',
+ },
+ {
+ name: 'path_2',
+ type: 'text',
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ // @ts-ignore
+ assets: {},
+ };
+
+ const inputsOverride: NewPackagePolicyInput[] = [
+ {
+ type: 'logs',
+ enabled: true,
+ streams: [],
+ policy_template: undefined, // preconfigured input overrides don't have a policy_template
+ vars: {
+ path: {
+ type: 'text',
+ value: '/var/log/new-logfile.log',
+ },
+ path_2: {
+ type: 'text',
+ value: '/var/log/custom.log',
+ },
+ },
+ },
+ ];
+
+ const result = preconfigurePackageInputs(
+ basePackagePolicy,
+ packageInfo,
+ // TODO: Update this type assertion when the `InputsOverride` type is updated such
+ // that it no longer causes unresolvable type errors when used directly
+ inputsOverride as InputsOverride[]
+ );
+
+ expect(result.inputs[0]?.vars?.path_2.value).toEqual('/var/log/custom.log');
+ });
+ });
+
+ describe('when an input of the same type exists under multiple policy templates', () => {
+ it('adds variable definitions to the proper streams', () => {
+ const basePackagePolicy: NewPackagePolicy = {
+ name: 'base-package-policy',
+ description: 'Base Package Policy',
+ namespace: 'default',
+ enabled: true,
+ policy_id: 'xxxx',
+ output_id: 'xxxx',
+ package: {
+ name: 'test-package',
+ title: 'Test Package',
+ version: '0.0.1',
+ },
+ inputs: [
+ {
+ type: 'logs',
+ policy_template: 'template_1',
+ enabled: true,
+ streams: [
+ {
+ enabled: true,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile',
+ },
+ vars: {
+ log_file_path: {
+ type: 'text',
+ },
+ },
+ },
+ ],
+ },
+ {
+ type: 'logs',
+ policy_template: 'template_2',
+ enabled: true,
+ streams: [
+ {
+ enabled: true,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile',
+ },
+ vars: {
+ log_file_path: {
+ type: 'text',
+ },
+ },
+ },
+ ],
+ },
+ ],
+ };
+
+ const packageInfo: PackageInfo = {
+ name: 'test-package',
+ description: 'Test Package',
+ title: 'Test Package',
+ version: '0.0.1',
+ latestVersion: '0.0.1',
+ release: 'experimental',
+ format_version: '1.0.0',
+ owner: { github: 'elastic/fleet' },
+ policy_templates: [
+ {
+ name: 'template_1',
+ title: 'Template 1',
+ description: 'Template 1',
+ inputs: [
+ {
+ type: 'logs',
+ title: 'Log',
+ description: 'Log Input',
+ vars: [],
+ },
+ ],
+ },
+ {
+ name: 'template_2',
+ title: 'Template 2',
+ description: 'Template 2',
+ inputs: [
+ {
+ type: 'logs',
+ title: 'Log',
+ description: 'Log Input',
+ vars: [],
+ },
+ ],
+ },
+ ],
+ // @ts-ignore
+ assets: {},
+ };
+
+ const inputsOverride: NewPackagePolicyInput[] = [
+ {
+ type: 'logs',
+ enabled: true,
+ policy_template: 'template_1',
+ streams: [
+ {
+ enabled: true,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile',
+ },
+ vars: {
+ log_file_path: {
+ type: 'text',
+ value: '/var/log/template1-logfile.log',
+ },
+ },
+ },
+ ],
+ },
+ {
+ type: 'logs',
+ enabled: true,
+ policy_template: 'template_2',
+ streams: [
+ {
+ enabled: true,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile',
+ },
+ vars: {
+ log_file_path: {
+ type: 'text',
+ value: '/var/log/template2-logfile.log',
+ },
+ },
+ },
+ ],
+ },
+ ];
+
+ const result = preconfigurePackageInputs(
+ basePackagePolicy,
+ packageInfo,
+ // TODO: Update this type assertion when the `InputsOverride` type is updated such
+ // that it no longer causes unresolvable type errors when used directly
+ inputsOverride as InputsOverride[]
+ );
+
+ expect(result.inputs).toHaveLength(2);
+
+ const template1Input = result.inputs.find(
+ (input) => input.policy_template === 'template_1'
+ );
+ const template2Input = result.inputs.find(
+ (input) => input.policy_template === 'template_2'
+ );
+
+ expect(template1Input).toBeDefined();
+ expect(template2Input).toBeDefined();
+
+ expect(template1Input?.streams[0].vars?.log_file_path.value).toBe(
+ '/var/log/template1-logfile.log'
+ );
+
+ expect(template2Input?.streams[0].vars?.log_file_path.value).toBe(
+ '/var/log/template2-logfile.log'
+ );
+ });
+ });
+
+ describe('when an input or stream is disabled on the original policy object', () => {
+ it('remains disabled on the resulting policy object', () => {
+ const basePackagePolicy: NewPackagePolicy = {
+ name: 'base-package-policy',
+ description: 'Base Package Policy',
+ namespace: 'default',
+ enabled: true,
+ policy_id: 'xxxx',
+ output_id: 'xxxx',
+ package: {
+ name: 'test-package',
+ title: 'Test Package',
+ version: '0.0.1',
+ },
+ inputs: [
+ {
+ type: 'logs',
+ policy_template: 'template_1',
+ enabled: false,
+ streams: [
+ {
+ enabled: false,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile',
+ },
+ vars: {
+ log_file_path: {
+ type: 'text',
+ },
+ },
+ },
+ {
+ enabled: true,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile2',
+ },
+ vars: {
+ log_file_path_2: {
+ type: 'text',
+ },
+ },
+ },
+ ],
+ },
+ {
+ type: 'logs_2',
+ policy_template: 'template_1',
+ enabled: true,
+ streams: [
+ {
+ enabled: true,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile',
+ },
+ vars: {
+ log_file_path: {
+ type: 'text',
+ },
+ },
+ },
+ ],
+ },
+ {
+ type: 'logs',
+ policy_template: 'template_2',
+ enabled: true,
+ streams: [
+ {
+ enabled: true,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile',
+ },
+ vars: {
+ log_file_path: {
+ type: 'text',
+ },
+ },
+ },
+ ],
+ },
+ ],
+ };
+
+ const packageInfo: PackageInfo = {
+ name: 'test-package',
+ description: 'Test Package',
+ title: 'Test Package',
+ version: '0.0.1',
+ latestVersion: '0.0.1',
+ release: 'experimental',
+ format_version: '1.0.0',
+ owner: { github: 'elastic/fleet' },
+ policy_templates: [
+ {
+ name: 'template_1',
+ title: 'Template 1',
+ description: 'Template 1',
+ inputs: [
+ {
+ type: 'logs',
+ title: 'Log',
+ description: 'Log Input',
+ vars: [],
+ },
+ {
+ type: 'logs_2',
+ title: 'Log 2',
+ description: 'Log Input 2',
+ vars: [],
+ },
+ ],
+ },
+ {
+ name: 'template_2',
+ title: 'Template 2',
+ description: 'Template 2',
+ inputs: [
+ {
+ type: 'logs',
+ title: 'Log',
+ description: 'Log Input',
+ vars: [],
+ },
+ ],
+ },
+ ],
+ // @ts-ignore
+ assets: {},
+ };
+
+ const inputsOverride: NewPackagePolicyInput[] = [
+ {
+ type: 'logs',
+ enabled: true,
+ policy_template: 'template_1',
+ streams: [
+ {
+ enabled: true,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile',
+ },
+ vars: {
+ log_file_path: {
+ type: 'text',
+ value: '/var/log/template1-logfile.log',
+ },
+ },
+ },
+ {
+ enabled: true,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile2',
+ },
+ vars: {
+ log_file_path_2: {
+ type: 'text',
+ value: '/var/log/template1-logfile2.log',
+ },
+ },
+ },
+ ],
+ },
+ {
+ type: 'logs',
+ enabled: true,
+ policy_template: 'template_2',
+ streams: [
+ {
+ enabled: true,
+ data_stream: {
+ dataset: 'test.logs',
+ type: 'logfile',
+ },
+ vars: {
+ log_file_path: {
+ type: 'text',
+ value: '/var/log/template2-logfile.log',
+ },
+ },
+ },
+ ],
+ },
+ ];
+
+ const result = preconfigurePackageInputs(
+ basePackagePolicy,
+ packageInfo,
+ // TODO: Update this type assertion when the `InputsOverride` type is updated such
+ // that it no longer causes unresolvable type errors when used directly
+ inputsOverride as InputsOverride[]
+ );
+
+ const template1Inputs = result.inputs.filter(
+ (input) => input.policy_template === 'template_1'
+ );
+
+ const template2Inputs = result.inputs.filter(
+ (input) => input.policy_template === 'template_2'
+ );
+
+ expect(template1Inputs).toHaveLength(2);
+ expect(template2Inputs).toHaveLength(1);
+
+ const logsInput = template1Inputs?.find((input) => input.type === 'logs');
+ expect(logsInput?.enabled).toBe(false);
+
+ const logfileStream = logsInput?.streams.find(
+ (stream) => stream.data_stream.type === 'logfile'
+ );
+
+ expect(logfileStream?.enabled).toBe(false);
+ });
+ });
+
+ describe('when a datastream is deleted from an input', () => {
+ it('it remove the non existing datastream', () => {
+ const basePackagePolicy: NewPackagePolicy = {
+ name: 'base-package-policy',
+ description: 'Base Package Policy',
+ namespace: 'default',
+ enabled: true,
+ policy_id: 'xxxx',
+ output_id: 'xxxx',
+ package: {
+ name: 'test-package',
+ title: 'Test Package',
+ version: '0.0.1',
+ },
+ inputs: [
+ {
+ type: 'logs',
+ policy_template: 'template_1',
+ enabled: true,
+ vars: {
+ path: {
+ type: 'text',
+ value: ['/var/log/logfile.log'],
+ },
+ },
+ streams: [
+ {
+ enabled: true,
+ data_stream: { dataset: 'dataset.test123', type: 'log' },
+ },
+ ],
+ },
+ ],
+ };
+
+ const packageInfo: PackageInfo = {
+ name: 'test-package',
+ description: 'Test Package',
+ title: 'Test Package',
+ version: '0.0.1',
+ latestVersion: '0.0.1',
+ release: 'experimental',
+ format_version: '1.0.0',
+ owner: { github: 'elastic/fleet' },
+ policy_templates: [
+ {
+ name: 'template_1',
+ title: 'Template 1',
+ description: 'Template 1',
+ inputs: [
+ {
+ type: 'logs',
+ title: 'Log',
+ description: 'Log Input',
+ vars: [
+ {
+ name: 'path',
+ type: 'text',
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ // @ts-ignore
+ assets: {},
+ };
+
+ const inputsOverride: NewPackagePolicyInput[] = [
+ {
+ type: 'logs',
+ enabled: true,
+ streams: [],
+ vars: {
+ path: {
+ type: 'text',
+ value: '/var/log/new-logfile.log',
+ },
+ },
+ },
+ ];
+
+ const result = preconfigurePackageInputs(
+ basePackagePolicy,
+ packageInfo,
+ // TODO: Update this type assertion when the `InputsOverride` type is updated such
+ // that it no longer causes unresolvable type errors when used directly
+ inputsOverride as InputsOverride[]
+ );
+ expect(result.inputs[0]?.vars?.path.value).toEqual('/var/log/new-logfile.log');
+ });
+ });
+ });
+
+ describe('updatePackageInputs', () => {
describe('when variable is already defined', () => {
it('preserves original variable value without overwriting', () => {
const basePackagePolicy: NewPackagePolicy = {
@@ -1248,7 +2018,7 @@ describe('Package policy service', () => {
},
];
- const result = overridePackageInputs(
+ const result = updatePackageInputs(
basePackagePolicy,
packageInfo,
// TODO: Update this type assertion when the `InputsOverride` type is updated such
@@ -1346,7 +2116,7 @@ describe('Package policy service', () => {
},
];
- const result = overridePackageInputs(
+ const result = updatePackageInputs(
basePackagePolicy,
packageInfo,
// TODO: Update this type assertion when the `InputsOverride` type is updated such
@@ -1445,7 +2215,7 @@ describe('Package policy service', () => {
},
];
- const result = overridePackageInputs(
+ const result = updatePackageInputs(
basePackagePolicy,
packageInfo,
// TODO: Update this type assertion when the `InputsOverride` type is updated such
@@ -1598,7 +2368,7 @@ describe('Package policy service', () => {
},
];
- const result = overridePackageInputs(
+ const result = updatePackageInputs(
basePackagePolicy,
packageInfo,
// TODO: Update this type assertion when the `InputsOverride` type is updated such
@@ -1819,7 +2589,7 @@ describe('Package policy service', () => {
},
];
- const result = overridePackageInputs(
+ const result = updatePackageInputs(
basePackagePolicy,
packageInfo,
// TODO: Update this type assertion when the `InputsOverride` type is updated such
@@ -1932,7 +2702,7 @@ describe('Package policy service', () => {
},
];
- const result = overridePackageInputs(
+ const result = updatePackageInputs(
basePackagePolicy,
packageInfo,
// TODO: Update this type assertion when the `InputsOverride` type is updated such
diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts
index 535d93cc3eceb..5ac348ad7c8a2 100644
--- a/x-pack/plugins/fleet/server/services/package_policy.ts
+++ b/x-pack/plugins/fleet/server/services/package_policy.ts
@@ -590,7 +590,7 @@ class PackagePolicyService {
try {
const { packagePolicy, packageInfo } = await this.getUpgradePackagePolicyInfo(soClient, id);
- const updatePackagePolicy = overridePackageInputs(
+ const updatePackagePolicy = updatePackageInputs(
{
...omit(packagePolicy, 'id'),
inputs: packagePolicy.inputs,
@@ -648,7 +648,7 @@ class PackagePolicyService {
packageVersion
);
- const updatedPackagePolicy = overridePackageInputs(
+ const updatedPackagePolicy = updatePackageInputs(
{
...omit(packagePolicy, 'id'),
inputs: packagePolicy.inputs,
@@ -1030,13 +1030,13 @@ export const packagePolicyService = new PackagePolicyService();
export type { PackagePolicyService };
-export function overridePackageInputs(
+export function updatePackageInputs(
basePackagePolicy: NewPackagePolicy,
packageInfo: PackageInfo,
- inputsOverride?: InputsOverride[],
+ inputsUpdated?: InputsOverride[],
dryRun?: boolean
): DryRunPackagePolicy {
- if (!inputsOverride) return basePackagePolicy;
+ if (!inputsUpdated) return basePackagePolicy;
const availablePolicyTemplates = packageInfo.policy_templates ?? [];
@@ -1065,42 +1065,40 @@ export function overridePackageInputs(
}),
];
- for (const override of inputsOverride) {
- // Preconfiguration does not currently support multiple policy templates, so overrides will have an undefined
- // policy template, so we only match on `type` in that case.
- let originalInput = override.policy_template
- ? inputs.find(
- (i) => i.type === override.type && i.policy_template === override.policy_template
- )
- : inputs.find((i) => i.type === override.type);
+ for (const update of inputsUpdated) {
+ // If update have an undefined policy template
+ // we only match on `type` .
+ let originalInput = update.policy_template
+ ? inputs.find((i) => i.type === update.type && i.policy_template === update.policy_template)
+ : inputs.find((i) => i.type === update.type);
// If there's no corresponding input on the original package policy, just
// take the override value from the new package as-is. This case typically
// occurs when inputs or package policy templates are added/removed between versions.
if (originalInput === undefined) {
- inputs.push(override as NewPackagePolicyInput);
+ inputs.push(update as NewPackagePolicyInput);
continue;
}
// For flags like this, we only want to override the original value if it was set
// as `undefined` in the original object. An explicit true/false value should be
// persisted from the original object to the result after the override process is complete.
- if (originalInput.enabled === undefined && override.enabled !== undefined) {
- originalInput.enabled = override.enabled;
+ if (originalInput.enabled === undefined && update.enabled !== undefined) {
+ originalInput.enabled = update.enabled;
}
- if (originalInput.keep_enabled === undefined && override.keep_enabled !== undefined) {
- originalInput.keep_enabled = override.keep_enabled;
+ if (originalInput.keep_enabled === undefined && update.keep_enabled !== undefined) {
+ originalInput.keep_enabled = update.keep_enabled;
}
- if (override.vars) {
+ if (update.vars) {
const indexOfInput = inputs.indexOf(originalInput);
- inputs[indexOfInput] = deepMergeVars(originalInput, override) as NewPackagePolicyInput;
+ inputs[indexOfInput] = deepMergeVars(originalInput, update, true) as NewPackagePolicyInput;
originalInput = inputs[indexOfInput];
}
- if (override.streams) {
- for (const stream of override.streams) {
+ if (update.streams) {
+ for (const stream of update.streams) {
let originalStream = originalInput?.streams.find(
(s) => s.data_stream.dataset === stream.data_stream.dataset
);
@@ -1118,7 +1116,8 @@ export function overridePackageInputs(
const indexOfStream = originalInput.streams.indexOf(originalStream);
originalInput.streams[indexOfStream] = deepMergeVars(
originalStream,
- stream as InputsOverride
+ stream as InputsOverride,
+ true
);
originalStream = originalInput.streams[indexOfStream];
}
@@ -1128,9 +1127,8 @@ export function overridePackageInputs(
// Filter all stream that have been removed from the input
originalInput.streams = originalInput.streams.filter((originalStream) => {
return (
- override.streams?.some(
- (s) => s.data_stream.dataset === originalStream.data_stream.dataset
- ) ?? false
+ update.streams?.some((s) => s.data_stream.dataset === originalStream.data_stream.dataset) ??
+ false
);
});
}
@@ -1171,7 +1169,110 @@ export function overridePackageInputs(
return resultingPackagePolicy;
}
-function deepMergeVars(original: any, override: any): any {
+export function preconfigurePackageInputs(
+ basePackagePolicy: NewPackagePolicy,
+ packageInfo: PackageInfo,
+ preconfiguredInputs?: InputsOverride[]
+): NewPackagePolicy {
+ if (!preconfiguredInputs) return basePackagePolicy;
+
+ const inputs = [...basePackagePolicy.inputs];
+
+ for (const preconfiguredInput of preconfiguredInputs) {
+ // Preconfiguration does not currently support multiple policy templates, so overrides will have an undefined
+ // policy template, so we only match on `type` in that case.
+ let originalInput = preconfiguredInput.policy_template
+ ? inputs.find(
+ (i) =>
+ i.type === preconfiguredInput.type &&
+ i.policy_template === preconfiguredInput.policy_template
+ )
+ : inputs.find((i) => i.type === preconfiguredInput.type);
+
+ // If the input do not exist skip
+ if (originalInput === undefined) {
+ continue;
+ }
+
+ // For flags like this, we only want to override the original value if it was set
+ // as `undefined` in the original object. An explicit true/false value should be
+ // persisted from the original object to the result after the override process is complete.
+ if (originalInput.enabled === undefined && preconfiguredInput.enabled !== undefined) {
+ originalInput.enabled = preconfiguredInput.enabled;
+ }
+
+ if (originalInput.keep_enabled === undefined && preconfiguredInput.keep_enabled !== undefined) {
+ originalInput.keep_enabled = preconfiguredInput.keep_enabled;
+ }
+
+ if (preconfiguredInput.vars) {
+ const indexOfInput = inputs.indexOf(originalInput);
+ inputs[indexOfInput] = deepMergeVars(
+ originalInput,
+ preconfiguredInput
+ ) as NewPackagePolicyInput;
+ originalInput = inputs[indexOfInput];
+ }
+
+ if (preconfiguredInput.streams) {
+ for (const stream of preconfiguredInput.streams) {
+ let originalStream = originalInput?.streams.find(
+ (s) => s.data_stream.dataset === stream.data_stream.dataset
+ );
+
+ if (originalStream === undefined) {
+ continue;
+ }
+
+ if (originalStream?.enabled === undefined) {
+ originalStream.enabled = stream.enabled;
+ }
+
+ if (stream.vars) {
+ const indexOfStream = originalInput.streams.indexOf(originalStream);
+ originalInput.streams[indexOfStream] = deepMergeVars(
+ originalStream,
+ stream as InputsOverride
+ );
+ originalStream = originalInput.streams[indexOfStream];
+ }
+ }
+ }
+ }
+
+ const resultingPackagePolicy: NewPackagePolicy = {
+ ...basePackagePolicy,
+ inputs,
+ };
+
+ const validationResults = validatePackagePolicy(resultingPackagePolicy, packageInfo, safeLoad);
+
+ if (validationHasErrors(validationResults)) {
+ const responseFormattedValidationErrors = Object.entries(getFlattenedObject(validationResults))
+ .map(([key, value]) => ({
+ key,
+ message: value,
+ }))
+ .filter(({ message }) => !!message);
+
+ if (responseFormattedValidationErrors.length) {
+ throw new PackagePolicyValidationError(
+ i18n.translate('xpack.fleet.packagePolicyInvalidError', {
+ defaultMessage: 'Package policy is invalid: {errors}',
+ values: {
+ errors: responseFormattedValidationErrors
+ .map(({ key, message }) => `${key}: ${message}`)
+ .join('\n'),
+ },
+ })
+ );
+ }
+ }
+
+ return resultingPackagePolicy;
+}
+
+function deepMergeVars(original: any, override: any, keepOriginalValue = false): any {
if (!original.vars) {
original.vars = { ...override.vars };
}
@@ -1192,7 +1293,7 @@ function deepMergeVars(original: any, override: any): any {
// Ensure that any value from the original object is persisted on the newly merged resulting object,
// even if we merge other data about the given variable
- if (originalVar?.value) {
+ if (keepOriginalValue && originalVar?.value) {
result.vars[name].value = originalVar.value;
}
}
diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.ts b/x-pack/plugins/fleet/server/services/preconfiguration.ts
index 8b906b68556a4..76fa7778eafa2 100644
--- a/x-pack/plugins/fleet/server/services/preconfiguration.ts
+++ b/x-pack/plugins/fleet/server/services/preconfiguration.ts
@@ -34,7 +34,7 @@ import { ensurePackagesCompletedInstall } from './epm/packages/install';
import { bulkInstallPackages } from './epm/packages/bulk_install_packages';
import { agentPolicyService, addPackageToAgentPolicy } from './agent_policy';
import type { InputsOverride } from './package_policy';
-import { overridePackageInputs, packagePolicyService } from './package_policy';
+import { preconfigurePackageInputs, packagePolicyService } from './package_policy';
import { appContextService } from './app_context';
import type { UpgradeManagedPackagePoliciesResult } from './managed_package_policies';
import { upgradeManagedPackagePolicies } from './managed_package_policies';
@@ -428,7 +428,7 @@ async function addPreconfiguredPolicyPackages(
defaultOutput,
name,
description,
- (policy) => overridePackageInputs(policy, packageInfo, inputs),
+ (policy) => preconfigurePackageInputs(policy, packageInfo, inputs),
bumpAgentPolicyRevison
);
}
From ab47ac64ad512329e59f99cbc1245582ead7c524 Mon Sep 17 00:00:00 2001
From: Luke Elmers
Date: Mon, 29 Nov 2021 12:27:42 -0700
Subject: [PATCH 012/236] [saved objects] Updates import docs to make it
clearer which versions are supported. (#119879)
---
docs/api/saved-objects/import.asciidoc | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/docs/api/saved-objects/import.asciidoc b/docs/api/saved-objects/import.asciidoc
index 923482954aa2e..a214598af31af 100644
--- a/docs/api/saved-objects/import.asciidoc
+++ b/docs/api/saved-objects/import.asciidoc
@@ -11,11 +11,13 @@ Saved objects can only be imported into the same version, a newer minor on the s
|=======
| Exporting version | Importing version | Compatible?
-| 6.7.0 | 6.8.1 | Yes
-| 6.8.1 | 7.3.0 | Yes
-| 7.3.0 | 7.11.1 | Yes
-| 7.11.1 | 7.6.0 | No
-| 6.8.1 | 8.0.0 | No
+| 6.7.x | 6.8.x | Yes
+| 6.x.x | 7.x.x | Yes
+| 7.x.x | 8.x.x | Yes
+| 7.1.x | 7.15.x | Yes
+| 7.x.x | 6.x.x | No
+| 7.15.x | 7.1.x | No
+| 6.x.x | 8.x.x | No
|=======
[[saved-objects-api-import-request]]
From db7423506c858354e593430e1832942fb1a13f6b Mon Sep 17 00:00:00 2001
From: Lisa Cawley
Date: Mon, 29 Nov 2021 11:46:33 -0800
Subject: [PATCH 013/236] Add workplace search links to doc link service
(#118814)
Co-authored-by: Scotty Bollinger
---
...-plugin-core-public.doclinksstart.links.md | 63 ++++++-
...kibana-plugin-core-public.doclinksstart.md | 2 +-
.../public/doc_links/doc_links_service.ts | 129 ++++++++++++-
src/core/public/public.api.md | 63 ++++++-
.../api_logs/components/empty_state.test.tsx | 4 +-
.../api_logs/components/empty_state.tsx | 10 +-
.../crawler/components/crawl_rules_table.tsx | 8 +-
.../deduplication_panel.tsx | 8 +-
.../crawler/components/entry_points_table.tsx | 8 +-
.../automatic_crawl_scheduler.tsx | 4 +-
.../components/crawler/crawler_overview.tsx | 10 +-
.../components/credentials/constants.ts | 4 +-
.../credentials_list/credentials_list.tsx | 9 +-
.../curations/components/empty_state.test.tsx | 4 +-
.../curations/components/empty_state.tsx | 9 +-
.../curations_settings.test.tsx | 4 +-
.../curations_settings/curations_settings.tsx | 6 +-
.../api_code_example.tsx | 6 +-
.../document_creation_buttons.tsx | 4 +-
.../documents/components/empty_state.test.tsx | 4 +-
.../documents/components/empty_state.tsx | 9 +-
.../engine_overview_empty.test.tsx | 2 +-
.../engine_overview/engine_overview_empty.tsx | 4 +-
.../empty_meta_engines_state.test.tsx | 4 +-
.../components/empty_meta_engines_state.tsx | 9 +-
.../components/engines/constants.tsx | 4 +-
.../meta_engine_creation/constants.tsx | 4 +-
.../components/empty_state.test.tsx | 4 +-
.../components/empty_state.tsx | 9 +-
.../precision_slider.test.tsx | 4 +-
.../precision_slider/precision_slider.tsx | 8 +-
.../relevance_tuning_callouts.tsx | 4 +-
.../components/empty_state.test.tsx | 4 +-
.../components/empty_state.tsx | 9 +-
.../role_mappings/role_mappings.tsx | 8 +-
.../schema/components/empty_state.test.tsx | 4 +-
.../schema/components/empty_state.tsx | 9 +-
.../search_ui/components/empty_state.test.tsx | 4 +-
.../search_ui/components/empty_state.tsx | 9 +-
.../components/search_ui/search_ui.tsx | 4 +-
.../log_retention/log_retention_panel.tsx | 4 +-
.../components/setup_guide/setup_guide.tsx | 6 +-
.../synonyms/components/empty_state.test.tsx | 4 +-
.../synonyms/components/empty_state.tsx | 9 +-
.../public/applications/app_search/routes.ts | 24 ++-
.../components/setup_guide/setup_guide.tsx | 6 +-
.../shared/doc_links/doc_links.test.ts | 22 +--
.../shared/doc_links/doc_links.ts | 175 ++++++++++++++++--
.../licensing/manage_license_button.test.tsx | 4 +-
.../licensing/manage_license_button.tsx | 7 +-
.../role_mapping/role_mappings_table.tsx | 2 +-
.../shared/role_mapping/user_selector.tsx | 2 +-
.../role_mapping/users_empty_prompt.tsx | 2 +-
.../shared/setup_guide/cloud/instructions.tsx | 10 +-
.../applications/workplace_search/routes.ts | 61 +++---
.../components/oauth_application.test.tsx | 4 +-
.../views/setup_guide/setup_guide.tsx | 12 +-
57 files changed, 585 insertions(+), 244 deletions(-)
diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md
index 5c2c1d5317543..7669b9b644916 100644
--- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md
+++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md
@@ -24,6 +24,9 @@ readonly links: {
readonly canvas: {
readonly guide: string;
};
+ readonly cloud: {
+ readonly indexManagement: string;
+ };
readonly dashboard: {
readonly guide: string;
readonly drilldowns: string;
@@ -55,10 +58,64 @@ readonly links: {
readonly install: string;
readonly start: string;
};
+ readonly appSearch: {
+ readonly apiRef: string;
+ readonly apiClients: string;
+ readonly apiKeys: string;
+ readonly authentication: string;
+ readonly crawlRules: string;
+ readonly curations: string;
+ readonly duplicateDocuments: string;
+ readonly entryPoints: string;
+ readonly guide: string;
+ readonly indexingDocuments: string;
+ readonly indexingDocumentsSchema: string;
+ readonly logSettings: string;
+ readonly metaEngines: string;
+ readonly nativeAuth: string;
+ readonly precisionTuning: string;
+ readonly relevanceTuning: string;
+ readonly resultSettings: string;
+ readonly searchUI: string;
+ readonly security: string;
+ readonly standardAuth: string;
+ readonly synonyms: string;
+ readonly webCrawler: string;
+ readonly webCrawlerEventLogs: string;
+ };
readonly enterpriseSearch: {
- readonly base: string;
- readonly appSearchBase: string;
- readonly workplaceSearchBase: string;
+ readonly configuration: string;
+ readonly licenseManagement: string;
+ readonly mailService: string;
+ readonly usersAccess: string;
+ };
+ readonly workplaceSearch: {
+ readonly box: string;
+ readonly confluenceCloud: string;
+ readonly confluenceServer: string;
+ readonly customSources: string;
+ readonly customSourcePermissions: string;
+ readonly documentPermissions: string;
+ readonly dropbox: string;
+ readonly externalIdentities: string;
+ readonly gitHub: string;
+ readonly gettingStarted: string;
+ readonly gmail: string;
+ readonly googleDrive: string;
+ readonly indexingSchedule: string;
+ readonly jiraCloud: string;
+ readonly jiraServer: string;
+ readonly nativeAuth: string;
+ readonly oneDrive: string;
+ readonly permissions: string;
+ readonly salesforce: string;
+ readonly security: string;
+ readonly serviceNow: string;
+ readonly sharePoint: string;
+ readonly slack: string;
+ readonly standardAuth: string;
+ readonly synch: string;
+ readonly zendesk: string;
};
readonly heartbeat: {
readonly base: string;
diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md
index cbfe53d3eaea0..6aa528d4f04d1 100644
--- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md
+++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md
@@ -17,5 +17,5 @@ export interface DocLinksStart
| --- | --- | --- |
| [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) | string | |
| [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) | string | |
-| [links](./kibana-plugin-core-public.doclinksstart.links.md) | { readonly settings: string; readonly elasticStackGetStarted: string; readonly upgrade: { readonly upgradingElasticStack: string; }; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; readonly customLinks: string; readonly droppedTransactionSpans: string; readonly upgrading: string; readonly metaData: string; }; readonly canvas: { readonly guide: string; }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; readonly urlDrilldownVariables: string; }; readonly discover: Record<string, string>; readonly filebeat: { readonly base: string; readonly installation: string; readonly configuration: string; readonly elasticsearchOutput: string; readonly elasticsearchModule: string; readonly startup: string; readonly exportedFields: string; readonly suricataModule: string; readonly zeekModule: string; }; readonly auditbeat: { readonly base: string; readonly auditdModule: string; readonly systemModule: string; }; readonly metricbeat: { readonly base: string; readonly configure: string; readonly httpEndpoint: string; readonly install: string; readonly start: string; }; readonly enterpriseSearch: { readonly base: string; readonly appSearchBase: string; readonly workplaceSearchBase: string; }; readonly heartbeat: { readonly base: string; }; readonly libbeat: { readonly getStarted: string; }; readonly logstash: { readonly base: string; }; readonly functionbeat: { readonly base: string; }; readonly winlogbeat: { readonly base: string; }; readonly aggs: { readonly composite: string; readonly composite\_missing\_bucket: string; readonly date\_histogram: string; readonly date\_range: string; readonly date\_format\_pattern: string; readonly filter: string; readonly filters: string; readonly geohash\_grid: string; readonly histogram: string; readonly ip\_range: string; readonly range: string; readonly significant\_terms: string; readonly terms: string; readonly terms\_doc\_count\_error: string; readonly avg: string; readonly avg\_bucket: string; readonly max\_bucket: string; readonly min\_bucket: string; readonly sum\_bucket: string; readonly cardinality: string; readonly count: string; readonly cumulative\_sum: string; readonly derivative: string; readonly geo\_bounds: string; readonly geo\_centroid: string; readonly max: string; readonly median: string; readonly min: string; readonly moving\_avg: string; readonly percentile\_ranks: string; readonly serial\_diff: string; readonly std\_dev: string; readonly sum: string; readonly top\_hits: string; }; readonly runtimeFields: { readonly overview: string; readonly mapping: string; }; readonly scriptedFields: { readonly scriptFields: string; readonly scriptAggs: string; readonly painless: string; readonly painlessApi: string; readonly painlessLangSpec: string; readonly painlessSyntax: string; readonly painlessWalkthrough: string; readonly luceneExpressions: string; }; readonly search: { readonly sessions: string; readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; }; readonly addData: string; readonly kibana: string; readonly upgradeAssistant: { readonly overview: string; readonly batchReindex: string; readonly remoteReindex: string; }; readonly rollupJobs: string; readonly elasticsearch: Record<string, string>; readonly siem: { readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }; readonly securitySolution: { readonly trustedApps: string; }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; readonly luceneQuerySyntax: string; readonly percolate: string; readonly queryDsl: string; }; readonly date: { readonly dateMath: string; readonly dateMathIndexNames: string; }; readonly management: Record<string, string>; readonly ml: Record<string, string>; readonly transforms: Record<string, string>; readonly visualize: Record<string, string>; readonly apis: Readonly<{ bulkIndexAlias: string; byteSizeUnits: string; createAutoFollowPattern: string; createFollower: string; createIndex: string; createSnapshotLifecyclePolicy: string; createRoleMapping: string; createRoleMappingTemplates: string; createRollupJobsRequest: string; createApiKey: string; createPipeline: string; createTransformRequest: string; cronExpressions: string; executeWatchActionModes: string; indexExists: string; openIndex: string; putComponentTemplate: string; painlessExecute: string; painlessExecuteAPIContexts: string; putComponentTemplateMetadata: string; putSnapshotLifecyclePolicy: string; putIndexTemplateV1: string; putWatch: string; simulatePipeline: string; timeUnits: string; updateTransform: string; }>; readonly observability: Readonly<{ guide: string; infrastructureThreshold: string; logsThreshold: string; metricsThreshold: string; monitorStatus: string; monitorUptime: string; tlsCertificate: string; uptimeDurationAnomaly: string; }>; readonly alerting: Record<string, string>; readonly maps: Readonly<{ guide: string; importGeospatialPrivileges: string; gdalTutorial: string; }>; readonly monitoring: Record<string, string>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; elasticsearchSettings: string; elasticsearchEnableSecurity: string; elasticsearchEnableApiKeys: string; indicesPrivileges: string; kibanaTLS: string; kibanaPrivileges: string; mappingRoles: string; mappingRolesFieldRules: string; runAsPrivilege: string; }>; readonly spaces: Readonly<{ kibanaLegacyUrlAliases: string; kibanaDisableLegacyUrlAliasesApi: string; }>; readonly watcher: Record<string, string>; readonly ccs: Record<string, string>; readonly plugins: Record<string, string>; readonly snapshotRestore: Record<string, string>; readonly ingest: Record<string, string>; readonly fleet: Readonly<{ beatsAgentComparison: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; settings: string; settingsFleetServerHostSettings: string; settingsFleetServerProxySettings: string; troubleshooting: string; elasticAgent: string; datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; installElasticAgentStandalone: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; apiKeysLearnMore: string; onPremRegistry: string; }>; readonly ecs: { readonly guide: string; }; readonly clients: { readonly guide: string; readonly goOverview: string; readonly javaIndex: string; readonly jsIntro: string; readonly netGuide: string; readonly perlGuide: string; readonly phpGuide: string; readonly pythonGuide: string; readonly rubyOverview: string; readonly rustGuide: string; }; readonly endpoints: { readonly troubleshooting: string; }; } | |
+| [links](./kibana-plugin-core-public.doclinksstart.links.md) | { readonly settings: string; readonly elasticStackGetStarted: string; readonly upgrade: { readonly upgradingElasticStack: string; }; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; readonly customLinks: string; readonly droppedTransactionSpans: string; readonly upgrading: string; readonly metaData: string; }; readonly canvas: { readonly guide: string; }; readonly cloud: { readonly indexManagement: string; }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; readonly urlDrilldownVariables: string; }; readonly discover: Record<string, string>; readonly filebeat: { readonly base: string; readonly installation: string; readonly configuration: string; readonly elasticsearchOutput: string; readonly elasticsearchModule: string; readonly startup: string; readonly exportedFields: string; readonly suricataModule: string; readonly zeekModule: string; }; readonly auditbeat: { readonly base: string; readonly auditdModule: string; readonly systemModule: string; }; readonly metricbeat: { readonly base: string; readonly configure: string; readonly httpEndpoint: string; readonly install: string; readonly start: string; }; readonly appSearch: { readonly apiRef: string; readonly apiClients: string; readonly apiKeys: string; readonly authentication: string; readonly crawlRules: string; readonly curations: string; readonly duplicateDocuments: string; readonly entryPoints: string; readonly guide: string; readonly indexingDocuments: string; readonly indexingDocumentsSchema: string; readonly logSettings: string; readonly metaEngines: string; readonly nativeAuth: string; readonly precisionTuning: string; readonly relevanceTuning: string; readonly resultSettings: string; readonly searchUI: string; readonly security: string; readonly standardAuth: string; readonly synonyms: string; readonly webCrawler: string; readonly webCrawlerEventLogs: string; }; readonly enterpriseSearch: { readonly configuration: string; readonly licenseManagement: string; readonly mailService: string; readonly usersAccess: string; }; readonly workplaceSearch: { readonly box: string; readonly confluenceCloud: string; readonly confluenceServer: string; readonly customSources: string; readonly customSourcePermissions: string; readonly documentPermissions: string; readonly dropbox: string; readonly externalIdentities: string; readonly gitHub: string; readonly gettingStarted: string; readonly gmail: string; readonly googleDrive: string; readonly indexingSchedule: string; readonly jiraCloud: string; readonly jiraServer: string; readonly nativeAuth: string; readonly oneDrive: string; readonly permissions: string; readonly salesforce: string; readonly security: string; readonly serviceNow: string; readonly sharePoint: string; readonly slack: string; readonly standardAuth: string; readonly synch: string; readonly zendesk: string; }; readonly heartbeat: { readonly base: string; }; readonly libbeat: { readonly getStarted: string; }; readonly logstash: { readonly base: string; }; readonly functionbeat: { readonly base: string; }; readonly winlogbeat: { readonly base: string; }; readonly aggs: { readonly composite: string; readonly composite\_missing\_bucket: string; readonly date\_histogram: string; readonly date\_range: string; readonly date\_format\_pattern: string; readonly filter: string; readonly filters: string; readonly geohash\_grid: string; readonly histogram: string; readonly ip\_range: string; readonly range: string; readonly significant\_terms: string; readonly terms: string; readonly terms\_doc\_count\_error: string; readonly avg: string; readonly avg\_bucket: string; readonly max\_bucket: string; readonly min\_bucket: string; readonly sum\_bucket: string; readonly cardinality: string; readonly count: string; readonly cumulative\_sum: string; readonly derivative: string; readonly geo\_bounds: string; readonly geo\_centroid: string; readonly max: string; readonly median: string; readonly min: string; readonly moving\_avg: string; readonly percentile\_ranks: string; readonly serial\_diff: string; readonly std\_dev: string; readonly sum: string; readonly top\_hits: string; }; readonly runtimeFields: { readonly overview: string; readonly mapping: string; }; readonly scriptedFields: { readonly scriptFields: string; readonly scriptAggs: string; readonly painless: string; readonly painlessApi: string; readonly painlessLangSpec: string; readonly painlessSyntax: string; readonly painlessWalkthrough: string; readonly luceneExpressions: string; }; readonly search: { readonly sessions: string; readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; }; readonly addData: string; readonly kibana: string; readonly upgradeAssistant: { readonly overview: string; readonly batchReindex: string; readonly remoteReindex: string; }; readonly rollupJobs: string; readonly elasticsearch: Record<string, string>; readonly siem: { readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }; readonly securitySolution: { readonly trustedApps: string; }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; readonly luceneQuerySyntax: string; readonly percolate: string; readonly queryDsl: string; }; readonly date: { readonly dateMath: string; readonly dateMathIndexNames: string; }; readonly management: Record<string, string>; readonly ml: Record<string, string>; readonly transforms: Record<string, string>; readonly visualize: Record<string, string>; readonly apis: Readonly<{ bulkIndexAlias: string; byteSizeUnits: string; createAutoFollowPattern: string; createFollower: string; createIndex: string; createSnapshotLifecyclePolicy: string; createRoleMapping: string; createRoleMappingTemplates: string; createRollupJobsRequest: string; createApiKey: string; createPipeline: string; createTransformRequest: string; cronExpressions: string; executeWatchActionModes: string; indexExists: string; openIndex: string; putComponentTemplate: string; painlessExecute: string; painlessExecuteAPIContexts: string; putComponentTemplateMetadata: string; putSnapshotLifecyclePolicy: string; putIndexTemplateV1: string; putWatch: string; simulatePipeline: string; timeUnits: string; updateTransform: string; }>; readonly observability: Readonly<{ guide: string; infrastructureThreshold: string; logsThreshold: string; metricsThreshold: string; monitorStatus: string; monitorUptime: string; tlsCertificate: string; uptimeDurationAnomaly: string; }>; readonly alerting: Record<string, string>; readonly maps: Readonly<{ guide: string; importGeospatialPrivileges: string; gdalTutorial: string; }>; readonly monitoring: Record<string, string>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; elasticsearchSettings: string; elasticsearchEnableSecurity: string; elasticsearchEnableApiKeys: string; indicesPrivileges: string; kibanaTLS: string; kibanaPrivileges: string; mappingRoles: string; mappingRolesFieldRules: string; runAsPrivilege: string; }>; readonly spaces: Readonly<{ kibanaLegacyUrlAliases: string; kibanaDisableLegacyUrlAliasesApi: string; }>; readonly watcher: Record<string, string>; readonly ccs: Record<string, string>; readonly plugins: Record<string, string>; readonly snapshotRestore: Record<string, string>; readonly ingest: Record<string, string>; readonly fleet: Readonly<{ beatsAgentComparison: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; settings: string; settingsFleetServerHostSettings: string; settingsFleetServerProxySettings: string; troubleshooting: string; elasticAgent: string; datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; installElasticAgentStandalone: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; apiKeysLearnMore: string; onPremRegistry: string; }>; readonly ecs: { readonly guide: string; }; readonly clients: { readonly guide: string; readonly goOverview: string; readonly javaIndex: string; readonly jsIntro: string; readonly netGuide: string; readonly perlGuide: string; readonly phpGuide: string; readonly pythonGuide: string; readonly rubyOverview: string; readonly rustGuide: string; }; readonly endpoints: { readonly troubleshooting: string; }; } | |
diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts
index 92b4c815f2249..5bc7691d6a40f 100644
--- a/src/core/public/doc_links/doc_links_service.ts
+++ b/src/core/public/doc_links/doc_links_service.ts
@@ -30,6 +30,9 @@ export class DocLinksService {
const APM_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/apm/`;
const SECURITY_SOLUTION_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/`;
const STACK_GETTING_STARTED = `${ELASTIC_WEBSITE_URL}guide/en/elastic-stack-get-started/${DOC_LINK_VERSION}/`;
+ const APP_SEARCH_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/app-search/${DOC_LINK_VERSION}/`;
+ const ENTERPRISE_SEARCH_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/enterprise-search/${DOC_LINK_VERSION}/`;
+ const WORKPLACE_SEARCH_DOCS = `${ELASTIC_WEBSITE_URL}guide/en/workplace-search/${DOC_LINK_VERSION}/`;
return deepFreeze({
DOC_LINK_VERSION,
@@ -51,6 +54,9 @@ export class DocLinksService {
canvas: {
guide: `${KIBANA_DOCS}canvas.html`,
},
+ cloud: {
+ indexManagement: `${ELASTIC_WEBSITE_URL}/guide/en/cloud/current/ec-configure-index-management.html`,
+ },
dashboard: {
guide: `${KIBANA_DOCS}dashboard.html`,
drilldowns: `${KIBANA_DOCS}drilldowns.html`,
@@ -77,10 +83,64 @@ export class DocLinksService {
auditdModule: `${ELASTIC_WEBSITE_URL}guide/en/beats/auditbeat/${DOC_LINK_VERSION}/auditbeat-module-auditd.html`,
systemModule: `${ELASTIC_WEBSITE_URL}guide/en/beats/auditbeat/${DOC_LINK_VERSION}/auditbeat-module-system.html`,
},
+ appSearch: {
+ apiRef: `${APP_SEARCH_DOCS}api-reference.html`,
+ apiClients: `${APP_SEARCH_DOCS}api-clients.html`,
+ apiKeys: `${APP_SEARCH_DOCS}authentication.html#authentication-api-keys`,
+ authentication: `${APP_SEARCH_DOCS}authentication.html`,
+ crawlRules: `${APP_SEARCH_DOCS}crawl-web-content.html#crawl-web-content-manage-crawl-rules`,
+ curations: `${APP_SEARCH_DOCS}curations-guide.html`,
+ duplicateDocuments: `${APP_SEARCH_DOCS}web-crawler-reference.html#web-crawler-reference-content-deduplication`,
+ entryPoints: `${APP_SEARCH_DOCS}crawl-web-content.html#crawl-web-content-manage-entry-points`,
+ guide: `${APP_SEARCH_DOCS}index.html`,
+ indexingDocuments: `${APP_SEARCH_DOCS}indexing-documents-guide.html`,
+ indexingDocumentsSchema: `${APP_SEARCH_DOCS}indexing-documents-guide.html#indexing-documents-guide-schema`,
+ logSettings: `${APP_SEARCH_DOCS}logs.html`,
+ metaEngines: `${APP_SEARCH_DOCS}meta-engines-guide.html`,
+ nativeAuth: `${APP_SEARCH_DOCS}security-and-users.html#app-search-self-managed-security-and-user-management-elasticsearch-native-realm`,
+ precisionTuning: `${APP_SEARCH_DOCS}precision-tuning.html`,
+ relevanceTuning: `${APP_SEARCH_DOCS}relevance-tuning-guide.html`,
+ resultSettings: `${APP_SEARCH_DOCS}result-settings-guide.html`,
+ searchUI: `${APP_SEARCH_DOCS}reference-ui-guide.html`,
+ security: `${APP_SEARCH_DOCS}security-and-users.html`,
+ standardAuth: `${APP_SEARCH_DOCS}security-and-users.html#app-search-self-managed-security-and-user-management-standard`,
+ synonyms: `${APP_SEARCH_DOCS}synonyms-guide.html`,
+ webCrawler: `${APP_SEARCH_DOCS}web-crawler.html`,
+ webCrawlerEventLogs: `${APP_SEARCH_DOCS}view-web-crawler-events-logs.html`,
+ },
enterpriseSearch: {
- base: `${ELASTIC_WEBSITE_URL}guide/en/enterprise-search/${DOC_LINK_VERSION}`,
- appSearchBase: `${ELASTIC_WEBSITE_URL}guide/en/app-search/${DOC_LINK_VERSION}`,
- workplaceSearchBase: `${ELASTIC_WEBSITE_URL}guide/en/workplace-search/${DOC_LINK_VERSION}`,
+ configuration: `${ENTERPRISE_SEARCH_DOCS}configuration.html`,
+ licenseManagement: `${ENTERPRISE_SEARCH_DOCS}license-management.html`,
+ mailService: `${ENTERPRISE_SEARCH_DOCS}mailer-configuration.html`,
+ usersAccess: `${ENTERPRISE_SEARCH_DOCS}users-access.html`,
+ },
+ workplaceSearch: {
+ box: `${WORKPLACE_SEARCH_DOCS}workplace-search-box-connector.html`,
+ confluenceCloud: `${WORKPLACE_SEARCH_DOCS}workplace-search-confluence-cloud-connector.html`,
+ confluenceServer: `${WORKPLACE_SEARCH_DOCS}workplace-search-confluence-server-connector.html`,
+ customSources: `${WORKPLACE_SEARCH_DOCS}workplace-search-custom-api-sources.html`,
+ customSourcePermissions: `${WORKPLACE_SEARCH_DOCS}workplace-search-custom-api-sources.html#custom-api-source-document-level-access-control`,
+ documentPermissions: `${WORKPLACE_SEARCH_DOCS}workplace-search-sources-document-permissions.html`,
+ dropbox: `${WORKPLACE_SEARCH_DOCS}workplace-search-dropbox-connector.html`,
+ externalIdentities: `${WORKPLACE_SEARCH_DOCS}workplace-search-external-identities-api.html`,
+ gettingStarted: `${WORKPLACE_SEARCH_DOCS}workplace-search-getting-started.html`,
+ gitHub: `${WORKPLACE_SEARCH_DOCS}workplace-search-github-connector.html`,
+ gmail: `${WORKPLACE_SEARCH_DOCS}workplace-search-gmail-connector.html`,
+ googleDrive: `${WORKPLACE_SEARCH_DOCS}workplace-search-google-drive-connector.html`,
+ indexingSchedule: `${WORKPLACE_SEARCH_DOCS}workplace-search-customizing-indexing-rules.html#_indexing_schedule`,
+ jiraCloud: `${WORKPLACE_SEARCH_DOCS}workplace-search-jira-cloud-connector.html`,
+ jiraServer: `${WORKPLACE_SEARCH_DOCS}workplace-search-jira-server-connector.html`,
+ nativeAuth: `${WORKPLACE_SEARCH_DOCS}workplace-search-security.html#elasticsearch-native-realm`,
+ oneDrive: `${WORKPLACE_SEARCH_DOCS}workplace-search-onedrive-connector.html`,
+ permissions: `${WORKPLACE_SEARCH_DOCS}workplace-search-permissions.html#organizational-sources-private-sources`,
+ salesforce: `${WORKPLACE_SEARCH_DOCS}workplace-search-salesforce-connector.html`,
+ security: `${WORKPLACE_SEARCH_DOCS}workplace-search-security.html`,
+ serviceNow: `${WORKPLACE_SEARCH_DOCS}workplace-search-servicenow-connector.html`,
+ sharePoint: `${WORKPLACE_SEARCH_DOCS}workplace-search-sharepoint-online-connector.html`,
+ slack: `${WORKPLACE_SEARCH_DOCS}workplace-search-slack-connector.html`,
+ standardAuth: `${WORKPLACE_SEARCH_DOCS}workplace-search-security.html#standard`,
+ synch: `${WORKPLACE_SEARCH_DOCS}workplace-search-customizing-indexing-rules.html`,
+ zendesk: `${WORKPLACE_SEARCH_DOCS}workplace-search-zendesk-connector.html`,
},
metricbeat: {
base: `${ELASTIC_WEBSITE_URL}guide/en/beats/metricbeat/${DOC_LINK_VERSION}`,
@@ -550,6 +610,9 @@ export interface DocLinksStart {
readonly canvas: {
readonly guide: string;
};
+ readonly cloud: {
+ readonly indexManagement: string;
+ };
readonly dashboard: {
readonly guide: string;
readonly drilldowns: string;
@@ -581,10 +644,64 @@ export interface DocLinksStart {
readonly install: string;
readonly start: string;
};
+ readonly appSearch: {
+ readonly apiRef: string;
+ readonly apiClients: string;
+ readonly apiKeys: string;
+ readonly authentication: string;
+ readonly crawlRules: string;
+ readonly curations: string;
+ readonly duplicateDocuments: string;
+ readonly entryPoints: string;
+ readonly guide: string;
+ readonly indexingDocuments: string;
+ readonly indexingDocumentsSchema: string;
+ readonly logSettings: string;
+ readonly metaEngines: string;
+ readonly nativeAuth: string;
+ readonly precisionTuning: string;
+ readonly relevanceTuning: string;
+ readonly resultSettings: string;
+ readonly searchUI: string;
+ readonly security: string;
+ readonly standardAuth: string;
+ readonly synonyms: string;
+ readonly webCrawler: string;
+ readonly webCrawlerEventLogs: string;
+ };
readonly enterpriseSearch: {
- readonly base: string;
- readonly appSearchBase: string;
- readonly workplaceSearchBase: string;
+ readonly configuration: string;
+ readonly licenseManagement: string;
+ readonly mailService: string;
+ readonly usersAccess: string;
+ };
+ readonly workplaceSearch: {
+ readonly box: string;
+ readonly confluenceCloud: string;
+ readonly confluenceServer: string;
+ readonly customSources: string;
+ readonly customSourcePermissions: string;
+ readonly documentPermissions: string;
+ readonly dropbox: string;
+ readonly externalIdentities: string;
+ readonly gitHub: string;
+ readonly gettingStarted: string;
+ readonly gmail: string;
+ readonly googleDrive: string;
+ readonly indexingSchedule: string;
+ readonly jiraCloud: string;
+ readonly jiraServer: string;
+ readonly nativeAuth: string;
+ readonly oneDrive: string;
+ readonly permissions: string;
+ readonly salesforce: string;
+ readonly security: string;
+ readonly serviceNow: string;
+ readonly sharePoint: string;
+ readonly slack: string;
+ readonly standardAuth: string;
+ readonly synch: string;
+ readonly zendesk: string;
};
readonly heartbeat: {
readonly base: string;
diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md
index 772faa5321d98..cec80af843c4c 100644
--- a/src/core/public/public.api.md
+++ b/src/core/public/public.api.md
@@ -506,6 +506,9 @@ export interface DocLinksStart {
readonly canvas: {
readonly guide: string;
};
+ readonly cloud: {
+ readonly indexManagement: string;
+ };
readonly dashboard: {
readonly guide: string;
readonly drilldowns: string;
@@ -537,10 +540,64 @@ export interface DocLinksStart {
readonly install: string;
readonly start: string;
};
+ readonly appSearch: {
+ readonly apiRef: string;
+ readonly apiClients: string;
+ readonly apiKeys: string;
+ readonly authentication: string;
+ readonly crawlRules: string;
+ readonly curations: string;
+ readonly duplicateDocuments: string;
+ readonly entryPoints: string;
+ readonly guide: string;
+ readonly indexingDocuments: string;
+ readonly indexingDocumentsSchema: string;
+ readonly logSettings: string;
+ readonly metaEngines: string;
+ readonly nativeAuth: string;
+ readonly precisionTuning: string;
+ readonly relevanceTuning: string;
+ readonly resultSettings: string;
+ readonly searchUI: string;
+ readonly security: string;
+ readonly standardAuth: string;
+ readonly synonyms: string;
+ readonly webCrawler: string;
+ readonly webCrawlerEventLogs: string;
+ };
readonly enterpriseSearch: {
- readonly base: string;
- readonly appSearchBase: string;
- readonly workplaceSearchBase: string;
+ readonly configuration: string;
+ readonly licenseManagement: string;
+ readonly mailService: string;
+ readonly usersAccess: string;
+ };
+ readonly workplaceSearch: {
+ readonly box: string;
+ readonly confluenceCloud: string;
+ readonly confluenceServer: string;
+ readonly customSources: string;
+ readonly customSourcePermissions: string;
+ readonly documentPermissions: string;
+ readonly dropbox: string;
+ readonly externalIdentities: string;
+ readonly gitHub: string;
+ readonly gettingStarted: string;
+ readonly gmail: string;
+ readonly googleDrive: string;
+ readonly indexingSchedule: string;
+ readonly jiraCloud: string;
+ readonly jiraServer: string;
+ readonly nativeAuth: string;
+ readonly oneDrive: string;
+ readonly permissions: string;
+ readonly salesforce: string;
+ readonly security: string;
+ readonly serviceNow: string;
+ readonly sharePoint: string;
+ readonly slack: string;
+ readonly standardAuth: string;
+ readonly synch: string;
+ readonly zendesk: string;
};
readonly heartbeat: {
readonly base: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.test.tsx
index 19f45ced5dc5d..cb1c34a19c018 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.test.tsx
@@ -11,6 +11,8 @@ import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
+import { docLinks } from '../../../../shared/doc_links';
+
import { EmptyState } from './';
describe('EmptyState', () => {
@@ -21,7 +23,7 @@ describe('EmptyState', () => {
expect(wrapper.find('h2').text()).toEqual('No API events in the last 24 hours');
expect(wrapper.find(EuiButton).prop('href')).toEqual(
- expect.stringContaining('/api-reference.html')
+ expect.stringContaining(docLinks.appSearchApis)
);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx
index 76bd0cba1731f..c78bf3e918737 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx
@@ -8,9 +8,10 @@
import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
+
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../../routes';
+import { API_DOCS_URL } from '../../../routes';
export const EmptyState: React.FC = () => (
(
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.empty.buttonLabel', {
defaultMessage: 'View the API reference',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_rules_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_rules_table.tsx
index d447db60fb25b..bef8ed4462fdc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_rules_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_rules_table.tsx
@@ -27,7 +27,7 @@ import { clearFlashMessages, flashSuccessToast } from '../../../../shared/flash_
import { GenericEndpointInlineEditableTable } from '../../../../shared/tables/generic_endpoint_inline_editable_table';
import { InlineEditableTableColumn } from '../../../../shared/tables/inline_editable_table/types';
import { ItemWithAnID } from '../../../../shared/tables/types';
-import { DOCS_PREFIX } from '../../../routes';
+import { CRAWL_RULES_DOCS_URL } from '../../../routes';
import { CrawlerSingleDomainLogic } from '../crawler_single_domain_logic';
import {
CrawlerPolicies,
@@ -53,11 +53,7 @@ const DEFAULT_DESCRIPTION = (
defaultMessage="Create a crawl rule to include or exclude pages whose URL matches the rule. Rules run in sequential order, and each URL is evaluated according to the first match. {link}"
values={{
link: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.crawlRulesTable.descriptionLinkText',
{ defaultMessage: 'Learn more about crawl rules' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/deduplication_panel/deduplication_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/deduplication_panel/deduplication_panel.tsx
index ea894e2b00acf..26794d0421353 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/deduplication_panel/deduplication_panel.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/deduplication_panel/deduplication_panel.tsx
@@ -27,7 +27,7 @@ import { EuiSelectableLIOption } from '@elastic/eui/src/components/selectable/se
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
-import { DOCS_PREFIX } from '../../../../routes';
+import { DUPLICATE_DOCS_URL } from '../../../../routes';
import { DataPanel } from '../../../data_panel';
import { CrawlerSingleDomainLogic } from '../../crawler_single_domain_logic';
@@ -84,11 +84,7 @@ export const DeduplicationPanel: React.FC = () => {
documents on this domain. {documentationLink}."
values={{
documentationLink: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.deduplicationPanel.learnMoreMessage',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/entry_points_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/entry_points_table.tsx
index aaf3cc4516067..4fc7a0569ba0e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/entry_points_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/entry_points_table.tsx
@@ -17,7 +17,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { GenericEndpointInlineEditableTable } from '../../../../shared/tables/generic_endpoint_inline_editable_table';
import { InlineEditableTableColumn } from '../../../../shared/tables/inline_editable_table/types';
import { ItemWithAnID } from '../../../../shared/tables/types';
-import { DOCS_PREFIX } from '../../../routes';
+import { ENTRY_POINTS_DOCS_URL } from '../../../routes';
import { CrawlerDomain, EntryPoint } from '../types';
import { EntryPointsTableLogic } from './entry_points_table_logic';
@@ -80,11 +80,7 @@ export const EntryPointsTable: React.FC = ({
defaultMessage:
'Include the most important URLs for your website here. Entry point URLs will be the first pages to be indexed and processed for links to other pages.',
})}{' '}
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.learnMoreLinkText',
{ defaultMessage: 'Learn more about entry points.' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/automatic_crawl_scheduler.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/automatic_crawl_scheduler.tsx
index 5f7200cb826df..128dcdcb778cf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/automatic_crawl_scheduler.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/automatic_crawl_scheduler.tsx
@@ -37,7 +37,7 @@ import {
} from '../../../../..//shared/constants/units';
import { CANCEL_BUTTON_LABEL, SAVE_BUTTON_LABEL } from '../../../../../shared/constants';
-import { DOCS_PREFIX } from '../../../../routes';
+import { WEB_CRAWLER_DOCS_URL } from '../../../../routes';
import { CrawlUnits } from '../../types';
import { AutomaticCrawlSchedulerLogic } from './automatic_crawl_scheduler_logic';
@@ -81,7 +81,7 @@ export const AutomaticCrawlScheduler: React.FC = () => {
defaultMessage="Don't worry about it, we'll start a crawl for you. {readMoreMessage}."
values={{
readMoreMessage: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.automaticCrawlSchedule.readMoreLink',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx
index 6c3cb51111ae1..c84deb3cb0c99 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx
@@ -13,7 +13,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiSpacer, EuiText, EuiTitle } from
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../routes';
+import { WEB_CRAWLER_DOCS_URL, WEB_CRAWLER_LOG_DOCS_URL } from '../../routes';
import { getEngineBreadcrumbs } from '../engine';
import { AppSearchPageTemplate } from '../layout';
@@ -77,7 +77,7 @@ export const CrawlerOverview: React.FC = () => {
defaultMessage:
"Easily index your website's content. To get started, enter your domain name, provide optional entry points and crawl rules, and we will handle the rest.",
})}{' '}
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.empty.crawlerDocumentationLinkDescription',
{
@@ -114,11 +114,7 @@ export const CrawlerOverview: React.FC = () => {
defaultMessage:
"Recent crawl requests are logged here. Using the request ID of each crawl, you can track progress and examine crawl events in Kibana's Discover or Logs user interfaces.",
})}{' '}
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.configurationDocumentationLinkDescription',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts
index 6a5f3df0e86f6..315b4d864b3f2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts
@@ -7,7 +7,7 @@
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../routes';
+import { AUTHENTICATION_DOCS_URL } from '../../routes';
export const CREDENTIALS_TITLE = i18n.translate(
'xpack.enterpriseSearch.appSearch.credentials.title',
@@ -109,4 +109,4 @@ export const TOKEN_TYPE_INFO = [
export const FLYOUT_ARIA_LABEL_ID = 'credentialsFlyoutTitle';
-export const DOCS_HREF = `${DOCS_PREFIX}/authentication.html`;
+export const DOCS_HREF = AUTHENTICATION_DOCS_URL;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx
index 040f313b12205..3ea2c022ec489 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx
@@ -21,7 +21,7 @@ import { i18n } from '@kbn/i18n';
import { EDIT_BUTTON_LABEL, DELETE_BUTTON_LABEL } from '../../../../shared/constants';
import { HiddenText } from '../../../../shared/hidden_text';
import { convertMetaToPagination, handlePageChange } from '../../../../shared/table_pagination';
-import { DOCS_PREFIX } from '../../../routes';
+import { API_KEYS_DOCS_URL } from '../../../routes';
import { TOKEN_TYPE_DISPLAY_NAMES } from '../constants';
import { CredentialsLogic } from '../credentials_logic';
import { ApiToken } from '../types';
@@ -141,12 +141,7 @@ export const CredentialsList: React.FC = () => {
defaultMessage: 'Allow applications to access Elastic App Search on your behalf.',
})}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.credentials.empty.buttonLabel', {
defaultMessage: 'Learn about API keys',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.test.tsx
index 60ae386bea58e..69c2cc4b987b1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.test.tsx
@@ -11,6 +11,8 @@ import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
+import { docLinks } from '../../../../shared/doc_links';
+
import { EmptyState } from './';
describe('EmptyState', () => {
@@ -21,7 +23,7 @@ describe('EmptyState', () => {
expect(wrapper.find('h2').text()).toEqual('Create your first curation');
expect(wrapper.find(EuiButton).prop('href')).toEqual(
- expect.stringContaining('/curations-guide.html')
+ expect.stringContaining(docLinks.appSearchCurations)
);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.tsx
index 872a7282136e3..10d81f1623959 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../../routes';
+import { CURATIONS_DOCS_URL } from '../../../routes';
export const EmptyState: React.FC = () => (
(
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.curations.empty.buttonLabel', {
defaultMessage: 'Read the curations guide',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.test.tsx
index 4b4e11c31d4b8..b95ae0bca5bf6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.test.tsx
@@ -19,6 +19,8 @@ import { EuiButtonEmpty, EuiCallOut, EuiSwitch } from '@elastic/eui';
import { mountWithIntl } from '@kbn/test/jest';
+import { docLinks } from '../../../../../shared/doc_links';
+
import { Loading } from '../../../../../shared/loading';
import { EuiButtonTo } from '../../../../../shared/react_router_helpers';
import { DataPanel } from '../../../data_panel';
@@ -227,7 +229,7 @@ describe('CurationsSettings', () => {
const wrapper = shallow();
expect(wrapper.is(DataPanel)).toBe(true);
expect(wrapper.prop('action').props.to).toEqual('/app/management/stack/license_management');
- expect(wrapper.find(EuiButtonEmpty).prop('href')).toEqual('/license-management.html');
+ expect(wrapper.find(EuiButtonEmpty).prop('href')).toEqual(docLinks.licenseManagement);
});
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.tsx
index d78ca852ee7d1..ffefea96d3a22 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.tsx
@@ -110,11 +110,7 @@ export const CurationsSettings: React.FC = () => {
}
>
-
+
{i18n.translate('xpack.enterpriseSearch.curations.settings.licenseUpgradeLink', {
defaultMessage: 'Learn more about license upgrades',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx
index 793c6250d859c..e86b06b423a9d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx
@@ -30,7 +30,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { CANCEL_BUTTON_LABEL } from '../../../../shared/constants';
import { getEnterpriseSearchUrl } from '../../../../shared/enterprise_search_url';
-import { DOCS_PREFIX } from '../../../routes';
+import { API_CLIENTS_DOCS_URL, INDEXING_DOCS_URL } from '../../../routes';
import { EngineLogic } from '../../engine';
import { EngineDetails } from '../../engine/types';
@@ -74,12 +74,12 @@ export const FlyoutBody: React.FC = () => {
defaultMessage="The {documentsApiLink} can be used to add new documents to your engine, update documents, retrieve documents by id, and delete documents. There are a variety of {clientLibrariesLink} to help you get started."
values={{
documentsApiLink: (
-
+
documents API
),
clientLibrariesLink: (
-
+
client libraries
),
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx
index 5366c00c0e7fc..a8179f297644f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx
@@ -27,7 +27,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { parseQueryParams } from '../../../shared/query_params';
import { EuiCardTo } from '../../../shared/react_router_helpers';
-import { DOCS_PREFIX, ENGINE_CRAWLER_PATH } from '../../routes';
+import { INDEXING_DOCS_URL, ENGINE_CRAWLER_PATH } from '../../routes';
import { generateEnginePath } from '../engine';
import { DocumentCreationLogic } from './';
@@ -66,7 +66,7 @@ export const DocumentCreationButtons: React.FC = ({ disabled = false }) =
jsonCode: .json,
postCode: POST,
documentsApiLink: (
-
+
documents API
),
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.test.tsx
index 907dcf8c9c208..b8bb26fa9ad63 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.test.tsx
@@ -11,6 +11,8 @@ import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
+import { docLinks } from '../../../../shared/doc_links';
+
import { EmptyState } from './';
describe('EmptyState', () => {
@@ -21,7 +23,7 @@ describe('EmptyState', () => {
expect(wrapper.find('h2').text()).toEqual('Add your first documents');
expect(wrapper.find(EuiButton).prop('href')).toEqual(
- expect.stringContaining('/indexing-documents-guide.html')
+ expect.stringContaining(docLinks.appSearchIndexingDocs)
);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.tsx
index 39fe02a84854c..85e834b320751 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../../routes';
+import { INDEXING_DOCS_URL } from '../../../routes';
export const EmptyState = () => (
(
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.documents.empty.buttonLabel', {
defaultMessage: 'Read the documents guide',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx
index 6750ebf1140e0..54bc7fb26e9d0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx
@@ -33,7 +33,7 @@ describe('EmptyEngineOverview', () => {
it('renders a documentation link', () => {
expect(getPageHeaderActions(wrapper).find(EuiButton).prop('href')).toEqual(
- `${docLinks.appSearchBase}/index.html`
+ docLinks.appSearchGuide
);
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx
index 6f8332e1e332e..ada2df654d52b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../routes';
+import { DOCS_URL } from '../../routes';
import { DocumentCreationButtons, DocumentCreationFlyout } from '../document_creation';
import { getEngineBreadcrumbs } from '../engine';
@@ -26,7 +26,7 @@ export const EmptyEngineOverview: React.FC = () => {
{ defaultMessage: 'Engine setup' }
),
rightSideItems: [
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.overview.empty.headingAction',
{ defaultMessage: 'View documentation' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.test.tsx
index 8b4f5a69b8141..350412825b996 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.test.tsx
@@ -11,6 +11,8 @@ import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
+import { docLinks } from '../../../../shared/doc_links';
+
import { EmptyMetaEnginesState } from './';
describe('EmptyMetaEnginesState', () => {
@@ -21,7 +23,7 @@ describe('EmptyMetaEnginesState', () => {
expect(wrapper.find('h3').text()).toEqual('Create your first meta engine');
expect(wrapper.find(EuiButton).prop('href')).toEqual(
- expect.stringContaining('/meta-engines-guide.html')
+ expect.stringContaining(docLinks.appSearchMetaEngines)
);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.tsx
index ad96f21022f2b..3cf461e3f7d45 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_meta_engines_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../../routes';
+import { META_ENGINES_DOCS_URL } from '../../../routes';
export const EmptyMetaEnginesState: React.FC = () => (
(
}
actions={
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engines.metaEngines.emptyPromptButtonLabel',
{ defaultMessage: 'Learn more about meta engines' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.tsx
index 8fbbf406cf5d3..bf2a122ead42b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/constants.tsx
@@ -11,7 +11,7 @@ import { EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
-import { DOCS_PREFIX } from '../../routes';
+import { META_ENGINES_DOCS_URL } from '../../routes';
import {
META_ENGINE_CREATION_FORM_META_ENGINE_DESCRIPTION,
META_ENGINE_CREATION_FORM_DOCUMENTATION_LINK,
@@ -40,7 +40,7 @@ export const META_ENGINES_DESCRIPTION = (
defaultMessage="{readDocumentationLink} for more information or upgrade to a Platinum license to get started."
values={{
readDocumentationLink: (
-
+
{META_ENGINE_CREATION_FORM_DOCUMENTATION_LINK}
),
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/constants.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/constants.tsx
index af7b6f3201b3e..e41809054e123 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/constants.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/meta_engine_creation/constants.tsx
@@ -11,7 +11,7 @@ import { EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
-import { DOCS_PREFIX } from '../../routes';
+import { META_ENGINES_DOCS_URL } from '../../routes';
export const DEFAULT_LANGUAGE = 'Universal';
@@ -57,7 +57,7 @@ export const META_ENGINE_CREATION_FORM_DOCUMENTATION_DESCRIPTION = (
defaultMessage="{documentationLink} for information about how to get started."
values={{
documentationLink: (
-
+
{META_ENGINE_CREATION_FORM_DOCUMENTATION_LINK}
),
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.test.tsx
index a60f68c19f6dc..454437a203bc2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.test.tsx
@@ -11,6 +11,8 @@ import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
+import { docLinks } from '../../../../shared/doc_links';
+
import { EmptyState } from './';
describe('EmptyState', () => {
@@ -21,7 +23,7 @@ describe('EmptyState', () => {
expect(wrapper.find('h2').text()).toEqual('Add documents to tune relevance');
expect(wrapper.find(EuiButton).prop('href')).toEqual(
- expect.stringContaining('/relevance-tuning-guide.html')
+ expect.stringContaining(docLinks.appSearchRelevance)
);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx
index df29010bd682f..f17f7a582efdf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../../routes';
+import { RELEVANCE_DOCS_URL } from '../../../routes';
export const EmptyState: React.FC = () => (
(
}
)}
actions={
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.buttonLabel',
{ defaultMessage: 'Read the relevance tuning guide' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.test.tsx
index 3be30b77bc2e4..0554b31c88356 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.test.tsx
@@ -11,6 +11,8 @@ import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
+import { docLinks } from '../../../../../shared/doc_links';
+
import { rerender } from '../../../../../test_helpers';
import { STEP_DESCRIPTIONS } from './constants';
@@ -82,7 +84,7 @@ describe('PrecisionSlider', () => {
it('contains a documentation link', () => {
const documentationLink = wrapper.find('[data-test-subj="documentationLink"]');
- expect(documentationLink.prop('href')).toContain('/precision-tuning.html');
+ expect(documentationLink.prop('href')).toContain(docLinks.appSearchPrecision);
expect(documentationLink.prop('target')).toEqual('_blank');
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx
index 8e7a59c290ce2..e4b2027aa3d6d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx
@@ -21,7 +21,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../../../routes';
+import { PRECISION_DOCS_URL } from '../../../../routes';
import { RelevanceTuningLogic } from '../../relevance_tuning_logic';
import { STEP_DESCRIPTIONS } from './constants';
@@ -57,11 +57,7 @@ export const PrecisionSlider: React.FC = () => {
defaultMessage: 'Fine tune the precision vs. recall settings on your engine.',
}
)}{' '}
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.precisionSlider.learnMore.link',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.tsx
index d8963b33b8ab2..463c61fb60c99 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_callouts.tsx
@@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiLinkTo } from '../../../shared/react_router_helpers';
-import { DOCS_PREFIX, ENGINE_SCHEMA_PATH } from '../../routes';
+import { META_ENGINES_DOCS_URL, ENGINE_SCHEMA_PATH } from '../../routes';
import { EngineLogic, generateEnginePath } from '../engine';
import { RelevanceTuningLogic } from '.';
@@ -98,7 +98,7 @@ export const RelevanceTuningCallouts: React.FC = () => {
values={{
schemaFieldsWithConflictsCount,
link: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.whatsThisLinkLabel',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.test.tsx
index 537fd9ec6a0d4..8798c1a4bc529 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.test.tsx
@@ -11,6 +11,8 @@ import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
+import { docLinks } from '../../../../shared/doc_links';
+
import { EmptyState } from './';
describe('EmptyState', () => {
@@ -21,7 +23,7 @@ describe('EmptyState', () => {
expect(wrapper.find('h2').text()).toEqual('Add documents to adjust settings');
expect(wrapper.find(EuiButton).prop('href')).toEqual(
- expect.stringContaining('/result-settings-guide.html')
+ expect.stringContaining(docLinks.appSearchResultSettings)
);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.tsx
index dae8390a35fd7..7f91447b910b6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../../routes';
+import { RESULT_SETTINGS_DOCS_URL } from '../../../routes';
export const EmptyState: React.FC = () => (
(
}
)}
actions={
-
+
{i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.buttonLabel',
{ defaultMessage: 'Read the result settings guide' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.tsx
index 3e692aa48623e..e2021ac582d0c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings.tsx
@@ -22,7 +22,7 @@ import {
} from '../../../shared/role_mapping';
import { ROLE_MAPPINGS_TITLE } from '../../../shared/role_mapping/constants';
-import { DOCS_PREFIX } from '../../routes';
+import { SECURITY_DOCS_URL } from '../../routes';
import { AppSearchPageTemplate } from '../layout';
import { ROLE_MAPPINGS_ENGINE_ACCESS_HEADING } from './constants';
@@ -30,8 +30,6 @@ import { RoleMapping } from './role_mapping';
import { RoleMappingsLogic } from './role_mappings_logic';
import { User } from './user';
-const ROLES_DOCS_LINK = `${DOCS_PREFIX}/security-and-users.html`;
-
export const RoleMappings: React.FC = () => {
const {
enableRoleBasedAccess,
@@ -60,7 +58,7 @@ export const RoleMappings: React.FC = () => {
const rolesEmptyState = (
);
@@ -69,7 +67,7 @@ export const RoleMappings: React.FC = () => {
initializeRoleMapping()}
/>
{
expect(wrapper.find('h2').text()).toEqual('Create a schema');
expect(wrapper.find(EuiButton).prop('href')).toEqual(
- expect.stringContaining('#indexing-documents-guide-schema')
+ expect.stringContaining(docLinks.appSearchIndexingDocsSchema)
);
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/empty_state.tsx
index ad9285c7b8fef..3c2d5fc4df66a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/schema/components/empty_state.tsx
@@ -13,7 +13,7 @@ import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { SchemaAddFieldModal } from '../../../../shared/schema';
-import { DOCS_PREFIX } from '../../../routes';
+import { INDEXING_SCHEMA_DOCS_URL } from '../../../routes';
import { SchemaLogic } from '../schema_logic';
export const EmptyState: React.FC = () => {
@@ -40,12 +40,7 @@ export const EmptyState: React.FC = () => {
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.schema.empty.buttonLabel', {
defaultMessage: 'Read the indexing schema guide',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.test.tsx
index 39f0cb376b325..3466542c09739 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.test.tsx
@@ -11,6 +11,8 @@ import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
+import { docLinks } from '../../../../shared/doc_links';
+
import { EmptyState } from './empty_state';
describe('EmptyState', () => {
@@ -21,7 +23,7 @@ describe('EmptyState', () => {
expect(wrapper.find('h2').text()).toEqual('Add documents to generate a Search UI');
expect(wrapper.find(EuiButton).prop('href')).toEqual(
- expect.stringContaining('/reference-ui-guide.html')
+ expect.stringContaining(docLinks.appSearchSearchUI)
);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.tsx
index b7665a58de300..9a663e1372211 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../../routes';
+import { SEARCH_UI_DOCS_URL } from '../../../routes';
export const EmptyState: React.FC = () => (
(
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.searchUI.empty.buttonLabel', {
defaultMessage: 'Read the Search UI guide',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.tsx
index 2b210bd07ab4b..43ea60fa84617 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/search_ui/search_ui.tsx
@@ -12,7 +12,7 @@ import { useActions, useValues } from 'kea';
import { EuiText, EuiFlexItem, EuiFlexGroup, EuiSpacer, EuiLink } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
-import { DOCS_PREFIX } from '../../routes';
+import { SEARCH_UI_DOCS_URL } from '../../routes';
import { EngineLogic, getEngineBreadcrumbs } from '../engine';
import { AppSearchPageTemplate } from '../layout';
@@ -62,7 +62,7 @@ export const SearchUI: React.FC = () => {
defaultMessage="Use the fields below to generate a sample search experience built with Search UI. Use the sample to preview search results, or build upon it to create your own custom search experience. {link}."
values={{
link: (
-
+
{
defaultMessage: 'Log retention is determined by the ILM policies for your deployment.',
})}
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.settings.logRetention.learnMore', {
defaultMessage: 'Learn more about log retention for Enterprise Search.',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx
index d460132dddbb1..f1d9beaca5136 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx
@@ -15,7 +15,7 @@ import { APP_SEARCH_PLUGIN } from '../../../../../common/constants';
import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SetupGuideLayout, SETUP_GUIDE_TITLE } from '../../../shared/setup_guide';
import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
-import { DOCS_PREFIX } from '../../routes';
+import { NATIVE_AUTH_DOCS_URL, STANDARD_AUTH_DOCS_URL } from '../../routes';
import GettingStarted from './assets/getting_started.png';
@@ -23,8 +23,8 @@ export const SetupGuide: React.FC = () => (
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.test.tsx
index a43f170e5822f..cdfdbadf6759c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.test.tsx
@@ -11,6 +11,8 @@ import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
+import { docLinks } from '../../../../shared/doc_links';
+
import { EmptyState, SynonymModal } from './';
describe('EmptyState', () => {
@@ -21,7 +23,7 @@ describe('EmptyState', () => {
expect(wrapper.find('h2').text()).toEqual('Create your first synonym set');
expect(wrapper.find(EuiButton).prop('href')).toEqual(
- expect.stringContaining('/synonyms-guide.html')
+ expect.stringContaining(docLinks.appSearchSynonyms)
);
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx
index f856a5c035f81..ac8383ccea9ee 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { DOCS_PREFIX } from '../../../routes';
+import { SYNONYMS_DOCS_URL } from '../../../routes';
import { SynonymModal, SynonymIcon } from './';
@@ -35,12 +35,7 @@ export const EmptyState: React.FC = () => {
}
actions={
-
+
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.synonyms.empty.buttonLabel', {
defaultMessage: 'Read the synonyms guide',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts
index 97a9b407b3cd6..1f2e7c883e1cb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts
@@ -7,7 +7,29 @@
import { docLinks } from '../shared/doc_links';
-export const DOCS_PREFIX = docLinks.appSearchBase;
+export const API_DOCS_URL = docLinks.appSearchApis;
+export const API_CLIENTS_DOCS_URL = docLinks.appSearchApiClients;
+export const API_KEYS_DOCS_URL = docLinks.appSearchApiKeys;
+export const AUTHENTICATION_DOCS_URL = docLinks.appSearchAuthentication;
+export const CRAWL_RULES_DOCS_URL = docLinks.appSearchCrawlRules;
+export const CURATIONS_DOCS_URL = docLinks.appSearchCurations;
+export const DOCS_URL = docLinks.appSearchGuide;
+export const DUPLICATE_DOCS_URL = docLinks.appSearchDuplicateDocuments;
+export const ENTRY_POINTS_DOCS_URL = docLinks.appSearchEntryPoints;
+export const INDEXING_DOCS_URL = docLinks.appSearchIndexingDocs;
+export const INDEXING_SCHEMA_DOCS_URL = docLinks.appSearchIndexingDocsSchema;
+export const LOG_SETTINGS_DOCS_URL = docLinks.appSearchLogSettings;
+export const META_ENGINES_DOCS_URL = docLinks.appSearchMetaEngines;
+export const NATIVE_AUTH_DOCS_URL = docLinks.appSearchNativeAuth;
+export const PRECISION_DOCS_URL = docLinks.appSearchPrecision;
+export const RELEVANCE_DOCS_URL = docLinks.appSearchRelevance;
+export const RESULT_SETTINGS_DOCS_URL = docLinks.appSearchResultSettings;
+export const SEARCH_UI_DOCS_URL = docLinks.appSearchSearchUI;
+export const SECURITY_DOCS_URL = docLinks.appSearchSecurity;
+export const STANDARD_AUTH_DOCS_URL = docLinks.appSearchStandardAuth;
+export const SYNONYMS_DOCS_URL = docLinks.appSearchSynonyms;
+export const WEB_CRAWLER_DOCS_URL = docLinks.appSearchWebCrawler;
+export const WEB_CRAWLER_LOG_DOCS_URL = docLinks.appSearchWebCrawlerEventLogs;
export const ROOT_PATH = '/';
export const SETUP_GUIDE_PATH = '/setup_guide';
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.tsx
index e82dbcaa41135..c7c85fdd49359 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.tsx
@@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { ENTERPRISE_SEARCH_PLUGIN } from '../../../../../common/constants';
-import { DOCS_PREFIX } from '../../../app_search/routes';
+import { NATIVE_AUTH_DOCS_URL, STANDARD_AUTH_DOCS_URL } from '../../../app_search/routes';
import { SetEnterpriseSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SetupGuideLayout, SETUP_GUIDE_TITLE } from '../../../shared/setup_guide';
import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
@@ -23,8 +23,8 @@ export const SetupGuide: React.FC = () => (
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.test.ts
index cbd7a1c6107b1..b14af1c69795a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.test.ts
@@ -5,27 +5,23 @@
* 2.0.
*/
+import { docLinksServiceMock } from '../../../../../../../src/core/public/mocks';
+
import { docLinks } from './';
describe('DocLinks', () => {
it('setDocLinks', () => {
const links = {
- DOC_LINK_VERSION: '',
- ELASTIC_WEBSITE_URL: 'https://elastic.co/',
- links: {
- enterpriseSearch: {
- base: 'http://elastic.enterprise.search',
- appSearchBase: 'http://elastic.app.search',
- workplaceSearchBase: 'http://elastic.workplace.search',
- },
- },
+ DOC_LINK_VERSION: docLinksServiceMock.createStartContract().DOC_LINK_VERSION,
+ ELASTIC_WEBSITE_URL: docLinksServiceMock.createStartContract().ELASTIC_WEBSITE_URL,
+ links: docLinksServiceMock.createStartContract().links,
};
docLinks.setDocLinks(links as any);
- expect(docLinks.enterpriseSearchBase).toEqual('http://elastic.enterprise.search');
- expect(docLinks.appSearchBase).toEqual('http://elastic.app.search');
- expect(docLinks.workplaceSearchBase).toEqual('http://elastic.workplace.search');
- expect(docLinks.cloudBase).toEqual('https://elastic.co/guide/en/cloud/current');
+ expect(docLinks.appSearchApis).toEqual(links.links.appSearch.apiRef);
+ expect(docLinks.cloudIndexManagement).toEqual(links.links.cloud.indexManagement);
+ expect(docLinks.enterpriseSearchConfig).toEqual(links.links.enterpriseSearch.configuration);
+ expect(docLinks.workplaceSearchZendesk).toEqual(links.links.workplaceSearch.zendesk);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.ts b/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.ts
index 6034846fac4f1..93bead4d31f4c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/doc_links/doc_links.ts
@@ -8,23 +8,174 @@
import { DocLinksStart } from 'kibana/public';
class DocLinks {
- public enterpriseSearchBase: string;
- public appSearchBase: string;
- public workplaceSearchBase: string;
- public cloudBase: string;
+ public appSearchApis: string;
+ public appSearchApiClients: string;
+ public appSearchApiKeys: string;
+ public appSearchAuthentication: string;
+ public appSearchCrawlRules: string;
+ public appSearchCurations: string;
+ public appSearchDuplicateDocuments: string;
+ public appSearchEntryPoints: string;
+ public appSearchGuide: string;
+ public appSearchIndexingDocs: string;
+ public appSearchIndexingDocsSchema: string;
+ public appSearchLogSettings: string;
+ public appSearchMetaEngines: string;
+ public appSearchNativeAuth: string;
+ public appSearchPrecision: string;
+ public appSearchRelevance: string;
+ public appSearchResultSettings: string;
+ public appSearchSearchUI: string;
+ public appSearchSecurity: string;
+ public appSearchStandardAuth: string;
+ public appSearchSynonyms: string;
+ public appSearchWebCrawler: string;
+ public appSearchWebCrawlerEventLogs: string;
+ public cloudIndexManagement: string;
+ public enterpriseSearchConfig: string;
+ public enterpriseSearchMailService: string;
+ public enterpriseSearchUsersAccess: string;
+ public licenseManagement: string;
+ public workplaceSearchBox: string;
+ public workplaceSearchConfluenceCloud: string;
+ public workplaceSearchConfluenceServer: string;
+ public workplaceSearchCustomSources: string;
+ public workplaceSearchCustomSourcePermissions: string;
+ public workplaceSearchDocumentPermissions: string;
+ public workplaceSearchDropbox: string;
+ public workplaceSearchExternalIdentities: string;
+ public workplaceSearchGettingStarted: string;
+ public workplaceSearchGitHub: string;
+ public workplaceSearchGmail: string;
+ public workplaceSearchGoogleDrive: string;
+ public workplaceSearchIndexingSchedule: string;
+ public workplaceSearchJiraCloud: string;
+ public workplaceSearchJiraServer: string;
+ public workplaceSearchNativeAuth: string;
+ public workplaceSearchOneDrive: string;
+ public workplaceSearchPermissions: string;
+ public workplaceSearchSalesforce: string;
+ public workplaceSearchSecurity: string;
+ public workplaceSearchServiceNow: string;
+ public workplaceSearchSharePoint: string;
+ public workplaceSearchSlack: string;
+ public workplaceSearchStandardAuth: string;
+ public workplaceSearchSynch: string;
+ public workplaceSearchZendesk: string;
constructor() {
- this.enterpriseSearchBase = '';
- this.appSearchBase = '';
- this.workplaceSearchBase = '';
- this.cloudBase = '';
+ this.appSearchApis = '';
+ this.appSearchApiClients = '';
+ this.appSearchApiKeys = '';
+ this.appSearchAuthentication = '';
+ this.appSearchCrawlRules = '';
+ this.appSearchCurations = '';
+ this.appSearchDuplicateDocuments = '';
+ this.appSearchEntryPoints = '';
+ this.appSearchGuide = '';
+ this.appSearchIndexingDocs = '';
+ this.appSearchIndexingDocsSchema = '';
+ this.appSearchLogSettings = '';
+ this.appSearchMetaEngines = '';
+ this.appSearchNativeAuth = '';
+ this.appSearchPrecision = '';
+ this.appSearchRelevance = '';
+ this.appSearchResultSettings = '';
+ this.appSearchSearchUI = '';
+ this.appSearchSecurity = '';
+ this.appSearchStandardAuth = '';
+ this.appSearchSynonyms = '';
+ this.appSearchWebCrawler = '';
+ this.appSearchWebCrawlerEventLogs = '';
+ this.cloudIndexManagement = '';
+ this.enterpriseSearchConfig = '';
+ this.enterpriseSearchMailService = '';
+ this.enterpriseSearchUsersAccess = '';
+ this.licenseManagement = '';
+ this.workplaceSearchBox = '';
+ this.workplaceSearchConfluenceCloud = '';
+ this.workplaceSearchConfluenceServer = '';
+ this.workplaceSearchCustomSources = '';
+ this.workplaceSearchCustomSourcePermissions = '';
+ this.workplaceSearchDocumentPermissions = '';
+ this.workplaceSearchDropbox = '';
+ this.workplaceSearchExternalIdentities = '';
+ this.workplaceSearchGettingStarted = '';
+ this.workplaceSearchGitHub = '';
+ this.workplaceSearchGmail = '';
+ this.workplaceSearchGoogleDrive = '';
+ this.workplaceSearchIndexingSchedule = '';
+ this.workplaceSearchJiraCloud = '';
+ this.workplaceSearchJiraServer = '';
+ this.workplaceSearchNativeAuth = '';
+ this.workplaceSearchOneDrive = '';
+ this.workplaceSearchPermissions = '';
+ this.workplaceSearchSalesforce = '';
+ this.workplaceSearchSecurity = '';
+ this.workplaceSearchServiceNow = '';
+ this.workplaceSearchSharePoint = '';
+ this.workplaceSearchSlack = '';
+ this.workplaceSearchStandardAuth = '';
+ this.workplaceSearchSynch = '';
+ this.workplaceSearchZendesk = '';
}
public setDocLinks(docLinks: DocLinksStart): void {
- this.enterpriseSearchBase = docLinks.links.enterpriseSearch.base;
- this.appSearchBase = docLinks.links.enterpriseSearch.appSearchBase;
- this.workplaceSearchBase = docLinks.links.enterpriseSearch.workplaceSearchBase;
- this.cloudBase = `${docLinks.ELASTIC_WEBSITE_URL}guide/en/cloud/current`;
+ this.appSearchApis = docLinks.links.appSearch.apiRef;
+ this.appSearchApiClients = docLinks.links.appSearch.apiClients;
+ this.appSearchApiKeys = docLinks.links.appSearch.apiKeys;
+ this.appSearchAuthentication = docLinks.links.appSearch.authentication;
+ this.appSearchCrawlRules = docLinks.links.appSearch.crawlRules;
+ this.appSearchCurations = docLinks.links.appSearch.curations;
+ this.appSearchDuplicateDocuments = docLinks.links.appSearch.duplicateDocuments;
+ this.appSearchEntryPoints = docLinks.links.appSearch.entryPoints;
+ this.appSearchGuide = docLinks.links.appSearch.guide;
+ this.appSearchIndexingDocs = docLinks.links.appSearch.indexingDocuments;
+ this.appSearchIndexingDocsSchema = docLinks.links.appSearch.indexingDocumentsSchema;
+ this.appSearchLogSettings = docLinks.links.appSearch.logSettings;
+ this.appSearchMetaEngines = docLinks.links.appSearch.metaEngines;
+ this.appSearchNativeAuth = docLinks.links.appSearch.nativeAuth;
+ this.appSearchPrecision = docLinks.links.appSearch.precisionTuning;
+ this.appSearchRelevance = docLinks.links.appSearch.relevanceTuning;
+ this.appSearchResultSettings = docLinks.links.appSearch.resultSettings;
+ this.appSearchSearchUI = docLinks.links.appSearch.searchUI;
+ this.appSearchSecurity = docLinks.links.appSearch.security;
+ this.appSearchStandardAuth = docLinks.links.appSearch.standardAuth;
+ this.appSearchSynonyms = docLinks.links.appSearch.synonyms;
+ this.appSearchWebCrawler = docLinks.links.appSearch.webCrawler;
+ this.appSearchWebCrawlerEventLogs = docLinks.links.appSearch.webCrawlerEventLogs;
+ this.cloudIndexManagement = docLinks.links.cloud.indexManagement;
+ this.enterpriseSearchConfig = docLinks.links.enterpriseSearch.configuration;
+ this.enterpriseSearchMailService = docLinks.links.enterpriseSearch.mailService;
+ this.enterpriseSearchUsersAccess = docLinks.links.enterpriseSearch.usersAccess;
+ this.licenseManagement = docLinks.links.enterpriseSearch.licenseManagement;
+ this.workplaceSearchBox = docLinks.links.workplaceSearch.box;
+ this.workplaceSearchConfluenceCloud = docLinks.links.workplaceSearch.confluenceCloud;
+ this.workplaceSearchConfluenceServer = docLinks.links.workplaceSearch.confluenceServer;
+ this.workplaceSearchCustomSources = docLinks.links.workplaceSearch.customSources;
+ this.workplaceSearchCustomSourcePermissions =
+ docLinks.links.workplaceSearch.customSourcePermissions;
+ this.workplaceSearchDocumentPermissions = docLinks.links.workplaceSearch.documentPermissions;
+ this.workplaceSearchDropbox = docLinks.links.workplaceSearch.dropbox;
+ this.workplaceSearchExternalIdentities = docLinks.links.workplaceSearch.externalIdentities;
+ this.workplaceSearchGettingStarted = docLinks.links.workplaceSearch.gettingStarted;
+ this.workplaceSearchGitHub = docLinks.links.workplaceSearch.gitHub;
+ this.workplaceSearchGmail = docLinks.links.workplaceSearch.gmail;
+ this.workplaceSearchGoogleDrive = docLinks.links.workplaceSearch.googleDrive;
+ this.workplaceSearchIndexingSchedule = docLinks.links.workplaceSearch.indexingSchedule;
+ this.workplaceSearchJiraCloud = docLinks.links.workplaceSearch.jiraCloud;
+ this.workplaceSearchJiraServer = docLinks.links.workplaceSearch.jiraServer;
+ this.workplaceSearchNativeAuth = docLinks.links.workplaceSearch.nativeAuth;
+ this.workplaceSearchOneDrive = docLinks.links.workplaceSearch.oneDrive;
+ this.workplaceSearchPermissions = docLinks.links.workplaceSearch.permissions;
+ this.workplaceSearchSalesforce = docLinks.links.workplaceSearch.salesforce;
+ this.workplaceSearchSecurity = docLinks.links.workplaceSearch.security;
+ this.workplaceSearchServiceNow = docLinks.links.workplaceSearch.serviceNow;
+ this.workplaceSearchSharePoint = docLinks.links.workplaceSearch.sharePoint;
+ this.workplaceSearchSlack = docLinks.links.workplaceSearch.slack;
+ this.workplaceSearchStandardAuth = docLinks.links.workplaceSearch.standardAuth;
+ this.workplaceSearchSynch = docLinks.links.workplaceSearch.synch;
+ this.workplaceSearchZendesk = docLinks.links.workplaceSearch.zendesk;
}
}
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/licensing/manage_license_button.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/licensing/manage_license_button.test.tsx
index 1877a4cbd0e42..07c71def01bed 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/licensing/manage_license_button.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/licensing/manage_license_button.test.tsx
@@ -13,6 +13,8 @@ import { shallow } from 'enzyme';
import { EuiButton } from '@elastic/eui';
+import { docLinks } from '../../shared/doc_links';
+
import { EuiButtonTo } from '../react_router_helpers';
import { ManageLicenseButton } from './';
@@ -35,7 +37,7 @@ describe('ManageLicenseButton', () => {
const wrapper = shallow();
expect(wrapper.find(EuiButton).prop('href')).toEqual(
- expect.stringContaining('/license-management.html')
+ expect.stringContaining(docLinks.licenseManagement)
);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/licensing/manage_license_button.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/licensing/manage_license_button.tsx
index af3b33e3d7a3d..d0fe98a7c1393 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/licensing/manage_license_button.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/licensing/manage_license_button.tsx
@@ -27,12 +27,7 @@ export const ManageLicenseButton: React.FC = (props) => {
})}
) : (
-
+
{i18n.translate('xpack.enterpriseSearch.licenseDocumentationLink', {
defaultMessage: 'Learn more about license features',
})}
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mappings_table.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mappings_table.tsx
index 6e213edf457b1..667980d5f0492 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mappings_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mappings_table.tsx
@@ -18,7 +18,7 @@ import { RoleRules } from '../types';
import './role_mappings_table.scss';
-const AUTH_PROVIDER_DOCUMENTATION_URL = `${docLinks.enterpriseSearchBase}/users-access.html`;
+const AUTH_PROVIDER_DOCUMENTATION_URL = `${docLinks.enterpriseSearchUsersAccess}`;
import {
ANY_AUTH_PROVIDER,
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_selector.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_selector.tsx
index 25aff5077c680..077ef44c66b2f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_selector.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_selector.tsx
@@ -24,7 +24,7 @@ import { Role as WSRole } from '../../workplace_search/types';
import { USERNAME_LABEL, EMAIL_LABEL } from '../constants';
import { docLinks } from '../doc_links';
-const SMTP_URL = `${docLinks.enterpriseSearchBase}/mailer-configuration.html`;
+const SMTP_URL = `${docLinks.enterpriseSearchMailService}`;
import {
NEW_USER_LABEL,
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_empty_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_empty_prompt.tsx
index 42bf690c388c4..56e0a325aafd0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_empty_prompt.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_empty_prompt.tsx
@@ -20,7 +20,7 @@ import { docLinks } from '../doc_links';
import { NO_USERS_TITLE, NO_USERS_DESCRIPTION, ENABLE_USERS_LINK } from './constants';
-const USERS_DOCS_URL = `${docLinks.enterpriseSearchBase}/users-access.html`;
+const USERS_DOCS_URL = `${docLinks.enterpriseSearchUsersAccess}`;
export const UsersEmptyPrompt: React.FC = () => (
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.tsx
index 4845d682b8771..8d41e221a2cc7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.tsx
@@ -80,10 +80,7 @@ export const CloudSetupInstructions: React.FC = ({ productName, cloudDepl
defaultMessage="After enabling Enterprise Search for your instance you can customize the instance, including fault tolerance, RAM, and other {optionsLink}."
values={{
optionsLink: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.setupGuide.cloud.step3.instruction1LinkText',
{ defaultMessage: 'configurable options' }
@@ -125,10 +122,7 @@ export const CloudSetupInstructions: React.FC = ({ productName, cloudDepl
values={{
productName,
configurePolicyLink: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.setupGuide.cloud.step5.instruction1LinkText',
{ defaultMessage: 'configure an index lifecycle policy' }
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts
index 1be152ad5ca0b..b28343f37ea25 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts
@@ -17,37 +17,36 @@ export const LOGOUT_ROUTE = '/logout';
export const LEAVE_FEEDBACK_EMAIL = 'support@elastic.co';
export const LEAVE_FEEDBACK_URL = `mailto:${LEAVE_FEEDBACK_EMAIL}?Subject=Elastic%20Workplace%20Search%20Feedback`;
-export const DOCS_PREFIX = docLinks.workplaceSearchBase;
-export const PERMISSIONS_DOCS_URL = `${DOCS_PREFIX}/workplace-search-permissions.html`;
-export const DOCUMENT_PERMISSIONS_DOCS_URL = `${DOCS_PREFIX}/workplace-search-sources-document-permissions.html`;
-export const DOCUMENT_PERMISSIONS_SYNC_DOCS_URL = `${DOCUMENT_PERMISSIONS_DOCS_URL}#sources-permissions-synchronizing`;
-export const PRIVATE_SOURCES_DOCS_URL = `${PERMISSIONS_DOCS_URL}#organizational-sources-private-sources`;
-export const EXTERNAL_IDENTITIES_DOCS_URL = `${DOCS_PREFIX}/workplace-search-external-identities-api.html`;
-export const SECURITY_DOCS_URL = `${DOCS_PREFIX}/workplace-search-security.html`;
-export const SMTP_DOCS_URL = `${DOCS_PREFIX}/workplace-search-smtp-mailer.html`;
-export const BOX_DOCS_URL = `${DOCS_PREFIX}/workplace-search-box-connector.html`;
-export const CONFLUENCE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-confluence-cloud-connector.html`;
-export const CONFLUENCE_SERVER_DOCS_URL = `${DOCS_PREFIX}/workplace-search-confluence-server-connector.html`;
-export const DROPBOX_DOCS_URL = `${DOCS_PREFIX}/workplace-search-dropbox-connector.html`;
-export const GITHUB_DOCS_URL = `${DOCS_PREFIX}/workplace-search-github-connector.html`;
-export const GITHUB_ENTERPRISE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-github-connector.html`;
-export const GMAIL_DOCS_URL = `${DOCS_PREFIX}/workplace-search-gmail-connector.html`;
-export const GOOGLE_DRIVE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-google-drive-connector.html`;
-export const JIRA_DOCS_URL = `${DOCS_PREFIX}/workplace-search-jira-cloud-connector.html`;
-export const JIRA_SERVER_DOCS_URL = `${DOCS_PREFIX}/workplace-search-jira-server-connector.html`;
-export const ONEDRIVE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-onedrive-connector.html`;
-export const SALESFORCE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-salesforce-connector.html`;
-export const SERVICENOW_DOCS_URL = `${DOCS_PREFIX}/workplace-search-servicenow-connector.html`;
-export const SHAREPOINT_DOCS_URL = `${DOCS_PREFIX}/workplace-search-sharepoint-online-connector.html`;
-export const SLACK_DOCS_URL = `${DOCS_PREFIX}/workplace-search-slack-connector.html`;
-export const ZENDESK_DOCS_URL = `${DOCS_PREFIX}/workplace-search-zendesk-connector.html`;
-export const CUSTOM_SOURCE_DOCS_URL = `${DOCS_PREFIX}/workplace-search-custom-api-sources.html`;
-export const CUSTOM_API_DOCS_URL = `${DOCS_PREFIX}/workplace-search-custom-sources-api.html`;
-export const CUSTOM_API_DOCUMENT_PERMISSIONS_DOCS_URL = `${CUSTOM_SOURCE_DOCS_URL}#custom-api-source-document-level-access-control`;
-export const ENT_SEARCH_LICENSE_MANAGEMENT = `${docLinks.enterpriseSearchBase}/license-management.html`;
-export const SYNCHRONIZATION_DOCS_URL = `${DOCS_PREFIX}}/workplace-search-customizing-indexing-rules.html#workplace-search-customizing-indexing-rules`;
-export const DIFFERENT_SYNC_TYPES_DOCS_URL = `${DOCS_PREFIX}}/workplace-search-customizing-indexing-rules.html#_indexing_schedule`;
-export const OBJECTS_AND_ASSETS_DOCS_URL = `${DOCS_PREFIX}}/workplace-search-customizing-indexing-rules.html#workplace-search-customizing-indexing-rules`;
+export const BOX_DOCS_URL = docLinks.workplaceSearchBox;
+export const CONFLUENCE_DOCS_URL = docLinks.workplaceSearchConfluenceCloud;
+export const CONFLUENCE_SERVER_DOCS_URL = docLinks.workplaceSearchConfluenceServer;
+export const CUSTOM_SOURCE_DOCS_URL = docLinks.workplaceSearchCustomSources;
+export const CUSTOM_API_DOCUMENT_PERMISSIONS_DOCS_URL =
+ docLinks.workplaceSearchCustomSourcePermissions;
+export const DIFFERENT_SYNC_TYPES_DOCS_URL = docLinks.workplaceSearchIndexingSchedule;
+export const DOCUMENT_PERMISSIONS_DOCS_URL = docLinks.workplaceSearchDocumentPermissions;
+export const DROPBOX_DOCS_URL = docLinks.workplaceSearchDropbox;
+export const ENT_SEARCH_LICENSE_MANAGEMENT = docLinks.licenseManagement;
+export const EXTERNAL_IDENTITIES_DOCS_URL = docLinks.workplaceSearchExternalIdentities;
+export const GETTING_STARTED_DOCS_URL = docLinks.workplaceSearchGettingStarted;
+export const GITHUB_DOCS_URL = docLinks.workplaceSearchGitHub;
+export const GITHUB_ENTERPRISE_DOCS_URL = docLinks.workplaceSearchGitHub;
+export const GMAIL_DOCS_URL = docLinks.workplaceSearchGmail;
+export const GOOGLE_DRIVE_DOCS_URL = docLinks.workplaceSearchGoogleDrive;
+export const JIRA_DOCS_URL = docLinks.workplaceSearchJiraCloud;
+export const JIRA_SERVER_DOCS_URL = docLinks.workplaceSearchJiraServer;
+export const NATIVE_AUTH_DOCS_URL = docLinks.workplaceSearchNativeAuth;
+export const OBJECTS_AND_ASSETS_DOCS_URL = docLinks.workplaceSearchSynch;
+export const ONEDRIVE_DOCS_URL = docLinks.workplaceSearchOneDrive;
+export const PRIVATE_SOURCES_DOCS_URL = docLinks.workplaceSearchPermissions;
+export const SALESFORCE_DOCS_URL = docLinks.workplaceSearchSalesforce;
+export const SECURITY_DOCS_URL = docLinks.workplaceSearchSecurity;
+export const SERVICENOW_DOCS_URL = docLinks.workplaceSearchServiceNow;
+export const SHAREPOINT_DOCS_URL = docLinks.workplaceSearchSharePoint;
+export const SLACK_DOCS_URL = docLinks.workplaceSearchSlack;
+export const STANDARD_AUTH_DOCS_URL = docLinks.workplaceSearchStandardAuth;
+export const SYNCHRONIZATION_DOCS_URL = docLinks.workplaceSearchSynch;
+export const ZENDESK_DOCS_URL = docLinks.workplaceSearchZendesk;
export const PERSONAL_PATH = '/p';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx
index 4d329ff357b89..a992cf49f75fb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx
@@ -124,9 +124,9 @@ describe('OauthApplication', () => {
`);
});
+ /* This href test should ultimately use the docLinkServiceMock */
it('renders description', () => {
const wrapper = shallow();
-
expect(wrapper.prop('pageHeader').description).toMatchInlineSnapshot(`
{
Explore Platinum features
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx
index 905ba20e4f660..e52a174850c4c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx
@@ -15,19 +15,23 @@ import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants';
import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SetupGuideLayout, SETUP_GUIDE_TITLE } from '../../../shared/setup_guide';
import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
-import { DOCS_PREFIX } from '../../routes';
+import {
+ GETTING_STARTED_DOCS_URL,
+ NATIVE_AUTH_DOCS_URL,
+ STANDARD_AUTH_DOCS_URL,
+} from '../../routes';
import GettingStarted from './assets/getting_started.png';
-const GETTING_STARTED_LINK_URL = `${DOCS_PREFIX}/workplace-search-getting-started.html`;
+const GETTING_STARTED_LINK_URL = GETTING_STARTED_DOCS_URL;
export const SetupGuide: React.FC = () => {
return (
From 50c02645cf32eded853f934e3cfe24d0d6daaaee Mon Sep 17 00:00:00 2001
From: gchaps <33642766+gchaps@users.noreply.github.com>
Date: Mon, 29 Nov 2021 11:46:58 -0800
Subject: [PATCH 014/236] [DOCS] Changes index pattern to data views in intro
docs (#119403)
* [DOCS] Changes index pattern to data views in intro docs
* [DOCS] Updates image of data views UI
* [DOCS] Removes faulty sentence
* [DOCS] removes sentence about index patterns
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
docs/concepts/data-views.asciidoc | 8 ++++----
docs/concepts/index.asciidoc | 5 +----
docs/concepts/save-query.asciidoc | 2 +-
docs/concepts/set-time-filter.asciidoc | 2 +-
.../getting-started/quick-start-guide.asciidoc | 8 ++++----
.../index-patterns/images/create-data-view.png | Bin 0 -> 190415 bytes
.../images/create-index-pattern.png | Bin 161561 -> 0 bytes
7 files changed, 11 insertions(+), 14 deletions(-)
create mode 100644 docs/management/index-patterns/images/create-data-view.png
delete mode 100644 docs/management/index-patterns/images/create-index-pattern.png
diff --git a/docs/concepts/data-views.asciidoc b/docs/concepts/data-views.asciidoc
index 7eb95405db6bc..954581faa2460 100644
--- a/docs/concepts/data-views.asciidoc
+++ b/docs/concepts/data-views.asciidoc
@@ -1,7 +1,7 @@
[[data-views]]
=== Create a data view
-{kib} requires a data view to access the {es} data that you want to explore.
+{kib} requires a data view to access the {es} data that you want to explore.
A data view selects the data to use and allows you to define properties of the fields.
A data view can point to one or more indices, {ref}/data-streams.html[data stream], or {ref}/alias.html[index aliases].
@@ -37,7 +37,7 @@ If you loaded your own data, follow these steps to create a data view.
. Click *Create data view*.
[role="screenshot"]
-image:management/index-patterns/images/create-index-pattern.png["Create data view"]
+image:management/index-patterns/images/create-data-view.png["Create data view"]
. Start typing in the *name* field, and {kib} looks for the names of
indices, data streams, and aliases that match your input.
@@ -87,11 +87,11 @@ For an example, refer to <:
+:
```
To query {ls} indices across two {es} clusters
diff --git a/docs/concepts/index.asciidoc b/docs/concepts/index.asciidoc
index eac26beee1f9b..457251e62ae8d 100644
--- a/docs/concepts/index.asciidoc
+++ b/docs/concepts/index.asciidoc
@@ -40,8 +40,6 @@ image:concepts/images/global-search.png["Global search showing matches to apps a
{kib} requires a data view to tell it which {es} data you want to access,
and whether the data is time-based. A data view can point to one or more {es}
data streams, indices, or index aliases by name.
-For example, `logs-elasticsearch-prod-*` is an index pattern,
-and it is time-based with a time field of `@timestamp`. The time field is not editable.
Data views are typically created by an administrator when sending data to {es}.
You can <> in *Stack Management*, or by using a script
@@ -129,8 +127,7 @@ Previously, {kib} used the {ref}/search-aggregations-bucket-terms-aggregation.ht
Structured filters are a more interactive way to create {es} queries,
and are commonly used when building dashboards that are shared by multiple analysts.
Each filter can be disabled, inverted, or pinned across all apps.
-The structured filters are the only way to use the {es} Query DSL in JSON form,
-or to target a specific index pattern for filtering. Each of the structured
+Each of the structured
filters is combined with AND logic on the rest of the query.
[role="screenshot"]
diff --git a/docs/concepts/save-query.asciidoc b/docs/concepts/save-query.asciidoc
index 61113b5491c29..54137d1f9f2cf 100644
--- a/docs/concepts/save-query.asciidoc
+++ b/docs/concepts/save-query.asciidoc
@@ -17,7 +17,7 @@ image:concepts/images/saved-query.png["Example of the saved query management pop
Saved queries are different than <>,
which include the *Discover* configuration—selected columns in the document table, sort order, and
-index pattern—in addition to the query.
+{data-source}—in addition to the query.
Saved searches are primarily used for adding search results to a dashboard.
[role="xpack"]
diff --git a/docs/concepts/set-time-filter.asciidoc b/docs/concepts/set-time-filter.asciidoc
index 116bcd6f91f77..b379c0ac279e5 100644
--- a/docs/concepts/set-time-filter.asciidoc
+++ b/docs/concepts/set-time-filter.asciidoc
@@ -2,7 +2,7 @@
=== Set the time range
Display data within a
specified time range when your index contains time-based events, and a time-field is configured for the
-selected <>.
+selected <>.
The default time range is 15 minutes, but you can customize
it in <>.
diff --git a/docs/getting-started/quick-start-guide.asciidoc b/docs/getting-started/quick-start-guide.asciidoc
index 03e40c7cc6cef..2667729f4b854 100644
--- a/docs/getting-started/quick-start-guide.asciidoc
+++ b/docs/getting-started/quick-start-guide.asciidoc
@@ -11,7 +11,7 @@ When you've finished, you'll know how to:
[float]
=== Required privileges
-You must have `read`, `write`, and `manage` privileges on the `kibana_sample_data_*` indices.
+You must have `read`, `write`, and `manage` privileges on the `kibana_sample_data_*` indices.
Learn how to <>, or refer to {ref}/security-privileges.html[Security privileges] for more information.
[float]
@@ -37,7 +37,7 @@ image::images/addData_sampleDataCards_7.15.0.png[Add data UI for the sample data
[[explore-the-data]]
== Explore the data
-*Discover* displays the data in an interactive histogram that shows the distribution of data, or documents, over time, and a table that lists the fields for each document that matches the index pattern. To view a subset of the documents, you can apply filters to the data, and customize the table to display only the fields you want to explore.
+*Discover* displays the data in an interactive histogram that shows the distribution of data, or documents, over time, and a table that lists the fields for each document that matches the {data-source}. To view a subset of the documents, you can apply filters to the data, and customize the table to display only the fields you want to explore.
. Open the main menu, then click *Discover*.
@@ -65,7 +65,7 @@ image::images/tutorial-discover-3.png[Discover table that displays only the prod
A dashboard is a collection of panels that you can use to view and analyze the data. Panels contain visualizations, interactive controls, text, and more.
-. Open the main menu, then click *Dashboard*.
+. Open the main menu, then click *Dashboard*.
. Click *[eCommerce] Revenue Dashboard*.
+
@@ -104,7 +104,7 @@ The treemap appears as the last visualization panel on the dashboard.
[[interact-with-the-data]]
=== Interact with the data
-You can interact with the dashboard data using controls that allow you to apply dashboard-level filters. Interact with the *[eCommerce] Controls* panel to view the women's clothing data from the Gnomehouse manufacturer.
+You can interact with the dashboard data using controls that allow you to apply dashboard-level filters. Interact with the *[eCommerce] Controls* panel to view the women's clothing data from the Gnomehouse manufacturer.
. From the *Manufacturer* dropdown, select *Gnomehouse*.
diff --git a/docs/management/index-patterns/images/create-data-view.png b/docs/management/index-patterns/images/create-data-view.png
new file mode 100644
index 0000000000000000000000000000000000000000..229ed0f490b41fe2db1e1d70d7b6f77f097f2cf0
GIT binary patch
literal 190415
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 |