From 9cebff12980d7afe2e4b13fcb15c26c627f38498 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cau=C3=AA=20Marcondes?=
<55978943+cauemarcondes@users.noreply.github.com>
Date: Mon, 5 Apr 2021 10:51:56 -0400
Subject: [PATCH 001/131] [OBS]home page is showing incorrect value of APM
throughput (tpm) (#95991)
* fixing obs transaction per minute value
* addressing PR comments
* fixing unit test
* addressing PR comments
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
...pm_observability_overview_fetchers.test.ts | 20 ++--
.../apm_observability_overview_fetchers.ts | 12 +--
.../get_transaction_coordinates.ts | 64 -------------
.../get_transactions_per_minute.ts | 95 +++++++++++++++++++
.../server/routes/observability_overview.ts | 8 +-
.../components/app/section/apm/index.test.tsx | 26 +++++
.../components/app/section/apm/index.tsx | 15 ++-
.../typings/fetch_overview_data/index.ts | 2 +-
.../observability_overview.ts | 19 ++--
9 files changed, 166 insertions(+), 95 deletions(-)
delete mode 100644 x-pack/plugins/apm/server/lib/observability_overview/get_transaction_coordinates.ts
create mode 100644 x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts
diff --git a/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.test.ts b/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.test.ts
index 1821e92ee5a78..29fabc51fd582 100644
--- a/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.test.ts
+++ b/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.test.ts
@@ -46,11 +46,14 @@ describe('Observability dashboard data', () => {
callApmApiMock.mockImplementation(() =>
Promise.resolve({
serviceCount: 10,
- transactionCoordinates: [
- { x: 1, y: 1 },
- { x: 2, y: 2 },
- { x: 3, y: 3 },
- ],
+ transactionPerMinute: {
+ value: 2,
+ timeseries: [
+ { x: 1, y: 1 },
+ { x: 2, y: 2 },
+ { x: 3, y: 3 },
+ ],
+ },
})
);
const response = await fetchObservabilityOverviewPageData(params);
@@ -81,7 +84,7 @@ describe('Observability dashboard data', () => {
callApmApiMock.mockImplementation(() =>
Promise.resolve({
serviceCount: 0,
- transactionCoordinates: [],
+ transactionPerMinute: { value: null, timeseries: [] },
})
);
const response = await fetchObservabilityOverviewPageData(params);
@@ -108,7 +111,10 @@ describe('Observability dashboard data', () => {
callApmApiMock.mockImplementation(() =>
Promise.resolve({
serviceCount: 0,
- transactionCoordinates: [{ x: 1 }, { x: 2 }, { x: 3 }],
+ transactionPerMinute: {
+ value: 0,
+ timeseries: [{ x: 1 }, { x: 2 }, { x: 3 }],
+ },
})
);
const response = await fetchObservabilityOverviewPageData(params);
diff --git a/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts b/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts
index 55ead8d942aca..3a02efd05e5a5 100644
--- a/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts
+++ b/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts
@@ -5,7 +5,6 @@
* 2.0.
*/
-import { mean } from 'lodash';
import {
ApmFetchDataResponse,
FetchDataParams,
@@ -31,7 +30,7 @@ export const fetchObservabilityOverviewPageData = async ({
},
});
- const { serviceCount, transactionCoordinates } = data;
+ const { serviceCount, transactionPerMinute } = data;
return {
appLink: `/app/apm/services?rangeFrom=${relativeTime.start}&rangeTo=${relativeTime.end}`,
@@ -42,17 +41,12 @@ export const fetchObservabilityOverviewPageData = async ({
},
transactions: {
type: 'number',
- value:
- mean(
- transactionCoordinates
- .map(({ y }) => y)
- .filter((y) => y && isFinite(y))
- ) || 0,
+ value: transactionPerMinute.value || 0,
},
},
series: {
transactions: {
- coordinates: transactionCoordinates,
+ coordinates: transactionPerMinute.timeseries,
},
},
};
diff --git a/x-pack/plugins/apm/server/lib/observability_overview/get_transaction_coordinates.ts b/x-pack/plugins/apm/server/lib/observability_overview/get_transaction_coordinates.ts
deleted file mode 100644
index aac18e2bdfe4c..0000000000000
--- a/x-pack/plugins/apm/server/lib/observability_overview/get_transaction_coordinates.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 { rangeQuery } from '../../../server/utils/queries';
-import { Coordinates } from '../../../../observability/typings/common';
-import { Setup, SetupTimeRange } from '../helpers/setup_request';
-import { getProcessorEventForAggregatedTransactions } from '../helpers/aggregated_transactions';
-import { calculateThroughput } from '../helpers/calculate_throughput';
-import { withApmSpan } from '../../utils/with_apm_span';
-
-export function getTransactionCoordinates({
- setup,
- bucketSize,
- searchAggregatedTransactions,
-}: {
- setup: Setup & SetupTimeRange;
- bucketSize: string;
- searchAggregatedTransactions: boolean;
-}): Promise {
- return withApmSpan(
- 'observability_overview_get_transaction_distribution',
- async () => {
- const { apmEventClient, start, end } = setup;
-
- const { aggregations } = await apmEventClient.search({
- apm: {
- events: [
- getProcessorEventForAggregatedTransactions(
- searchAggregatedTransactions
- ),
- ],
- },
- body: {
- size: 0,
- query: {
- bool: {
- filter: rangeQuery(start, end),
- },
- },
- aggs: {
- distribution: {
- date_histogram: {
- field: '@timestamp',
- fixed_interval: bucketSize,
- min_doc_count: 0,
- },
- },
- },
- },
- });
-
- return (
- aggregations?.distribution.buckets.map((bucket) => ({
- x: bucket.key,
- y: calculateThroughput({ start, end, value: bucket.doc_count }),
- })) || []
- );
- }
- );
-}
diff --git a/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts b/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts
new file mode 100644
index 0000000000000..da8ac7c50b594
--- /dev/null
+++ b/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts
@@ -0,0 +1,95 @@
+/*
+ * 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 {
+ TRANSACTION_PAGE_LOAD,
+ TRANSACTION_REQUEST,
+} from '../../../common/transaction_types';
+import { TRANSACTION_TYPE } from '../../../common/elasticsearch_fieldnames';
+import { rangeQuery } from '../../../server/utils/queries';
+import { Setup, SetupTimeRange } from '../helpers/setup_request';
+import { getProcessorEventForAggregatedTransactions } from '../helpers/aggregated_transactions';
+import { calculateThroughput } from '../helpers/calculate_throughput';
+import { withApmSpan } from '../../utils/with_apm_span';
+
+export function getTransactionsPerMinute({
+ setup,
+ bucketSize,
+ searchAggregatedTransactions,
+}: {
+ setup: Setup & SetupTimeRange;
+ bucketSize: string;
+ searchAggregatedTransactions: boolean;
+}) {
+ return withApmSpan(
+ 'observability_overview_get_transactions_per_minute',
+ async () => {
+ const { apmEventClient, start, end } = setup;
+
+ const { aggregations } = await apmEventClient.search({
+ apm: {
+ events: [
+ getProcessorEventForAggregatedTransactions(
+ searchAggregatedTransactions
+ ),
+ ],
+ },
+ body: {
+ size: 0,
+ query: {
+ bool: {
+ filter: rangeQuery(start, end),
+ },
+ },
+ aggs: {
+ transactionType: {
+ terms: {
+ field: TRANSACTION_TYPE,
+ },
+ aggs: {
+ timeseries: {
+ date_histogram: {
+ field: '@timestamp',
+ fixed_interval: bucketSize,
+ min_doc_count: 0,
+ },
+ aggs: {
+ throughput: { rate: { unit: 'minute' as const } },
+ },
+ },
+ },
+ },
+ },
+ },
+ });
+
+ if (!aggregations || !aggregations.transactionType.buckets) {
+ return { value: undefined, timeseries: [] };
+ }
+
+ const topTransactionTypeBucket =
+ aggregations.transactionType.buckets.find(
+ ({ key: transactionType }) =>
+ transactionType === TRANSACTION_REQUEST ||
+ transactionType === TRANSACTION_PAGE_LOAD
+ ) || aggregations.transactionType.buckets[0];
+
+ return {
+ value: calculateThroughput({
+ start,
+ end,
+ value: topTransactionTypeBucket?.doc_count || 0,
+ }),
+ timeseries:
+ topTransactionTypeBucket?.timeseries.buckets.map((bucket) => ({
+ x: bucket.key,
+ y: bucket.throughput.value,
+ })) || [],
+ };
+ }
+ );
+}
diff --git a/x-pack/plugins/apm/server/routes/observability_overview.ts b/x-pack/plugins/apm/server/routes/observability_overview.ts
index b9c0a76b6fb90..1aac2c09d01c5 100644
--- a/x-pack/plugins/apm/server/routes/observability_overview.ts
+++ b/x-pack/plugins/apm/server/routes/observability_overview.ts
@@ -8,7 +8,7 @@
import * as t from 'io-ts';
import { setupRequest } from '../lib/helpers/setup_request';
import { getServiceCount } from '../lib/observability_overview/get_service_count';
-import { getTransactionCoordinates } from '../lib/observability_overview/get_transaction_coordinates';
+import { getTransactionsPerMinute } from '../lib/observability_overview/get_transactions_per_minute';
import { getHasData } from '../lib/observability_overview/has_data';
import { createRoute } from './create_route';
import { rangeRt } from './default_api_types';
@@ -39,18 +39,18 @@ export const observabilityOverviewRoute = createRoute({
);
return withApmSpan('observability_overview', async () => {
- const [serviceCount, transactionCoordinates] = await Promise.all([
+ const [serviceCount, transactionPerMinute] = await Promise.all([
getServiceCount({
setup,
searchAggregatedTransactions,
}),
- getTransactionCoordinates({
+ getTransactionsPerMinute({
setup,
bucketSize,
searchAggregatedTransactions,
}),
]);
- return { serviceCount, transactionCoordinates };
+ return { serviceCount, transactionPerMinute };
});
},
});
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 e5f100be285e1..d29481a39eb72 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
@@ -56,6 +56,32 @@ describe('APMSection', () => {
} as unknown) as ObservabilityPublicPluginsStart,
}));
});
+
+ it('renders transaction stat less then 1k', () => {
+ const resp = {
+ appLink: '/app/apm',
+ stats: {
+ services: { value: 11, type: 'number' },
+ transactions: { value: 900, type: 'number' },
+ },
+ series: {
+ transactions: { coordinates: [] },
+ },
+ };
+ jest.spyOn(fetcherHook, 'useFetcher').mockReturnValue({
+ data: resp,
+ status: fetcherHook.FETCH_STATUS.SUCCESS,
+ refetch: jest.fn(),
+ });
+ const { getByText, queryAllByTestId } = render();
+
+ expect(getByText('APM')).toBeInTheDocument();
+ expect(getByText('View in app')).toBeInTheDocument();
+ expect(getByText('Services 11')).toBeInTheDocument();
+ expect(getByText('Throughput 900.0 tpm')).toBeInTheDocument();
+ expect(queryAllByTestId('loading')).toEqual([]);
+ });
+
it('renders with transaction series and stats', () => {
jest.spyOn(fetcherHook, 'useFetcher').mockReturnValue({
data: response,
diff --git a/x-pack/plugins/observability/public/components/app/section/apm/index.tsx b/x-pack/plugins/observability/public/components/app/section/apm/index.tsx
index 91a536840ecbd..e71468d3b028c 100644
--- a/x-pack/plugins/observability/public/components/app/section/apm/index.tsx
+++ b/x-pack/plugins/observability/public/components/app/section/apm/index.tsx
@@ -31,6 +31,19 @@ function formatTpm(value?: number) {
return numeral(value).format('0.00a');
}
+function formatTpmStat(value?: number) {
+ if (!value || value === 0) {
+ return '0';
+ }
+ if (value <= 0.1) {
+ return '< 0.1';
+ }
+ if (value > 1000) {
+ return numeral(value).format('0.00a');
+ }
+ return numeral(value).format('0,0.0');
+}
+
export function APMSection({ bucketSize }: Props) {
const theme = useContext(ThemeContext);
const chartTheme = useChartTheme();
@@ -93,7 +106,7 @@ export function APMSection({ bucketSize }: Props) {
({
x: new Date(x).toISOString(),
@@ -67,23 +68,23 @@ export default function ApiTest({ getService }: FtrProviderContext) {
Array [
Object {
"x": "2020-12-08T13:57:00.000Z",
- "y": 0.166666666666667,
+ "y": 2,
},
Object {
"x": "2020-12-08T13:58:00.000Z",
- "y": 5.23333333333333,
+ "y": 61,
},
Object {
"x": "2020-12-08T13:59:00.000Z",
- "y": 4.4,
+ "y": 36,
},
Object {
"x": "2020-12-08T14:00:00.000Z",
- "y": 5.73333333333333,
+ "y": 75,
},
Object {
"x": "2020-12-08T14:01:00.000Z",
- "y": 4.33333333333333,
+ "y": 36,
},
]
`);
From 123f3400a82f89a7be5a6c2d9526e62102530c47 Mon Sep 17 00:00:00 2001
From: Scotty Bollinger
Date: Mon, 5 Apr 2021 10:19:32 -0500
Subject: [PATCH 002/131] [Workplace Search] Add sub nav and fix rendering bugs
in Personal dashboard (#96100)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Fix route for private deferated source summary
* Make schema types nullable
Federated sources don’t have counts and the server returns null so our routes have to expect that sometimes these values will be null
* Add SourceSubNav to Personal dashboard
We are able to leverage the existing component with a couple a small change; the existing componet is a subnav in the larger Enterprise Search shared navigation component and does not include its styles. This caused the list items to render with bullet points next to them. Adding this class and displaying the nav items as block elements fixes this issue.
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../views/content_sources/components/source_sub_nav.tsx | 4 ++--
.../views/content_sources/private_sources_layout.test.tsx | 3 +++
.../views/content_sources/private_sources_layout.tsx | 3 +++
.../views/content_sources/source_logic.test.ts | 2 +-
.../workplace_search/views/content_sources/source_logic.ts | 2 +-
.../workplace_search/views/content_sources/sources.scss | 6 ++++++
.../server/routes/workplace_search/sources.ts | 6 +++---
7 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx
index 99cebd5ded585..bf0c5471f7b57 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx
@@ -33,7 +33,7 @@ export const SourceSubNav: React.FC = () => {
const isCustom = serviceType === CUSTOM_SERVICE_TYPE;
return (
- <>
+
{NAV.OVERVIEW}
@@ -53,6 +53,6 @@ export const SourceSubNav: React.FC = () => {
{NAV.SETTINGS}
- >
+
);
};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.test.tsx
index 488eb4b49853b..9e3b50ea083eb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.test.tsx
@@ -17,6 +17,8 @@ import { EuiCallOut } from '@elastic/eui';
import { ViewContentHeader } from '../../components/shared/view_content_header';
+import { SourceSubNav } from './components/source_sub_nav';
+
import {
PRIVATE_CAN_CREATE_PAGE_TITLE,
PRIVATE_VIEW_ONLY_PAGE_TITLE,
@@ -40,6 +42,7 @@ describe('PrivateSourcesLayout', () => {
const wrapper = shallow({children});
expect(wrapper.find('[data-test-subj="TestChildren"]')).toHaveLength(1);
+ expect(wrapper.find(SourceSubNav)).toHaveLength(1);
});
it('uses correct title and description when private sources are enabled', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.tsx
index bdc2421432c8a..2a6281075dc40 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources_layout.tsx
@@ -14,6 +14,8 @@ import { EuiPage, EuiPageSideBar, EuiPageBody, EuiCallOut } from '@elastic/eui';
import { AppLogic } from '../../app_logic';
import { ViewContentHeader } from '../../components/shared/view_content_header';
+import { SourceSubNav } from './components/source_sub_nav';
+
import {
PRIVATE_DASHBOARD_READ_ONLY_MODE_WARNING,
PRIVATE_CAN_CREATE_PAGE_TITLE,
@@ -49,6 +51,7 @@ export const PrivateSourcesLayout: React.FC = ({
+
{readOnlyMode && (
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts
index d20d0576d11ce..a9712cc4e1dc0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts
@@ -214,7 +214,7 @@ describe('SourceLogic', () => {
SourceLogic.actions.initializeFederatedSummary(contentSource.id);
expect(http.get).toHaveBeenCalledWith(
- '/api/workplace_search/org/sources/123/federated_summary'
+ '/api/workplace_search/account/sources/123/federated_summary'
);
await promise;
expect(onUpdateSummarySpy).toHaveBeenCalledWith(contentSource.summary);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts
index 72700ce42c75d..3da90c4fc7739 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts
@@ -156,7 +156,7 @@ export const SourceLogic = kea>({
}
},
initializeFederatedSummary: async ({ sourceId }) => {
- const route = `/api/workplace_search/org/sources/${sourceId}/federated_summary`;
+ const route = `/api/workplace_search/account/sources/${sourceId}/federated_summary`;
try {
const response = await HttpLogic.values.http.get(route);
actions.onUpdateSummary(response.summary);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources.scss b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources.scss
index f142567fb621f..abab139e32369 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources.scss
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources.scss
@@ -30,3 +30,9 @@
margin-left: -$sideBarWidth;
}
}
+
+.sourcesSubNav {
+ li {
+ display: block;
+ }
+}
diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts
index 8257dd0dc52b0..1dd6d859d88ad 100644
--- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/sources.ts
@@ -22,9 +22,9 @@ const schemaValuesSchema = schema.recordOf(
);
const pageSchema = schema.object({
- current: schema.number(),
- size: schema.number(),
- total_pages: schema.number(),
+ current: schema.nullable(schema.number()),
+ size: schema.nullable(schema.number()),
+ total_pages: schema.nullable(schema.number()),
total_results: schema.number(),
});
From ea03eb1bab086b6e6e526d8c1eb11ffa877d7d52 Mon Sep 17 00:00:00 2001
From: Scotty Bollinger
Date: Mon, 5 Apr 2021 10:27:05 -0500
Subject: [PATCH 003/131] [Enterprise Search] Expose core.chrome.setIsVisible
for use in Workplace Search (#95984)
* Hide chrome for Workplace Search by default
The Workplace Search Personal dashboard needs the chrome hidden. We hide it globally here first to prevent a flash of chrome on the Personal dashboard and unhide it for admin routes, which will be in a future commit
* Add core.chrome.setIsVisible to KibanaLogic
* Toggle chrome visibility for Workplace Search
* Add test
* Refactor to set context and chrome when pathname changes
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../applications/__mocks__/kibana_logic.mock.ts | 1 +
.../enterprise_search/public/applications/index.tsx | 1 +
.../applications/shared/kibana/kibana_logic.ts | 2 ++
.../applications/workplace_search/index.test.tsx | 4 +++-
.../public/applications/workplace_search/index.tsx | 12 +++++++-----
x-pack/plugins/enterprise_search/public/plugin.ts | 3 +++
6 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts
index 133f704fd59a9..2325ddcf2b270 100644
--- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts
@@ -19,6 +19,7 @@ export const mockKibanaValues = {
history: mockHistory,
navigateToUrl: jest.fn(),
setBreadcrumbs: jest.fn(),
+ setChromeIsVisible: jest.fn(),
setDocTitle: jest.fn(),
renderHeaderActions: jest.fn(),
};
diff --git a/x-pack/plugins/enterprise_search/public/applications/index.tsx b/x-pack/plugins/enterprise_search/public/applications/index.tsx
index 155ff5b92ba27..c2bf77751528a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/index.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/index.tsx
@@ -49,6 +49,7 @@ export const renderApp = (
history: params.history,
navigateToUrl: core.application.navigateToUrl,
setBreadcrumbs: core.chrome.setBreadcrumbs,
+ setChromeIsVisible: core.chrome.setIsVisible,
setDocTitle: core.chrome.docTitle.change,
renderHeaderActions: (HeaderActions) =>
params.setHeaderActionMenu((el) => renderHeaderActions(HeaderActions, store, el)),
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts
index 8015d22f7c44a..2bef7d373f160 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts
@@ -24,6 +24,7 @@ interface KibanaLogicProps {
charts: ChartsPluginStart;
navigateToUrl: ApplicationStart['navigateToUrl'];
setBreadcrumbs(crumbs: ChromeBreadcrumb[]): void;
+ setChromeIsVisible(isVisible: boolean): void;
setDocTitle(title: string): void;
renderHeaderActions(HeaderActions: FC): void;
}
@@ -47,6 +48,7 @@ export const KibanaLogic = kea>({
{},
],
setBreadcrumbs: [props.setBreadcrumbs, {}],
+ setChromeIsVisible: [props.setChromeIsVisible, {}],
setDocTitle: [props.setDocTitle, {}],
renderHeaderActions: [props.renderHeaderActions, {}],
}),
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx
index 48bdcd6551b65..a2c0ec18def4b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx
@@ -57,11 +57,13 @@ describe('WorkplaceSearchConfigured', () => {
setMockActions({ initializeAppData, setContext });
});
- it('renders layout and header actions', () => {
+ it('renders layout, chrome, and header actions', () => {
const wrapper = shallow();
expect(wrapper.find(Layout).first().prop('readOnlyMode')).toBeFalsy();
expect(wrapper.find(OverviewMVP)).toHaveLength(1);
+
+ expect(mockKibanaValues.setChromeIsVisible).toHaveBeenCalledWith(true);
expect(mockKibanaValues.renderHeaderActions).toHaveBeenCalledWith(WorkplaceSearchHeaderActions);
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx
index c269a987dc092..7a76de43be41b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx
@@ -53,7 +53,7 @@ export const WorkplaceSearch: React.FC = (props) => {
export const WorkplaceSearchConfigured: React.FC = (props) => {
const { hasInitialized } = useValues(AppLogic);
const { initializeAppData, setContext } = useActions(AppLogic);
- const { renderHeaderActions } = useValues(KibanaLogic);
+ const { renderHeaderActions, setChromeIsVisible } = useValues(KibanaLogic);
const { errorConnecting, readOnlyMode } = useValues(HttpLogic);
const { pathname } = useLocation();
@@ -66,11 +66,13 @@ export const WorkplaceSearchConfigured: React.FC = (props) => {
* Personal dashboard urls begin with /p/
* EX: http://localhost:5601/app/enterprise_search/workplace_search/p/sources
*/
- const personalSourceUrlRegex = /^\/p\//g; // matches '/p/*'
+ useEffect(() => {
+ const personalSourceUrlRegex = /^\/p\//g; // matches '/p/*'
+ const isOrganization = !pathname.match(personalSourceUrlRegex); // TODO: Once auth is figured out, we need to have a check for the equivilent of `isAdmin`.
- // TODO: Once auth is figured out, we need to have a check for the equivilent of `isAdmin`.
- const isOrganization = !pathname.match(personalSourceUrlRegex);
- setContext(isOrganization);
+ setContext(isOrganization);
+ setChromeIsVisible(isOrganization);
+ }, [pathname]);
useEffect(() => {
if (!hasInitialized) {
diff --git a/x-pack/plugins/enterprise_search/public/plugin.ts b/x-pack/plugins/enterprise_search/public/plugin.ts
index f00e81a5accf7..dd1a62d243d03 100644
--- a/x-pack/plugins/enterprise_search/public/plugin.ts
+++ b/x-pack/plugins/enterprise_search/public/plugin.ts
@@ -114,6 +114,9 @@ export class EnterpriseSearchPlugin implements Plugin {
const { chrome, http } = kibanaDeps.core;
chrome.docTitle.change(WORKPLACE_SEARCH_PLUGIN.NAME);
+ // The Workplace Search Personal dashboard needs the chrome hidden. We hide it globally
+ // here first to prevent a flash of chrome on the Personal dashboard and unhide it for admin routes.
+ chrome.setIsVisible(false);
await this.getInitialData(http);
const pluginData = this.getPluginData();
From 95e45ddebc6e86bb3d63f04bd7c4e56ad8ef55bb Mon Sep 17 00:00:00 2001
From: Pierre Gayvallet
Date: Mon, 5 Apr 2021 18:00:13 +0200
Subject: [PATCH 004/131] Use plugin version in its publicPath (#95945)
* Use plugin version in its publicPath
* remove useless comment
* fix types
* update generated doc
---
.../register_bundle_routes.test.ts | 15 +++++++------
.../bundle_routes/register_bundle_routes.ts | 8 +++----
src/core/server/legacy/legacy_service.test.ts | 1 +
.../server/plugins/plugins_service.test.ts | 14 ++++++++++---
src/core/server/plugins/plugins_service.ts | 1 +
src/core/server/plugins/plugins_system.ts | 1 +
src/core/server/plugins/types.ts | 13 +++++++++---
.../bootstrap/get_plugin_bundle_paths.test.ts | 21 ++++++++++++-------
.../bootstrap/get_plugin_bundle_paths.ts | 10 +++++++--
src/core/server/server.api.md | 8 +++----
10 files changed, 63 insertions(+), 29 deletions(-)
diff --git a/src/core/server/core_app/bundle_routes/register_bundle_routes.test.ts b/src/core/server/core_app/bundle_routes/register_bundle_routes.test.ts
index d51c369146957..830f4a9a94364 100644
--- a/src/core/server/core_app/bundle_routes/register_bundle_routes.test.ts
+++ b/src/core/server/core_app/bundle_routes/register_bundle_routes.test.ts
@@ -10,7 +10,7 @@ import { registerRouteForBundleMock } from './register_bundle_routes.test.mocks'
import { PackageInfo } from '@kbn/config';
import { httpServiceMock } from '../../http/http_service.mock';
-import { UiPlugins } from '../../plugins';
+import { InternalPluginInfo, UiPlugins } from '../../plugins';
import { registerBundleRoutes } from './register_bundle_routes';
import { FileHashCache } from './file_hash_cache';
@@ -29,9 +29,12 @@ const createUiPlugins = (...ids: string[]): UiPlugins => ({
internal: ids.reduce((map, id) => {
map.set(id, {
publicTargetDir: `/plugins/${id}/public-target-dir`,
+ publicAssetsDir: `/plugins/${id}/public-assets-dir`,
+ version: '8.0.0',
+ requiredBundles: [],
});
return map;
- }, new Map()),
+ }, new Map()),
});
describe('registerBundleRoutes', () => {
@@ -86,16 +89,16 @@ describe('registerBundleRoutes', () => {
fileHashCache: expect.any(FileHashCache),
isDist: true,
bundlesPath: '/plugins/plugin-a/public-target-dir',
- publicPath: '/server-base-path/42/bundles/plugin/plugin-a/',
- routePath: '/42/bundles/plugin/plugin-a/',
+ publicPath: '/server-base-path/42/bundles/plugin/plugin-a/8.0.0/',
+ routePath: '/42/bundles/plugin/plugin-a/8.0.0/',
});
expect(registerRouteForBundleMock).toHaveBeenCalledWith(router, {
fileHashCache: expect.any(FileHashCache),
isDist: true,
bundlesPath: '/plugins/plugin-b/public-target-dir',
- publicPath: '/server-base-path/42/bundles/plugin/plugin-b/',
- routePath: '/42/bundles/plugin/plugin-b/',
+ publicPath: '/server-base-path/42/bundles/plugin/plugin-b/8.0.0/',
+ routePath: '/42/bundles/plugin/plugin-b/8.0.0/',
});
});
});
diff --git a/src/core/server/core_app/bundle_routes/register_bundle_routes.ts b/src/core/server/core_app/bundle_routes/register_bundle_routes.ts
index ee54f8ef34622..df46753747f5b 100644
--- a/src/core/server/core_app/bundle_routes/register_bundle_routes.ts
+++ b/src/core/server/core_app/bundle_routes/register_bundle_routes.ts
@@ -27,7 +27,7 @@ import { registerRouteForBundle } from './bundles_route';
*/
export function registerBundleRoutes({
router,
- serverBasePath, // serverBasePath
+ serverBasePath,
uiPlugins,
packageInfo,
}: {
@@ -57,10 +57,10 @@ export function registerBundleRoutes({
isDist,
});
- [...uiPlugins.internal.entries()].forEach(([id, { publicTargetDir }]) => {
+ [...uiPlugins.internal.entries()].forEach(([id, { publicTargetDir, version }]) => {
registerRouteForBundle(router, {
- publicPath: `${serverBasePath}/${buildNum}/bundles/plugin/${id}/`,
- routePath: `/${buildNum}/bundles/plugin/${id}/`,
+ publicPath: `${serverBasePath}/${buildNum}/bundles/plugin/${id}/${version}/`,
+ routePath: `/${buildNum}/bundles/plugin/${id}/${version}/`,
bundlesPath: publicTargetDir,
fileHashCache,
isDist,
diff --git a/src/core/server/legacy/legacy_service.test.ts b/src/core/server/legacy/legacy_service.test.ts
index d0a02b9859960..67b5393f0b838 100644
--- a/src/core/server/legacy/legacy_service.test.ts
+++ b/src/core/server/legacy/legacy_service.test.ts
@@ -91,6 +91,7 @@ beforeEach(() => {
'plugin-id',
{
requiredBundles: [],
+ version: '8.0.0',
publicTargetDir: 'path/to/target/public',
publicAssetsDir: '/plugins/name/assets/',
},
diff --git a/src/core/server/plugins/plugins_service.test.ts b/src/core/server/plugins/plugins_service.test.ts
index 2d54648d22950..6bf7a1fadb4d3 100644
--- a/src/core/server/plugins/plugins_service.test.ts
+++ b/src/core/server/plugins/plugins_service.test.ts
@@ -562,12 +562,12 @@ describe('PluginsService', () => {
plugin$: from([
createPlugin('plugin-1', {
path: 'path-1',
- version: 'some-version',
+ version: 'version-1',
configPath: 'plugin1',
}),
createPlugin('plugin-2', {
path: 'path-2',
- version: 'some-version',
+ version: 'version-2',
configPath: 'plugin2',
}),
]),
@@ -577,7 +577,7 @@ describe('PluginsService', () => {
});
describe('uiPlugins.internal', () => {
- it('includes disabled plugins', async () => {
+ it('contains internal properties for plugins', async () => {
config$.next({ plugins: { initialize: true }, plugin1: { enabled: false } });
const { uiPlugins } = await pluginsService.discover({ environment: environmentSetup });
expect(uiPlugins.internal).toMatchInlineSnapshot(`
@@ -586,15 +586,23 @@ describe('PluginsService', () => {
"publicAssetsDir": /path-1/public/assets,
"publicTargetDir": /path-1/target/public,
"requiredBundles": Array [],
+ "version": "version-1",
},
"plugin-2" => Object {
"publicAssetsDir": /path-2/public/assets,
"publicTargetDir": /path-2/target/public,
"requiredBundles": Array [],
+ "version": "version-2",
},
}
`);
});
+
+ it('includes disabled plugins', async () => {
+ config$.next({ plugins: { initialize: true }, plugin1: { enabled: false } });
+ const { uiPlugins } = await pluginsService.discover({ environment: environmentSetup });
+ expect([...uiPlugins.internal.keys()].sort()).toEqual(['plugin-1', 'plugin-2']);
+ });
});
describe('plugin initialization', () => {
diff --git a/src/core/server/plugins/plugins_service.ts b/src/core/server/plugins/plugins_service.ts
index 8b33e2cf4cc6b..09be40ecaf2a2 100644
--- a/src/core/server/plugins/plugins_service.ts
+++ b/src/core/server/plugins/plugins_service.ts
@@ -222,6 +222,7 @@ export class PluginsService implements CoreService();
diff --git a/src/core/server/plugins/types.ts b/src/core/server/plugins/types.ts
index a6086bd6f17e8..3a01049c5e1fe 100644
--- a/src/core/server/plugins/types.ts
+++ b/src/core/server/plugins/types.ts
@@ -224,12 +224,15 @@ export interface DiscoveredPlugin {
*/
export interface InternalPluginInfo {
/**
- * Bundles that must be loaded for this plugoin
+ * Version of the plugin
+ */
+ readonly version: string;
+ /**
+ * Bundles that must be loaded for this plugin
*/
readonly requiredBundles: readonly string[];
/**
- * Path to the target/public directory of the plugin which should be
- * served
+ * Path to the target/public directory of the plugin which should be served
*/
readonly publicTargetDir: string;
/**
@@ -250,7 +253,9 @@ export interface Plugin<
TPluginsStart extends object = object
> {
setup(core: CoreSetup, plugins: TPluginsSetup): TSetup;
+
start(core: CoreStart, plugins: TPluginsStart): TStart;
+
stop?(): void;
}
@@ -267,7 +272,9 @@ export interface AsyncPlugin<
TPluginsStart extends object = object
> {
setup(core: CoreSetup, plugins: TPluginsSetup): TSetup | Promise;
+
start(core: CoreStart, plugins: TPluginsStart): TStart | Promise;
+
stop?(): void;
}
diff --git a/src/core/server/rendering/bootstrap/get_plugin_bundle_paths.test.ts b/src/core/server/rendering/bootstrap/get_plugin_bundle_paths.test.ts
index ea3843884df31..0abd8fd5a0057 100644
--- a/src/core/server/rendering/bootstrap/get_plugin_bundle_paths.test.ts
+++ b/src/core/server/rendering/bootstrap/get_plugin_bundle_paths.test.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { UiPlugins } from '../../plugins';
+import { InternalPluginInfo, UiPlugins } from '../../plugins';
import { getPluginsBundlePaths } from './get_plugin_bundle_paths';
const createUiPlugins = (pluginDeps: Record) => {
@@ -16,12 +16,13 @@ const createUiPlugins = (pluginDeps: Record) => {
browserConfigs: new Map(),
};
- Object.entries(pluginDeps).forEach(([pluginId, deps]) => {
+ const addPlugin = (pluginId: string, deps: string[]) => {
uiPlugins.internal.set(pluginId, {
requiredBundles: deps,
+ version: '8.0.0',
publicTargetDir: '',
publicAssetsDir: '',
- } as any);
+ } as InternalPluginInfo);
uiPlugins.public.set(pluginId, {
id: pluginId,
configPath: 'config-path',
@@ -29,6 +30,12 @@ const createUiPlugins = (pluginDeps: Record) => {
requiredPlugins: [],
requiredBundles: deps,
});
+
+ deps.forEach((dep) => addPlugin(dep, []));
+ };
+
+ Object.entries(pluginDeps).forEach(([pluginId, deps]) => {
+ addPlugin(pluginId, deps);
});
return uiPlugins;
@@ -56,13 +63,13 @@ describe('getPluginsBundlePaths', () => {
});
expect(pluginBundlePaths.get('a')).toEqual({
- bundlePath: '/regular-bundle-path/plugin/a/a.plugin.js',
- publicPath: '/regular-bundle-path/plugin/a/',
+ bundlePath: '/regular-bundle-path/plugin/a/8.0.0/a.plugin.js',
+ publicPath: '/regular-bundle-path/plugin/a/8.0.0/',
});
expect(pluginBundlePaths.get('b')).toEqual({
- bundlePath: '/regular-bundle-path/plugin/b/b.plugin.js',
- publicPath: '/regular-bundle-path/plugin/b/',
+ bundlePath: '/regular-bundle-path/plugin/b/8.0.0/b.plugin.js',
+ publicPath: '/regular-bundle-path/plugin/b/8.0.0/',
});
});
});
diff --git a/src/core/server/rendering/bootstrap/get_plugin_bundle_paths.ts b/src/core/server/rendering/bootstrap/get_plugin_bundle_paths.ts
index c8291b2720a92..86ffdcf835f7b 100644
--- a/src/core/server/rendering/bootstrap/get_plugin_bundle_paths.ts
+++ b/src/core/server/rendering/bootstrap/get_plugin_bundle_paths.ts
@@ -25,9 +25,15 @@ export const getPluginsBundlePaths = ({
while (pluginsToProcess.length > 0) {
const pluginId = pluginsToProcess.pop() as string;
+ const plugin = uiPlugins.internal.get(pluginId);
+ if (!plugin) {
+ continue;
+ }
+ const { version } = plugin;
+
pluginBundlePaths.set(pluginId, {
- publicPath: `${regularBundlePath}/plugin/${pluginId}/`,
- bundlePath: `${regularBundlePath}/plugin/${pluginId}/${pluginId}.plugin.js`,
+ publicPath: `${regularBundlePath}/plugin/${pluginId}/${version}/`,
+ bundlePath: `${regularBundlePath}/plugin/${pluginId}/${version}/${pluginId}.plugin.js`,
});
const pluginBundleIds = uiPlugins.internal.get(pluginId)?.requiredBundles ?? [];
diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md
index de96c5ccfb81e..fb5fe3efd3e06 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -3259,9 +3259,9 @@ export const validBodyOutput: readonly ["data", "stream"];
//
// src/core/server/elasticsearch/client/types.ts:94:7 - (ae-forgotten-export) The symbol "Explanation" needs to be exported by the entry point index.d.ts
// src/core/server/http/router/response.ts:297:3 - (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts
-// src/core/server/plugins/types.ts:286:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
-// src/core/server/plugins/types.ts:286:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
-// src/core/server/plugins/types.ts:289:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts
-// src/core/server/plugins/types.ts:394:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "create"
+// src/core/server/plugins/types.ts:293:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
+// src/core/server/plugins/types.ts:293:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
+// src/core/server/plugins/types.ts:296:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts
+// src/core/server/plugins/types.ts:401:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "create"
```
From 8e11e2598e874d603e99bcfac407ef9e09784102 Mon Sep 17 00:00:00 2001
From: Thomas Neirynck
Date: Mon, 5 Apr 2021 12:04:20 -0400
Subject: [PATCH 005/131] [Maps] Enable all zoom levels for all users (#96093)
---
.github/CODEOWNERS | 1 -
docs/developer/plugin-list.asciidoc | 4 -
packages/kbn-optimizer/limits.yml | 1 -
.../service_settings/service_settings.test.js | 50 ++-------
.../service_settings/service_settings.ts | 17 +--
.../service_settings_types.ts | 2 -
src/plugins/maps_legacy/kibana.json | 2 +-
.../public/map/base_maps_visualization.js | 3 +-
.../maps_legacy/public/map/kibana_map.js | 23 ----
.../maps_legacy/public/map/map_messages.js | 105 ------------------
test/functional/apps/visualize/_tile_map.ts | 59 ----------
tsconfig.json | 1 -
tsconfig.refs.json | 1 -
.../plugins/maps_legacy_licensing/README.md | 4 -
.../plugins/maps_legacy_licensing/kibana.json | 8 --
.../maps_legacy_licensing/public/index.ts | 12 --
.../maps_legacy_licensing/public/plugin.ts | 48 --------
.../maps_legacy_licensing/tsconfig.json | 15 ---
.../translations/translations/ja-JP.json | 1 -
.../translations/translations/zh-CN.json | 1 -
20 files changed, 12 insertions(+), 346 deletions(-)
delete mode 100644 src/plugins/maps_legacy/public/map/map_messages.js
delete mode 100644 x-pack/plugins/maps_legacy_licensing/README.md
delete mode 100644 x-pack/plugins/maps_legacy_licensing/kibana.json
delete mode 100644 x-pack/plugins/maps_legacy_licensing/public/index.ts
delete mode 100644 x-pack/plugins/maps_legacy_licensing/public/plugin.ts
delete mode 100644 x-pack/plugins/maps_legacy_licensing/tsconfig.json
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index d14556ea1dabf..b9afc197bac9c 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -146,7 +146,6 @@
/x-pack/test/visual_regression/tests/maps/index.js @elastic/kibana-gis
#CC# /src/plugins/maps_legacy/ @elastic/kibana-gis
#CC# /x-pack/plugins/file_upload @elastic/kibana-gis
-#CC# /x-pack/plugins/maps_legacy_licensing @elastic/kibana-gis
/src/plugins/tile_map/ @elastic/kibana-gis
/src/plugins/region_map/ @elastic/kibana-gis
diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc
index bcf74936077ec..691d7fb82f3bc 100644
--- a/docs/developer/plugin-list.asciidoc
+++ b/docs/developer/plugin-list.asciidoc
@@ -452,10 +452,6 @@ using the CURL scripts in the scripts folder.
|Visualize geo data from Elasticsearch or 3rd party geo-services.
-|{kib-repo}blob/{branch}/x-pack/plugins/maps_legacy_licensing/README.md[mapsLegacyLicensing]
-|This plugin provides access to the detailed tile map services from Elastic.
-
-
|{kib-repo}blob/{branch}/x-pack/plugins/ml/readme.md[ml]
|This plugin provides access to the machine learning features provided by
Elastic.
diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml
index 3c9fd4f59a406..a027768ad66a0 100644
--- a/packages/kbn-optimizer/limits.yml
+++ b/packages/kbn-optimizer/limits.yml
@@ -51,7 +51,6 @@ pageLoadAssetSize:
management: 46112
maps: 80000
mapsLegacy: 87859
- mapsLegacyLicensing: 20214
ml: 82187
monitoring: 80000
navigation: 37269
diff --git a/src/plugins/maps_ems/public/service_settings/service_settings.test.js b/src/plugins/maps_ems/public/service_settings/service_settings.test.js
index 5bd371aace79b..eb67997c253b9 100644
--- a/src/plugins/maps_ems/public/service_settings/service_settings.test.js
+++ b/src/plugins/maps_ems/public/service_settings/service_settings.test.js
@@ -103,43 +103,8 @@ describe('service_settings (FKA tile_map test)', function () {
expect(tmsService.attribution.includes('OpenStreetMap')).toEqual(true);
});
- describe('modify - url', function () {
- let tilemapServices;
-
+ describe('tms mods', function () {
let serviceSettings;
- async function assertQuery(expected) {
- const attrs = await serviceSettings.getAttributesForTMSLayer(tilemapServices[0]);
- const urlObject = url.parse(attrs.url, true);
- Object.keys(expected).forEach((key) => {
- expect(urlObject.query[key]).toEqual(expected[key]);
- });
- }
-
- it('accepts an object', async () => {
- serviceSettings = makeServiceSettings();
- serviceSettings.setQueryParams({ foo: 'bar' });
- tilemapServices = await serviceSettings.getTMSServices();
- await assertQuery({ foo: 'bar' });
- });
-
- it('merged additions with previous values', async () => {
- // ensure that changes are always additive
- serviceSettings = makeServiceSettings();
- serviceSettings.setQueryParams({ foo: 'bar' });
- serviceSettings.setQueryParams({ bar: 'stool' });
- tilemapServices = await serviceSettings.getTMSServices();
- await assertQuery({ foo: 'bar', bar: 'stool' });
- });
-
- it('overwrites conflicting previous values', async () => {
- serviceSettings = makeServiceSettings();
- // ensure that conflicts are overwritten
- serviceSettings.setQueryParams({ foo: 'bar' });
- serviceSettings.setQueryParams({ bar: 'stool' });
- serviceSettings.setQueryParams({ foo: 'tstool' });
- tilemapServices = await serviceSettings.getTMSServices();
- await assertQuery({ foo: 'tstool', bar: 'stool' });
- });
it('should merge in tilemap url', async () => {
serviceSettings = makeServiceSettings(
@@ -161,7 +126,7 @@ describe('service_settings (FKA tile_map test)', function () {
id: 'road_map',
name: 'Road Map - Bright',
url:
- 'https://tiles.foobar/raster/styles/osm-bright/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=1.2.3',
+ 'https://tiles.foobar/raster/styles/osm-bright/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=1.2.3&license=sspl',
minZoom: 0,
maxZoom: 10,
attribution:
@@ -208,19 +173,19 @@ describe('service_settings (FKA tile_map test)', function () {
);
expect(desaturationFalse.url).toEqual(
- 'https://tiles.foobar/raster/styles/osm-bright/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=1.2.3'
+ 'https://tiles.foobar/raster/styles/osm-bright/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=1.2.3&license=sspl'
);
expect(desaturationFalse.maxZoom).toEqual(10);
expect(desaturationTrue.url).toEqual(
- 'https://tiles.foobar/raster/styles/osm-bright-desaturated/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=1.2.3'
+ 'https://tiles.foobar/raster/styles/osm-bright-desaturated/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=1.2.3&license=sspl'
);
expect(desaturationTrue.maxZoom).toEqual(18);
expect(darkThemeDesaturationFalse.url).toEqual(
- 'https://tiles.foobar/raster/styles/dark-matter/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=1.2.3'
+ 'https://tiles.foobar/raster/styles/dark-matter/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=1.2.3&license=sspl'
);
expect(darkThemeDesaturationFalse.maxZoom).toEqual(22);
expect(darkThemeDesaturationTrue.url).toEqual(
- 'https://tiles.foobar/raster/styles/dark-matter/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=1.2.3'
+ 'https://tiles.foobar/raster/styles/dark-matter/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=1.2.3&license=sspl'
);
expect(darkThemeDesaturationTrue.maxZoom).toEqual(22);
});
@@ -264,14 +229,13 @@ describe('service_settings (FKA tile_map test)', function () {
describe('File layers', function () {
it('should load manifest (all props)', async function () {
const serviceSettings = makeServiceSettings();
- serviceSettings.setQueryParams({ foo: 'bar' });
const fileLayers = await serviceSettings.getFileLayers();
expect(fileLayers.length).toEqual(19);
const assertions = fileLayers.map(async function (fileLayer) {
expect(fileLayer.origin).toEqual(ORIGIN.EMS);
const fileUrl = await serviceSettings.getUrlForRegionLayer(fileLayer);
const urlObject = url.parse(fileUrl, true);
- Object.keys({ foo: 'bar', elastic_tile_service_tos: 'agree' }).forEach((key) => {
+ Object.keys({ elastic_tile_service_tos: 'agree' }).forEach((key) => {
expect(typeof urlObject.query[key]).toEqual('string');
});
});
diff --git a/src/plugins/maps_ems/public/service_settings/service_settings.ts b/src/plugins/maps_ems/public/service_settings/service_settings.ts
index f7c735b6c3037..412db42a1570c 100644
--- a/src/plugins/maps_ems/public/service_settings/service_settings.ts
+++ b/src/plugins/maps_ems/public/service_settings/service_settings.ts
@@ -22,7 +22,6 @@ export class ServiceSettings implements IServiceSettings {
private readonly _mapConfig: MapsEmsConfig;
private readonly _tilemapsConfig: TileMapConfig;
private readonly _hasTmsConfigured: boolean;
- private _showZoomMessage: boolean;
private readonly _emsClient: EMSClient;
private readonly tmsOptionsFromConfig: any;
@@ -31,7 +30,6 @@ export class ServiceSettings implements IServiceSettings {
this._tilemapsConfig = tilemapsConfig;
this._hasTmsConfigured = typeof tilemapsConfig.url === 'string' && tilemapsConfig.url !== '';
- this._showZoomMessage = true;
this._emsClient = new EMSClient({
language: i18n.getLocale(),
appVersion: getKibanaVersion(),
@@ -45,6 +43,9 @@ export class ServiceSettings implements IServiceSettings {
return fetch(...args);
},
});
+ // any kibana user, regardless of distribution, should get all zoom levels
+ // use `sspl` license to indicate this
+ this._emsClient.addQueryParams({ license: 'sspl' });
const markdownIt = new MarkdownIt({
html: false,
@@ -58,18 +59,6 @@ export class ServiceSettings implements IServiceSettings {
});
}
- shouldShowZoomMessage({ origin }: { origin: string }): boolean {
- return origin === ORIGIN.EMS && this._showZoomMessage;
- }
-
- enableZoomMessage(): void {
- this._showZoomMessage = true;
- }
-
- disableZoomMessage(): void {
- this._showZoomMessage = false;
- }
-
__debugStubManifestCalls(manifestRetrieval: () => Promise): { removeStub: () => void } {
const oldGetManifest = this._emsClient.getManifest;
diff --git a/src/plugins/maps_ems/public/service_settings/service_settings_types.ts b/src/plugins/maps_ems/public/service_settings/service_settings_types.ts
index 80a9aae835844..6b04bd200eba8 100644
--- a/src/plugins/maps_ems/public/service_settings/service_settings_types.ts
+++ b/src/plugins/maps_ems/public/service_settings/service_settings_types.ts
@@ -46,8 +46,6 @@ export interface IServiceSettings {
getFileLayers(): Promise;
getUrlForRegionLayer(layer: FileLayer): Promise;
setQueryParams(params: { [p: string]: string }): void;
- enableZoomMessage(): void;
- disableZoomMessage(): void;
getAttributesForTMSLayer(
tmsServiceConfig: TmsLayer,
isDesaturated: boolean,
diff --git a/src/plugins/maps_legacy/kibana.json b/src/plugins/maps_legacy/kibana.json
index 8e283288e34b2..f321274791a3b 100644
--- a/src/plugins/maps_legacy/kibana.json
+++ b/src/plugins/maps_legacy/kibana.json
@@ -5,5 +5,5 @@
"ui": true,
"server": true,
"requiredPlugins": ["mapsEms"],
- "requiredBundles": ["kibanaReact", "visDefaultEditor", "mapsEms"]
+ "requiredBundles": ["visDefaultEditor", "mapsEms"]
}
diff --git a/src/plugins/maps_legacy/public/map/base_maps_visualization.js b/src/plugins/maps_legacy/public/map/base_maps_visualization.js
index 9cd574c5246e8..a261bcf6edd80 100644
--- a/src/plugins/maps_legacy/public/map/base_maps_visualization.js
+++ b/src/plugins/maps_legacy/public/map/base_maps_visualization.js
@@ -193,13 +193,12 @@ export function BaseMapsVisualizationProvider() {
isDesaturated,
isDarkMode
);
- const showZoomMessage = serviceSettings.shouldShowZoomMessage(tmsLayer);
const options = { ...tmsLayer };
delete options.id;
delete options.subdomains;
this._kibanaMap.setBaseLayer({
baseLayerType: 'tms',
- options: { ...options, showZoomMessage, ...meta },
+ options: { ...options, ...meta },
});
}
diff --git a/src/plugins/maps_legacy/public/map/kibana_map.js b/src/plugins/maps_legacy/public/map/kibana_map.js
index eea8315419289..62dbbda2588a5 100644
--- a/src/plugins/maps_legacy/public/map/kibana_map.js
+++ b/src/plugins/maps_legacy/public/map/kibana_map.js
@@ -7,13 +7,11 @@
*/
import { EventEmitter } from 'events';
-import { createZoomWarningMsg } from './map_messages';
import $ from 'jquery';
import { get, isEqual, escape } from 'lodash';
import { zoomToPrecision } from './zoom_to_precision';
import { i18n } from '@kbn/i18n';
import { ORIGIN } from '../../../maps_ems/common';
-import { getToasts } from '../kibana_services';
import { L } from '../leaflet';
function makeFitControl(fitContainer, kibanaMap) {
@@ -479,22 +477,6 @@ export class KibanaMap extends EventEmitter {
this._updateLegend();
}
- _addMaxZoomMessage = (layer) => {
- const zoomWarningMsg = createZoomWarningMsg(
- getToasts(),
- this.getZoomLevel,
- this.getMaxZoomLevel
- );
-
- this._leafletMap.on('zoomend', zoomWarningMsg);
- this._containerNode.setAttribute('data-test-subj', 'zoomWarningEnabled');
-
- layer.on('remove', () => {
- this._leafletMap.off('zoomend', zoomWarningMsg);
- this._containerNode.removeAttribute('data-test-subj');
- });
- };
-
setLegendPosition(position) {
if (this._legendPosition === position) {
if (!this._leafletLegendControl) {
@@ -572,11 +554,6 @@ export class KibanaMap extends EventEmitter {
});
this._leafletBaseLayer = baseLayer;
- if (settings.options.showZoomMessage) {
- baseLayer.on('add', () => {
- this._addMaxZoomMessage(baseLayer);
- });
- }
this._leafletBaseLayer.addTo(this._leafletMap);
this._leafletBaseLayer.bringToBack();
if (settings.options.minZoom > this._leafletMap.getZoom()) {
diff --git a/src/plugins/maps_legacy/public/map/map_messages.js b/src/plugins/maps_legacy/public/map/map_messages.js
deleted file mode 100644
index f60d819f0b390..0000000000000
--- a/src/plugins/maps_legacy/public/map/map_messages.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import React from 'react';
-import { FormattedMessage } from '@kbn/i18n/react';
-import { EuiSpacer, EuiButtonEmpty } from '@elastic/eui';
-import { toMountPoint } from '../../../kibana_react/public';
-
-export const createZoomWarningMsg = (function () {
- let disableZoomMsg = false;
- const setZoomMsg = (boolDisableMsg) => (disableZoomMsg = boolDisableMsg);
-
- class ZoomWarning extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- disabled: false,
- };
- }
-
- render() {
- return (
-
- );
- }
- }
-
- const zoomToast = {
- title: 'No additional zoom levels',
- text: toMountPoint(),
- 'data-test-subj': 'maxZoomWarning',
- };
-
- return (toastService, getZoomLevel, getMaxZoomLevel) => {
- return () => {
- const zoomLevel = getZoomLevel();
- const maxMapZoom = getMaxZoomLevel();
- if (!disableZoomMsg && zoomLevel === maxMapZoom) {
- toastService.addDanger(zoomToast);
- }
- };
- };
-})();
diff --git a/test/functional/apps/visualize/_tile_map.ts b/test/functional/apps/visualize/_tile_map.ts
index 668aec6ac5783..3af467affa1fb 100644
--- a/test/functional/apps/visualize/_tile_map.ts
+++ b/test/functional/apps/visualize/_tile_map.ts
@@ -15,7 +15,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const retry = getService('retry');
const inspector = getService('inspector');
const filterBar = getService('filterBar');
- const testSubjects = getService('testSubjects');
const browser = getService('browser');
const PageObjects = getPageObjects([
'common',
@@ -221,63 +220,5 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
});
-
- describe('zoom warning behavior', function describeIndexTests() {
- // Zoom warning is only applicable to OSS
- this.tags(['skipCloud', 'skipFirefox']);
-
- const waitForLoading = false;
- let zoomWarningEnabled;
- let last = false;
- const toastDefaultLife = 6000;
-
- before(async function () {
- await browser.setWindowSize(1280, 1000);
-
- log.debug('navigateToApp visualize');
- await PageObjects.visualize.navigateToNewAggBasedVisualization();
- log.debug('clickTileMap');
- await PageObjects.visualize.clickTileMap();
- await PageObjects.visualize.clickNewSearch();
-
- zoomWarningEnabled = await testSubjects.exists('zoomWarningEnabled');
- log.debug(`Zoom warning enabled: ${zoomWarningEnabled}`);
-
- const zoomLevel = 9;
- for (let i = 0; i < zoomLevel; i++) {
- await PageObjects.tileMap.clickMapZoomIn();
- }
- });
-
- beforeEach(async function () {
- await PageObjects.tileMap.clickMapZoomIn(waitForLoading);
- });
-
- afterEach(async function () {
- if (!last) {
- await PageObjects.common.sleep(toastDefaultLife);
- await PageObjects.tileMap.clickMapZoomOut(waitForLoading);
- }
- });
-
- it('should show warning at zoom 10', async () => {
- await testSubjects.existOrFail('maxZoomWarning');
- });
-
- it('should continue providing zoom warning if left alone', async () => {
- await testSubjects.existOrFail('maxZoomWarning');
- });
-
- it('should suppress zoom warning if suppress warnings button clicked', async () => {
- last = true;
- await PageObjects.visChart.waitForVisualization();
- await testSubjects.click('suppressZoomWarnings');
- await PageObjects.tileMap.clickMapZoomOut(waitForLoading);
- await testSubjects.waitForDeleted('suppressZoomWarnings');
- await PageObjects.tileMap.clickMapZoomIn(waitForLoading);
-
- await testSubjects.missingOrFail('maxZoomWarning');
- });
- });
});
}
diff --git a/tsconfig.json b/tsconfig.json
index 30944ac71fcc8..7c06e80858640 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -181,7 +181,6 @@
{ "path": "./x-pack/plugins/license_management/tsconfig.json" },
{ "path": "./x-pack/plugins/licensing/tsconfig.json" },
{ "path": "./x-pack/plugins/logstash/tsconfig.json" },
- { "path": "./x-pack/plugins/maps_legacy_licensing/tsconfig.json" },
{ "path": "./x-pack/plugins/maps/tsconfig.json" },
{ "path": "./x-pack/plugins/ml/tsconfig.json" },
{ "path": "./x-pack/plugins/monitoring/tsconfig.json" },
diff --git a/tsconfig.refs.json b/tsconfig.refs.json
index 2d9ddc1b9e568..f13455a14b4df 100644
--- a/tsconfig.refs.json
+++ b/tsconfig.refs.json
@@ -85,7 +85,6 @@
{ "path": "./x-pack/plugins/license_management/tsconfig.json" },
{ "path": "./x-pack/plugins/licensing/tsconfig.json" },
{ "path": "./x-pack/plugins/logstash/tsconfig.json" },
- { "path": "./x-pack/plugins/maps_legacy_licensing/tsconfig.json" },
{ "path": "./x-pack/plugins/maps/tsconfig.json" },
{ "path": "./x-pack/plugins/ml/tsconfig.json" },
{ "path": "./x-pack/plugins/monitoring/tsconfig.json" },
diff --git a/x-pack/plugins/maps_legacy_licensing/README.md b/x-pack/plugins/maps_legacy_licensing/README.md
deleted file mode 100644
index 7c2ce84d848d4..0000000000000
--- a/x-pack/plugins/maps_legacy_licensing/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Tile Map Plugin
-
-This plugin provides access to the detailed tile map services from Elastic.
-
diff --git a/x-pack/plugins/maps_legacy_licensing/kibana.json b/x-pack/plugins/maps_legacy_licensing/kibana.json
deleted file mode 100644
index 7a49e0aaa7be1..0000000000000
--- a/x-pack/plugins/maps_legacy_licensing/kibana.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "id": "mapsLegacyLicensing",
- "version": "8.0.0",
- "kibanaVersion": "kibana",
- "server": false,
- "ui": true,
- "requiredPlugins": ["licensing", "mapsEms"]
-}
diff --git a/x-pack/plugins/maps_legacy_licensing/public/index.ts b/x-pack/plugins/maps_legacy_licensing/public/index.ts
deleted file mode 100644
index 9105919eaa635..0000000000000
--- a/x-pack/plugins/maps_legacy_licensing/public/index.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * 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 { MapsLegacyLicensing } from './plugin';
-
-export function plugin() {
- return new MapsLegacyLicensing();
-}
diff --git a/x-pack/plugins/maps_legacy_licensing/public/plugin.ts b/x-pack/plugins/maps_legacy_licensing/public/plugin.ts
deleted file mode 100644
index f8118575cd6a2..0000000000000
--- a/x-pack/plugins/maps_legacy_licensing/public/plugin.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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 { CoreSetup, CoreStart, Plugin } from 'kibana/public';
-import { LicensingPluginSetup, ILicense } from '../../licensing/public';
-import { IServiceSettings, MapsEmsPluginSetup } from '../../../../src/plugins/maps_ems/public';
-
-/**
- * These are the interfaces with your public contracts. You should export these
- * for other plugins to use in _their_ `SetupDeps`/`StartDeps` interfaces.
- * @public
- */
-
-export interface MapsLegacyLicensingSetupDependencies {
- licensing: LicensingPluginSetup;
- mapsEms: MapsEmsPluginSetup;
-}
-// eslint-disable-next-line @typescript-eslint/no-empty-interface
-export interface MapsLegacyLicensingStartDependencies {}
-
-export type MapsLegacyLicensingSetup = ReturnType;
-export type MapsLegacyLicensingStart = ReturnType;
-
-export class MapsLegacyLicensing
- implements Plugin {
- public setup(core: CoreSetup, plugins: MapsLegacyLicensingSetupDependencies) {
- const { licensing, mapsEms } = plugins;
- if (licensing) {
- licensing.license$.subscribe(async (license: ILicense) => {
- const serviceSettings: IServiceSettings = await mapsEms.getServiceSettings();
- const { uid, isActive } = license;
- if (isActive && license.hasAtLeast('basic')) {
- serviceSettings.setQueryParams({ license: uid || '' });
- serviceSettings.disableZoomMessage();
- } else {
- serviceSettings.setQueryParams({ license: '' });
- serviceSettings.enableZoomMessage();
- }
- });
- }
- }
-
- public start(core: CoreStart, plugins: MapsLegacyLicensingStartDependencies) {}
-}
diff --git a/x-pack/plugins/maps_legacy_licensing/tsconfig.json b/x-pack/plugins/maps_legacy_licensing/tsconfig.json
deleted file mode 100644
index 3b8102b5205a8..0000000000000
--- a/x-pack/plugins/maps_legacy_licensing/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": "../../../tsconfig.project.json",
- "compilerOptions": {
- "composite": true,
- "outDir": "./target/types",
- "emitDeclarationOnly": true,
- "declaration": true,
- "declarationMap": true
- },
- "include": ["public/**/*"],
- "references": [
- { "path": "../licensing/tsconfig.json" },
- { "path": "../../../src/plugins/maps_ems/tsconfig.json" }
- ]
-}
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 133b4d0b6aaa8..6dc490b4ffc53 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -3080,7 +3080,6 @@
"maps_legacy.baseMapsVisualization.childShouldImplementMethodErrorMessage": "子はdata-updateに対応できるようこのメソッドを導入する必要があります",
"maps_legacy.defaultDistributionMessage": "Mapsを入手するには、ElasticsearchとKibanaの{defaultDistribution}にアップグレードしてください。",
"maps_legacy.kibanaMap.leaflet.fitDataBoundsAriaLabel": "データバウンドを合わせる",
- "maps_legacy.kibanaMap.zoomWarning": "ズームレベルが最大に達しました。完全にズームインするには、ElasticsearchとKibanaの{defaultDistribution}にアップグレードしてください。{ems}ではより多くのズームレベルを無料で利用できます。または、独自のマップサーバーを構成できます。詳細は、{ wms }または{ configSettings}をご覧ください。",
"maps_legacy.legacyMapDeprecationMessage": "Mapsを使用すると、複数のレイヤーとインデックスを追加する、個別のドキュメントをプロットする、データ値から特徴を表現する、ヒートマップ、グリッド、クラスターを追加するなど、さまざまなことが可能です。{getMapsMessage}",
"maps_legacy.legacyMapDeprecationTitle": "{label}は8.0でMapsに移行されます。",
"maps_legacy.openInMapsButtonLabel": "Mapsで表示",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 0f9d8b90a2578..32574690b13f2 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -3101,7 +3101,6 @@
"maps_legacy.baseMapsVisualization.childShouldImplementMethodErrorMessage": "子对象应实现此方法以响应数据更新",
"maps_legacy.defaultDistributionMessage": "要获取 Maps,请升级到 {defaultDistribution} 版的 Elasticsearch 和 Kibana。",
"maps_legacy.kibanaMap.leaflet.fitDataBoundsAriaLabel": "适应数据边界",
- "maps_legacy.kibanaMap.zoomWarning": "已达到缩放级别数目上限。要一直放大,请升级到 Elasticsearch 和 Kibana 的{defaultDistribution}。您可以通过 {ems} 免费使用其他缩放级别。或者,您可以配置自己的地图服务器。请前往 { wms } 或 { configSettings} 以获取详细信息。",
"maps_legacy.legacyMapDeprecationMessage": "使用 Maps,可以添加多个图层和索引,绘制单个文档,使用数据值表示特征,添加热图、网格和集群,等等。{getMapsMessage}",
"maps_legacy.legacyMapDeprecationTitle": "在 8.0 中,{label} 将迁移到 Maps。",
"maps_legacy.openInMapsButtonLabel": "在 Maps 中查看",
From bcb72c596a438f6a223e875395380afe1efc291c Mon Sep 17 00:00:00 2001
From: Andrew Goldstein
Date: Mon, 5 Apr 2021 11:39:09 -0600
Subject: [PATCH 006/131] [RAC][Alert Triage][TGrid] Update the Alerts Table
(TGrid) API to implement `renderCellValue` (#96098)
### [RAC][Alert Triage][TGrid] Update the Alerts Table (TGrid) API to implement `renderCellValue`
- This PR implements a superset of the `renderCellValue` API from [EuiDataGrid](https://elastic.github.io/eui/#/tabular-content/data-grid) in the `TGrid` (Timeline grid) API
- The TGrid API was also updated to accept a collection of `RowRenderer`s as a prop
The API changes are summarized by the following screenshot:
The following screenshot shows the `signal.rule.risk_score` column in the Alerts table being rendered with a green background color, using the same technique illustrated by `EuiDataGrid`'s [codesandbox example](https://codesandbox.io/s/nsmzs):
Note: In the screenshot above, the values in the Alerts table are also _not_ rendered as draggables.
Related (RAC) issue: https://github.com/elastic/kibana/issues/94520
### Details
The `StatefulEventsViewer` has been updated to accept `renderCellValue` as a (required) prop:
```
renderCellValue: (props: CellValueElementProps) => React.ReactNode;
```
The type definition of `CellValueElementProps` is:
```
export type CellValueElementProps = EuiDataGridCellValueElementProps & {
data: TimelineNonEcsData[];
eventId: string; // _id
header: ColumnHeaderOptions;
linkValues: string[] | undefined;
timelineId: string;
};
```
The `CellValueElementProps` type above is a _superset_ of `EuiDataGridCellValueElementProps`. The additional properties above include the `data` returned by the TGrid when it performs IO to retrieve alerts and events.
### Using `renderCellValue` to control rendering
The internal implementation of TGrid's cell rendering didn't change with this PR; it moved to
`x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.tsx` as shown below:
```
export const DefaultCellRenderer: React.FC = ({
columnId,
data,
eventId,
header,
linkValues,
setCellProps,
timelineId,
}) => (
<>
{getColumnRenderer(header.id, columnRenderers, data).renderColumn({
columnName: header.id,
eventId,
field: header,
linkValues,
timelineId,
truncate: true,
values: getMappedNonEcsValue({
data,
fieldName: header.id,
}),
})}
>
);
```
Any usages of TGrid were updated to pass `DefaultCellRenderer` as the value of the `renderCellValue` prop, as shown in the screenshot below:
The `EuiDataGrid` [codesandbox example](https://codesandbox.io/s/nsmzs) provides the following example `renderCellValue` implementation, which highlights a cell green based on it's numeric value:
```
const renderCellValue = useMemo(() => {
return ({ rowIndex, columnId, setCellProps }) => {
const data = useContext(DataContext);
useEffect(() => {
if (columnId === 'amount') {
if (data.hasOwnProperty(rowIndex)) {
const numeric = parseFloat(
data[rowIndex][columnId].match(/\d+\.\d+/)[0],
10
);
setCellProps({
style: {
backgroundColor: `rgba(0, 255, 0, ${numeric * 0.0002})`,
},
});
}
}
}, [rowIndex, columnId, setCellProps, data]);
function getFormatted() {
return data[rowIndex][columnId].formatted
? data[rowIndex][columnId].formatted
: data[rowIndex][columnId];
}
return data.hasOwnProperty(rowIndex)
? getFormatted(rowIndex, columnId)
: null;
};
}, []);
```
The sample code above formats the `amount` column in the example `EuiDataGrid` with a green `backgroundColor` based on the value of the data, as shown in the screenshot below:
To demonstrate that similar styling can be applied to TGrid using the same technique illustrated by `EuiDataGrid`'s [codesandbox example](https://codesandbox.io/s/nsmzs), we can update the `DefaultCellRenderer` in `x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.tsx` to apply a similar technique:
```
export const DefaultCellRenderer: React.FC = ({
columnId,
data,
eventId,
header,
linkValues,
setCellProps,
timelineId,
}) => {
useEffect(() => {
if (columnId === 'signal.rule.risk_score') {
const value = getMappedNonEcsValue({
data,
fieldName: columnId,
});
if (Array.isArray(value) && value.length > 0) {
const numeric = parseFloat(value[0]);
setCellProps({
style: {
backgroundColor: `rgba(0, 255, 0, ${numeric * 0.002})`,
},
});
}
}
}, [columnId, data, setCellProps]);
return (
<>
{getMappedNonEcsValue({
data,
fieldName: columnId,
})}
>
);
};
```
The example code above renders the `signal.rule.risk_score` column in the Alerts table with a green `backgroundColor` based on the value of the data, as shown in the screenshot below:
Note: In the screenshot above, the values in the Alerts table are not rendered as draggables.
---
.../components/alerts_viewer/alerts_table.tsx | 4 +
.../events_viewer/events_viewer.test.tsx | 6 +
.../events_viewer/events_viewer.tsx | 14 +-
.../components/events_viewer/index.test.tsx | 4 +
.../common/components/events_viewer/index.tsx | 13 +-
.../components/alerts_table/index.tsx | 4 +
.../navigation/events_query_tab_body.tsx | 4 +
.../components/flyout/pane/index.tsx | 8 +-
.../__snapshots__/index.test.tsx.snap | 553 ++++++++--
.../body/data_driven_columns/index.test.tsx | 4 +-
.../body/data_driven_columns/index.tsx | 30 +-
.../stateful_cell.test.tsx | 171 +++
.../data_driven_columns/stateful_cell.tsx | 63 ++
.../body/events/event_column_view.test.tsx | 2 +
.../body/events/event_column_view.tsx | 8 +-
.../components/timeline/body/events/index.tsx | 8 +-
.../timeline/body/events/stateful_event.tsx | 10 +-
.../components/timeline/body/index.test.tsx | 8 +-
.../components/timeline/body/index.tsx | 13 +-
.../body/renderers/get_row_renderer.test.tsx | 16 +-
.../timeline/body/renderers/index.ts | 2 +-
.../default_cell_renderer.test.tsx | 107 ++
.../cell_rendering/default_cell_renderer.tsx | 39 +
.../timeline/cell_rendering/index.tsx | 20 +
.../__snapshots__/index.test.tsx.snap | 980 ++++++++++++++++++
.../timeline/eql_tab_content/index.test.tsx | 4 +
.../timeline/eql_tab_content/index.tsx | 8 +
.../components/timeline/index.test.tsx | 4 +
.../timelines/components/timeline/index.tsx | 14 +-
.../__snapshots__/index.test.tsx.snap | 980 ++++++++++++++++++
.../pinned_tab_content/index.test.tsx | 5 +-
.../timeline/pinned_tab_content/index.tsx | 8 +
.../__snapshots__/index.test.tsx.snap | 980 ++++++++++++++++++
.../timeline/query_tab_content/index.test.tsx | 4 +
.../timeline/query_tab_content/index.tsx | 8 +
.../timeline/tabs_content/index.tsx | 64 +-
.../timeline/epic_local_storage.test.tsx | 5 +-
37 files changed, 4047 insertions(+), 128 deletions(-)
create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/stateful_cell.test.tsx
create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/stateful_cell.tsx
create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx
create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.tsx
create mode 100644 x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/index.tsx
diff --git a/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx
index af90d17fe62b8..43d5c66655808 100644
--- a/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx
@@ -12,6 +12,8 @@ import { TimelineIdLiteral } from '../../../../common/types/timeline';
import { StatefulEventsViewer } from '../events_viewer';
import { alertsDefaultModel } from './default_headers';
import { useManageTimeline } from '../../../timelines/components/manage_timeline';
+import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers';
+import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell_rendering/default_cell_renderer';
import * as i18n from './translations';
import { useKibana } from '../../lib/kibana';
import { SourcererScopeName } from '../../store/sourcerer/model';
@@ -91,6 +93,8 @@ const AlertsTableComponent: React.FC = ({
defaultModel={alertsDefaultModel}
end={endDate}
id={timelineId}
+ renderCellValue={DefaultCellRenderer}
+ rowRenderers={defaultRowRenderers}
scopeId={SourcererScopeName.default}
start={startDate}
/>
diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx
index 3ecc17589fe08..8962f5e6c5146 100644
--- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx
@@ -26,6 +26,8 @@ import { KqlMode } from '../../../timelines/store/timeline/model';
import { SortDirection } from '../../../timelines/components/timeline/body/sort';
import { AlertsTableFilterGroup } from '../../../detections/components/alerts_table/alerts_filter_group';
import { SourcererScopeName } from '../../store/sourcerer/model';
+import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers';
+import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell_rendering/default_cell_renderer';
import { useTimelineEvents } from '../../../timelines/containers';
jest.mock('../../../timelines/components/graph_overlay', () => ({
@@ -99,6 +101,8 @@ const eventsViewerDefaultProps = {
query: '',
language: 'kql',
},
+ renderCellValue: DefaultCellRenderer,
+ rowRenderers: defaultRowRenderers,
start: from,
sort: [
{
@@ -118,6 +122,8 @@ describe('EventsViewer', () => {
defaultModel: eventsDefaultModel,
end: to,
id: TimelineId.test,
+ renderCellValue: DefaultCellRenderer,
+ rowRenderers: defaultRowRenderers,
start: from,
scopeId: SourcererScopeName.timeline,
};
diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx
index 050cd92b0556e..e6e868f1a7365 100644
--- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx
@@ -4,7 +4,6 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-
import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
import { isEmpty } from 'lodash/fp';
import React, { useEffect, useMemo, useState } from 'react';
@@ -41,7 +40,9 @@ import { useManageTimeline } from '../../../timelines/components/manage_timeline
import { ExitFullScreen } from '../exit_full_screen';
import { useGlobalFullScreen } from '../../containers/use_full_screen';
import { TimelineId, TimelineTabs } from '../../../../common/types/timeline';
+import { RowRenderer } from '../../../timelines/components/timeline/body/renderers/row_renderer';
import { GraphOverlay } from '../../../timelines/components/graph_overlay';
+import { CellValueElementProps } from '../../../timelines/components/timeline/cell_rendering';
import { SELECTOR_TIMELINE_GLOBAL_CONTAINER } from '../../../timelines/components/timeline/styles';
export const EVENTS_VIEWER_HEADER_HEIGHT = 90; // px
@@ -122,6 +123,8 @@ interface Props {
kqlMode: KqlMode;
query: Query;
onRuleChange?: () => void;
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
start: string;
sort: Sort[];
utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode;
@@ -146,8 +149,10 @@ const EventsViewerComponent: React.FC = ({
itemsPerPage,
itemsPerPageOptions,
kqlMode,
- query,
onRuleChange,
+ query,
+ renderCellValue,
+ rowRenderers,
start,
sort,
utilityBar,
@@ -310,6 +315,8 @@ const EventsViewerComponent: React.FC = ({
isEventViewer={true}
onRuleChange={onRuleChange}
refetch={refetch}
+ renderCellValue={renderCellValue}
+ rowRenderers={rowRenderers}
sort={sort}
tabType={TimelineTabs.query}
totalPages={calculateTotalPages({
@@ -343,6 +350,7 @@ const EventsViewerComponent: React.FC = ({
export const EventsViewer = React.memo(
EventsViewerComponent,
+ // eslint-disable-next-line complexity
(prevProps, nextProps) =>
deepEqual(prevProps.browserFields, nextProps.browserFields) &&
prevProps.columns === nextProps.columns &&
@@ -359,6 +367,8 @@ export const EventsViewer = React.memo(
prevProps.itemsPerPageOptions === nextProps.itemsPerPageOptions &&
prevProps.kqlMode === nextProps.kqlMode &&
deepEqual(prevProps.query, nextProps.query) &&
+ prevProps.renderCellValue === nextProps.renderCellValue &&
+ prevProps.rowRenderers === nextProps.rowRenderers &&
prevProps.start === nextProps.start &&
deepEqual(prevProps.sort, nextProps.sort) &&
prevProps.utilityBar === nextProps.utilityBar &&
diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx
index 5004c23f9111c..cd27177643b44 100644
--- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx
@@ -18,7 +18,9 @@ import { StatefulEventsViewer } from '.';
import { eventsDefaultModel } from './default_model';
import { TimelineId } from '../../../../common/types/timeline';
import { SourcererScopeName } from '../../store/sourcerer/model';
+import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell_rendering/default_cell_renderer';
import { useTimelineEvents } from '../../../timelines/containers';
+import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers';
jest.mock('../../../timelines/containers', () => ({
useTimelineEvents: jest.fn(),
@@ -38,6 +40,8 @@ const testProps = {
end: to,
indexNames: [],
id: TimelineId.test,
+ renderCellValue: DefaultCellRenderer,
+ rowRenderers: defaultRowRenderers,
scopeId: SourcererScopeName.default,
start: from,
};
diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx
index 59dc756bb2b3e..b58aa2236d292 100644
--- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx
@@ -22,6 +22,8 @@ import { useGlobalFullScreen } from '../../containers/use_full_screen';
import { SourcererScopeName } from '../../store/sourcerer/model';
import { useSourcererScope } from '../../containers/sourcerer';
import { DetailsPanel } from '../../../timelines/components/side_panel';
+import { RowRenderer } from '../../../timelines/components/timeline/body/renderers/row_renderer';
+import { CellValueElementProps } from '../../../timelines/components/timeline/cell_rendering';
const DEFAULT_EVENTS_VIEWER_HEIGHT = 652;
@@ -41,6 +43,8 @@ export interface OwnProps {
headerFilterGroup?: React.ReactNode;
pageFilters?: Filter[];
onRuleChange?: () => void;
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode;
}
@@ -67,8 +71,10 @@ const StatefulEventsViewerComponent: React.FC = ({
itemsPerPageOptions,
kqlMode,
pageFilters,
- query,
onRuleChange,
+ query,
+ renderCellValue,
+ rowRenderers,
start,
scopeId,
showCheckboxes,
@@ -129,6 +135,8 @@ const StatefulEventsViewerComponent: React.FC = ({
kqlMode={kqlMode}
query={query}
onRuleChange={onRuleChange}
+ renderCellValue={renderCellValue}
+ rowRenderers={rowRenderers}
start={start}
sort={sort}
utilityBar={utilityBar}
@@ -201,6 +209,7 @@ type PropsFromRedux = ConnectedProps;
export const StatefulEventsViewer = connector(
React.memo(
StatefulEventsViewerComponent,
+ // eslint-disable-next-line complexity
(prevProps, nextProps) =>
prevProps.id === nextProps.id &&
prevProps.scopeId === nextProps.scopeId &&
@@ -215,6 +224,8 @@ export const StatefulEventsViewer = connector(
deepEqual(prevProps.itemsPerPageOptions, nextProps.itemsPerPageOptions) &&
prevProps.kqlMode === nextProps.kqlMode &&
deepEqual(prevProps.query, nextProps.query) &&
+ prevProps.renderCellValue === nextProps.renderCellValue &&
+ prevProps.rowRenderers === nextProps.rowRenderers &&
deepEqual(prevProps.sort, nextProps.sort) &&
prevProps.start === nextProps.start &&
deepEqual(prevProps.pageFilters, nextProps.pageFilters) &&
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx
index 6c88b8e29800b..cf6db52d0cece 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx
@@ -48,6 +48,8 @@ import {
import { SourcererScopeName } from '../../../common/store/sourcerer/model';
import { useSourcererScope } from '../../../common/containers/sourcerer';
import { buildTimeRangeFilter } from './helpers';
+import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell_rendering/default_cell_renderer';
+import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers';
interface OwnProps {
timelineId: TimelineIdLiteral;
@@ -336,6 +338,8 @@ export const AlertsTableComponent: React.FC = ({
headerFilterGroup={headerFilterGroup}
id={timelineId}
onRuleChange={onRuleChange}
+ renderCellValue={DefaultCellRenderer}
+ rowRenderers={defaultRowRenderers}
scopeId={SourcererScopeName.detections}
start={from}
utilityBar={utilityBarCallback}
diff --git a/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx b/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx
index 922d52b6cfe5a..f88709e6e95ac 100644
--- a/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx
+++ b/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx
@@ -21,6 +21,8 @@ import { useGlobalFullScreen } from '../../../common/containers/use_full_screen'
import * as i18n from '../translations';
import { MatrixHistogramType } from '../../../../common/search_strategy/security_solution';
import { useManageTimeline } from '../../../timelines/components/manage_timeline';
+import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers';
+import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell_rendering/default_cell_renderer';
import { SourcererScopeName } from '../../../common/store/sourcerer/model';
const EVENTS_HISTOGRAM_ID = 'eventsHistogramQuery';
@@ -96,6 +98,8 @@ const EventsQueryTabBodyComponent: React.FC = ({
defaultModel={eventsDefaultModel}
end={endDate}
id={TimelineId.hostsPageEvents}
+ renderCellValue={DefaultCellRenderer}
+ rowRenderers={defaultRowRenderers}
scopeId={SourcererScopeName.default}
start={startDate}
pageFilters={pageFilters}
diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx
index e63ffedf3da7c..459706de36569 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx
@@ -14,6 +14,8 @@ import { StatefulTimeline } from '../../timeline';
import { TimelineId } from '../../../../../common/types/timeline';
import * as i18n from './translations';
import { timelineActions } from '../../../store/timeline';
+import { defaultRowRenderers } from '../../timeline/body/renderers';
+import { DefaultCellRenderer } from '../../timeline/cell_rendering/default_cell_renderer';
import { focusActiveTimelineButton } from '../../timeline/helpers';
interface FlyoutPaneComponentProps {
@@ -46,7 +48,11 @@ const FlyoutPaneComponent: React.FC = ({ timelineId })
onClose={handleClose}
size="l"
>
-
+
);
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap
index 72d2956bd4086..91d039a19495c 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/__snapshots__/index.test.tsx.snap
@@ -22,26 +22,77 @@ exports[`Columns it renders the expected columns 1`] = `
You are in a table cell. row: 2, column: 2
-
@@ -63,15 +114,77 @@ exports[`Columns it renders the expected columns 1`] = `
You are in a table cell. row: 2, column: 3
-
@@ -93,15 +206,77 @@ exports[`Columns it renders the expected columns 1`] = `
You are in a table cell. row: 2, column: 4
-
@@ -123,15 +298,77 @@ exports[`Columns it renders the expected columns 1`] = `
You are in a table cell. row: 2, column: 5
-
@@ -153,15 +390,77 @@ exports[`Columns it renders the expected columns 1`] = `
You are in a table cell. row: 2, column: 6
-
@@ -183,15 +482,77 @@ exports[`Columns it renders the expected columns 1`] = `
You are in a table cell. row: 2, column: 7
-
@@ -213,15 +574,77 @@ exports[`Columns it renders the expected columns 1`] = `
You are in a table cell. row: 2, column: 8
-
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.test.tsx
index f20978c6ba726..234e28e6231c5 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.test.tsx
@@ -9,10 +9,10 @@ import { shallow } from 'enzyme';
import React from 'react';
+import { DefaultCellRenderer } from '../../cell_rendering/default_cell_renderer';
import '../../../../../common/mock/match_media';
import { mockTimelineData } from '../../../../../common/mock';
import { defaultHeaders } from '../column_headers/default_headers';
-import { columnRenderers } from '../renderers';
import { DataDrivenColumns } from '.';
@@ -25,11 +25,11 @@ describe('Columns', () => {
ariaRowindex={2}
_id={mockTimelineData[0]._id}
columnHeaders={headersSansTimestamp}
- columnRenderers={columnRenderers}
data={mockTimelineData[0].data}
ecsData={mockTimelineData[0].ecs}
hasRowRenderers={false}
notesCount={0}
+ renderCellValue={DefaultCellRenderer}
timelineId="test"
/>
);
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.tsx
index 5aba562749f01..aeb9af46ea2ec 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/index.tsx
@@ -9,6 +9,7 @@ import { EuiScreenReaderOnly } from '@elastic/eui';
import React from 'react';
import { getOr } from 'lodash/fp';
+import { CellValueElementProps } from '../../cell_rendering';
import { DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME } from '../../../../../common/components/drag_and_drop/helpers';
import { Ecs } from '../../../../../../common/ecs';
import { TimelineNonEcsData } from '../../../../../../common/search_strategy/timeline';
@@ -16,20 +17,19 @@ import { TimelineTabs } from '../../../../../../common/types/timeline';
import { ColumnHeaderOptions } from '../../../../../timelines/store/timeline/model';
import { ARIA_COLUMN_INDEX_OFFSET } from '../../helpers';
import { EventsTd, EVENTS_TD_CLASS_NAME, EventsTdContent, EventsTdGroupData } from '../../styles';
-import { ColumnRenderer } from '../renderers/column_renderer';
-import { getColumnRenderer } from '../renderers/get_column_renderer';
+import { StatefulCell } from './stateful_cell';
import * as i18n from './translations';
interface Props {
_id: string;
ariaRowindex: number;
columnHeaders: ColumnHeaderOptions[];
- columnRenderers: ColumnRenderer[];
data: TimelineNonEcsData[];
ecsData: Ecs;
hasRowRenderers: boolean;
notesCount: number;
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
tabType?: TimelineTabs;
timelineId: string;
}
@@ -82,11 +82,11 @@ export const DataDrivenColumns = React.memo(
_id,
ariaRowindex,
columnHeaders,
- columnRenderers,
data,
ecsData,
hasRowRenderers,
notesCount,
+ renderCellValue,
tabType,
timelineId,
}) => (
@@ -105,18 +105,16 @@ export const DataDrivenColumns = React.memo(
{i18n.YOU_ARE_IN_A_TABLE_CELL({ row: ariaRowindex, column: i + 2 })}
- {getColumnRenderer(header.id, columnRenderers, data).renderColumn({
- columnName: header.id,
- eventId: _id,
- field: header,
- linkValues: getOr([], header.linkField ?? '', ecsData),
- timelineId: tabType != null ? `${timelineId}-${tabType}` : timelineId,
- truncate: true,
- values: getMappedNonEcsValue({
- data,
- fieldName: header.id,
- }),
- })}
+
>
{hasRowRenderers ? (
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/stateful_cell.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/stateful_cell.test.tsx
new file mode 100644
index 0000000000000..3c75bc7fb2649
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/stateful_cell.test.tsx
@@ -0,0 +1,171 @@
+/*
+ * 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 { mount } from 'enzyme';
+import { cloneDeep } from 'lodash/fp';
+import React, { useEffect } from 'react';
+
+import { CellValueElementProps } from '../../cell_rendering';
+import { defaultHeaders, mockTimelineData } from '../../../../../common/mock';
+import { TimelineNonEcsData } from '../../../../../../common/search_strategy/timeline';
+import { TimelineTabs } from '../../../../../../common/types/timeline';
+import { ColumnHeaderOptions } from '../../../../store/timeline/model';
+
+import { StatefulCell } from './stateful_cell';
+import { getMappedNonEcsValue } from '.';
+
+/**
+ * This (test) component implement's `EuiDataGrid`'s `renderCellValue` interface,
+ * as documented here: https://elastic.github.io/eui/#/tabular-content/data-grid
+ *
+ * Its `CellValueElementProps` props are a superset of `EuiDataGridCellValueElementProps`.
+ * The `setCellProps` function, defined by the `EuiDataGridCellValueElementProps` interface,
+ * is typically called in a `useEffect`, as illustrated by `EuiDataGrid`'s code sandbox example:
+ * https://codesandbox.io/s/zhxmo
+ */
+const RenderCellValue: React.FC = ({ columnId, data, setCellProps }) => {
+ useEffect(() => {
+ // branching logic that conditionally renders a specific cell green:
+ if (columnId === defaultHeaders[0].id) {
+ const value = getMappedNonEcsValue({
+ data,
+ fieldName: columnId,
+ });
+
+ if (value?.length) {
+ setCellProps({
+ style: {
+ backgroundColor: 'green',
+ },
+ });
+ }
+ }
+ }, [columnId, data, setCellProps]);
+
+ return (
+
+ {getMappedNonEcsValue({
+ data,
+ fieldName: columnId,
+ })}
+
+ );
+};
+
+describe('StatefulCell', () => {
+ const ariaRowindex = 123;
+ const eventId = '_id-123';
+ const linkValues = ['foo', 'bar', '@baz'];
+ const tabType = TimelineTabs.query;
+ const timelineId = 'test';
+
+ let header: ColumnHeaderOptions;
+ let data: TimelineNonEcsData[];
+ beforeEach(() => {
+ data = cloneDeep(mockTimelineData[0].data);
+ header = cloneDeep(defaultHeaders[0]);
+ });
+
+ test('it invokes renderCellValue with the expected arguments when tabType is specified', () => {
+ const renderCellValue = jest.fn();
+
+ mount(
+
+ );
+
+ expect(renderCellValue).toBeCalledWith(
+ expect.objectContaining({
+ columnId: header.id,
+ eventId,
+ data,
+ header,
+ isExpandable: true,
+ isExpanded: false,
+ isDetails: false,
+ linkValues,
+ rowIndex: ariaRowindex - 1,
+ timelineId: `${timelineId}-${tabType}`,
+ })
+ );
+ });
+
+ test('it invokes renderCellValue with the expected arguments when tabType is NOT specified', () => {
+ const renderCellValue = jest.fn();
+
+ mount(
+
+ );
+
+ expect(renderCellValue).toBeCalledWith(
+ expect.objectContaining({
+ columnId: header.id,
+ eventId,
+ data,
+ header,
+ isExpandable: true,
+ isExpanded: false,
+ isDetails: false,
+ linkValues,
+ rowIndex: ariaRowindex - 1,
+ timelineId,
+ })
+ );
+ });
+
+ test('it renders the React.Node returned by renderCellValue', () => {
+ const renderCellValue = () => ;
+
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper.find('[data-test-subj="renderCellValue"]').exists()).toBe(true);
+ });
+
+ test("it renders a div with the styles set by `renderCellValue`'s `setCellProps` argument", () => {
+ const wrapper = mount(
+
+ );
+
+ expect(
+ wrapper.find('[data-test-subj="statefulCell"]').getDOMNode().getAttribute('style')
+ ).toEqual('background-color: green;');
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/stateful_cell.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/stateful_cell.tsx
new file mode 100644
index 0000000000000..83f603364ba8c
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/data_driven_columns/stateful_cell.tsx
@@ -0,0 +1,63 @@
+/*
+ * 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, { HTMLAttributes, useState } from 'react';
+
+import { CellValueElementProps } from '../../cell_rendering';
+import { TimelineNonEcsData } from '../../../../../../common/search_strategy/timeline';
+import { TimelineTabs } from '../../../../../../common/types/timeline';
+import { ColumnHeaderOptions } from '../../../../../timelines/store/timeline/model';
+
+export interface CommonProps {
+ className?: string;
+ 'aria-label'?: string;
+ 'data-test-subj'?: string;
+}
+
+const StatefulCellComponent = ({
+ ariaRowindex,
+ data,
+ header,
+ eventId,
+ linkValues,
+ renderCellValue,
+ tabType,
+ timelineId,
+}: {
+ ariaRowindex: number;
+ data: TimelineNonEcsData[];
+ header: ColumnHeaderOptions;
+ eventId: string;
+ linkValues: string[] | undefined;
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ tabType?: TimelineTabs;
+ timelineId: string;
+}) => {
+ const [cellProps, setCellProps] = useState>({});
+
+ return (
+
+ {renderCellValue({
+ columnId: header.id,
+ eventId,
+ data,
+ header,
+ isExpandable: true,
+ isExpanded: false,
+ isDetails: false,
+ linkValues,
+ rowIndex: ariaRowindex - 1,
+ setCellProps,
+ timelineId: tabType != null ? `${timelineId}-${tabType}` : timelineId,
+ })}
+
+ );
+};
+
+StatefulCellComponent.displayName = 'StatefulCellComponent';
+
+export const StatefulCell = React.memo(StatefulCellComponent);
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.test.tsx
index abdfda3272d6a..74724dedf4d11 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.test.tsx
@@ -14,6 +14,7 @@ import { DEFAULT_ACTIONS_COLUMN_WIDTH } from '../constants';
import * as i18n from '../translations';
import { EventColumnView } from './event_column_view';
+import { DefaultCellRenderer } from '../../cell_rendering/default_cell_renderer';
import { TimelineTabs, TimelineType, TimelineId } from '../../../../../../common/types/timeline';
import { useShallowEqualSelector } from '../../../../../common/hooks/use_selector';
@@ -56,6 +57,7 @@ describe('EventColumnView', () => {
onRowSelected: jest.fn(),
onUnPinEvent: jest.fn(),
refetch: jest.fn(),
+ renderCellValue: DefaultCellRenderer,
selectedEventIds: {},
showCheckboxes: false,
showNotes: false,
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.tsx
index c6caf0a7b5b15..a0a0aeb23e8f7 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/event_column_view.tsx
@@ -7,6 +7,7 @@
import React, { useCallback, useMemo } from 'react';
+import { CellValueElementProps } from '../../cell_rendering';
import { useShallowEqualSelector } from '../../../../../common/hooks/use_selector';
import { Ecs } from '../../../../../../common/ecs';
import { TimelineNonEcsData } from '../../../../../../common/search_strategy/timeline';
@@ -21,7 +22,6 @@ import {
getPinOnClick,
InvestigateInResolverAction,
} from '../helpers';
-import { ColumnRenderer } from '../renderers/column_renderer';
import { AlertContextMenu } from '../../../../../detections/components/alerts_table/timeline_actions/alert_context_menu';
import { InvestigateInTimelineAction } from '../../../../../detections/components/alerts_table/timeline_actions/investigate_in_timeline_action';
import { AddEventNoteAction } from '../actions/add_note_icon_item';
@@ -38,7 +38,6 @@ interface Props {
actionsColumnWidth: number;
ariaRowindex: number;
columnHeaders: ColumnHeaderOptions[];
- columnRenderers: ColumnRenderer[];
data: TimelineNonEcsData[];
ecsData: Ecs;
eventIdToNoteIds: Readonly>;
@@ -51,6 +50,7 @@ interface Props {
onRowSelected: OnRowSelected;
onUnPinEvent: OnUnPinEvent;
refetch: inputsModel.Refetch;
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
onRuleChange?: () => void;
hasRowRenderers: boolean;
selectedEventIds: Readonly>;
@@ -69,7 +69,6 @@ export const EventColumnView = React.memo(
actionsColumnWidth,
ariaRowindex,
columnHeaders,
- columnRenderers,
data,
ecsData,
eventIdToNoteIds,
@@ -84,6 +83,7 @@ export const EventColumnView = React.memo(
refetch,
hasRowRenderers,
onRuleChange,
+ renderCellValue,
selectedEventIds,
showCheckboxes,
showNotes,
@@ -227,11 +227,11 @@ export const EventColumnView = React.memo(
_id={id}
ariaRowindex={ariaRowindex}
columnHeaders={columnHeaders}
- columnRenderers={columnRenderers}
data={data}
ecsData={ecsData}
hasRowRenderers={hasRowRenderers}
notesCount={notesCount}
+ renderCellValue={renderCellValue}
tabType={tabType}
timelineId={timelineId}
/>
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/index.tsx
index d76b5834c233e..7f8a3a92fb5ba 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/index.tsx
@@ -8,6 +8,7 @@
import React from 'react';
import { isEmpty } from 'lodash';
+import { CellValueElementProps } from '../../cell_rendering';
import { inputsModel } from '../../../../../common/store';
import { BrowserFields } from '../../../../../common/containers/source';
import {
@@ -18,7 +19,6 @@ import { TimelineTabs } from '../../../../../../common/types/timeline';
import { ColumnHeaderOptions } from '../../../../../timelines/store/timeline/model';
import { OnRowSelected } from '../../events';
import { EventsTbody } from '../../styles';
-import { ColumnRenderer } from '../renderers/column_renderer';
import { RowRenderer } from '../renderers/row_renderer';
import { StatefulEvent } from './stateful_event';
import { eventIsPinned } from '../helpers';
@@ -30,7 +30,6 @@ interface Props {
actionsColumnWidth: number;
browserFields: BrowserFields;
columnHeaders: ColumnHeaderOptions[];
- columnRenderers: ColumnRenderer[];
containerRef: React.MutableRefObject;
data: TimelineItem[];
eventIdToNoteIds: Readonly>;
@@ -41,6 +40,7 @@ interface Props {
onRowSelected: OnRowSelected;
pinnedEventIds: Readonly>;
refetch: inputsModel.Refetch;
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
onRuleChange?: () => void;
rowRenderers: RowRenderer[];
selectedEventIds: Readonly>;
@@ -52,7 +52,6 @@ const EventsComponent: React.FC = ({
actionsColumnWidth,
browserFields,
columnHeaders,
- columnRenderers,
containerRef,
data,
eventIdToNoteIds,
@@ -64,6 +63,7 @@ const EventsComponent: React.FC = ({
pinnedEventIds,
refetch,
onRuleChange,
+ renderCellValue,
rowRenderers,
selectedEventIds,
showCheckboxes,
@@ -76,7 +76,6 @@ const EventsComponent: React.FC = ({
ariaRowindex={i + ARIA_ROW_INDEX_OFFSET}
browserFields={browserFields}
columnHeaders={columnHeaders}
- columnRenderers={columnRenderers}
containerRef={containerRef}
event={event}
eventIdToNoteIds={eventIdToNoteIds}
@@ -88,6 +87,7 @@ const EventsComponent: React.FC = ({
lastFocusedAriaColindex={lastFocusedAriaColindex}
loadingEventIds={loadingEventIds}
onRowSelected={onRowSelected}
+ renderCellValue={renderCellValue}
refetch={refetch}
rowRenderers={rowRenderers}
onRuleChange={onRuleChange}
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx
index 4191badd6b03f..97ab088b61583 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx
@@ -8,6 +8,7 @@
import React, { useCallback, useMemo, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
+import { CellValueElementProps } from '../../cell_rendering';
import { useDeepEqualSelector } from '../../../../../common/hooks/use_selector';
import {
TimelineExpandedDetailType,
@@ -23,7 +24,6 @@ import { ColumnHeaderOptions } from '../../../../../timelines/store/timeline/mod
import { OnPinEvent, OnRowSelected } from '../../events';
import { STATEFUL_EVENT_CSS_CLASS_NAME } from '../../helpers';
import { EventsTrGroup, EventsTrSupplement, EventsTrSupplementContainer } from '../../styles';
-import { ColumnRenderer } from '../renderers/column_renderer';
import { RowRenderer } from '../renderers/row_renderer';
import { isEventBuildingBlockType, getEventType, isEvenEqlSequence } from '../helpers';
import { NoteCards } from '../../../notes/note_cards';
@@ -45,7 +45,6 @@ interface Props {
containerRef: React.MutableRefObject;
browserFields: BrowserFields;
columnHeaders: ColumnHeaderOptions[];
- columnRenderers: ColumnRenderer[];
event: TimelineItem;
eventIdToNoteIds: Readonly>;
isEventViewer?: boolean;
@@ -56,6 +55,7 @@ interface Props {
refetch: inputsModel.Refetch;
ariaRowindex: number;
onRuleChange?: () => void;
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
rowRenderers: RowRenderer[];
selectedEventIds: Readonly>;
showCheckboxes: boolean;
@@ -77,7 +77,6 @@ const StatefulEventComponent: React.FC = ({
browserFields,
containerRef,
columnHeaders,
- columnRenderers,
event,
eventIdToNoteIds,
isEventViewer = false,
@@ -86,8 +85,9 @@ const StatefulEventComponent: React.FC = ({
loadingEventIds,
onRowSelected,
refetch,
- onRuleChange,
+ renderCellValue,
rowRenderers,
+ onRuleChange,
ariaRowindex,
selectedEventIds,
showCheckboxes,
@@ -259,7 +259,6 @@ const StatefulEventComponent: React.FC = ({
actionsColumnWidth={actionsColumnWidth}
ariaRowindex={ariaRowindex}
columnHeaders={columnHeaders}
- columnRenderers={columnRenderers}
data={event.data}
ecsData={event.ecs}
eventIdToNoteIds={eventIdToNoteIds}
@@ -273,6 +272,7 @@ const StatefulEventComponent: React.FC = ({
onRowSelected={onRowSelected}
onUnPinEvent={onUnPinEvent}
refetch={refetch}
+ renderCellValue={renderCellValue}
onRuleChange={onRuleChange}
selectedEventIds={selectedEventIds}
showCheckboxes={showCheckboxes}
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx
index 723e4c3de5c27..76dbfc553d228 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx
@@ -8,6 +8,7 @@
import React from 'react';
import { waitFor } from '@testing-library/react';
+import { DefaultCellRenderer } from '../cell_rendering/default_cell_renderer';
import '../../../../common/mock/match_media';
import { mockBrowserFields } from '../../../../common/containers/source/mock';
import { Direction } from '../../../../../common/search_strategy';
@@ -19,6 +20,7 @@ import { Sort } from './sort';
import { useMountAppended } from '../../../../common/utils/use_mount_appended';
import { timelineActions } from '../../../store/timeline';
import { TimelineTabs } from '../../../../../common/types/timeline';
+import { defaultRowRenderers } from './renderers';
const mockSort: Sort[] = [
{
@@ -39,8 +41,8 @@ jest.mock('react-redux', () => {
});
jest.mock('../../../../common/hooks/use_selector', () => ({
- useShallowEqualSelector: jest.fn().mockReturnValue(mockTimelineModel),
- useDeepEqualSelector: jest.fn().mockReturnValue(mockTimelineModel),
+ useShallowEqualSelector: () => mockTimelineModel,
+ useDeepEqualSelector: () => mockTimelineModel,
}));
jest.mock('../../../../common/components/link_to');
@@ -76,6 +78,8 @@ describe('Body', () => {
loadingEventIds: [],
pinnedEventIds: {},
refetch: jest.fn(),
+ renderCellValue: DefaultCellRenderer,
+ rowRenderers: defaultRowRenderers,
selectedEventIds: {},
setSelected: (jest.fn() as unknown) as StatefulBodyProps['setSelected'],
sort: mockSort,
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.tsx
index 4df6eb16ccb62..59c0610c544e9 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.tsx
@@ -11,6 +11,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { connect, ConnectedProps } from 'react-redux';
import deepEqual from 'fast-deep-equal';
+import { CellValueElementProps } from '../cell_rendering';
import { RowRendererId, TimelineId, TimelineTabs } from '../../../../../common/types/timeline';
import {
FIRST_ARIA_INDEX,
@@ -28,9 +29,9 @@ import { timelineActions, timelineSelectors } from '../../../store/timeline';
import { OnRowSelected, OnSelectAll } from '../events';
import { getActionsColumnWidth, getColumnHeaders } from './column_headers/helpers';
import { getEventIdToDataMapping } from './helpers';
-import { columnRenderers, rowRenderers } from './renderers';
import { Sort } from './sort';
import { plainRowRenderer } from './renderers/plain_row_renderer';
+import { RowRenderer } from './renderers/row_renderer';
import { EventsTable, TimelineBody, TimelineBodyGlobalStyle } from '../styles';
import { ColumnHeaders } from './column_headers';
import { Events } from './events';
@@ -44,6 +45,8 @@ interface OwnProps {
isEventViewer?: boolean;
sort: Sort[];
refetch: inputsModel.Refetch;
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
tabType: TimelineTabs;
totalPages: number;
onRuleChange?: () => void;
@@ -83,6 +86,8 @@ export const BodyComponent = React.memo(
onRuleChange,
showCheckboxes,
refetch,
+ renderCellValue,
+ rowRenderers,
sort,
tabType,
totalPages,
@@ -141,7 +146,7 @@ export const BodyComponent = React.memo(
if (!excludedRowRendererIds) return rowRenderers;
return rowRenderers.filter((rowRenderer) => !excludedRowRendererIds.includes(rowRenderer.id));
- }, [excludedRowRendererIds]);
+ }, [excludedRowRendererIds, rowRenderers]);
const actionsColumnWidth = useMemo(
() =>
@@ -209,7 +214,6 @@ export const BodyComponent = React.memo(
actionsColumnWidth={actionsColumnWidth}
browserFields={browserFields}
columnHeaders={columnHeaders}
- columnRenderers={columnRenderers}
data={data}
eventIdToNoteIds={eventIdToNoteIds}
id={id}
@@ -219,6 +223,7 @@ export const BodyComponent = React.memo(
onRowSelected={onRowSelected}
pinnedEventIds={pinnedEventIds}
refetch={refetch}
+ renderCellValue={renderCellValue}
rowRenderers={enabledRowRenderers}
onRuleChange={onRuleChange}
selectedEventIds={selectedEventIds}
@@ -244,6 +249,8 @@ export const BodyComponent = React.memo(
prevProps.id === nextProps.id &&
prevProps.isEventViewer === nextProps.isEventViewer &&
prevProps.isSelectAllChecked === nextProps.isSelectAllChecked &&
+ prevProps.renderCellValue === nextProps.renderCellValue &&
+ prevProps.rowRenderers === nextProps.rowRenderers &&
prevProps.showCheckboxes === nextProps.showCheckboxes &&
prevProps.tabType === nextProps.tabType
);
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx
index 6e36102da2de9..b92a4381d837b 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/get_row_renderer.test.tsx
@@ -17,7 +17,7 @@ import { mockTimelineData } from '../../../../../common/mock';
import { TestProviders } from '../../../../../common/mock/test_providers';
import { useMountAppended } from '../../../../../common/utils/use_mount_appended';
-import { rowRenderers } from '.';
+import { defaultRowRenderers } from '.';
import { getRowRenderer } from './get_row_renderer';
jest.mock('@elastic/eui', () => {
@@ -48,7 +48,7 @@ describe('get_column_renderer', () => {
});
test('renders correctly against snapshot', () => {
- const rowRenderer = getRowRenderer(nonSuricata, rowRenderers);
+ const rowRenderer = getRowRenderer(nonSuricata, defaultRowRenderers);
const row = rowRenderer?.renderRow({
browserFields: mockBrowserFields,
data: nonSuricata,
@@ -60,7 +60,7 @@ describe('get_column_renderer', () => {
});
test('should render plain row data when it is a non suricata row', () => {
- const rowRenderer = getRowRenderer(nonSuricata, rowRenderers);
+ const rowRenderer = getRowRenderer(nonSuricata, defaultRowRenderers);
const row = rowRenderer?.renderRow({
browserFields: mockBrowserFields,
data: nonSuricata,
@@ -75,7 +75,7 @@ describe('get_column_renderer', () => {
});
test('should render a suricata row data when it is a suricata row', () => {
- const rowRenderer = getRowRenderer(suricata, rowRenderers);
+ const rowRenderer = getRowRenderer(suricata, defaultRowRenderers);
const row = rowRenderer?.renderRow({
browserFields: mockBrowserFields,
data: suricata,
@@ -93,7 +93,7 @@ describe('get_column_renderer', () => {
test('should render a suricata row data if event.category is network_traffic', () => {
suricata.event = { ...suricata.event, ...{ category: ['network_traffic'] } };
- const rowRenderer = getRowRenderer(suricata, rowRenderers);
+ const rowRenderer = getRowRenderer(suricata, defaultRowRenderers);
const row = rowRenderer?.renderRow({
browserFields: mockBrowserFields,
data: suricata,
@@ -111,7 +111,7 @@ describe('get_column_renderer', () => {
test('should render a zeek row data if event.category is network_traffic', () => {
zeek.event = { ...zeek.event, ...{ category: ['network_traffic'] } };
- const rowRenderer = getRowRenderer(zeek, rowRenderers);
+ const rowRenderer = getRowRenderer(zeek, defaultRowRenderers);
const row = rowRenderer?.renderRow({
browserFields: mockBrowserFields,
data: zeek,
@@ -129,7 +129,7 @@ describe('get_column_renderer', () => {
test('should render a system row data if event.category is network_traffic', () => {
system.event = { ...system.event, ...{ category: ['network_traffic'] } };
- const rowRenderer = getRowRenderer(system, rowRenderers);
+ const rowRenderer = getRowRenderer(system, defaultRowRenderers);
const row = rowRenderer?.renderRow({
browserFields: mockBrowserFields,
data: system,
@@ -147,7 +147,7 @@ describe('get_column_renderer', () => {
test('should render a auditd row data if event.category is network_traffic', () => {
auditd.event = { ...auditd.event, ...{ category: ['network_traffic'] } };
- const rowRenderer = getRowRenderer(auditd, rowRenderers);
+ const rowRenderer = getRowRenderer(auditd, defaultRowRenderers);
const row = rowRenderer?.renderRow({
browserFields: mockBrowserFields,
data: auditd,
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/index.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/index.ts
index 671d183c62e6d..209a9414f62f1 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/index.ts
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/index.ts
@@ -23,7 +23,7 @@ import { systemRowRenderers } from './system/generic_row_renderer';
// Suricata and Zeek which is why Suricata and Zeek are above it. The
// plainRowRenderer always returns true to everything which is why it always
// should be last.
-export const rowRenderers: RowRenderer[] = [
+export const defaultRowRenderers: RowRenderer[] = [
...auditdRowRenderers,
...systemRowRenderers,
suricataRowRenderer,
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx
new file mode 100644
index 0000000000000..5ac1dcf8805cf
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.test.tsx
@@ -0,0 +1,107 @@
+/*
+ * 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 { mount } from 'enzyme';
+import { cloneDeep } from 'lodash/fp';
+import React from 'react';
+
+import { columnRenderers } from '../body/renderers';
+import { getColumnRenderer } from '../body/renderers/get_column_renderer';
+import { DragDropContextWrapper } from '../../../../common/components/drag_and_drop/drag_drop_context_wrapper';
+import { DroppableWrapper } from '../../../../common/components/drag_and_drop/droppable_wrapper';
+import { mockBrowserFields } from '../../../../common/containers/source/mock';
+import { defaultHeaders, mockTimelineData, TestProviders } from '../../../../common/mock';
+import { DefaultCellRenderer } from './default_cell_renderer';
+
+jest.mock('../body/renderers/get_column_renderer');
+const getColumnRendererMock = getColumnRenderer as jest.Mock;
+const mockImplementation = {
+ renderColumn: jest.fn(),
+};
+
+describe('DefaultCellRenderer', () => {
+ const columnId = 'signal.rule.risk_score';
+ const eventId = '_id-123';
+ const isDetails = true;
+ const isExpandable = true;
+ const isExpanded = true;
+ const linkValues = ['foo', 'bar', '@baz'];
+ const rowIndex = 3;
+ const setCellProps = jest.fn();
+ const timelineId = 'test';
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ getColumnRendererMock.mockImplementation(() => mockImplementation);
+ });
+
+ test('it invokes `getColumnRenderer` with the expected arguments', () => {
+ const data = cloneDeep(mockTimelineData[0].data);
+ const header = cloneDeep(defaultHeaders[0]);
+
+ mount(
+
+
+
+
+
+
+
+ );
+
+ expect(getColumnRenderer).toBeCalledWith(header.id, columnRenderers, data);
+ });
+
+ test('it invokes `renderColumn` with the expected arguments', () => {
+ const data = cloneDeep(mockTimelineData[0].data);
+ const header = cloneDeep(defaultHeaders[0]);
+
+ mount(
+
+
+
+
+
+
+
+ );
+
+ expect(mockImplementation.renderColumn).toBeCalledWith({
+ columnName: header.id,
+ eventId,
+ field: header,
+ linkValues,
+ timelineId,
+ truncate: true,
+ values: ['2018-11-05T19:03:25.937Z'],
+ });
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.tsx
new file mode 100644
index 0000000000000..8d8f821107e7b
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/default_cell_renderer.tsx
@@ -0,0 +1,39 @@
+/*
+ * 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 { getMappedNonEcsValue } from '../body/data_driven_columns';
+import { columnRenderers } from '../body/renderers';
+import { getColumnRenderer } from '../body/renderers/get_column_renderer';
+
+import { CellValueElementProps } from '.';
+
+export const DefaultCellRenderer: React.FC = ({
+ columnId,
+ data,
+ eventId,
+ header,
+ linkValues,
+ setCellProps,
+ timelineId,
+}) => (
+ <>
+ {getColumnRenderer(header.id, columnRenderers, data).renderColumn({
+ columnName: header.id,
+ eventId,
+ field: header,
+ linkValues,
+ timelineId,
+ truncate: true,
+ values: getMappedNonEcsValue({
+ data,
+ fieldName: header.id,
+ }),
+ })}
+ >
+);
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/index.tsx
new file mode 100644
index 0000000000000..03e444e3a9afd
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/cell_rendering/index.tsx
@@ -0,0 +1,20 @@
+/*
+ * 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 { EuiDataGridCellValueElementProps } from '@elastic/eui';
+
+import { TimelineNonEcsData } from '../../../../../common/search_strategy/timeline';
+import { ColumnHeaderOptions } from '../../../store/timeline/model';
+
+/** The following props are provided to the function called by `renderCellValue` */
+export type CellValueElementProps = EuiDataGridCellValueElementProps & {
+ data: TimelineNonEcsData[];
+ eventId: string; // _id
+ header: ColumnHeaderOptions;
+ linkValues: string[] | undefined;
+ timelineId: string;
+};
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/__snapshots__/index.test.tsx.snap
index 2595f29144b80..7d237ecaf92df 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/__snapshots__/index.test.tsx.snap
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/__snapshots__/index.test.tsx.snap
@@ -140,6 +140,986 @@ In other use cases the message field can be used to concatenate different values
]
}
onEventClosed={[MockFunction]}
+ renderCellValue={[Function]}
+ rowRenderers={
+ Array [
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_dns",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "library",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "registry",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "suricata",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "zeek",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "netflow",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ ]
+ }
showExpandedDetails={false}
start="2018-03-23T18:49:23.132Z"
timelineId="test"
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx
index 7b77a915f2f05..e13bed1e2eff6 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.test.tsx
@@ -9,6 +9,8 @@ import { shallow } from 'enzyme';
import React from 'react';
import useResizeObserver from 'use-resize-observer/polyfilled';
+import { defaultRowRenderers } from '../body/renderers';
+import { DefaultCellRenderer } from '../cell_rendering/default_cell_renderer';
import { defaultHeaders, mockTimelineData } from '../../../../common/mock';
import '../../../../common/mock/match_media';
import { TestProviders } from '../../../../common/mock/test_providers';
@@ -94,6 +96,8 @@ describe('Timeline', () => {
itemsPerPage: 5,
itemsPerPageOptions: [5, 10, 20],
onEventClosed: jest.fn(),
+ renderCellValue: DefaultCellRenderer,
+ rowRenderers: defaultRowRenderers,
showExpandedDetails: false,
start: startDate,
timerangeKind: 'absolute',
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.tsx
index 51f8db4e796e5..6bb19ce5a6852 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/eql_tab_content/index.tsx
@@ -22,10 +22,12 @@ import deepEqual from 'fast-deep-equal';
import { InPortal } from 'react-reverse-portal';
import { timelineActions, timelineSelectors } from '../../../store/timeline';
+import { CellValueElementProps } from '../cell_rendering';
import { TimelineItem } from '../../../../../common/search_strategy';
import { useTimelineEvents } from '../../../containers/index';
import { defaultHeaders } from '../body/column_headers/default_headers';
import { StatefulBody } from '../body';
+import { RowRenderer } from '../body/renderers/row_renderer';
import { Footer, footerHeight } from '../footer';
import { calculateTotalPages } from '../helpers';
import { TimelineRefetch } from '../refetch_timeline';
@@ -133,6 +135,8 @@ const isTimerangeSame = (prevProps: Props, nextProps: Props) =>
prevProps.timerangeKind === nextProps.timerangeKind;
interface OwnProps {
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
timelineId: string;
}
@@ -154,6 +158,8 @@ export const EqlTabContentComponent: React.FC = ({
itemsPerPage,
itemsPerPageOptions,
onEventClosed,
+ renderCellValue,
+ rowRenderers,
showExpandedDetails,
start,
timerangeKind,
@@ -284,6 +290,8 @@ export const EqlTabContentComponent: React.FC = ({
data={isBlankTimeline ? EMPTY_EVENTS : events}
id={timelineId}
refetch={refetch}
+ renderCellValue={renderCellValue}
+ rowRenderers={rowRenderers}
sort={NO_SORTING}
tabType={TimelineTabs.eql}
totalPages={calculateTotalPages({
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx
index ee2ce8cf8103b..db7a3cc3c9900 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx
@@ -17,7 +17,9 @@ import { mockIndexNames, mockIndexPattern, TestProviders } from '../../../common
import { StatefulTimeline, Props as StatefulTimelineOwnProps } from './index';
import { useTimelineEvents } from '../../containers/index';
+import { DefaultCellRenderer } from './cell_rendering/default_cell_renderer';
import { SELECTOR_TIMELINE_GLOBAL_CONTAINER } from './styles';
+import { defaultRowRenderers } from './body/renderers';
jest.mock('../../containers/index', () => ({
useTimelineEvents: jest.fn(),
@@ -63,6 +65,8 @@ jest.mock('../../../common/containers/sourcerer', () => {
});
describe('StatefulTimeline', () => {
const props: StatefulTimelineOwnProps = {
+ renderCellValue: DefaultCellRenderer,
+ rowRenderers: defaultRowRenderers,
timelineId: TimelineId.test,
};
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx
index 6d2374dd8eef7..367357511c9c8 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx
@@ -14,6 +14,8 @@ import styled from 'styled-components';
import { timelineActions, timelineSelectors } from '../../store/timeline';
import { timelineDefaults } from '../../../timelines/store/timeline/defaults';
import { defaultHeaders } from './body/column_headers/default_headers';
+import { RowRenderer } from './body/renderers/row_renderer';
+import { CellValueElementProps } from './cell_rendering';
import { isTab } from '../../../common/components/accessibility/helpers';
import { useSourcererScope } from '../../../common/containers/sourcerer';
import { SourcererScopeName } from '../../../common/store/sourcerer/model';
@@ -36,10 +38,12 @@ const TimelineTemplateBadge = styled.div`
`;
export interface Props {
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
timelineId: TimelineId;
}
-const TimelineSavingProgressComponent: React.FC = ({ timelineId }) => {
+const TimelineSavingProgressComponent: React.FC<{ timelineId: TimelineId }> = ({ timelineId }) => {
const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []);
const isSaving = useShallowEqualSelector(
(state) => (getTimeline(state, timelineId) ?? timelineDefaults).isSaving
@@ -50,7 +54,11 @@ const TimelineSavingProgressComponent: React.FC = ({ timelineId }) => {
const TimelineSavingProgress = React.memo(TimelineSavingProgressComponent);
-const StatefulTimelineComponent: React.FC = ({ timelineId }) => {
+const StatefulTimelineComponent: React.FC = ({
+ renderCellValue,
+ rowRenderers,
+ timelineId,
+}) => {
const dispatch = useDispatch();
const containerElement = useRef(null);
const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []);
@@ -131,6 +139,8 @@ const StatefulTimelineComponent: React.FC = ({ timelineId }) => {
{
timelineId: TimelineId.test,
itemsPerPage: 5,
itemsPerPageOptions: [5, 10, 20],
+ renderCellValue: DefaultCellRenderer,
+ rowRenderers: defaultRowRenderers,
sort,
pinnedEventIds: {},
showExpandedDetails: false,
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.tsx
index a19a61d8268ff..dfc14747dacf3 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/pinned_tab_content/index.tsx
@@ -14,10 +14,12 @@ import { connect, ConnectedProps } from 'react-redux';
import deepEqual from 'fast-deep-equal';
import { timelineActions, timelineSelectors } from '../../../store/timeline';
+import { CellValueElementProps } from '../cell_rendering';
import { Direction } from '../../../../../common/search_strategy';
import { useTimelineEvents } from '../../../containers/index';
import { defaultHeaders } from '../body/column_headers/default_headers';
import { StatefulBody } from '../body';
+import { RowRenderer } from '../body/renderers/row_renderer';
import { Footer, footerHeight } from '../footer';
import { requiredFieldsForActions } from '../../../../detections/components/alerts_table/default_config';
import { EventDetailsWidthProvider } from '../../../../common/components/events_viewer/event_details_width_context';
@@ -87,6 +89,8 @@ const VerticalRule = styled.div`
VerticalRule.displayName = 'VerticalRule';
interface OwnProps {
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
timelineId: string;
}
@@ -106,6 +110,8 @@ export const PinnedTabContentComponent: React.FC = ({
itemsPerPageOptions,
pinnedEventIds,
onEventClosed,
+ renderCellValue,
+ rowRenderers,
showExpandedDetails,
sort,
}) => {
@@ -217,6 +223,8 @@ export const PinnedTabContentComponent: React.FC = ({
data={events}
id={timelineId}
refetch={refetch}
+ renderCellValue={renderCellValue}
+ rowRenderers={rowRenderers}
sort={sort}
tabType={TimelineTabs.pinned}
totalPages={calculateTotalPages({
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/__snapshots__/index.test.tsx.snap
index 0688a10b31eef..46c85f634ff6b 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/__snapshots__/index.test.tsx.snap
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/__snapshots__/index.test.tsx.snap
@@ -276,6 +276,986 @@ In other use cases the message field can be used to concatenate different values
kqlMode="search"
kqlQueryExpression=""
onEventClosed={[MockFunction]}
+ renderCellValue={[Function]}
+ rowRenderers={
+ Array [
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "auditd",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_dns",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "alerts",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "library",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "registry",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_fim",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_security_event",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_file",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system_socket",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "system",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "suricata",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "zeek",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ Object {
+ "id": "netflow",
+ "isInstance": [Function],
+ "renderRow": [Function],
+ },
+ ]
+ }
show={true}
showCallOutUnauthorizedMsg={false}
showExpandedDetails={false}
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx
index c7d27da64c650..ede473acbfb2a 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.test.tsx
@@ -10,11 +10,13 @@ import React from 'react';
import useResizeObserver from 'use-resize-observer/polyfilled';
import { Direction } from '../../../../graphql/types';
+import { DefaultCellRenderer } from '../cell_rendering/default_cell_renderer';
import { defaultHeaders, mockTimelineData } from '../../../../common/mock';
import '../../../../common/mock/match_media';
import { TestProviders } from '../../../../common/mock/test_providers';
import { QueryTabContentComponent, Props as QueryTabContentComponentProps } from './index';
+import { defaultRowRenderers } from '../body/renderers';
import { Sort } from '../body/sort';
import { mockDataProviders } from '../data_providers/mock/mock_data_providers';
import { useMountAppended } from '../../../../common/utils/use_mount_appended';
@@ -106,6 +108,8 @@ describe('Timeline', () => {
kqlMode: 'search' as QueryTabContentComponentProps['kqlMode'],
kqlQueryExpression: '',
onEventClosed: jest.fn(),
+ renderCellValue: DefaultCellRenderer,
+ rowRenderers: defaultRowRenderers,
showCallOutUnauthorizedMsg: false,
showExpandedDetails: false,
sort,
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx
index 28fec7ded9ca2..74a0f02354219 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_tab_content/index.tsx
@@ -22,6 +22,8 @@ import deepEqual from 'fast-deep-equal';
import { InPortal } from 'react-reverse-portal';
import { timelineActions, timelineSelectors } from '../../../store/timeline';
+import { RowRenderer } from '../body/renderers/row_renderer';
+import { CellValueElementProps } from '../cell_rendering';
import { Direction, TimelineItem } from '../../../../../common/search_strategy';
import { useTimelineEvents } from '../../../containers/index';
import { useKibana } from '../../../../common/lib/kibana';
@@ -142,6 +144,8 @@ const compareQueryProps = (prevProps: Props, nextProps: Props) =>
deepEqual(prevProps.filters, nextProps.filters);
interface OwnProps {
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
timelineId: string;
}
@@ -164,6 +168,8 @@ export const QueryTabContentComponent: React.FC = ({
kqlMode,
kqlQueryExpression,
onEventClosed,
+ renderCellValue,
+ rowRenderers,
show,
showCallOutUnauthorizedMsg,
showExpandedDetails,
@@ -330,6 +336,8 @@ export const QueryTabContentComponent: React.FC = ({
data={isBlankTimeline ? EMPTY_EVENTS : events}
id={timelineId}
refetch={refetch}
+ renderCellValue={renderCellValue}
+ rowRenderers={rowRenderers}
sort={sort}
tabType={TimelineTabs.query}
totalPages={calculateTotalPages({
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx
index f29211d519841..76a2ad0960322 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/index.tsx
@@ -20,6 +20,8 @@ import {
TimelineEventsCountBadge,
} from '../../../../common/hooks/use_timeline_events_count';
import { timelineActions } from '../../../store/timeline';
+import { RowRenderer } from '../body/renderers/row_renderer';
+import { CellValueElementProps } from '../cell_rendering';
import {
getActiveTabSelector,
getNoteIdsSelector,
@@ -46,6 +48,8 @@ const NotesTabContent = lazy(() => import('../notes_tab_content'));
const PinnedTabContent = lazy(() => import('../pinned_tab_content'));
interface BasicTimelineTab {
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
setTimelineFullScreen?: (fullScreen: boolean) => void;
timelineFullScreen?: boolean;
timelineId: TimelineId;
@@ -53,16 +57,32 @@ interface BasicTimelineTab {
graphEventId?: string;
}
-const QueryTab: React.FC<{ timelineId: TimelineId }> = memo(({ timelineId }) => (
+const QueryTab: React.FC<{
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
+ timelineId: TimelineId;
+}> = memo(({ renderCellValue, rowRenderers, timelineId }) => (
}>
-
+
));
QueryTab.displayName = 'QueryTab';
-const EqlTab: React.FC<{ timelineId: TimelineId }> = memo(({ timelineId }) => (
+const EqlTab: React.FC<{
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
+ timelineId: TimelineId;
+}> = memo(({ renderCellValue, rowRenderers, timelineId }) => (
}>
-
+
));
EqlTab.displayName = 'EqlTab';
@@ -81,9 +101,17 @@ const NotesTab: React.FC<{ timelineId: TimelineId }> = memo(({ timelineId }) =>
));
NotesTab.displayName = 'NotesTab';
-const PinnedTab: React.FC<{ timelineId: TimelineId }> = memo(({ timelineId }) => (
+const PinnedTab: React.FC<{
+ renderCellValue: (props: CellValueElementProps) => React.ReactNode;
+ rowRenderers: RowRenderer[];
+ timelineId: TimelineId;
+}> = memo(({ renderCellValue, rowRenderers, timelineId }) => (
}>
-
+
));
PinnedTab.displayName = 'PinnedTab';
@@ -91,7 +119,7 @@ PinnedTab.displayName = 'PinnedTab';
type ActiveTimelineTabProps = BasicTimelineTab & { activeTimelineTab: TimelineTabs };
const ActiveTimelineTab = memo(
- ({ activeTimelineTab, timelineId, timelineType }) => {
+ ({ activeTimelineTab, renderCellValue, rowRenderers, timelineId, timelineType }) => {
const getTab = useCallback(
(tab: TimelineTabs) => {
switch (tab) {
@@ -119,14 +147,26 @@ const ActiveTimelineTab = memo(
return (
<>
-
+
-
+
{timelineType === TimelineType.default && (
-
+
)}
@@ -160,6 +200,8 @@ const StyledEuiTab = styled(EuiTab)`
`;
const TabsContentComponent: React.FC = ({
+ renderCellValue,
+ rowRenderers,
timelineId,
timelineFullScreen,
timelineType,
@@ -300,6 +342,8 @@ const TabsContentComponent: React.FC = ({
diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx
index 3d92397f4ab50..0b70ba8991686 100644
--- a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx
@@ -30,11 +30,12 @@ import {
updateItemsPerPage,
updateSort,
} from './actions';
-
+import { DefaultCellRenderer } from '../../components/timeline/cell_rendering/default_cell_renderer';
import {
QueryTabContentComponent,
Props as QueryTabContentComponentProps,
} from '../../components/timeline/query_tab_content';
+import { defaultRowRenderers } from '../../components/timeline/body/renderers';
import { mockDataProviders } from '../../components/timeline/data_providers/mock/mock_data_providers';
import { Sort } from '../../components/timeline/body/sort';
import { Direction } from '../../../graphql/types';
@@ -90,6 +91,8 @@ describe('epicLocalStorage', () => {
kqlMode: 'search' as QueryTabContentComponentProps['kqlMode'],
kqlQueryExpression: '',
onEventClosed: jest.fn(),
+ renderCellValue: DefaultCellRenderer,
+ rowRenderers: defaultRowRenderers,
showCallOutUnauthorizedMsg: false,
showExpandedDetails: false,
start: startDate,
From 1fad3175f9526882f4eab02829d73b75194e6b4e Mon Sep 17 00:00:00 2001
From: Thomas Neirynck
Date: Mon, 5 Apr 2021 13:42:46 -0400
Subject: [PATCH 007/131] [Maps] Safe-erase text-field (#94873)
---
.../properties/dynamic_text_property.test.tsx | 109 ++++++++++++++++++
.../properties/dynamic_text_property.ts | 4 +-
.../properties/static_text_property.test.ts | 70 +++++++++++
.../vector/properties/static_text_property.ts | 4 +-
4 files changed, 185 insertions(+), 2 deletions(-)
create mode 100644 x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.test.tsx
create mode 100644 x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.test.ts
diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.test.tsx b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.test.tsx
new file mode 100644
index 0000000000000..4550a27ac2d9a
--- /dev/null
+++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.test.tsx
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+jest.mock('../components/vector_style_editor', () => ({
+ VectorStyleEditor: () => {
+ return mockVectorStyleEditor
;
+ },
+}));
+
+import React from 'react';
+
+// @ts-ignore
+import { DynamicTextProperty } from './dynamic_text_property';
+import { RawValue, VECTOR_STYLES } from '../../../../../common/constants';
+import { IField } from '../../../fields/field';
+import { Map as MbMap } from 'mapbox-gl';
+import { mockField, MockLayer, MockStyle } from './test_helpers/test_util';
+import { IVectorLayer } from '../../../layers/vector_layer';
+
+export class MockMbMap {
+ _paintPropertyCalls: unknown[];
+ _lastTextFieldValue: unknown | undefined;
+
+ constructor(lastTextFieldValue?: unknown) {
+ this._paintPropertyCalls = [];
+ this._lastTextFieldValue = lastTextFieldValue;
+ }
+ setLayoutProperty(layerId: string, propName: string, value: undefined | 'string') {
+ if (propName !== 'text-field') {
+ throw new Error('should only use to test `text-field`');
+ }
+ this._lastTextFieldValue = value;
+ this._paintPropertyCalls.push([layerId, value]);
+ }
+
+ getLayoutProperty(layername: string, propName: string): unknown | undefined {
+ if (propName !== 'text-field') {
+ throw new Error('should only use to test `text-field`');
+ }
+ return this._lastTextFieldValue;
+ }
+
+ getPaintPropertyCalls(): unknown[] {
+ return this._paintPropertyCalls;
+ }
+}
+
+const makeProperty = (mockStyle: MockStyle, field: IField | null) => {
+ return new DynamicTextProperty(
+ {},
+ VECTOR_STYLES.LABEL_TEXT,
+ field,
+ (new MockLayer(mockStyle) as unknown) as IVectorLayer,
+ () => {
+ return (value: RawValue) => value + '_format';
+ }
+ );
+};
+
+describe('syncTextFieldWithMb', () => {
+ describe('with field', () => {
+ test('Should set', async () => {
+ const dynamicTextProperty = makeProperty(new MockStyle({ min: 0, max: 100 }), mockField);
+ const mockMbMap = (new MockMbMap() as unknown) as MbMap;
+
+ dynamicTextProperty.syncTextFieldWithMb('foobar', mockMbMap);
+
+ // @ts-expect-error
+ expect(mockMbMap.getPaintPropertyCalls()).toEqual([
+ ['foobar', ['coalesce', ['get', '__kbn__dynamic__foobar__labelText'], '']],
+ ]);
+ });
+ });
+
+ describe('without field', () => {
+ test('Should clear', async () => {
+ const dynamicTextProperty = makeProperty(new MockStyle({ min: 0, max: 100 }), null);
+ const mockMbMap = (new MockMbMap([
+ 'foobar',
+ ['coalesce', ['get', '__kbn__dynamic__foobar__labelText'], ''],
+ ]) as unknown) as MbMap;
+
+ dynamicTextProperty.syncTextFieldWithMb('foobar', mockMbMap);
+
+ // @ts-expect-error
+ expect(mockMbMap.getPaintPropertyCalls()).toEqual([['foobar', undefined]]);
+ });
+
+ test('Should not clear when already cleared', async () => {
+ // This verifies a weird edge-case in mapbox-gl, where setting the `text-field` layout-property to null causes tiles to be invalidated.
+ // This triggers a refetch of the tile during panning and zooming
+ // This affects vector-tile rendering in tiled_vector_layers with custom vector_styles
+ // It does _not_ affect EMS, since that does not have a code-path where a `text-field` need to be resynced.
+ // Do not remove this logic without verifying that mapbox-gl does not re-issue tile-requests for previously requested tiles
+
+ const dynamicTextProperty = makeProperty(new MockStyle({ min: 0, max: 100 }), null);
+ const mockMbMap = (new MockMbMap(undefined) as unknown) as MbMap;
+
+ dynamicTextProperty.syncTextFieldWithMb('foobar', mockMbMap);
+
+ // @ts-expect-error
+ expect(mockMbMap.getPaintPropertyCalls()).toEqual([]);
+ });
+ });
+});
diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.ts b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.ts
index 22ea3067b1748..e8612388a5ae1 100644
--- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.ts
+++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_text_property.ts
@@ -20,7 +20,9 @@ export class DynamicTextProperty extends DynamicStyleProperty {
+ return new StaticTextProperty({ value }, VECTOR_STYLES.LABEL_TEXT);
+};
+
+describe('syncTextFieldWithMb', () => {
+ test('Should set with value', async () => {
+ const dynamicTextProperty = makeProperty('foo');
+ const mockMbMap = (new MockMbMap() as unknown) as MbMap;
+
+ dynamicTextProperty.syncTextFieldWithMb('foobar', mockMbMap);
+
+ // @ts-expect-error
+ expect(mockMbMap.getPaintPropertyCalls()).toEqual([['foobar', 'foo']]);
+ });
+
+ test('Should not clear when already cleared', async () => {
+ // This verifies a weird edge-case in mapbox-gl, where setting the `text-field` layout-property to null causes tiles to be invalidated.
+ // This triggers a refetch of the tile during panning and zooming
+ // This affects vector-tile rendering in tiled_vector_layers with custom vector_styles
+ // It does _not_ affect EMS, since that does not have a code-path where a `text-field` need to be resynced.
+ // Do not remove this logic without verifying that mapbox-gl does not re-issue tile-requests for previously requested tiles
+
+ const dynamicTextProperty = makeProperty('');
+ const mockMbMap = (new MockMbMap(undefined) as unknown) as MbMap;
+
+ dynamicTextProperty.syncTextFieldWithMb('foobar', mockMbMap);
+
+ // @ts-expect-error
+ expect(mockMbMap.getPaintPropertyCalls()).toEqual([]);
+ });
+});
diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.ts b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.ts
index b0016106b8c31..fb05fa052db21 100644
--- a/x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.ts
+++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/static_text_property.ts
@@ -18,7 +18,9 @@ export class StaticTextProperty extends StaticStyleProperty
if (this.getOptions().value.length) {
mbMap.setLayoutProperty(mbLayerId, 'text-field', this.getOptions().value);
} else {
- mbMap.setLayoutProperty(mbLayerId, 'text-field', null);
+ if (typeof mbMap.getLayoutProperty(mbLayerId, 'text-field') !== 'undefined') {
+ mbMap.setLayoutProperty(mbLayerId, 'text-field', undefined);
+ }
}
}
}
From ad5f83a36230abeff79d01bfff0a104f5fd615d2 Mon Sep 17 00:00:00 2001
From: Jason Stoltzfus
Date: Mon, 5 Apr 2021 13:49:54 -0400
Subject: [PATCH 008/131] [App Search] Added Sample Response section to Result
Settings (#95971)
---
.../result_settings/result_settings.tsx | 4 +-
.../non_text_fields_body.tsx | 5 +
.../text_fields_body.tsx | 13 ++
.../result_settings/sample_response/index.ts | 8 +
.../sample_response/sample_response.test.tsx | 75 ++++++
.../sample_response/sample_response.tsx | 72 ++++++
.../sample_response_logic.test.ts | 214 ++++++++++++++++++
.../sample_response/sample_response_logic.ts | 100 ++++++++
.../components/result_settings/types.ts | 4 +
.../routes/app_search/result_settings.test.ts | 44 ++++
.../routes/app_search/result_settings.ts | 18 ++
11 files changed, 556 insertions(+), 1 deletion(-)
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/index.ts
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response.test.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.ts
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.tsx
index 38db5c60e98a9..7f4373835f8d5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.tsx
@@ -17,6 +17,8 @@ import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chro
import { RESULT_SETTINGS_TITLE } from './constants';
import { ResultSettingsTable } from './result_settings_table';
+import { SampleResponse } from './sample_response';
+
import { ResultSettingsLogic } from '.';
interface Props {
@@ -40,7 +42,7 @@ export const ResultSettings: React.FC = ({ engineBreadcrumb }) => {
- TODO
+
>
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/non_text_fields_body.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/non_text_fields_body.tsx
index 145654be20461..dc91b5039a3c9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/non_text_fields_body.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings_table/non_text_fields_body.tsx
@@ -10,6 +10,7 @@ import React, { useMemo } from 'react';
import { useValues, useActions } from 'kea';
import { EuiTableRow, EuiTableRowCell, EuiCheckbox, EuiTableRowCellCheckbox } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { ResultSettingsLogic } from '..';
import { FieldResultSetting } from '../types';
@@ -33,6 +34,10 @@ export const NonTextFieldsBody: React.FC = () => {
{
{
{
{
+ const actions = {
+ queryChanged: jest.fn(),
+ getSearchResults: jest.fn(),
+ };
+
+ const values = {
+ reducedServerResultFields: {},
+ query: 'foo',
+ response: {
+ bar: 'baz',
+ },
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ setMockActions(actions);
+ setMockValues(values);
+ });
+
+ it('renders a text box with the current user "query" value from state', () => {
+ const wrapper = shallow();
+ expect(wrapper.find(EuiFieldSearch).prop('value')).toEqual('foo');
+ });
+
+ it('updates the "query" value in state when a user updates the text in the text box', () => {
+ const wrapper = shallow();
+ wrapper.find(EuiFieldSearch).simulate('change', { target: { value: 'bar' } });
+ expect(actions.queryChanged).toHaveBeenCalledWith('bar');
+ });
+
+ it('will call getSearchResults with the current value of query and reducedServerResultFields in a useEffect, which updates the displayed response', () => {
+ const wrapper = shallow();
+ expect(wrapper.find(EuiFieldSearch).prop('value')).toEqual('foo');
+ });
+
+ it('renders the response from the given user "query" in a code block', () => {
+ const wrapper = shallow();
+ expect(wrapper.find(EuiCodeBlock).prop('children')).toEqual('{\n "bar": "baz"\n}');
+ });
+
+ it('renders a plain old string in the code block if the response is a string', () => {
+ setMockValues({
+ response: 'No results.',
+ });
+ const wrapper = shallow();
+ expect(wrapper.find(EuiCodeBlock).prop('children')).toEqual('No results.');
+ });
+
+ it('will not render a code block at all if there is no response yet', () => {
+ setMockValues({
+ response: null,
+ });
+ const wrapper = shallow();
+ expect(wrapper.find(EuiCodeBlock).exists()).toEqual(false);
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response.tsx
new file mode 100644
index 0000000000000..ae91b9648356c
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response.tsx
@@ -0,0 +1,72 @@
+/*
+ * 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, { useEffect } from 'react';
+
+import { useActions, useValues } from 'kea';
+
+import {
+ EuiCodeBlock,
+ EuiFieldSearch,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiPanel,
+ EuiSpacer,
+ EuiTitle,
+} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+
+import { ResultSettingsLogic } from '../result_settings_logic';
+
+import { SampleResponseLogic } from './sample_response_logic';
+
+export const SampleResponse: React.FC = () => {
+ const { reducedServerResultFields } = useValues(ResultSettingsLogic);
+
+ const { query, response } = useValues(SampleResponseLogic);
+ const { queryChanged, getSearchResults } = useActions(SampleResponseLogic);
+
+ useEffect(() => {
+ getSearchResults(query, reducedServerResultFields);
+ }, [query, reducedServerResultFields]);
+
+ return (
+
+
+
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.resultSettings.sampleResponseTitle',
+ { defaultMessage: 'Sample response' }
+ )}
+
+
+
+
+ {/* TODO */}
+
+
+
+ queryChanged(e.target.value)}
+ placeholder={i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.resultSettings.sampleResponse.inputPlaceholder',
+ { defaultMessage: 'Type a search query to test a response...' }
+ )}
+ data-test-subj="ResultSettingsQuerySampleResponse"
+ />
+
+ {!!response && (
+
+ {typeof response === 'string' ? response : JSON.stringify(response, null, 2)}
+
+ )}
+
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts
new file mode 100644
index 0000000000000..79379306c1618
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.test.ts
@@ -0,0 +1,214 @@
+/*
+ * 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 { LogicMounter, mockHttpValues } from '../../../../__mocks__';
+import '../../../__mocks__/engine_logic.mock';
+
+import { nextTick } from '@kbn/test/jest';
+
+import { flashAPIErrors } from '../../../../shared/flash_messages';
+
+import { SampleResponseLogic } from './sample_response_logic';
+
+describe('SampleResponseLogic', () => {
+ const { mount } = new LogicMounter(SampleResponseLogic);
+ const { http } = mockHttpValues;
+
+ const DEFAULT_VALUES = {
+ query: '',
+ response: null,
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('has expected default values', () => {
+ mount();
+ expect(SampleResponseLogic.values).toEqual({
+ ...DEFAULT_VALUES,
+ });
+ });
+
+ describe('actions', () => {
+ describe('queryChanged', () => {
+ it('updates the query', () => {
+ mount({
+ query: '',
+ });
+
+ SampleResponseLogic.actions.queryChanged('foo');
+
+ expect(SampleResponseLogic.values).toEqual({
+ ...DEFAULT_VALUES,
+ query: 'foo',
+ });
+ });
+ });
+
+ describe('getSearchResultsSuccess', () => {
+ it('sets the response from a search API request', () => {
+ mount({
+ response: null,
+ });
+
+ SampleResponseLogic.actions.getSearchResultsSuccess({});
+
+ expect(SampleResponseLogic.values).toEqual({
+ ...DEFAULT_VALUES,
+ response: {},
+ });
+ });
+ });
+
+ describe('getSearchResultsFailure', () => {
+ it('sets a string response from a search API request', () => {
+ mount({
+ response: null,
+ });
+
+ SampleResponseLogic.actions.getSearchResultsFailure('An error occured.');
+
+ expect(SampleResponseLogic.values).toEqual({
+ ...DEFAULT_VALUES,
+ response: 'An error occured.',
+ });
+ });
+ });
+ });
+
+ describe('listeners', () => {
+ describe('getSearchResults', () => {
+ beforeAll(() => jest.useFakeTimers());
+ afterAll(() => jest.useRealTimers());
+
+ it('makes a search API request and calls getSearchResultsSuccess with the first result of the response', async () => {
+ mount();
+ jest.spyOn(SampleResponseLogic.actions, 'getSearchResultsSuccess');
+
+ http.post.mockReturnValue(
+ Promise.resolve({
+ results: [
+ { id: { raw: 'foo' }, _meta: {} },
+ { id: { raw: 'bar' }, _meta: {} },
+ { id: { raw: 'baz' }, _meta: {} },
+ ],
+ })
+ );
+
+ SampleResponseLogic.actions.getSearchResults('foo', { foo: { raw: true } });
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(SampleResponseLogic.actions.getSearchResultsSuccess).toHaveBeenCalledWith({
+ // Note that the _meta field was stripped from the result
+ id: { raw: 'foo' },
+ });
+ });
+
+ it('calls getSearchResultsSuccess with a "No Results." message if there are no results', async () => {
+ mount();
+ jest.spyOn(SampleResponseLogic.actions, 'getSearchResultsSuccess');
+
+ http.post.mockReturnValue(
+ Promise.resolve({
+ results: [],
+ })
+ );
+
+ SampleResponseLogic.actions.getSearchResults('foo', { foo: { raw: true } });
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(SampleResponseLogic.actions.getSearchResultsSuccess).toHaveBeenCalledWith(
+ 'No results.'
+ );
+ });
+
+ it('handles 500 errors by setting a generic error response and showing a flash message error', async () => {
+ mount();
+ jest.spyOn(SampleResponseLogic.actions, 'getSearchResultsFailure');
+
+ const error = {
+ response: {
+ status: 500,
+ },
+ };
+
+ http.post.mockReturnValueOnce(Promise.reject(error));
+
+ SampleResponseLogic.actions.getSearchResults('foo', { foo: { raw: true } });
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(flashAPIErrors).toHaveBeenCalledWith(error);
+ expect(SampleResponseLogic.actions.getSearchResultsFailure).toHaveBeenCalledWith(
+ 'An error occured.'
+ );
+ });
+
+ it('handles 400 errors by setting the response, but does not show a flash error message', async () => {
+ mount();
+ jest.spyOn(SampleResponseLogic.actions, 'getSearchResultsFailure');
+
+ http.post.mockReturnValueOnce(
+ Promise.reject({
+ response: {
+ status: 400,
+ },
+ body: {
+ attributes: {
+ errors: ['A validation error occurred.'],
+ },
+ },
+ })
+ );
+
+ SampleResponseLogic.actions.getSearchResults('foo', { foo: { raw: true } });
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(SampleResponseLogic.actions.getSearchResultsFailure).toHaveBeenCalledWith({
+ errors: ['A validation error occurred.'],
+ });
+ });
+
+ it('sets a generic message on a 400 error if no custom message is provided in the response', async () => {
+ mount();
+ jest.spyOn(SampleResponseLogic.actions, 'getSearchResultsFailure');
+
+ http.post.mockReturnValueOnce(
+ Promise.reject({
+ response: {
+ status: 400,
+ },
+ })
+ );
+
+ SampleResponseLogic.actions.getSearchResults('foo', { foo: { raw: true } });
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(SampleResponseLogic.actions.getSearchResultsFailure).toHaveBeenCalledWith(
+ 'An error occured.'
+ );
+ });
+
+ it('does nothing if an empty object is passed for the resultFields parameter', async () => {
+ mount();
+ jest.spyOn(SampleResponseLogic.actions, 'getSearchResultsSuccess');
+
+ SampleResponseLogic.actions.getSearchResults('foo', {});
+
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(SampleResponseLogic.actions.getSearchResultsSuccess).not.toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.ts
new file mode 100644
index 0000000000000..808a7ec9c65dc
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/sample_response/sample_response_logic.ts
@@ -0,0 +1,100 @@
+/*
+ * 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 { kea, MakeLogicType } from 'kea';
+
+import { i18n } from '@kbn/i18n';
+
+import { flashAPIErrors } from '../../../../shared/flash_messages';
+
+import { HttpLogic } from '../../../../shared/http';
+import { EngineLogic } from '../../engine';
+
+import { SampleSearchResponse, ServerFieldResultSettingObject } from '../types';
+
+const NO_RESULTS_MESSAGE = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.resultSettings.sampleResponse.noResultsMessage',
+ { defaultMessage: 'No results.' }
+);
+
+const ERROR_MESSAGE = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.resultSettings.sampleResponse.errorMessage',
+ { defaultMessage: 'An error occured.' }
+);
+
+interface SampleResponseValues {
+ query: string;
+ response: SampleSearchResponse | string | null;
+}
+
+interface SampleResponseActions {
+ queryChanged: (query: string) => { query: string };
+ getSearchResultsSuccess: (
+ response: SampleSearchResponse | string
+ ) => { response: SampleSearchResponse | string };
+ getSearchResultsFailure: (response: string) => { response: string };
+ getSearchResults: (
+ query: string,
+ resultFields: ServerFieldResultSettingObject
+ ) => { query: string; resultFields: ServerFieldResultSettingObject };
+}
+
+export const SampleResponseLogic = kea>({
+ path: ['enterprise_search', 'app_search', 'sample_response_logic'],
+ actions: {
+ queryChanged: (query) => ({ query }),
+ getSearchResultsSuccess: (response) => ({ response }),
+ getSearchResultsFailure: (response) => ({ response }),
+ getSearchResults: (query, resultFields) => ({ query, resultFields }),
+ },
+ reducers: {
+ query: ['', { queryChanged: (_, { query }) => query }],
+ response: [
+ null,
+ {
+ getSearchResultsSuccess: (_, { response }) => response,
+ getSearchResultsFailure: (_, { response }) => response,
+ },
+ ],
+ },
+ listeners: ({ actions }) => ({
+ getSearchResults: async ({ query, resultFields }, breakpoint) => {
+ if (Object.keys(resultFields).length < 1) return;
+ await breakpoint(250);
+
+ const { http } = HttpLogic.values;
+ const { engineName } = EngineLogic.values;
+
+ const url = `/api/app_search/engines/${engineName}/sample_response_search`;
+
+ try {
+ const response = await http.post(url, {
+ body: JSON.stringify({
+ query,
+ result_fields: resultFields,
+ }),
+ });
+
+ const result = response.results?.[0];
+ actions.getSearchResultsSuccess(
+ result ? { ...result, _meta: undefined } : NO_RESULTS_MESSAGE
+ );
+ } catch (e) {
+ if (e.response.status >= 500) {
+ // 4XX Validation errors are expected, as a user could enter something like 2 as a size, which is out of valid range.
+ // In this case, we simply render the message from the server as the response.
+ //
+ // 5xx Server errors are unexpected, and need to be reported in a flash message.
+ flashAPIErrors(e);
+ actions.getSearchResultsFailure(ERROR_MESSAGE);
+ } else {
+ actions.getSearchResultsFailure(e.body?.attributes || ERROR_MESSAGE);
+ }
+ }
+ },
+ }),
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/types.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/types.ts
index 96bf277314a7b..18843112f46bf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/types.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/types.ts
@@ -5,6 +5,8 @@
* 2.0.
*/
+import { FieldValue } from '../result/types';
+
export enum OpenModal {
None,
ConfirmResetModal,
@@ -35,3 +37,5 @@ export interface FieldResultSetting {
}
export type FieldResultSettingObject = Record;
+
+export type SampleSearchResponse = Record;
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.test.ts
index 8d1a7e3ead37b..e38380d60c6e9 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.test.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.test.ts
@@ -88,4 +88,48 @@ describe('result settings routes', () => {
});
});
});
+
+ describe('POST /api/app_search/engines/{name}/sample_response_search', () => {
+ const mockRouter = new MockRouter({
+ method: 'post',
+ path: '/api/app_search/engines/{engineName}/sample_response_search',
+ });
+
+ beforeEach(() => {
+ registerResultSettingsRoutes({
+ ...mockDependencies,
+ router: mockRouter.router,
+ });
+ });
+
+ it('creates a request to enterprise search', () => {
+ mockRouter.callRoute({
+ params: { engineName: 'some-engine' },
+ body: {
+ query: 'test',
+ result_fields: resultFields,
+ },
+ });
+
+ expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
+ path: '/as/engines/:engineName/sample_response_search',
+ });
+ });
+
+ describe('validates', () => {
+ it('correctly', () => {
+ const request = {
+ body: {
+ query: 'test',
+ result_fields: resultFields,
+ },
+ };
+ mockRouter.shouldValidate(request);
+ });
+ it('missing required fields', () => {
+ const request = { body: {} };
+ mockRouter.shouldThrow(request);
+ });
+ });
+ });
});
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.ts
index 38cb4aa922738..b091ae7a539c2 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/result_settings.ts
@@ -45,4 +45,22 @@ export function registerResultSettingsRoutes({
path: '/as/engines/:engineName/result_settings',
})
);
+
+ router.post(
+ {
+ path: '/api/app_search/engines/{engineName}/sample_response_search',
+ validate: {
+ params: schema.object({
+ engineName: schema.string(),
+ }),
+ body: schema.object({
+ query: schema.string(),
+ result_fields: schema.recordOf(schema.string(), schema.object({}, { unknowns: 'allow' })),
+ }),
+ },
+ },
+ enterpriseSearchRequestHandler.createRequest({
+ path: '/as/engines/:engineName/sample_response_search',
+ })
+ );
}
From e457f212c4e513b467fc9fd540b76d4a6949111f Mon Sep 17 00:00:00 2001
From: Mikhail Shustov
Date: Mon, 5 Apr 2021 20:59:26 +0200
Subject: [PATCH 009/131] Revert "TS Incremental build exclude test files
(#95610)" (#96223)
This reverts commit b6e582c53ebb9c496c232408066b128d2ca2f92c.
---
packages/kbn-storybook/tsconfig.json | 2 +-
src/core/tsconfig.json | 2 +-
src/dev/typescript/project.ts | 37 ++------
src/plugins/advanced_settings/tsconfig.json | 2 +-
src/plugins/apm_oss/tsconfig.json | 2 +-
src/plugins/bfetch/tsconfig.json | 2 +-
src/plugins/charts/tsconfig.json | 2 +-
src/plugins/console/tsconfig.json | 2 +-
src/plugins/dashboard/tsconfig.json | 2 +-
.../search/expressions/exists_filter.test.ts | 2 +-
.../search/expressions/kibana_filter.test.ts | 2 +-
.../search/expressions/phrase_filter.test.ts | 2 +-
.../search/expressions/range_filter.test.ts | 2 +-
src/plugins/data/tsconfig.json | 2 +-
src/plugins/dev_tools/tsconfig.json | 2 +-
src/plugins/discover/tsconfig.json | 2 +-
src/plugins/embeddable/tsconfig.json | 2 +-
src/plugins/es_ui_shared/tsconfig.json | 2 +-
src/plugins/expressions/common/mocks.ts | 2 -
src/plugins/expressions/common/util/index.ts | 1 +
src/plugins/expressions/tsconfig.json | 2 +-
src/plugins/home/tsconfig.json | 2 +-
.../index_pattern_field_editor/tsconfig.json | 2 +-
.../index_pattern_management/tsconfig.json | 2 +-
src/plugins/input_control_vis/tsconfig.json | 2 +-
src/plugins/inspector/tsconfig.json | 2 +-
src/plugins/kibana_legacy/tsconfig.json | 2 +-
src/plugins/kibana_overview/tsconfig.json | 2 +-
src/plugins/kibana_react/tsconfig.json | 2 +-
.../kibana_usage_collection/tsconfig.json | 2 +-
src/plugins/kibana_utils/tsconfig.json | 2 +-
src/plugins/legacy_export/tsconfig.json | 2 +-
src/plugins/management/tsconfig.json | 2 +-
src/plugins/maps_ems/tsconfig.json | 2 +-
src/plugins/maps_legacy/tsconfig.json | 2 +-
src/plugins/navigation/tsconfig.json | 2 +-
src/plugins/newsfeed/tsconfig.json | 2 +-
src/plugins/presentation_util/tsconfig.json | 2 +-
src/plugins/region_map/tsconfig.json | 2 +-
src/plugins/saved_objects/tsconfig.json | 2 +-
.../saved_objects_management/tsconfig.json | 2 +-
.../saved_objects_tagging_oss/tsconfig.json | 2 +-
src/plugins/security_oss/tsconfig.json | 2 +-
src/plugins/share/tsconfig.json | 2 +-
src/plugins/spaces_oss/tsconfig.json | 2 +-
src/plugins/telemetry/tsconfig.json | 2 +-
.../tsconfig.json | 2 +-
.../tsconfig.json | 2 +-
src/plugins/tile_map/tsconfig.json | 2 +-
src/plugins/timelion/tsconfig.json | 2 +-
src/plugins/ui_actions/tsconfig.json | 2 +-
src/plugins/url_forwarding/tsconfig.json | 2 +-
src/plugins/usage_collection/tsconfig.json | 2 +-
src/plugins/vis_default_editor/tsconfig.json | 2 +-
src/plugins/vis_type_markdown/tsconfig.json | 2 +-
src/plugins/vis_type_metric/tsconfig.json | 2 +-
src/plugins/vis_type_table/tsconfig.json | 2 +-
src/plugins/vis_type_tagcloud/tsconfig.json | 2 +-
src/plugins/vis_type_timelion/tsconfig.json | 2 +-
src/plugins/vis_type_timeseries/tsconfig.json | 2 +-
src/plugins/vis_type_vega/tsconfig.json | 2 +-
src/plugins/vis_type_vislib/tsconfig.json | 2 +-
src/plugins/vis_type_xy/tsconfig.json | 2 +-
src/plugins/visualizations/tsconfig.json | 2 +-
src/plugins/visualize/tsconfig.json | 2 +-
tsconfig.base.json | 3 +-
tsconfig.json | 73 ----------------
tsconfig.project.json | 65 --------------
x-pack/plugins/actions/tsconfig.json | 2 +-
x-pack/plugins/alerting/tsconfig.json | 2 +-
x-pack/plugins/apm/e2e/tsconfig.json | 2 +-
x-pack/plugins/apm/ftr_e2e/tsconfig.json | 4 +-
.../apm/scripts/optimize-tsconfig/optimize.js | 2 +-
.../apm/scripts/optimize-tsconfig/paths.js | 2 +-
x-pack/plugins/apm/tsconfig.json | 2 +-
x-pack/plugins/banners/tsconfig.json | 2 +-
x-pack/plugins/beats_management/tsconfig.json | 2 +-
.../canvas/storybook/addon/tsconfig.json | 2 +-
x-pack/plugins/canvas/tsconfig.json | 2 +-
x-pack/plugins/cloud/tsconfig.json | 2 +-
.../plugins/console_extensions/tsconfig.json | 2 +-
.../cross_cluster_replication/tsconfig.json | 2 +-
.../plugins/dashboard_enhanced/tsconfig.json | 2 +-
x-pack/plugins/dashboard_mode/tsconfig.json | 2 +-
x-pack/plugins/data_enhanced/tsconfig.json | 2 +-
.../plugins/discover_enhanced/tsconfig.json | 2 +-
.../drilldowns/url_drilldown/tsconfig.json | 2 +-
.../plugins/embeddable_enhanced/tsconfig.json | 2 +-
.../encrypted_saved_objects/tsconfig.json | 2 +-
.../plugins/enterprise_search/tsconfig.json | 2 +-
x-pack/plugins/event_log/tsconfig.json | 2 +-
x-pack/plugins/features/tsconfig.json | 2 +-
x-pack/plugins/file_upload/tsconfig.json | 2 +-
x-pack/plugins/fleet/tsconfig.json | 2 +-
x-pack/plugins/global_search/tsconfig.json | 2 +-
.../plugins/global_search_bar/tsconfig.json | 2 +-
.../global_search_providers/tsconfig.json | 2 +-
x-pack/plugins/graph/tsconfig.json | 4 +-
x-pack/plugins/grokdebugger/tsconfig.json | 2 +-
.../index_lifecycle_management/tsconfig.json | 3 +-
x-pack/plugins/index_management/tsconfig.json | 4 +-
.../infra/public/utils/enzyme_helpers.tsx | 87 +++++++++++++++++++
.../queries/metrics_hosts_anomalies.ts | 2 +-
.../infra_ml/queries/metrics_k8s_anomalies.ts | 2 +-
x-pack/plugins/infra/tsconfig.json | 2 +-
x-pack/plugins/ingest_pipelines/tsconfig.json | 3 +-
x-pack/plugins/lens/tsconfig.json | 4 +-
.../plugins/license_management/tsconfig.json | 2 +-
x-pack/plugins/licensing/tsconfig.json | 2 +-
x-pack/plugins/logstash/tsconfig.json | 2 +-
.../components/validated_number_input.tsx | 4 +-
x-pack/plugins/maps/tsconfig.json | 2 +-
.../routes/apidoc_scripts/tsconfig.json | 2 +-
x-pack/plugins/ml/tsconfig.json | 2 +-
x-pack/plugins/monitoring/tsconfig.json | 2 +-
x-pack/plugins/observability/tsconfig.json | 2 +-
x-pack/plugins/osquery/tsconfig.json | 2 +-
x-pack/plugins/painless_lab/tsconfig.json | 2 +-
x-pack/plugins/remote_clusters/tsconfig.json | 2 +-
x-pack/plugins/reporting/tsconfig.json | 2 +-
x-pack/plugins/rollup/tsconfig.json | 2 +-
x-pack/plugins/runtime_fields/tsconfig.json | 2 +-
.../saved_objects_tagging/tsconfig.json | 2 +-
x-pack/plugins/searchprofiler/tsconfig.json | 2 +-
x-pack/plugins/security/tsconfig.json | 2 +-
.../security_solution/cypress/tsconfig.json | 2 +-
x-pack/plugins/snapshot_restore/tsconfig.json | 4 +-
x-pack/plugins/spaces/tsconfig.json | 2 +-
x-pack/plugins/stack_alerts/tsconfig.json | 2 +-
.../server/monitoring/workload_statistics.ts | 3 +-
x-pack/plugins/task_manager/tsconfig.json | 2 +-
.../telemetry_collection_xpack/tsconfig.json | 2 +-
x-pack/plugins/transform/tsconfig.json | 2 +-
.../plugins/triggers_actions_ui/tsconfig.json | 2 +-
.../plugins/ui_actions_enhanced/tsconfig.json | 2 +-
.../plugins/upgrade_assistant/tsconfig.json | 2 +-
.../certificates/cert_monitors.test.tsx | 2 +-
.../certificates/cert_search.test.tsx | 2 +-
.../certificates/cert_status.test.tsx | 2 +-
.../certificates/certificates_list.test.tsx | 2 +-
.../certificates/fingerprint_col.test.tsx | 2 +-
.../common/charts/duration_charts.test.tsx | 2 +-
.../common/charts/monitor_bar_series.test.tsx | 3 +-
.../common/header/page_header.test.tsx | 2 +-
.../components/common/monitor_tags.test.tsx | 2 +-
.../common/uptime_date_picker.test.tsx | 4 +-
.../monitor/ml/ml_integerations.test.tsx | 2 +-
.../monitor/ml/ml_manage_job.test.tsx | 2 +-
.../monitor/monitor_charts.test.tsx | 2 +-
.../components/monitor/monitor_title.test.tsx | 2 +-
.../monitor_status.bar.test.tsx | 2 +-
.../status_details/ssl_certificate.test.tsx | 6 +-
.../overview/empty_state/empty_state.test.tsx | 2 +-
.../columns/enable_alert.test.tsx | 2 +-
.../filter_status_button.test.tsx | 3 +-
.../monitor_list/monitor_list.test.tsx | 2 +-
.../monitor_list_drawer.test.tsx | 2 +-
.../monitor_list/status_filter.test.tsx | 4 +-
.../settings/certificate_form.test.tsx | 2 +-
.../components/settings/indices_form.test.tsx | 2 +-
.../public/hooks/use_breadcrumbs.test.tsx | 5 +-
.../public/hooks/use_url_params.test.tsx | 3 +-
.../plugins/uptime/public/lib/helper/index.ts | 1 +
x-pack/plugins/uptime/public/lib/index.ts | 9 ++
.../uptime/public/pages/certificates.test.tsx | 2 +-
.../uptime/public/pages/monitor.test.tsx | 2 +-
.../uptime/public/pages/not_found.test.tsx | 2 +-
.../uptime/public/pages/overview.test.tsx | 2 +-
x-pack/plugins/uptime/tsconfig.json | 3 +-
x-pack/plugins/watcher/tsconfig.json | 2 +-
x-pack/plugins/xpack_legacy/tsconfig.json | 2 +-
171 files changed, 281 insertions(+), 351 deletions(-)
delete mode 100644 tsconfig.project.json
create mode 100644 x-pack/plugins/infra/public/utils/enzyme_helpers.tsx
create mode 100644 x-pack/plugins/uptime/public/lib/index.ts
diff --git a/packages/kbn-storybook/tsconfig.json b/packages/kbn-storybook/tsconfig.json
index 5c81c9100e601..db10d4630ff9c 100644
--- a/packages/kbn-storybook/tsconfig.json
+++ b/packages/kbn-storybook/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../tsconfig.base.json",
+ "extends": "../../tsconfig.json",
"compilerOptions": {
"incremental": false,
"outDir": "target",
diff --git a/src/core/tsconfig.json b/src/core/tsconfig.json
index f19e379482d3c..855962070457e 100644
--- a/src/core/tsconfig.json
+++ b/src/core/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../tsconfig.project.json",
+ "extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/dev/typescript/project.ts b/src/dev/typescript/project.ts
index 04a5de945619b..8d92284e49637 100644
--- a/src/dev/typescript/project.ts
+++ b/src/dev/typescript/project.ts
@@ -7,7 +7,7 @@
*/
import { basename, dirname, relative, resolve } from 'path';
-import { memoize } from 'lodash';
+
import { IMinimatch, Minimatch } from 'minimatch';
import { REPO_ROOT } from '@kbn/utils';
@@ -26,10 +26,6 @@ function testMatchers(matchers: IMinimatch[], path: string) {
return matchers.some((matcher) => matcher.match(path));
}
-const parentProjectFactory = memoize(function (parentConfigPath: string) {
- return new Project(parentConfigPath);
-});
-
export class Project {
public directory: string;
public name: string;
@@ -38,7 +34,6 @@ export class Project {
private readonly include: IMinimatch[];
private readonly exclude: IMinimatch[];
- private readonly parent?: Project;
constructor(
public tsConfigPath: string,
@@ -46,16 +41,15 @@ export class Project {
) {
this.config = parseTsConfig(tsConfigPath);
- const { files, include, exclude = [], extends: extendsPath } = this.config as {
+ const { files, include, exclude = [] } = this.config as {
files?: string[];
include?: string[];
exclude?: string[];
- extends?: string;
};
if (files || !include) {
throw new Error(
- `[${tsConfigPath}]: tsconfig.json files in the Kibana repo must use "include" keys and not "files"`
+ 'tsconfig.json files in the Kibana repo must use "include" keys and not "files"'
);
}
@@ -64,30 +58,9 @@ export class Project {
this.name = options.name || relative(REPO_ROOT, this.directory) || basename(this.directory);
this.include = makeMatchers(this.directory, include);
this.exclude = makeMatchers(this.directory, exclude);
-
- if (extendsPath !== undefined) {
- const parentConfigPath = resolve(this.directory, extendsPath);
- this.parent = parentProjectFactory(parentConfigPath);
- }
- }
-
- public isAbsolutePathSelected(path: string): boolean {
- return this.isExcluded(path) ? false : this.isIncluded(path);
}
- public isExcluded(path: string): boolean {
- if (testMatchers(this.exclude, path)) return true;
- if (this.parent) {
- return this.parent.isExcluded(path);
- }
- return false;
- }
-
- public isIncluded(path: string): boolean {
- if (testMatchers(this.include, path)) return true;
- if (this.parent) {
- return this.parent.isIncluded(path);
- }
- return false;
+ public isAbsolutePathSelected(path: string) {
+ return testMatchers(this.exclude, path) ? false : testMatchers(this.include, path);
}
}
diff --git a/src/plugins/advanced_settings/tsconfig.json b/src/plugins/advanced_settings/tsconfig.json
index 97a855959903d..4d62e410326b6 100644
--- a/src/plugins/advanced_settings/tsconfig.json
+++ b/src/plugins/advanced_settings/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/apm_oss/tsconfig.json b/src/plugins/apm_oss/tsconfig.json
index ccb123aaec83b..aeb6837c69a99 100644
--- a/src/plugins/apm_oss/tsconfig.json
+++ b/src/plugins/apm_oss/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/bfetch/tsconfig.json b/src/plugins/bfetch/tsconfig.json
index 6c01479f1929e..173ff725d07d0 100644
--- a/src/plugins/bfetch/tsconfig.json
+++ b/src/plugins/bfetch/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/charts/tsconfig.json b/src/plugins/charts/tsconfig.json
index 99edb2ffe3c16..a4f65d5937204 100644
--- a/src/plugins/charts/tsconfig.json
+++ b/src/plugins/charts/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/console/tsconfig.json b/src/plugins/console/tsconfig.json
index d9f49036be8f8..34aca5021bac4 100644
--- a/src/plugins/console/tsconfig.json
+++ b/src/plugins/console/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/dashboard/tsconfig.json b/src/plugins/dashboard/tsconfig.json
index 452208b39af60..dd99119cfb457 100644
--- a/src/plugins/dashboard/tsconfig.json
+++ b/src/plugins/dashboard/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/data/common/search/expressions/exists_filter.test.ts b/src/plugins/data/common/search/expressions/exists_filter.test.ts
index 60e8a9c7a09ce..e3b53b2281398 100644
--- a/src/plugins/data/common/search/expressions/exists_filter.test.ts
+++ b/src/plugins/data/common/search/expressions/exists_filter.test.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { createMockContext } from '../../../../expressions/common/mocks';
+import { createMockContext } from '../../../../expressions/common';
import { functionWrapper } from './utils';
import { existsFilterFunction } from './exists_filter';
diff --git a/src/plugins/data/common/search/expressions/kibana_filter.test.ts b/src/plugins/data/common/search/expressions/kibana_filter.test.ts
index 56a9e1ce660cd..ac8ae55492cc0 100644
--- a/src/plugins/data/common/search/expressions/kibana_filter.test.ts
+++ b/src/plugins/data/common/search/expressions/kibana_filter.test.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { createMockContext } from '../../../../expressions/common/mocks';
+import { createMockContext } from '../../../../expressions/common';
import { functionWrapper } from './utils';
import { kibanaFilterFunction } from './kibana_filter';
diff --git a/src/plugins/data/common/search/expressions/phrase_filter.test.ts b/src/plugins/data/common/search/expressions/phrase_filter.test.ts
index 90e471e166f5e..39bd907513a0d 100644
--- a/src/plugins/data/common/search/expressions/phrase_filter.test.ts
+++ b/src/plugins/data/common/search/expressions/phrase_filter.test.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { createMockContext } from '../../../../expressions/common/mocks';
+import { createMockContext } from '../../../../expressions/common';
import { functionWrapper } from './utils';
import { phraseFilterFunction } from './phrase_filter';
diff --git a/src/plugins/data/common/search/expressions/range_filter.test.ts b/src/plugins/data/common/search/expressions/range_filter.test.ts
index 129e6bd82e16a..92670f8a044ba 100644
--- a/src/plugins/data/common/search/expressions/range_filter.test.ts
+++ b/src/plugins/data/common/search/expressions/range_filter.test.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { createMockContext } from '../../../../expressions/common/mocks';
+import { createMockContext } from '../../../../expressions/common';
import { functionWrapper } from './utils';
import { rangeFilterFunction } from './range_filter';
diff --git a/src/plugins/data/tsconfig.json b/src/plugins/data/tsconfig.json
index b99a2f6f85904..9c95878af631e 100644
--- a/src/plugins/data/tsconfig.json
+++ b/src/plugins/data/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/dev_tools/tsconfig.json b/src/plugins/dev_tools/tsconfig.json
index f369396b17fbe..c17b2341fd42f 100644
--- a/src/plugins/dev_tools/tsconfig.json
+++ b/src/plugins/dev_tools/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json
index 96765d76a340b..ec98199c3423e 100644
--- a/src/plugins/discover/tsconfig.json
+++ b/src/plugins/discover/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/embeddable/tsconfig.json b/src/plugins/embeddable/tsconfig.json
index eacfa831ecee5..27a887500fb68 100644
--- a/src/plugins/embeddable/tsconfig.json
+++ b/src/plugins/embeddable/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/es_ui_shared/tsconfig.json b/src/plugins/es_ui_shared/tsconfig.json
index 3d102daaf3aaf..9bcda2e0614de 100644
--- a/src/plugins/es_ui_shared/tsconfig.json
+++ b/src/plugins/es_ui_shared/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/expressions/common/mocks.ts b/src/plugins/expressions/common/mocks.ts
index 20bdbca07f008..eaeebd8e53492 100644
--- a/src/plugins/expressions/common/mocks.ts
+++ b/src/plugins/expressions/common/mocks.ts
@@ -34,5 +34,3 @@ export const createMockExecutionContext =
...extraContext,
};
};
-
-export { createMockContext } from './util/test_utils';
diff --git a/src/plugins/expressions/common/util/index.ts b/src/plugins/expressions/common/util/index.ts
index 5f83d962d5aea..470dfc3c2d436 100644
--- a/src/plugins/expressions/common/util/index.ts
+++ b/src/plugins/expressions/common/util/index.ts
@@ -10,3 +10,4 @@ export * from './create_error';
export * from './get_by_alias';
export * from './tables_adapter';
export * from './expressions_inspector_adapter';
+export * from './test_utils';
diff --git a/src/plugins/expressions/tsconfig.json b/src/plugins/expressions/tsconfig.json
index fe76ba3050a3b..cce71013cefa5 100644
--- a/src/plugins/expressions/tsconfig.json
+++ b/src/plugins/expressions/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/home/tsconfig.json b/src/plugins/home/tsconfig.json
index 19ab5a8e6efec..b15e1fc011b92 100644
--- a/src/plugins/home/tsconfig.json
+++ b/src/plugins/home/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/index_pattern_field_editor/tsconfig.json b/src/plugins/index_pattern_field_editor/tsconfig.json
index c638fd34c6bbb..559b1aaf0fc26 100644
--- a/src/plugins/index_pattern_field_editor/tsconfig.json
+++ b/src/plugins/index_pattern_field_editor/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/index_pattern_management/tsconfig.json b/src/plugins/index_pattern_management/tsconfig.json
index 3c8fdb1cf6597..37bd3e4aa5bbb 100644
--- a/src/plugins/index_pattern_management/tsconfig.json
+++ b/src/plugins/index_pattern_management/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/input_control_vis/tsconfig.json b/src/plugins/input_control_vis/tsconfig.json
index c2f8d8783e822..bef7bc394a6cc 100644
--- a/src/plugins/input_control_vis/tsconfig.json
+++ b/src/plugins/input_control_vis/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/inspector/tsconfig.json b/src/plugins/inspector/tsconfig.json
index 0e42e577428c6..2a9c41464532c 100644
--- a/src/plugins/inspector/tsconfig.json
+++ b/src/plugins/inspector/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/kibana_legacy/tsconfig.json b/src/plugins/kibana_legacy/tsconfig.json
index 0b3f42cd3b57b..709036c9e82f4 100644
--- a/src/plugins/kibana_legacy/tsconfig.json
+++ b/src/plugins/kibana_legacy/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/kibana_overview/tsconfig.json b/src/plugins/kibana_overview/tsconfig.json
index 3396861cb9179..ac3ac109cb35f 100644
--- a/src/plugins/kibana_overview/tsconfig.json
+++ b/src/plugins/kibana_overview/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/kibana_react/tsconfig.json b/src/plugins/kibana_react/tsconfig.json
index 857b8cf83645c..eb9a24ca141f6 100644
--- a/src/plugins/kibana_react/tsconfig.json
+++ b/src/plugins/kibana_react/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/kibana_usage_collection/tsconfig.json b/src/plugins/kibana_usage_collection/tsconfig.json
index 100f1f03955d0..d664d936f6667 100644
--- a/src/plugins/kibana_usage_collection/tsconfig.json
+++ b/src/plugins/kibana_usage_collection/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/kibana_utils/tsconfig.json b/src/plugins/kibana_utils/tsconfig.json
index d9572707e8662..ae5e9b90af807 100644
--- a/src/plugins/kibana_utils/tsconfig.json
+++ b/src/plugins/kibana_utils/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/legacy_export/tsconfig.json b/src/plugins/legacy_export/tsconfig.json
index d6689ea1067db..ec006d492499e 100644
--- a/src/plugins/legacy_export/tsconfig.json
+++ b/src/plugins/legacy_export/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/management/tsconfig.json b/src/plugins/management/tsconfig.json
index 3423299a53df7..ba3661666631a 100644
--- a/src/plugins/management/tsconfig.json
+++ b/src/plugins/management/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/maps_ems/tsconfig.json b/src/plugins/maps_ems/tsconfig.json
index 7f44da00d47a4..b85c3da66b83a 100644
--- a/src/plugins/maps_ems/tsconfig.json
+++ b/src/plugins/maps_ems/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/maps_legacy/tsconfig.json b/src/plugins/maps_legacy/tsconfig.json
index c600024cc4a74..f757e35f785af 100644
--- a/src/plugins/maps_legacy/tsconfig.json
+++ b/src/plugins/maps_legacy/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/navigation/tsconfig.json b/src/plugins/navigation/tsconfig.json
index bb86142e1c443..07cfe10d7d81f 100644
--- a/src/plugins/navigation/tsconfig.json
+++ b/src/plugins/navigation/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/newsfeed/tsconfig.json b/src/plugins/newsfeed/tsconfig.json
index 84626b2f3a6a8..66244a22336c7 100644
--- a/src/plugins/newsfeed/tsconfig.json
+++ b/src/plugins/newsfeed/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/presentation_util/tsconfig.json b/src/plugins/presentation_util/tsconfig.json
index cb39c5fb36f56..37b9380f6f2b9 100644
--- a/src/plugins/presentation_util/tsconfig.json
+++ b/src/plugins/presentation_util/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/region_map/tsconfig.json b/src/plugins/region_map/tsconfig.json
index 385c31e6bd2d6..899611d027465 100644
--- a/src/plugins/region_map/tsconfig.json
+++ b/src/plugins/region_map/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/saved_objects/tsconfig.json b/src/plugins/saved_objects/tsconfig.json
index 46b3f9a5afcb6..d9045b91b9dfa 100644
--- a/src/plugins/saved_objects/tsconfig.json
+++ b/src/plugins/saved_objects/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/saved_objects_management/tsconfig.json b/src/plugins/saved_objects_management/tsconfig.json
index cb74b06179225..99849dea38618 100644
--- a/src/plugins/saved_objects_management/tsconfig.json
+++ b/src/plugins/saved_objects_management/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/saved_objects_tagging_oss/tsconfig.json b/src/plugins/saved_objects_tagging_oss/tsconfig.json
index ae566d9626895..b0059c71424bf 100644
--- a/src/plugins/saved_objects_tagging_oss/tsconfig.json
+++ b/src/plugins/saved_objects_tagging_oss/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/security_oss/tsconfig.json b/src/plugins/security_oss/tsconfig.json
index 156e4ffee9d79..530e01a034b00 100644
--- a/src/plugins/security_oss/tsconfig.json
+++ b/src/plugins/security_oss/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/share/tsconfig.json b/src/plugins/share/tsconfig.json
index 62c0b3739f4b7..985066915f1dd 100644
--- a/src/plugins/share/tsconfig.json
+++ b/src/plugins/share/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/spaces_oss/tsconfig.json b/src/plugins/spaces_oss/tsconfig.json
index 96584842ec32b..0cc82d7e5d124 100644
--- a/src/plugins/spaces_oss/tsconfig.json
+++ b/src/plugins/spaces_oss/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/telemetry/tsconfig.json b/src/plugins/telemetry/tsconfig.json
index 40370082f99e2..bdced01d9eb6f 100644
--- a/src/plugins/telemetry/tsconfig.json
+++ b/src/plugins/telemetry/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/telemetry_collection_manager/tsconfig.json b/src/plugins/telemetry_collection_manager/tsconfig.json
index 8bbc440fb1a54..1bba81769f0dd 100644
--- a/src/plugins/telemetry_collection_manager/tsconfig.json
+++ b/src/plugins/telemetry_collection_manager/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/telemetry_management_section/tsconfig.json b/src/plugins/telemetry_management_section/tsconfig.json
index c6a21733b2d6b..48e40814b8570 100644
--- a/src/plugins/telemetry_management_section/tsconfig.json
+++ b/src/plugins/telemetry_management_section/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/tile_map/tsconfig.json b/src/plugins/tile_map/tsconfig.json
index 385c31e6bd2d6..899611d027465 100644
--- a/src/plugins/tile_map/tsconfig.json
+++ b/src/plugins/tile_map/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/timelion/tsconfig.json b/src/plugins/timelion/tsconfig.json
index bb8a48339d44e..5b96d69a878ea 100644
--- a/src/plugins/timelion/tsconfig.json
+++ b/src/plugins/timelion/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/ui_actions/tsconfig.json b/src/plugins/ui_actions/tsconfig.json
index 89b66d18705c2..a871d7215cdc5 100644
--- a/src/plugins/ui_actions/tsconfig.json
+++ b/src/plugins/ui_actions/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/url_forwarding/tsconfig.json b/src/plugins/url_forwarding/tsconfig.json
index f1916e4ce5957..8e867a6bad14f 100644
--- a/src/plugins/url_forwarding/tsconfig.json
+++ b/src/plugins/url_forwarding/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/usage_collection/tsconfig.json b/src/plugins/usage_collection/tsconfig.json
index b4a0721ef3672..96b2c4d37e17c 100644
--- a/src/plugins/usage_collection/tsconfig.json
+++ b/src/plugins/usage_collection/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/vis_default_editor/tsconfig.json b/src/plugins/vis_default_editor/tsconfig.json
index 54a84e08224a8..27bb775c2d0e8 100644
--- a/src/plugins/vis_default_editor/tsconfig.json
+++ b/src/plugins/vis_default_editor/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/vis_type_markdown/tsconfig.json b/src/plugins/vis_type_markdown/tsconfig.json
index f940c295e7cee..d5ab89b98081b 100644
--- a/src/plugins/vis_type_markdown/tsconfig.json
+++ b/src/plugins/vis_type_markdown/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/vis_type_metric/tsconfig.json b/src/plugins/vis_type_metric/tsconfig.json
index 8cee918a3dc82..7441848d5a430 100644
--- a/src/plugins/vis_type_metric/tsconfig.json
+++ b/src/plugins/vis_type_metric/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/vis_type_table/tsconfig.json b/src/plugins/vis_type_table/tsconfig.json
index 4f2e80575497b..ccff3c349cf21 100644
--- a/src/plugins/vis_type_table/tsconfig.json
+++ b/src/plugins/vis_type_table/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/vis_type_tagcloud/tsconfig.json b/src/plugins/vis_type_tagcloud/tsconfig.json
index f7f3688183a48..18bbad2257466 100644
--- a/src/plugins/vis_type_tagcloud/tsconfig.json
+++ b/src/plugins/vis_type_tagcloud/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/vis_type_timelion/tsconfig.json b/src/plugins/vis_type_timelion/tsconfig.json
index d29fb25b15315..77f97de28366d 100644
--- a/src/plugins/vis_type_timelion/tsconfig.json
+++ b/src/plugins/vis_type_timelion/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/vis_type_timeseries/tsconfig.json b/src/plugins/vis_type_timeseries/tsconfig.json
index edc2d25b867d1..7b2dd4b608c1c 100644
--- a/src/plugins/vis_type_timeseries/tsconfig.json
+++ b/src/plugins/vis_type_timeseries/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/vis_type_vega/tsconfig.json b/src/plugins/vis_type_vega/tsconfig.json
index f375a2483e24f..4091dafcbe357 100644
--- a/src/plugins/vis_type_vega/tsconfig.json
+++ b/src/plugins/vis_type_vega/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/vis_type_vislib/tsconfig.json b/src/plugins/vis_type_vislib/tsconfig.json
index 845628a6b86f9..74bc1440d9dbc 100644
--- a/src/plugins/vis_type_vislib/tsconfig.json
+++ b/src/plugins/vis_type_vislib/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/vis_type_xy/tsconfig.json b/src/plugins/vis_type_xy/tsconfig.json
index 7e23b07bd80f6..5cb0bc8d0bc8e 100644
--- a/src/plugins/vis_type_xy/tsconfig.json
+++ b/src/plugins/vis_type_xy/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/visualizations/tsconfig.json b/src/plugins/visualizations/tsconfig.json
index 65de6908228b3..d7c5e6a4b4366 100644
--- a/src/plugins/visualizations/tsconfig.json
+++ b/src/plugins/visualizations/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/src/plugins/visualize/tsconfig.json b/src/plugins/visualize/tsconfig.json
index 046202d82d1aa..bc0891f391746 100644
--- a/src/plugins/visualize/tsconfig.json
+++ b/src/plugins/visualize/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/tsconfig.base.json b/tsconfig.base.json
index c28ed0d8c8750..da4de5ef3712b 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -56,6 +56,5 @@
"jest-styled-components",
"@testing-library/jest-dom"
]
- },
- "include": []
+ }
}
diff --git a/tsconfig.json b/tsconfig.json
index 7c06e80858640..40763ede1bbdd 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -19,79 +19,6 @@
"x-pack/plugins/cases/**/*",
"x-pack/plugins/lists/**/*",
"x-pack/plugins/security_solution/**/*",
-
- // tests
- "src/**/*.test.ts",
- "src/**/*.test.tsx",
- "src/**/integration_tests/*",
- "src/**/tests/*",
- // mocks
- "src/**/__mocks__/*",
- "src/**/mock/*",
- "src/**/mocks/*",
- "src/**/*/mock.ts",
- "src/**/*/mocks.ts",
- "src/**/*/mocks.tsx",
- "src/**/*.mock.ts",
- "src/**/*.mock.tsx",
- "src/**/*.mocks.ts",
- "src/**/*.mocks.tsx",
-
- // test helpers
- "src/**/test_helpers/*",
- "src/**/test_utils/*",
- "src/**/*/test_utils.ts",
- "src/**/*/test_helpers.ts",
- "src/**/*/test_helper.tsx",
-
- // stubs
- "src/**/*/stubs.ts",
- "src/**/*.stub.ts",
- "src/**/*.stories.tsx",
- "src/**/*/_mock_handler_arguments.ts",
-
- // tests
- "x-pack/plugins/**/*.test.ts",
- "x-pack/plugins/**/*.test.tsx",
- "x-pack/plugins/**/test/**/*",
- "x-pack/plugins/**/tests/*",
- "x-pack/plugins/**/integration_tests/*",
- "x-pack/plugins/**/tests_client_integration/*",
- "x-pack/plugins/**/__fixtures__/*",
- "x-pack/plugins/**/__stories__/*",
- "x-pack/plugins/**/__jest__/**/*",
-
- // mocks
- "x-pack/plugins/**/__mocks__/*",
- "x-pack/plugins/**/mock/*",
- "x-pack/plugins/**/mocks/*",
- "x-pack/plugins/**/*/mock.ts",
- "x-pack/plugins/**/*/mocks.ts",
- "x-pack/plugins/**/*/mocks.tsx",
- "x-pack/plugins/**/*.mock.ts",
- "x-pack/plugins/**/*.mock.tsx",
- "x-pack/plugins/**/*.mocks.ts",
- "x-pack/plugins/**/*.mocks.tsx",
-
- // test helpers
- "x-pack/plugins/**/test_helpers/*",
- "x-pack/plugins/**/test_utils/*",
- "x-pack/plugins/**/*/test_utils.ts",
- "x-pack/plugins/**/*/test_helper.tsx",
- "x-pack/plugins/**/*/test_helpers.ts",
- "x-pack/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx",
- "x-pack/plugins/uptime/server/lib/requests/helper.ts",
- "x-pack/plugins/uptime/public/lib/helper/rtl_helpers.tsx",
- "x-pack/plugins/uptime/public/lib/helper/enzyme_helpers.tsx",
- "x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx",
- "x-pack/plugins/apm/server/utils/test_helpers.tsx",
- "x-pack/plugins/apm/public/utils/testHelpers.tsx",
-
- // stubs
- "x-pack/plugins/**/*/stubs.ts",
- "x-pack/plugins/**/*.stub.ts",
- "x-pack/plugins/**/*.stories.tsx",
- "x-pack/plugins/**/*/_mock_handler_arguments.ts"
],
"exclude": [
"x-pack/plugins/security_solution/cypress/**/*"
diff --git a/tsconfig.project.json b/tsconfig.project.json
deleted file mode 100644
index 174c3fdf0fd54..0000000000000
--- a/tsconfig.project.json
+++ /dev/null
@@ -1,65 +0,0 @@
-{
- "extends": "./tsconfig.base.json",
- "compilerOptions": {
- "composite": true,
- "emitDeclarationOnly": true,
- "declaration": true,
- "declarationMap": true
- },
- "exclude": [
- // tests
- "**/*.test.ts",
- "**/*.test.tsx",
- "**/integration_tests/*",
- "**/test/**/*",
- "**/test/*",
- "**/tests/*",
- "**/tests_client_integration/*",
- "**/__fixtures__/*",
- "**/__stories__/*",
- "**/__jest__/**",
-
- // mocks
- "**/__mocks__/*",
- "**/mock/*",
- "**/mocks/*",
- "**/*/mock.ts",
- "**/*/mocks.ts",
- "**/*/mocks.tsx",
- "**/*.mock.ts",
- "**/*.mock.tsx",
- "**/*.mocks.ts",
- "**/*.mocks.tsx",
-
- // test helpers
- "**/test_helpers/*",
- "**/test_utils/*",
- "**/*/test_utils.ts",
- "**/*/test_helper.tsx",
- "**/*/test_helpers.ts",
- // x-pack/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx
- "**/*/test_data.tsx",
- "**/*/shared_columns_tests.tsx",
- // x-pack/plugins/uptime/server/lib/requests/helper.ts
- "**/*/requests/helper.ts",
- // x-pack/plugins/uptime/public/lib/helper/rtl_helpers.tsx
- "**/*/rtl_helpers.tsx",
- // x-pack/plugins/uptime/public/lib/helper/enzyme_helpers.tsx
- "**/*/enzyme_helpers.tsx",
- // x-pack/plugins/apm/server/utils/test_helpers.tsx
- "**/*/test_helpers.tsx",
- // x-pack/plugins/apm/public/utils/testHelpers.tsx
- "**/*/testHelpers.tsx",
-
- // stubs
- "**/*/stubs.ts",
- "**/*.stub.ts",
- "**/*.stories.tsx",
- "**/*/_mock_handler_arguments.ts"
- ],
- "include": [],
- "types": [
- "node",
- "flot"
- ]
-}
diff --git a/x-pack/plugins/actions/tsconfig.json b/x-pack/plugins/actions/tsconfig.json
index 10ebd09235236..d5c1105c99ad0 100644
--- a/x-pack/plugins/actions/tsconfig.json
+++ b/x-pack/plugins/actions/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/alerting/tsconfig.json b/x-pack/plugins/alerting/tsconfig.json
index 4010688746901..86ab00faeb5ad 100644
--- a/x-pack/plugins/alerting/tsconfig.json
+++ b/x-pack/plugins/alerting/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/apm/e2e/tsconfig.json b/x-pack/plugins/apm/e2e/tsconfig.json
index 0c13dd717991c..c4587349c7ad7 100644
--- a/x-pack/plugins/apm/e2e/tsconfig.json
+++ b/x-pack/plugins/apm/e2e/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../../tsconfig.project.json",
+ "extends": "../../../../tsconfig.base.json",
"exclude": ["tmp"],
"include": ["./**/*"],
"compilerOptions": {
diff --git a/x-pack/plugins/apm/ftr_e2e/tsconfig.json b/x-pack/plugins/apm/ftr_e2e/tsconfig.json
index f699943a254fa..168801f782607 100644
--- a/x-pack/plugins/apm/ftr_e2e/tsconfig.json
+++ b/x-pack/plugins/apm/ftr_e2e/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../../tsconfig.project.json",
+ "extends": "../../../../tsconfig.base.json",
"exclude": [
"tmp"
],
@@ -12,4 +12,4 @@
"node"
]
}
-}
+}
\ No newline at end of file
diff --git a/x-pack/plugins/apm/scripts/optimize-tsconfig/optimize.js b/x-pack/plugins/apm/scripts/optimize-tsconfig/optimize.js
index 613435fe186bf..fed938119c4a6 100644
--- a/x-pack/plugins/apm/scripts/optimize-tsconfig/optimize.js
+++ b/x-pack/plugins/apm/scripts/optimize-tsconfig/optimize.js
@@ -22,7 +22,7 @@ const { kibanaRoot, tsconfigTpl, filesToIgnore } = require('./paths');
const { unoptimizeTsConfig } = require('./unoptimize');
async function prepareBaseTsConfig() {
- const baseConfigFilename = path.resolve(kibanaRoot, 'tsconfig.project.json');
+ const baseConfigFilename = path.resolve(kibanaRoot, 'tsconfig.base.json');
const config = json5.parse(await readFile(baseConfigFilename, 'utf-8'));
await writeFile(
diff --git a/x-pack/plugins/apm/scripts/optimize-tsconfig/paths.js b/x-pack/plugins/apm/scripts/optimize-tsconfig/paths.js
index b501ec3a8eedf..dbc207c9e6d26 100644
--- a/x-pack/plugins/apm/scripts/optimize-tsconfig/paths.js
+++ b/x-pack/plugins/apm/scripts/optimize-tsconfig/paths.js
@@ -12,7 +12,7 @@ const tsconfigTpl = path.resolve(__dirname, './tsconfig.json');
const filesToIgnore = [
path.resolve(kibanaRoot, 'tsconfig.json'),
- path.resolve(kibanaRoot, 'tsconfig.project.json'),
+ path.resolve(kibanaRoot, 'tsconfig.base.json'),
path.resolve(kibanaRoot, 'x-pack/plugins/apm', 'tsconfig.json'),
];
diff --git a/x-pack/plugins/apm/tsconfig.json b/x-pack/plugins/apm/tsconfig.json
index ae2085dc24003..ffbf11c23f63a 100644
--- a/x-pack/plugins/apm/tsconfig.json
+++ b/x-pack/plugins/apm/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/banners/tsconfig.json b/x-pack/plugins/banners/tsconfig.json
index 6c4c80173208b..85608a8a78ad5 100644
--- a/x-pack/plugins/banners/tsconfig.json
+++ b/x-pack/plugins/banners/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/beats_management/tsconfig.json b/x-pack/plugins/beats_management/tsconfig.json
index 398438712b26b..ad68cc900e638 100644
--- a/x-pack/plugins/beats_management/tsconfig.json
+++ b/x-pack/plugins/beats_management/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/canvas/storybook/addon/tsconfig.json b/x-pack/plugins/canvas/storybook/addon/tsconfig.json
index b115d1c46546c..2ab1856de661a 100644
--- a/x-pack/plugins/canvas/storybook/addon/tsconfig.json
+++ b/x-pack/plugins/canvas/storybook/addon/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../../../tsconfig.project.json",
+ "extends": "../../../../../tsconfig.base.json",
"include": [
"src/**/*.ts",
"src/**/*.tsx"
diff --git a/x-pack/plugins/canvas/tsconfig.json b/x-pack/plugins/canvas/tsconfig.json
index 679165f0a1b76..487b68ba3542b 100644
--- a/x-pack/plugins/canvas/tsconfig.json
+++ b/x-pack/plugins/canvas/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/cloud/tsconfig.json b/x-pack/plugins/cloud/tsconfig.json
index f6edb9fb7ccae..46e81aa7fa086 100644
--- a/x-pack/plugins/cloud/tsconfig.json
+++ b/x-pack/plugins/cloud/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/console_extensions/tsconfig.json b/x-pack/plugins/console_extensions/tsconfig.json
index edcd46c4fafc5..5ad28f230a0bb 100644
--- a/x-pack/plugins/console_extensions/tsconfig.json
+++ b/x-pack/plugins/console_extensions/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/cross_cluster_replication/tsconfig.json b/x-pack/plugins/cross_cluster_replication/tsconfig.json
index 156a851abb8db..9c7590b9c2553 100644
--- a/x-pack/plugins/cross_cluster_replication/tsconfig.json
+++ b/x-pack/plugins/cross_cluster_replication/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/dashboard_enhanced/tsconfig.json b/x-pack/plugins/dashboard_enhanced/tsconfig.json
index f6acdddc6f997..567c390edfa5a 100644
--- a/x-pack/plugins/dashboard_enhanced/tsconfig.json
+++ b/x-pack/plugins/dashboard_enhanced/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/dashboard_mode/tsconfig.json b/x-pack/plugins/dashboard_mode/tsconfig.json
index c4a11959ec3e3..6e4ed11ffa7ff 100644
--- a/x-pack/plugins/dashboard_mode/tsconfig.json
+++ b/x-pack/plugins/dashboard_mode/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/data_enhanced/tsconfig.json b/x-pack/plugins/data_enhanced/tsconfig.json
index 5538a2db3e4cd..047b9b06516ba 100644
--- a/x-pack/plugins/data_enhanced/tsconfig.json
+++ b/x-pack/plugins/data_enhanced/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/discover_enhanced/tsconfig.json b/x-pack/plugins/discover_enhanced/tsconfig.json
index 2a055bd0e0710..38a55e557909b 100644
--- a/x-pack/plugins/discover_enhanced/tsconfig.json
+++ b/x-pack/plugins/discover_enhanced/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/drilldowns/url_drilldown/tsconfig.json b/x-pack/plugins/drilldowns/url_drilldown/tsconfig.json
index 99aea16a9aaba..50fe41c49b0c8 100644
--- a/x-pack/plugins/drilldowns/url_drilldown/tsconfig.json
+++ b/x-pack/plugins/drilldowns/url_drilldown/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../../tsconfig.project.json",
+ "extends": "../../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/embeddable_enhanced/tsconfig.json b/x-pack/plugins/embeddable_enhanced/tsconfig.json
index 32754f2fd5524..6e9eb69585cbc 100644
--- a/x-pack/plugins/embeddable_enhanced/tsconfig.json
+++ b/x-pack/plugins/embeddable_enhanced/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/encrypted_saved_objects/tsconfig.json b/x-pack/plugins/encrypted_saved_objects/tsconfig.json
index 9eae8b7366bea..2b51b313d34fc 100644
--- a/x-pack/plugins/encrypted_saved_objects/tsconfig.json
+++ b/x-pack/plugins/encrypted_saved_objects/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/enterprise_search/tsconfig.json b/x-pack/plugins/enterprise_search/tsconfig.json
index a4f1c55463e75..6b4c50770b49f 100644
--- a/x-pack/plugins/enterprise_search/tsconfig.json
+++ b/x-pack/plugins/enterprise_search/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/event_log/tsconfig.json b/x-pack/plugins/event_log/tsconfig.json
index e21dbc93b7b47..9b7cde10da3d6 100644
--- a/x-pack/plugins/event_log/tsconfig.json
+++ b/x-pack/plugins/event_log/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/features/tsconfig.json b/x-pack/plugins/features/tsconfig.json
index 11e2dbc8f093f..1260af55fbff6 100644
--- a/x-pack/plugins/features/tsconfig.json
+++ b/x-pack/plugins/features/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/file_upload/tsconfig.json b/x-pack/plugins/file_upload/tsconfig.json
index 8a982f83632aa..887a05af31174 100644
--- a/x-pack/plugins/file_upload/tsconfig.json
+++ b/x-pack/plugins/file_upload/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/fleet/tsconfig.json b/x-pack/plugins/fleet/tsconfig.json
index 66849e017395b..a20d82de3c859 100644
--- a/x-pack/plugins/fleet/tsconfig.json
+++ b/x-pack/plugins/fleet/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/global_search/tsconfig.json b/x-pack/plugins/global_search/tsconfig.json
index 2571f7c2e2935..2d05328f445df 100644
--- a/x-pack/plugins/global_search/tsconfig.json
+++ b/x-pack/plugins/global_search/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/global_search_bar/tsconfig.json b/x-pack/plugins/global_search_bar/tsconfig.json
index 595d55c3c5a0d..266eecc35c84b 100644
--- a/x-pack/plugins/global_search_bar/tsconfig.json
+++ b/x-pack/plugins/global_search_bar/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/global_search_providers/tsconfig.json b/x-pack/plugins/global_search_providers/tsconfig.json
index 9be9a681ee7c5..f2759954a6845 100644
--- a/x-pack/plugins/global_search_providers/tsconfig.json
+++ b/x-pack/plugins/global_search_providers/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/graph/tsconfig.json b/x-pack/plugins/graph/tsconfig.json
index ae0d143455d52..741c603e3aae4 100644
--- a/x-pack/plugins/graph/tsconfig.json
+++ b/x-pack/plugins/graph/tsconfig.json
@@ -1,6 +1,6 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
@@ -27,4 +27,4 @@
{ "path": "../../../src/plugins/kibana_utils/tsconfig.json" },
{ "path": "../../../src/plugins/kibana_react/tsconfig.json" }
]
- }
+ }
\ No newline at end of file
diff --git a/x-pack/plugins/grokdebugger/tsconfig.json b/x-pack/plugins/grokdebugger/tsconfig.json
index 3e9e2f7870814..51d2d0b6db0ea 100644
--- a/x-pack/plugins/grokdebugger/tsconfig.json
+++ b/x-pack/plugins/grokdebugger/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/index_lifecycle_management/tsconfig.json b/x-pack/plugins/index_lifecycle_management/tsconfig.json
index bf43817cbc407..75bd775a36749 100644
--- a/x-pack/plugins/index_lifecycle_management/tsconfig.json
+++ b/x-pack/plugins/index_lifecycle_management/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
@@ -8,6 +8,7 @@
"declarationMap": true
},
"include": [
+ "__jest__/**/*",
"common/**/*",
"public/**/*",
"server/**/*",
diff --git a/x-pack/plugins/index_management/tsconfig.json b/x-pack/plugins/index_management/tsconfig.json
index 0766839a230b9..81a96a77cef83 100644
--- a/x-pack/plugins/index_management/tsconfig.json
+++ b/x-pack/plugins/index_management/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
@@ -8,9 +8,11 @@
"declarationMap": true
},
"include": [
+ "__jest__/**/*",
"common/**/*",
"public/**/*",
"server/**/*",
+ "test/**/*",
"../../../typings/**/*",
],
"references": [
diff --git a/x-pack/plugins/infra/public/utils/enzyme_helpers.tsx b/x-pack/plugins/infra/public/utils/enzyme_helpers.tsx
new file mode 100644
index 0000000000000..33fbbd03d790a
--- /dev/null
+++ b/x-pack/plugins/infra/public/utils/enzyme_helpers.tsx
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { mount, ReactWrapper } from 'enzyme';
+import React from 'react';
+import { act as reactAct } from 'react-dom/test-utils';
+/**
+ * A wrapper object to provide access to the state of a hook under test and to
+ * enable interaction with that hook.
+ */
+interface ReactHookWrapper {
+ /* Ensures that async React operations have settled before and after the
+ * given actor callback is called. The actor callback arguments provide easy
+ * access to the last hook value and allow for updating the arguments passed
+ * to the hook body to trigger reevaluation.
+ */
+ act: (actor: (lastHookValue: HookValue, setArgs: (args: Args) => void) => void) => void;
+ /* The enzyme wrapper around the test component. */
+ component: ReactWrapper;
+ /* The most recent value return the by test harness of the hook. */
+ getLastHookValue: () => HookValue;
+ /* The jest Mock function that receives the hook values for introspection. */
+ hookValueCallback: jest.Mock;
+}
+
+/**
+ * Allows for execution of hooks inside of a test component which records the
+ * returned values.
+ *
+ * @param body A function that calls the hook and returns data derived from it
+ * @param WrapperComponent A component that, if provided, will be wrapped
+ * around the test component. This can be useful to provide context values.
+ * @return {ReactHookWrapper} An object providing access to the hook state and
+ * functions to interact with it.
+ */
+export const mountHook = (
+ body: (args: Args) => HookValue,
+ WrapperComponent?: React.ComponentType,
+ initialArgs: Args = {} as Args
+): ReactHookWrapper => {
+ const hookValueCallback = jest.fn();
+ let component!: ReactWrapper;
+
+ const act: ReactHookWrapper['act'] = (actor) => {
+ reactAct(() => {
+ actor(getLastHookValue(), (args: Args) => component.setProps(args));
+ component.update();
+ });
+ };
+
+ const getLastHookValue = () => {
+ const calls = hookValueCallback.mock.calls;
+ if (calls.length <= 0) {
+ throw Error('No recent hook value present.');
+ }
+ return calls[calls.length - 1][0];
+ };
+
+ const HookComponent = (props: Args) => {
+ hookValueCallback(body(props));
+ return null;
+ };
+ const TestComponent: React.FunctionComponent = (args) =>
+ WrapperComponent ? (
+
+
+
+ ) : (
+
+ );
+
+ reactAct(() => {
+ component = mount();
+ });
+
+ return {
+ act,
+ component,
+ getLastHookValue,
+ hookValueCallback,
+ };
+};
diff --git a/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_hosts_anomalies.ts b/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_hosts_anomalies.ts
index b9bfcd302fb83..ab50986c3b3d5 100644
--- a/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_hosts_anomalies.ts
+++ b/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_hosts_anomalies.ts
@@ -84,7 +84,7 @@ export const createMetricsHostsAnomaliesQuery = ({
const sortOptions = [
{ [sortToMlFieldMap[field]]: querySortDirection },
{ [TIEBREAKER_FIELD]: querySortDirection }, // Tiebreaker
- ] as const;
+ ];
const resultsQuery = {
...defaultRequestParameters,
diff --git a/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_k8s_anomalies.ts b/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_k8s_anomalies.ts
index 8dadcfe87c6f9..8fb8df5eef3d7 100644
--- a/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_k8s_anomalies.ts
+++ b/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_k8s_anomalies.ts
@@ -83,7 +83,7 @@ export const createMetricsK8sAnomaliesQuery = ({
const sortOptions = [
{ [sortToMlFieldMap[field]]: querySortDirection },
{ [TIEBREAKER_FIELD]: querySortDirection }, // Tiebreaker
- ] as const;
+ ];
const resultsQuery = {
...defaultRequestParameters,
diff --git a/x-pack/plugins/infra/tsconfig.json b/x-pack/plugins/infra/tsconfig.json
index b684e1866282f..765af7974a2f1 100644
--- a/x-pack/plugins/infra/tsconfig.json
+++ b/x-pack/plugins/infra/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/ingest_pipelines/tsconfig.json b/x-pack/plugins/ingest_pipelines/tsconfig.json
index 5917b94caf76b..a248bc9f337fe 100644
--- a/x-pack/plugins/ingest_pipelines/tsconfig.json
+++ b/x-pack/plugins/ingest_pipelines/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
@@ -11,6 +11,7 @@
"common/**/*",
"public/**/*",
"server/**/*",
+ "__jest__/**/*",
"../../../typings/**/*"
],
"references": [
diff --git a/x-pack/plugins/lens/tsconfig.json b/x-pack/plugins/lens/tsconfig.json
index 69ef52535dd9d..134f0b4185b84 100644
--- a/x-pack/plugins/lens/tsconfig.json
+++ b/x-pack/plugins/lens/tsconfig.json
@@ -1,6 +1,6 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
@@ -38,4 +38,4 @@
{ "path": "../../../src/plugins/embeddable/tsconfig.json"},
{ "path": "../../../src/plugins/presentation_util/tsconfig.json"},
]
- }
+ }
\ No newline at end of file
diff --git a/x-pack/plugins/license_management/tsconfig.json b/x-pack/plugins/license_management/tsconfig.json
index 925049ca924cf..e6cb0101ee838 100644
--- a/x-pack/plugins/license_management/tsconfig.json
+++ b/x-pack/plugins/license_management/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/licensing/tsconfig.json b/x-pack/plugins/licensing/tsconfig.json
index 2d744e57c1895..6118bcd81d342 100644
--- a/x-pack/plugins/licensing/tsconfig.json
+++ b/x-pack/plugins/licensing/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/logstash/tsconfig.json b/x-pack/plugins/logstash/tsconfig.json
index 6430248e46396..6f21cfdb0b191 100644
--- a/x-pack/plugins/logstash/tsconfig.json
+++ b/x-pack/plugins/logstash/tsconfig.json
@@ -1,6 +1,6 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/maps/public/components/validated_number_input.tsx b/x-pack/plugins/maps/public/components/validated_number_input.tsx
index 942f31074000f..cd525cf1ee2c9 100644
--- a/x-pack/plugins/maps/public/components/validated_number_input.tsx
+++ b/x-pack/plugins/maps/public/components/validated_number_input.tsx
@@ -6,8 +6,8 @@
*/
import React, { Component, ChangeEvent, ReactNode } from 'react';
-import { EuiFieldNumber, EuiFormRow } from '@elastic/eui';
-import type { EuiFormRowDisplayKeys } from '@elastic/eui/src/components/form/form_row/form_row';
+// @ts-expect-error
+import { EuiFieldNumber, EuiFormRow, EuiFormRowDisplayKeys } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import _ from 'lodash';
diff --git a/x-pack/plugins/maps/tsconfig.json b/x-pack/plugins/maps/tsconfig.json
index 59af94bea0b68..1b74b7ee7566a 100644
--- a/x-pack/plugins/maps/tsconfig.json
+++ b/x-pack/plugins/maps/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/ml/server/routes/apidoc_scripts/tsconfig.json b/x-pack/plugins/ml/server/routes/apidoc_scripts/tsconfig.json
index 599dee1e56c0f..6d01a853698b8 100644
--- a/x-pack/plugins/ml/server/routes/apidoc_scripts/tsconfig.json
+++ b/x-pack/plugins/ml/server/routes/apidoc_scripts/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../../../../tsconfig.project.json",
+ "extends": "../../../../../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./target",
"target": "es6",
diff --git a/x-pack/plugins/ml/tsconfig.json b/x-pack/plugins/ml/tsconfig.json
index b1135b867dc08..6b396b1c59642 100644
--- a/x-pack/plugins/ml/tsconfig.json
+++ b/x-pack/plugins/ml/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/monitoring/tsconfig.json b/x-pack/plugins/monitoring/tsconfig.json
index b1999101f7c12..d0fb7e1a88dcf 100644
--- a/x-pack/plugins/monitoring/tsconfig.json
+++ b/x-pack/plugins/monitoring/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/observability/tsconfig.json b/x-pack/plugins/observability/tsconfig.json
index cc6e298795e4a..f55ae640a8026 100644
--- a/x-pack/plugins/observability/tsconfig.json
+++ b/x-pack/plugins/observability/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/osquery/tsconfig.json b/x-pack/plugins/osquery/tsconfig.json
index 03c9e451f3b52..291b0f7c607cf 100644
--- a/x-pack/plugins/osquery/tsconfig.json
+++ b/x-pack/plugins/osquery/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/painless_lab/tsconfig.json b/x-pack/plugins/painless_lab/tsconfig.json
index 2519206b0fcdb..a869b21e06d4d 100644
--- a/x-pack/plugins/painless_lab/tsconfig.json
+++ b/x-pack/plugins/painless_lab/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/remote_clusters/tsconfig.json b/x-pack/plugins/remote_clusters/tsconfig.json
index b48933bc9f1ec..0bee6300cf0b2 100644
--- a/x-pack/plugins/remote_clusters/tsconfig.json
+++ b/x-pack/plugins/remote_clusters/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/reporting/tsconfig.json b/x-pack/plugins/reporting/tsconfig.json
index 4f252743ed078..88e8d343f4700 100644
--- a/x-pack/plugins/reporting/tsconfig.json
+++ b/x-pack/plugins/reporting/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/rollup/tsconfig.json b/x-pack/plugins/rollup/tsconfig.json
index bf589c62713d6..9b994d1710ffc 100644
--- a/x-pack/plugins/rollup/tsconfig.json
+++ b/x-pack/plugins/rollup/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/runtime_fields/tsconfig.json b/x-pack/plugins/runtime_fields/tsconfig.json
index e1ad141f1c702..a1efe4c9cf2dd 100644
--- a/x-pack/plugins/runtime_fields/tsconfig.json
+++ b/x-pack/plugins/runtime_fields/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/saved_objects_tagging/tsconfig.json b/x-pack/plugins/saved_objects_tagging/tsconfig.json
index 5c37481f982d9..d00156ad1277c 100644
--- a/x-pack/plugins/saved_objects_tagging/tsconfig.json
+++ b/x-pack/plugins/saved_objects_tagging/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/searchprofiler/tsconfig.json b/x-pack/plugins/searchprofiler/tsconfig.json
index 57cd882422b39..f8ac3a61f7812 100644
--- a/x-pack/plugins/searchprofiler/tsconfig.json
+++ b/x-pack/plugins/searchprofiler/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/security/tsconfig.json b/x-pack/plugins/security/tsconfig.json
index 4ace497dbd5ad..6c3fd1851a8cb 100644
--- a/x-pack/plugins/security/tsconfig.json
+++ b/x-pack/plugins/security/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/security_solution/cypress/tsconfig.json b/x-pack/plugins/security_solution/cypress/tsconfig.json
index bd8d9aa058bc3..270d877a362a6 100644
--- a/x-pack/plugins/security_solution/cypress/tsconfig.json
+++ b/x-pack/plugins/security_solution/cypress/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../../tsconfig.project.json",
+ "extends": "../../../../tsconfig.base.json",
"exclude": [],
"include": [
"./**/*"
diff --git a/x-pack/plugins/snapshot_restore/tsconfig.json b/x-pack/plugins/snapshot_restore/tsconfig.json
index c496847e4dd9b..39beda02977e1 100644
--- a/x-pack/plugins/snapshot_restore/tsconfig.json
+++ b/x-pack/plugins/snapshot_restore/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
@@ -8,9 +8,11 @@
"declarationMap": true
},
"include": [
+ "__jest__/**/*",
"common/**/*",
"public/**/*",
"server/**/*",
+ "test/**/*",
"../../../typings/**/*",
],
"references": [
diff --git a/x-pack/plugins/spaces/tsconfig.json b/x-pack/plugins/spaces/tsconfig.json
index 4c67cbe8912bd..95fbecaa90936 100644
--- a/x-pack/plugins/spaces/tsconfig.json
+++ b/x-pack/plugins/spaces/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/stack_alerts/tsconfig.json b/x-pack/plugins/stack_alerts/tsconfig.json
index 97eb9a9a05b86..c83935945c67b 100644
--- a/x-pack/plugins/stack_alerts/tsconfig.json
+++ b/x-pack/plugins/stack_alerts/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts
index 70b4ba55c2393..c79b310822c3e 100644
--- a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts
+++ b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts
@@ -56,7 +56,7 @@ export interface WorkloadAggregation {
scheduleDensity: {
range: {
field: string;
- ranges: [{ from: number; to: number }];
+ ranges: [{ from: string; to: string }];
};
aggs: {
histogram: {
@@ -86,6 +86,7 @@ export interface WorkloadAggregation {
// The type of a bucket in the scheduleDensity range aggregation
type ScheduleDensityResult = AggregationResultOf<
+ // @ts-expect-error AggregationRange reqires from: number
WorkloadAggregation['aggs']['idleTasks']['aggs']['scheduleDensity'],
{}
>['buckets'][0];
diff --git a/x-pack/plugins/task_manager/tsconfig.json b/x-pack/plugins/task_manager/tsconfig.json
index 95a098e54619e..a72b678da1f7c 100644
--- a/x-pack/plugins/task_manager/tsconfig.json
+++ b/x-pack/plugins/task_manager/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/telemetry_collection_xpack/tsconfig.json b/x-pack/plugins/telemetry_collection_xpack/tsconfig.json
index 80488bd74617d..476f5926f757a 100644
--- a/x-pack/plugins/telemetry_collection_xpack/tsconfig.json
+++ b/x-pack/plugins/telemetry_collection_xpack/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/transform/tsconfig.json b/x-pack/plugins/transform/tsconfig.json
index 30da887cc1c43..2717f92c7a4df 100644
--- a/x-pack/plugins/transform/tsconfig.json
+++ b/x-pack/plugins/transform/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/triggers_actions_ui/tsconfig.json b/x-pack/plugins/triggers_actions_ui/tsconfig.json
index b7a63d7043f49..8202449b22298 100644
--- a/x-pack/plugins/triggers_actions_ui/tsconfig.json
+++ b/x-pack/plugins/triggers_actions_ui/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/ui_actions_enhanced/tsconfig.json b/x-pack/plugins/ui_actions_enhanced/tsconfig.json
index 1513669cdc1ad..39318770126e5 100644
--- a/x-pack/plugins/ui_actions_enhanced/tsconfig.json
+++ b/x-pack/plugins/ui_actions_enhanced/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/upgrade_assistant/tsconfig.json b/x-pack/plugins/upgrade_assistant/tsconfig.json
index 08e45bebf125b..0d65c8ddd8fed 100644
--- a/x-pack/plugins/upgrade_assistant/tsconfig.json
+++ b/x-pack/plugins/upgrade_assistant/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/uptime/public/components/certificates/cert_monitors.test.tsx b/x-pack/plugins/uptime/public/components/certificates/cert_monitors.test.tsx
index 719c90574b088..5dfc11837b72d 100644
--- a/x-pack/plugins/uptime/public/components/certificates/cert_monitors.test.tsx
+++ b/x-pack/plugins/uptime/public/components/certificates/cert_monitors.test.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { CertMonitors } from './cert_monitors';
-import { renderWithRouter, shallowWithRouter } from '../../lib/helper/enzyme_helpers';
+import { renderWithRouter, shallowWithRouter } from '../../lib';
describe('CertMonitors', () => {
const certMons = [
diff --git a/x-pack/plugins/uptime/public/components/certificates/cert_search.test.tsx b/x-pack/plugins/uptime/public/components/certificates/cert_search.test.tsx
index a0166fc573754..a991634de22a6 100644
--- a/x-pack/plugins/uptime/public/components/certificates/cert_search.test.tsx
+++ b/x-pack/plugins/uptime/public/components/certificates/cert_search.test.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { renderWithRouter, shallowWithRouter } from '../../lib/helper/enzyme_helpers';
+import { renderWithRouter, shallowWithRouter } from '../../lib';
import { CertificateSearch } from './cert_search';
describe('CertificatesSearch', () => {
diff --git a/x-pack/plugins/uptime/public/components/certificates/cert_status.test.tsx b/x-pack/plugins/uptime/public/components/certificates/cert_status.test.tsx
index 999d76f690867..e331a6e5c34fe 100644
--- a/x-pack/plugins/uptime/public/components/certificates/cert_status.test.tsx
+++ b/x-pack/plugins/uptime/public/components/certificates/cert_status.test.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { renderWithRouter, shallowWithRouter } from '../../lib/helper/enzyme_helpers';
+import { renderWithRouter, shallowWithRouter } from '../../lib';
import { CertStatus } from './cert_status';
import * as redux from 'react-redux';
import moment from 'moment';
diff --git a/x-pack/plugins/uptime/public/components/certificates/certificates_list.test.tsx b/x-pack/plugins/uptime/public/components/certificates/certificates_list.test.tsx
index 8ae0cdb791d9b..ec6a5d91a67c3 100644
--- a/x-pack/plugins/uptime/public/components/certificates/certificates_list.test.tsx
+++ b/x-pack/plugins/uptime/public/components/certificates/certificates_list.test.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { shallowWithRouter } from '../../lib/helper/enzyme_helpers';
+import { shallowWithRouter } from '../../lib';
import { CertificateList, CertSort } from './certificates_list';
describe('CertificateList', () => {
diff --git a/x-pack/plugins/uptime/public/components/certificates/fingerprint_col.test.tsx b/x-pack/plugins/uptime/public/components/certificates/fingerprint_col.test.tsx
index 550b7f75623f0..1affd1f990f90 100644
--- a/x-pack/plugins/uptime/public/components/certificates/fingerprint_col.test.tsx
+++ b/x-pack/plugins/uptime/public/components/certificates/fingerprint_col.test.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { renderWithRouter, shallowWithRouter } from '../../lib/helper/enzyme_helpers';
+import { renderWithRouter, shallowWithRouter } from '../../lib';
import { FingerprintCol } from './fingerprint_col';
import moment from 'moment';
diff --git a/x-pack/plugins/uptime/public/components/common/charts/duration_charts.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/duration_charts.test.tsx
index 72b1145a9f34e..d7ae92a0e7654 100644
--- a/x-pack/plugins/uptime/public/components/common/charts/duration_charts.test.tsx
+++ b/x-pack/plugins/uptime/public/components/common/charts/duration_charts.test.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import DateMath from '@elastic/datemath';
import { DurationChartComponent } from './duration_chart';
import { MonitorDurationResult } from '../../../../common/types';
-import { shallowWithRouter } from '../../../lib/helper/enzyme_helpers';
+import { shallowWithRouter } from '../../../lib';
describe('MonitorCharts component', () => {
let dateMathSpy: any;
diff --git a/x-pack/plugins/uptime/public/components/common/charts/monitor_bar_series.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/monitor_bar_series.test.tsx
index b11595eafae4f..792b357b3baba 100644
--- a/x-pack/plugins/uptime/public/components/common/charts/monitor_bar_series.test.tsx
+++ b/x-pack/plugins/uptime/public/components/common/charts/monitor_bar_series.test.tsx
@@ -7,8 +7,7 @@
import React from 'react';
import { MonitorBarSeries, MonitorBarSeriesProps } from './monitor_bar_series';
-import { renderWithRouter, shallowWithRouter } from '../../../lib/helper/enzyme_helpers';
-import { MountWithReduxProvider } from '../../../lib/helper/helper_with_redux';
+import { renderWithRouter, shallowWithRouter, MountWithReduxProvider } from '../../../lib';
import { HistogramPoint } from '../../../../common/runtime_types';
describe('MonitorBarSeries component', () => {
diff --git a/x-pack/plugins/uptime/public/components/common/header/page_header.test.tsx b/x-pack/plugins/uptime/public/components/common/header/page_header.test.tsx
index bede71b8ba03d..6e04648a817f0 100644
--- a/x-pack/plugins/uptime/public/components/common/header/page_header.test.tsx
+++ b/x-pack/plugins/uptime/public/components/common/header/page_header.test.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import moment from 'moment';
import { PageHeader } from './page_header';
import { Ping } from '../../../../common/runtime_types';
-import { renderWithRouter } from '../../../lib/helper/enzyme_helpers';
+import { renderWithRouter } from '../../../lib';
import { mockReduxHooks } from '../../../lib/helper/test_helpers';
describe('PageHeader', () => {
diff --git a/x-pack/plugins/uptime/public/components/common/monitor_tags.test.tsx b/x-pack/plugins/uptime/public/components/common/monitor_tags.test.tsx
index 63465aefcdd43..fdb5498969d39 100644
--- a/x-pack/plugins/uptime/public/components/common/monitor_tags.test.tsx
+++ b/x-pack/plugins/uptime/public/components/common/monitor_tags.test.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { MonitorTags } from './monitor_tags';
import * as hooks from '../../hooks/use_url_params';
-import { renderWithRouter, shallowWithRouter } from '../../lib/helper/enzyme_helpers';
+import { renderWithRouter, shallowWithRouter } from '../../lib';
describe('MonitorTags component', () => {
const summaryPing = {
diff --git a/x-pack/plugins/uptime/public/components/common/uptime_date_picker.test.tsx b/x-pack/plugins/uptime/public/components/common/uptime_date_picker.test.tsx
index d433e7fccd1b8..4bfe7de33cba5 100644
--- a/x-pack/plugins/uptime/public/components/common/uptime_date_picker.test.tsx
+++ b/x-pack/plugins/uptime/public/components/common/uptime_date_picker.test.tsx
@@ -10,9 +10,9 @@ import { UptimeDatePicker } from './uptime_date_picker';
import {
renderWithRouter,
shallowWithRouter,
+ MountWithReduxProvider,
mountWithRouterRedux,
-} from '../../lib/helper/enzyme_helpers';
-import { MountWithReduxProvider } from '../../lib/helper/helper_with_redux';
+} from '../../lib';
import { UptimeStartupPluginsContextProvider } from '../../contexts';
import { startPlugins } from '../../lib/__mocks__/uptime_plugin_start_mock';
import { ClientPluginsStart } from '../../apps/plugin';
diff --git a/x-pack/plugins/uptime/public/components/monitor/ml/ml_integerations.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/ml_integerations.test.tsx
index 16d96148af340..f29be50633fab 100644
--- a/x-pack/plugins/uptime/public/components/monitor/ml/ml_integerations.test.tsx
+++ b/x-pack/plugins/uptime/public/components/monitor/ml/ml_integerations.test.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { MLIntegrationComponent } from './ml_integeration';
-import { renderWithRouter, shallowWithRouter } from '../../../lib/helper/enzyme_helpers';
+import { renderWithRouter, shallowWithRouter } from '../../../lib';
import * as redux from 'react-redux';
import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public';
import { coreMock } from 'src/core/public/mocks';
diff --git a/x-pack/plugins/uptime/public/components/monitor/ml/ml_manage_job.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/ml_manage_job.test.tsx
index 6bff0b61d7349..15a537a49ccf3 100644
--- a/x-pack/plugins/uptime/public/components/monitor/ml/ml_manage_job.test.tsx
+++ b/x-pack/plugins/uptime/public/components/monitor/ml/ml_manage_job.test.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import { coreMock } from 'src/core/public/mocks';
import { ManageMLJobComponent } from './manage_ml_job';
import * as redux from 'react-redux';
-import { renderWithRouter, shallowWithRouter } from '../../../lib/helper/enzyme_helpers';
+import { renderWithRouter, shallowWithRouter } from '../../../lib';
import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public';
const core = coreMock.createStart();
diff --git a/x-pack/plugins/uptime/public/components/monitor/monitor_charts.test.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_charts.test.tsx
index a1be391833bc3..3f107581c1eea 100644
--- a/x-pack/plugins/uptime/public/components/monitor/monitor_charts.test.tsx
+++ b/x-pack/plugins/uptime/public/components/monitor/monitor_charts.test.tsx
@@ -8,7 +8,7 @@
import React from 'react';
import DateMath from '@elastic/datemath';
import { MonitorCharts } from './monitor_charts';
-import { shallowWithRouter } from '../../lib/helper/enzyme_helpers';
+import { shallowWithRouter } from '../../lib';
describe('MonitorCharts component', () => {
let dateMathSpy: any;
diff --git a/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx
index 682be99b9b418..dabc0021898eb 100644
--- a/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx
+++ b/x-pack/plugins/uptime/public/components/monitor/monitor_title.test.tsx
@@ -10,7 +10,7 @@ import moment from 'moment';
import * as reactRouterDom from 'react-router-dom';
import { Ping } from '../../../common/runtime_types';
import { MonitorPageTitle } from './monitor_title';
-import { renderWithRouter } from '../../lib/helper/enzyme_helpers';
+import { renderWithRouter } from '../../lib';
import { mockReduxHooks } from '../../lib/helper/test_helpers';
jest.mock('react-router-dom', () => {
diff --git a/x-pack/plugins/uptime/public/components/monitor/status_details/monitor_status.bar.test.tsx b/x-pack/plugins/uptime/public/components/monitor/status_details/monitor_status.bar.test.tsx
index ba0853b5b1b60..af3c47b9caf30 100644
--- a/x-pack/plugins/uptime/public/components/monitor/status_details/monitor_status.bar.test.tsx
+++ b/x-pack/plugins/uptime/public/components/monitor/status_details/monitor_status.bar.test.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { MonitorStatusBar } from './status_bar';
import { Ping } from '../../../../common/runtime_types';
import * as redux from 'react-redux';
-import { renderWithRouter } from '../../../lib/helper/enzyme_helpers';
+import { renderWithRouter } from '../../../lib';
import { createMemoryHistory } from 'history';
describe('MonitorStatusBar component', () => {
diff --git a/x-pack/plugins/uptime/public/components/monitor/status_details/ssl_certificate.test.tsx b/x-pack/plugins/uptime/public/components/monitor/status_details/ssl_certificate.test.tsx
index 0cb7ff7168404..03ce292e63621 100644
--- a/x-pack/plugins/uptime/public/components/monitor/status_details/ssl_certificate.test.tsx
+++ b/x-pack/plugins/uptime/public/components/monitor/status_details/ssl_certificate.test.tsx
@@ -11,11 +11,7 @@ import { EuiIcon } from '@elastic/eui';
import { Tls } from '../../../../common/runtime_types';
import { MonitorSSLCertificate } from './status_bar';
import * as redux from 'react-redux';
-import {
- mountWithRouter,
- renderWithRouter,
- shallowWithRouter,
-} from '../../../lib/helper/enzyme_helpers';
+import { mountWithRouter, renderWithRouter, shallowWithRouter } from '../../../lib';
import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants';
describe('SSL Certificate component', () => {
diff --git a/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.test.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.test.tsx
index c751e6a0c24fa..a617ba0db1eb3 100644
--- a/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.test.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.test.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import { EmptyStateComponent } from './empty_state';
import { StatesIndexStatus } from '../../../../common/runtime_types';
import { HttpFetchError, IHttpFetchError } from 'src/core/public';
-import { mountWithRouter, shallowWithRouter } from '../../../lib/helper/enzyme_helpers';
+import { mountWithRouter, shallowWithRouter } from '../../../lib';
describe('EmptyState component', () => {
let statesIndexStatus: StatesIndexStatus;
diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/enable_alert.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/enable_alert.test.tsx
index a4e7f10d97bfc..a325edc243129 100644
--- a/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/enable_alert.test.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/columns/enable_alert.test.tsx
@@ -12,7 +12,7 @@ import {
mountWithRouterRedux,
renderWithRouterRedux,
shallowWithRouterRedux,
-} from '../../../../lib/helper/enzyme_helpers';
+} from '../../../../lib';
import { EuiPopover, EuiText } from '@elastic/eui';
import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../common/constants';
import { ReactRouterEuiLink } from '../../../common/react_router_helpers';
diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/filter_status_button.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/filter_status_button.test.tsx
index c95e3cd61c5fd..4d0e82dc8a296 100644
--- a/x-pack/plugins/uptime/public/components/overview/monitor_list/filter_status_button.test.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/filter_status_button.test.tsx
@@ -7,8 +7,7 @@
import React from 'react';
import { FilterStatusButton, FilterStatusButtonProps } from './filter_status_button';
-import { renderWithRouter, shallowWithRouter } from '../../../lib/helper/enzyme_helpers';
-import { MountWithReduxProvider } from '../../../lib/helper/helper_with_redux';
+import { renderWithRouter, shallowWithRouter, MountWithReduxProvider } from '../../../lib';
describe('FilterStatusButton', () => {
let props: FilterStatusButtonProps;
diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.test.tsx
index f7a2ad9a536bd..39f9b20624b63 100644
--- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.test.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.test.tsx
@@ -15,7 +15,7 @@ import {
MonitorSummary,
} from '../../../../common/runtime_types';
import { MonitorListComponent, noItemsMessage } from './monitor_list';
-import { renderWithRouter, shallowWithRouter } from '../../../lib/helper/enzyme_helpers';
+import { renderWithRouter, shallowWithRouter } from '../../../lib';
import * as redux from 'react-redux';
import moment from 'moment';
import { IHttpFetchError } from '../../../../../../../src/core/public';
diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.test.tsx
index 39c6d6bd9215d..d044ad4e6a3a2 100644
--- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.test.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.test.tsx
@@ -9,7 +9,7 @@ import 'jest';
import React from 'react';
import { MonitorListDrawerComponent } from './monitor_list_drawer';
import { MonitorDetails, MonitorSummary, makePing } from '../../../../../common/runtime_types';
-import { shallowWithRouter } from '../../../../lib/helper/enzyme_helpers';
+import { shallowWithRouter } from '../../../../lib';
describe('MonitorListDrawer component', () => {
let summary: MonitorSummary;
diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/status_filter.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/status_filter.test.tsx
index c2515ab55b126..bbc4e13c9eca2 100644
--- a/x-pack/plugins/uptime/public/components/overview/monitor_list/status_filter.test.tsx
+++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/status_filter.test.tsx
@@ -10,8 +10,8 @@ import {
mountWithRouter,
renderWithRouter,
shallowWithRouter,
-} from '../../../lib/helper/enzyme_helpers';
-import { MountWithReduxProvider } from '../../../lib/helper/helper_with_redux';
+ MountWithReduxProvider,
+} from '../../../lib';
import { createMemoryHistory } from 'history';
import { StatusFilter } from './status_filter';
import { FilterStatusButton } from './filter_status_button';
diff --git a/x-pack/plugins/uptime/public/components/settings/certificate_form.test.tsx b/x-pack/plugins/uptime/public/components/settings/certificate_form.test.tsx
index 051c4166d0fdd..84c9923bfc419 100644
--- a/x-pack/plugins/uptime/public/components/settings/certificate_form.test.tsx
+++ b/x-pack/plugins/uptime/public/components/settings/certificate_form.test.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { CertificateExpirationForm } from './certificate_form';
-import { shallowWithRouter, mountWithRouter } from '../../lib/helper/enzyme_helpers';
+import { shallowWithRouter, mountWithRouter } from '../../lib';
describe('CertificateForm', () => {
it('shallow renders expected elements for valid props', () => {
diff --git a/x-pack/plugins/uptime/public/components/settings/indices_form.test.tsx b/x-pack/plugins/uptime/public/components/settings/indices_form.test.tsx
index fc2567ea98c45..67ca142d8a8ea 100644
--- a/x-pack/plugins/uptime/public/components/settings/indices_form.test.tsx
+++ b/x-pack/plugins/uptime/public/components/settings/indices_form.test.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { IndicesForm } from './indices_form';
-import { shallowWithRouter } from '../../lib/helper/enzyme_helpers';
+import { shallowWithRouter } from '../../lib';
describe('CertificateForm', () => {
it('shallow renders expected elements for valid props', () => {
diff --git a/x-pack/plugins/uptime/public/hooks/use_breadcrumbs.test.tsx b/x-pack/plugins/uptime/public/hooks/use_breadcrumbs.test.tsx
index 7aeac9706af58..6fc98fbaf1f5b 100644
--- a/x-pack/plugins/uptime/public/hooks/use_breadcrumbs.test.tsx
+++ b/x-pack/plugins/uptime/public/hooks/use_breadcrumbs.test.tsx
@@ -8,11 +8,10 @@
import { ChromeBreadcrumb } from 'kibana/public';
import React from 'react';
import { Route } from 'react-router-dom';
-import { mountWithRouter } from '../lib/helper/enzyme_helpers';
+import { mountWithRouter } from '../lib';
import { OVERVIEW_ROUTE } from '../../common/constants';
import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public';
-import { UptimeUrlParams, getSupportedUrlParams } from '../lib/helper';
-import { MountWithReduxProvider } from '../lib/helper/helper_with_redux';
+import { UptimeUrlParams, getSupportedUrlParams, MountWithReduxProvider } from '../lib/helper';
import { makeBaseBreadcrumb, useBreadcrumbs } from './use_breadcrumbs';
describe('useBreadcrumbs', () => {
diff --git a/x-pack/plugins/uptime/public/hooks/use_url_params.test.tsx b/x-pack/plugins/uptime/public/hooks/use_url_params.test.tsx
index 31580ec22d48c..3ce112b1cb835 100644
--- a/x-pack/plugins/uptime/public/hooks/use_url_params.test.tsx
+++ b/x-pack/plugins/uptime/public/hooks/use_url_params.test.tsx
@@ -9,8 +9,7 @@ import DateMath from '@elastic/datemath';
import React, { useState, Fragment } from 'react';
import { useUrlParams, UptimeUrlParamsHook } from './use_url_params';
import { UptimeRefreshContext } from '../contexts';
-import { MountWithReduxProvider } from '../lib/helper/helper_with_redux';
-import { mountWithRouter } from '../lib/helper/enzyme_helpers';
+import { mountWithRouter, MountWithReduxProvider } from '../lib';
import { createMemoryHistory } from 'history';
interface MockUrlParamsComponentProps {
diff --git a/x-pack/plugins/uptime/public/lib/helper/index.ts b/x-pack/plugins/uptime/public/lib/helper/index.ts
index 6546b5f9ae6c4..2fce3cc0e54dc 100644
--- a/x-pack/plugins/uptime/public/lib/helper/index.ts
+++ b/x-pack/plugins/uptime/public/lib/helper/index.ts
@@ -10,3 +10,4 @@ export * from './observability_integration';
export { getChartDateLabel } from './charts';
export { seriesHasDownValues } from './series_has_down_values';
export { UptimeUrlParams, getSupportedUrlParams } from './url_params';
+export { MountWithReduxProvider } from './helper_with_redux';
diff --git a/x-pack/plugins/uptime/public/lib/index.ts b/x-pack/plugins/uptime/public/lib/index.ts
new file mode 100644
index 0000000000000..9added9af6592
--- /dev/null
+++ b/x-pack/plugins/uptime/public/lib/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 { MountWithReduxProvider } from './helper';
+export * from './helper/enzyme_helpers';
diff --git a/x-pack/plugins/uptime/public/pages/certificates.test.tsx b/x-pack/plugins/uptime/public/pages/certificates.test.tsx
index 1218a1882b3bf..ff5f1afcaa290 100644
--- a/x-pack/plugins/uptime/public/pages/certificates.test.tsx
+++ b/x-pack/plugins/uptime/public/pages/certificates.test.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { shallowWithRouter } from '../lib/helper/enzyme_helpers';
+import { shallowWithRouter } from '../lib';
import { CertificatesPage } from './certificates';
describe('CertificatesPage', () => {
diff --git a/x-pack/plugins/uptime/public/pages/monitor.test.tsx b/x-pack/plugins/uptime/public/pages/monitor.test.tsx
index 2664f73d26075..80fcfcc271964 100644
--- a/x-pack/plugins/uptime/public/pages/monitor.test.tsx
+++ b/x-pack/plugins/uptime/public/pages/monitor.test.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { MonitorPage } from './monitor';
-import { shallowWithRouter } from '../lib/helper/enzyme_helpers';
+import { shallowWithRouter } from '../lib';
describe('MonitorPage', () => {
it('shallow renders expected elements for valid props', () => {
diff --git a/x-pack/plugins/uptime/public/pages/not_found.test.tsx b/x-pack/plugins/uptime/public/pages/not_found.test.tsx
index cc9ea1a62cd0f..8d5b20e45303d 100644
--- a/x-pack/plugins/uptime/public/pages/not_found.test.tsx
+++ b/x-pack/plugins/uptime/public/pages/not_found.test.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { shallowWithRouter } from '../lib/helper/enzyme_helpers';
+import { shallowWithRouter } from '../lib';
import { NotFoundPage } from './not_found';
describe('NotFoundPage', () => {
diff --git a/x-pack/plugins/uptime/public/pages/overview.test.tsx b/x-pack/plugins/uptime/public/pages/overview.test.tsx
index b4949a84a6e36..cfc140e6b22a3 100644
--- a/x-pack/plugins/uptime/public/pages/overview.test.tsx
+++ b/x-pack/plugins/uptime/public/pages/overview.test.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { OverviewPageComponent } from './overview';
-import { shallowWithRouter } from '../lib/helper/enzyme_helpers';
+import { shallowWithRouter } from '../lib';
describe('MonitorPage', () => {
const indexPattern = {
diff --git a/x-pack/plugins/uptime/tsconfig.json b/x-pack/plugins/uptime/tsconfig.json
index 0b98204001753..531ee2ecd8d2b 100644
--- a/x-pack/plugins/uptime/tsconfig.json
+++ b/x-pack/plugins/uptime/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
@@ -12,6 +12,7 @@
"public/**/*",
"public/components/monitor/status_details/location_map/embeddables/low_poly_layer.json",
"server/**/*",
+ "server/lib/requests/__fixtures__/monitor_charts_mock.json",
"../../../typings/**/*"
],
"references": [
diff --git a/x-pack/plugins/watcher/tsconfig.json b/x-pack/plugins/watcher/tsconfig.json
index 41bcb015d2d94..e8dabe8cd40a9 100644
--- a/x-pack/plugins/watcher/tsconfig.json
+++ b/x-pack/plugins/watcher/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
diff --git a/x-pack/plugins/xpack_legacy/tsconfig.json b/x-pack/plugins/xpack_legacy/tsconfig.json
index fdac21a391313..3bfc78b72cb3e 100644
--- a/x-pack/plugins/xpack_legacy/tsconfig.json
+++ b/x-pack/plugins/xpack_legacy/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../../tsconfig.project.json",
+ "extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./target/types",
From 2eae0969cbfe81ceb42b4d5e1146a2f172062ecd Mon Sep 17 00:00:00 2001
From: Nathan Reese
Date: Mon, 5 Apr 2021 13:39:15 -0600
Subject: [PATCH 010/131] [file upload] document file upload privileges and
provide actionable UI when failures occur (#95883)
* [file upload] document file upload privileges and provide actionable UI when failures occur
* doc link
* call hasImportPermission
* docs tweeks
* tslint
* Update docs/maps/import-geospatial-data.asciidoc
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
* Update docs/maps/import-geospatial-data.asciidoc
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
* Update docs/maps/import-geospatial-data.asciidoc
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
* Update docs/maps/import-geospatial-data.asciidoc
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
* review feedback
* fix bullet list format
* clean-up i18n ids
* Update docs/maps/import-geospatial-data.asciidoc
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
* documenation review feedback
* add period to last privilege bullet item
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
docs/maps/import-geospatial-data.asciidoc | 24 ++++
.../public/doc_links/doc_links_service.ts | 1 +
x-pack/plugins/file_upload/common/types.ts | 5 +-
.../components/import_complete_view.tsx | 133 +++++++++++++-----
.../components/json_upload_and_parse.tsx | 26 ++++
.../file_upload/public/kibana_services.ts | 1 +
.../translations/translations/ja-JP.json | 4 -
.../translations/translations/zh-CN.json | 4 -
8 files changed, 154 insertions(+), 44 deletions(-)
diff --git a/docs/maps/import-geospatial-data.asciidoc b/docs/maps/import-geospatial-data.asciidoc
index fb4250368086e..0218bac58815a 100644
--- a/docs/maps/import-geospatial-data.asciidoc
+++ b/docs/maps/import-geospatial-data.asciidoc
@@ -6,6 +6,30 @@ To import geospatical data into the Elastic Stack, the data must be indexed as {
Geospatial data comes in many formats.
Choose an import tool based on the format of your geospatial data.
+[discrete]
+[[import-geospatial-privileges]]
+=== Security privileges
+
+The {stack-security-features} provide roles and privileges that control which users can upload files.
+You can manage your roles, privileges, and
+spaces in **{stack-manage-app}** in {kib}. For more information, see
+{ref}/security-privileges.html[Security privileges],
+<>, and <>.
+
+To upload GeoJSON files in {kib} with *Maps*, you must have:
+
+* The `all` {kib} privilege for *Maps*.
+* The `all` {kib} privilege for *Index Pattern Management*.
+* The `create` and `create_index` index privileges for destination indices.
+* To use the index in *Maps*, you must also have the `read` and `view_index_metadata` index privileges for destination indices.
+
+To upload CSV files in {kib} with the *{file-data-viz}*, you must have privileges to upload GeoJSON files and:
+
+* The `manage_pipeline` cluster privilege.
+* The `read` {kib} privilege for *Machine Learning*.
+* The `machine_learning_admin` or `machine_learning_user` role.
+
+
[discrete]
=== Upload CSV with latitude and longitude columns
diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts
index a946640f58b0d..b179c998f1126 100644
--- a/src/core/public/doc_links/doc_links_service.ts
+++ b/src/core/public/doc_links/doc_links_service.ts
@@ -216,6 +216,7 @@ export class DocLinksService {
},
maps: {
guide: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/maps.html`,
+ importGeospatialPrivileges: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/import-geospatial-data.html#import-geospatial-privileges`,
},
monitoring: {
alertsKibana: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/kibana-alerts.html`,
diff --git a/x-pack/plugins/file_upload/common/types.ts b/x-pack/plugins/file_upload/common/types.ts
index 0fc59e2b525a8..11cf4ac3615bf 100644
--- a/x-pack/plugins/file_upload/common/types.ts
+++ b/x-pack/plugins/file_upload/common/types.ts
@@ -5,6 +5,7 @@
* 2.0.
*/
+import type { estypes } from '@elastic/elasticsearch';
import { ES_FIELD_TYPES } from '../../../../src/plugins/data/common';
export interface HasImportPermission {
@@ -83,7 +84,9 @@ export interface ImportResponse {
pipelineId?: string;
docCount: number;
failures: ImportFailure[];
- error?: any;
+ error?: {
+ error: estypes.ErrorCause;
+ };
ingestError?: boolean;
}
diff --git a/x-pack/plugins/file_upload/public/components/import_complete_view.tsx b/x-pack/plugins/file_upload/public/components/import_complete_view.tsx
index 29aed0cd52f7e..a3bc2ed082b1a 100644
--- a/x-pack/plugins/file_upload/public/components/import_complete_view.tsx
+++ b/x-pack/plugins/file_upload/public/components/import_complete_view.tsx
@@ -7,19 +7,20 @@
import React, { Component, Fragment } from 'react';
import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiButtonIcon,
EuiCallOut,
EuiCopy,
EuiFlexGroup,
EuiFlexItem,
+ EuiLink,
EuiSpacer,
EuiText,
EuiTitle,
} from '@elastic/eui';
-import { FormattedMessage } from '@kbn/i18n/react';
import { CodeEditor, KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public';
-import { getHttp, getUiSettings } from '../kibana_services';
+import { getDocLinks, getHttp, getUiSettings } from '../kibana_services';
import { ImportResults } from '../importer';
const services = {
@@ -27,8 +28,10 @@ const services = {
};
interface Props {
+ failedPermissionCheck: boolean;
importResults?: ImportResults;
indexPatternResp?: object;
+ indexName: string;
}
export class ImportCompleteView extends Component {
@@ -57,9 +60,12 @@ export class ImportCompleteView extends Component {
iconType="copy"
color="text"
data-test-subj={copyButtonDataTestSubj}
- aria-label={i18n.translate('xpack.fileUpload.copyButtonAriaLabel', {
- defaultMessage: 'Copy to clipboard',
- })}
+ aria-label={i18n.translate(
+ 'xpack.fileUpload.importComplete.copyButtonAriaLabel',
+ {
+ defaultMessage: 'Copy to clipboard',
+ }
+ )}
/>
)}
@@ -90,21 +96,65 @@ export class ImportCompleteView extends Component {
}
_getStatusMsg() {
+ if (this.props.failedPermissionCheck) {
+ return (
+
+
+ {i18n.translate('xpack.fileUpload.importComplete.permissionFailureMsg', {
+ defaultMessage:
+ 'You do not have permission to create or import data into index "{indexName}".',
+ values: { indexName: this.props.indexName },
+ })}
+
+
+ {i18n.translate('xpack.fileUpload.importComplete.permission.docLink', {
+ defaultMessage: 'View file import permissions',
+ })}
+
+
+ );
+ }
+
if (!this.props.importResults || !this.props.importResults.success) {
- return i18n.translate('xpack.fileUpload.uploadFailureMsg', {
- defaultMessage: 'File upload failed.',
- });
+ const errorMsg =
+ this.props.importResults && this.props.importResults.error
+ ? i18n.translate('xpack.fileUpload.importComplete.uploadFailureMsgErrorBlock', {
+ defaultMessage: 'Error: {reason}',
+ values: { reason: this.props.importResults.error.error.reason },
+ })
+ : '';
+ return (
+
+ {errorMsg}
+
+ );
}
- const successMsg = i18n.translate('xpack.fileUpload.uploadSuccessMsg', {
- defaultMessage: 'File upload complete: indexed {numFeatures} features.',
+ const successMsg = i18n.translate('xpack.fileUpload.importComplete.uploadSuccessMsg', {
+ defaultMessage: 'Indexed {numFeatures} features.',
values: {
numFeatures: this.props.importResults.docCount,
},
});
const failedFeaturesMsg = this.props.importResults.failures?.length
- ? i18n.translate('xpack.fileUpload.failedFeaturesMsg', {
+ ? i18n.translate('xpack.fileUpload.importComplete.failedFeaturesMsg', {
defaultMessage: 'Unable to index {numFailures} features.',
values: {
numFailures: this.props.importResults.failures.length,
@@ -112,47 +162,60 @@ export class ImportCompleteView extends Component {
})
: '';
- return `${successMsg} ${failedFeaturesMsg}`;
+ return (
+
+ {`${successMsg} ${failedFeaturesMsg}`}
+
+ );
+ }
+
+ _renderIndexManagementMsg() {
+ return this.props.importResults && this.props.importResults.success ? (
+
+
+
+
+
+
+
+
+ ) : null;
}
render() {
return (
-
- {this._getStatusMsg()}
-
+ {this._getStatusMsg()}
+
{this._renderCodeEditor(
this.props.importResults,
- i18n.translate('xpack.fileUpload.jsonImport.indexingResponse', {
+ i18n.translate('xpack.fileUpload.importComplete.indexingResponse', {
defaultMessage: 'Import response',
}),
'indexRespCopyButton'
)}
{this._renderCodeEditor(
this.props.indexPatternResp,
- i18n.translate('xpack.fileUpload.jsonImport.indexPatternResponse', {
+ i18n.translate('xpack.fileUpload.importComplete.indexPatternResponse', {
defaultMessage: 'Index pattern response',
}),
'indexPatternRespCopyButton'
)}
-
-
-
+ {this._renderIndexManagementMsg()}
);
}
diff --git a/x-pack/plugins/file_upload/public/components/json_upload_and_parse.tsx b/x-pack/plugins/file_upload/public/components/json_upload_and_parse.tsx
index 371d68443bc2c..d73c6e9c5fb3a 100644
--- a/x-pack/plugins/file_upload/public/components/json_upload_and_parse.tsx
+++ b/x-pack/plugins/file_upload/public/components/json_upload_and_parse.tsx
@@ -16,6 +16,7 @@ import { FileUploadComponentProps } from '../lazy_load_bundle';
import { ImportResults } from '../importer';
import { GeoJsonImporter } from '../importer/geojson_importer';
import { Settings } from '../../common';
+import { hasImportPermission } from '../api';
enum PHASE {
CONFIGURE = 'CONFIGURE',
@@ -31,6 +32,7 @@ function getWritingToIndexMsg(progress: number) {
}
interface State {
+ failedPermissionCheck: boolean;
geoFieldType: ES_FIELD_TYPES.GEO_POINT | ES_FIELD_TYPES.GEO_SHAPE;
importStatus: string;
importResults?: ImportResults;
@@ -45,6 +47,7 @@ export class JsonUploadAndParse extends Component
);
}
diff --git a/x-pack/plugins/file_upload/public/kibana_services.ts b/x-pack/plugins/file_upload/public/kibana_services.ts
index a604136ca34e4..dfe2785e7a2bc 100644
--- a/x-pack/plugins/file_upload/public/kibana_services.ts
+++ b/x-pack/plugins/file_upload/public/kibana_services.ts
@@ -15,6 +15,7 @@ export function setStartServices(core: CoreStart, plugins: FileUploadStartDepend
pluginsStart = plugins;
}
+export const getDocLinks = () => coreStart.docLinks;
export const getIndexPatternService = () => pluginsStart.data.indexPatterns;
export const getHttp = () => coreStart.http;
export const getSavedObjectsClient = () => coreStart.savedObjects.client;
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 6dc490b4ffc53..dc038c1a7959d 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -8169,10 +8169,6 @@
"xpack.fileUpload.indexSettings.indexNameAlreadyExistsErrorMessage": "インデックス名またはパターンはすでに存在します。",
"xpack.fileUpload.indexSettings.indexNameContainsIllegalCharactersErrorMessage": "インデックス名に許可されていない文字が含まれています。",
"xpack.fileUpload.indexSettings.indexNameGuidelines": "インデックス名ガイドライン",
- "xpack.fileUpload.jsonImport.indexingResponse": "インデックス応答",
- "xpack.fileUpload.jsonImport.indexMgmtLink": "インデックス管理",
- "xpack.fileUpload.jsonImport.indexModsMsg": "次を使用すると、その他のインデックス修正を行うことができます。\n",
- "xpack.fileUpload.jsonImport.indexPatternResponse": "インデックスパターン応答",
"xpack.fileUpload.jsonUploadAndParse.dataIndexingError": "データインデックスエラー",
"xpack.fileUpload.jsonUploadAndParse.indexPatternError": "インデックスパターンエラー",
"xpack.fleet.agentBulkActions.clearSelection": "選択した項目をクリア",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 32574690b13f2..117c33a286d88 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -8242,10 +8242,6 @@
"xpack.fileUpload.indexSettings.indexNameAlreadyExistsErrorMessage": "索引名称或模式已存在。",
"xpack.fileUpload.indexSettings.indexNameContainsIllegalCharactersErrorMessage": "索引名称包含非法字符。",
"xpack.fileUpload.indexSettings.indexNameGuidelines": "索引名称指引",
- "xpack.fileUpload.jsonImport.indexingResponse": "索引响应",
- "xpack.fileUpload.jsonImport.indexMgmtLink": "索引管理",
- "xpack.fileUpload.jsonImport.indexModsMsg": "要进一步做索引修改,可以使用\n",
- "xpack.fileUpload.jsonImport.indexPatternResponse": "索引模式响应",
"xpack.fileUpload.jsonUploadAndParse.dataIndexingError": "数据索引错误",
"xpack.fileUpload.jsonUploadAndParse.indexPatternError": "索引模式错误",
"xpack.fleet.agentBulkActions.agentsSelected": "已选择 {count, plural, other {# 个代理}}",
From f9917a6c8a9d8cf41642e696e959e07ca4455f28 Mon Sep 17 00:00:00 2001
From: Clint Andrew Hall
Date: Mon, 5 Apr 2021 15:28:15 -0500
Subject: [PATCH 011/131] Add Input Controls project configuration (#96238)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.github/workflows/project-assigner.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/project-assigner.yml b/.github/workflows/project-assigner.yml
index d9d2d6d1ddb8b..37d04abda7530 100644
--- a/.github/workflows/project-assigner.yml
+++ b/.github/workflows/project-assigner.yml
@@ -11,7 +11,7 @@ jobs:
uses: elastic/github-actions/project-assigner@v2.0.0
id: project_assigner
with:
- issue-mappings: '[{"label": "Feature:Lens", "projectNumber": 32, "columnName": "Long-term goals"}, {"label": "Feature:Canvas", "projectNumber": 38, "columnName": "Inbox"}, {"label": "Feature:Dashboard", "projectNumber": 68, "columnName": "Inbox"}, {"label": "Feature:Drilldowns", "projectNumber": 68, "columnName": "Inbox"}]'
+ issue-mappings: '[{"label": "Feature:Lens", "projectNumber": 32, "columnName": "Long-term goals"}, {"label": "Feature:Canvas", "projectNumber": 38, "columnName": "Inbox"}, {"label": "Feature:Dashboard", "projectNumber": 68, "columnName": "Inbox"}, {"label": "Feature:Drilldowns", "projectNumber": 68, "columnName": "Inbox"}], {"label": "Feature:Input Controls", "projectNumber": 72, "columnName": "Inbox"}]'
ghToken: ${{ secrets.PROJECT_ASSIGNER_TOKEN }}
From 5667435c382a49fa92df0a2acbc27fdb07b49192 Mon Sep 17 00:00:00 2001
From: Clint Andrew Hall
Date: Mon, 5 Apr 2021 15:32:29 -0500
Subject: [PATCH 012/131] [tech-debt] Remove defunct opacity parameters from
EUI shadow functions (#96191)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../canvas/public/components/page_manager/page_manager.scss | 2 +-
.../canvas/public/components/workpad_page/workpad_page.scss | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/x-pack/plugins/canvas/public/components/page_manager/page_manager.scss b/x-pack/plugins/canvas/public/components/page_manager/page_manager.scss
index 2ed6884542b18..620e0eb113d36 100644
--- a/x-pack/plugins/canvas/public/components/page_manager/page_manager.scss
+++ b/x-pack/plugins/canvas/public/components/page_manager/page_manager.scss
@@ -66,7 +66,7 @@
text-decoration: none;
.canvasPageManager__pagePreview {
- @include euiBottomShadowMedium($opacity: .3);
+ @include euiBottomShadowMedium;
}
.canvasPageManager__controls {
diff --git a/x-pack/plugins/canvas/public/components/workpad_page/workpad_page.scss b/x-pack/plugins/canvas/public/components/workpad_page/workpad_page.scss
index 9266273406b84..e770f10927552 100644
--- a/x-pack/plugins/canvas/public/components/workpad_page/workpad_page.scss
+++ b/x-pack/plugins/canvas/public/components/workpad_page/workpad_page.scss
@@ -1,5 +1,5 @@
.canvasPage {
- @include euiBottomShadowFlat($opacity: .4);
+ @include euiBottomShadowFlat;
z-index: initial;
position: absolute;
top: 0;
From 56d9f3d96832f67283ee4a35e306f89fa59ad2f4 Mon Sep 17 00:00:00 2001
From: Constance
Date: Mon, 5 Apr 2021 13:48:00 -0700
Subject: [PATCH 013/131] [App Search] API logs: Add log detail flyout (#96162)
* Set up helper for showing JSON request/response bodies
* Set up mock API log obj for tests to use
* Add ApiLogLogic file for flyout handling
* Add ApiLogFlyout component
* Update views to load flyout
* Update table to open flyout
* Update x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts
* PR feedback: comments
Co-authored-by: Byron Hulcher
Co-authored-by: Byron Hulcher
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../api_logs/__mocks__/api_log.mock.ts | 17 +++
.../api_logs/api_log/api_log_flyout.test.tsx | 62 ++++++++
.../api_logs/api_log/api_log_flyout.tsx | 137 ++++++++++++++++++
.../api_logs/api_log/api_log_logic.test.tsx | 57 ++++++++
.../api_logs/api_log/api_log_logic.ts | 44 ++++++
.../components/api_logs/api_log/index.ts | 9 ++
.../components/api_logs/api_logs.tsx | 2 +
.../api_logs/api_logs_logic.test.ts | 13 +-
.../components/api_logs_table.test.tsx | 3 +-
.../api_logs/components/api_logs_table.tsx | 4 +-
.../app_search/components/api_logs/index.ts | 1 +
.../components/api_logs/utils.test.ts | 21 ++-
.../app_search/components/api_logs/utils.ts | 10 ++
.../components/recent_api_logs.tsx | 3 +-
14 files changed, 368 insertions(+), 15 deletions(-)
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/__mocks__/api_log.mock.ts
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.ts
create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/__mocks__/api_log.mock.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/__mocks__/api_log.mock.ts
new file mode 100644
index 0000000000000..6106cb049c7a1
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/__mocks__/api_log.mock.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 const mockApiLog = {
+ timestamp: '1970-01-01T12:00:00.000Z',
+ http_method: 'POST',
+ status: 200,
+ user_agent: 'Mozilla/5.0',
+ full_request_path: '/api/as/v1/engines/national-parks-demo/search.json',
+ request_body: '{"query":"test search"}',
+ response_body:
+ '{"meta":{"page":{"current":1,"total_pages":0,"total_results":0,"size":20}},"results":[]}',
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx
new file mode 100644
index 0000000000000..6bebeee80465c
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.test.tsx
@@ -0,0 +1,62 @@
+/*
+ * 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 { setMockValues, setMockActions } from '../../../../__mocks__';
+import { mockApiLog } from '../__mocks__/api_log.mock';
+
+import React from 'react';
+
+import { shallow } from 'enzyme';
+
+import { EuiFlyout, EuiBadge } from '@elastic/eui';
+
+import { ApiLogFlyout, ApiLogHeading } from './api_log_flyout';
+
+describe('ApiLogFlyout', () => {
+ const values = {
+ isFlyoutOpen: true,
+ apiLog: mockApiLog,
+ };
+ const actions = {
+ closeFlyout: jest.fn(),
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ setMockValues(values);
+ setMockActions(actions);
+ });
+
+ it('renders', () => {
+ const wrapper = shallow();
+
+ expect(wrapper.find('h2').text()).toEqual('Request details');
+ expect(wrapper.find(ApiLogHeading).last().dive().find('h3').text()).toEqual('Response body');
+ expect(wrapper.find(EuiBadge).prop('children')).toEqual('POST');
+ });
+
+ it('closes the flyout', () => {
+ const wrapper = shallow();
+
+ wrapper.find(EuiFlyout).simulate('close');
+ expect(actions.closeFlyout).toHaveBeenCalled();
+ });
+
+ it('does not render if the flyout is not open', () => {
+ setMockValues({ ...values, isFlyoutOpen: false });
+ const wrapper = shallow();
+
+ expect(wrapper.isEmptyRender()).toBe(true);
+ });
+
+ it('does not render if a current apiLog has not been set', () => {
+ setMockValues({ ...values, apiLog: null });
+ const wrapper = shallow();
+
+ expect(wrapper.isEmptyRender()).toBe(true);
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx
new file mode 100644
index 0000000000000..dd53e997da0f7
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_flyout.tsx
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+/*
+ * 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 { useActions, useValues } from 'kea';
+
+import {
+ EuiPortal,
+ EuiFlyout,
+ EuiFlyoutHeader,
+ EuiTitle,
+ EuiFlyoutBody,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiSpacer,
+ EuiBadge,
+ EuiHealth,
+ EuiText,
+ EuiCode,
+ EuiCodeBlock,
+} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+
+import { getStatusColor, attemptToFormatJson } from '../utils';
+
+import { ApiLogLogic } from './';
+
+export const ApiLogFlyout: React.FC = () => {
+ const { isFlyoutOpen, apiLog } = useValues(ApiLogLogic);
+ const { closeFlyout } = useActions(ApiLogLogic);
+
+ if (!isFlyoutOpen) return null;
+ if (!apiLog) return null;
+
+ return (
+
+
+
+
+
+ {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.flyout.title', {
+ defaultMessage: 'Request details',
+ })}
+
+
+
+
+
+
+
+ {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.methodTitle', {
+ defaultMessage: 'Method',
+ })}
+
+
+ {apiLog.http_method}
+
+
+
+
+ {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.statusTitle', {
+ defaultMessage: 'Status',
+ })}
+
+ {apiLog.status}
+
+
+
+ {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.timestampTitle', {
+ defaultMessage: 'Timestamp',
+ })}
+
+ {apiLog.timestamp}
+
+
+
+
+
+ {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.userAgentTitle', {
+ defaultMessage: 'User agent',
+ })}
+
+
+ {apiLog.user_agent}
+
+
+
+
+ {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.requestPathTitle', {
+ defaultMessage: 'Request path',
+ })}
+
+
+ {apiLog.full_request_path}
+
+
+
+
+ {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.requestBodyTitle', {
+ defaultMessage: 'Request body',
+ })}
+
+
+ {attemptToFormatJson(apiLog.request_body)}
+
+
+
+
+ {i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.responseBodyTitle', {
+ defaultMessage: 'Response body',
+ })}
+
+
+ {attemptToFormatJson(apiLog.response_body)}
+
+
+
+
+ );
+};
+
+export const ApiLogHeading: React.FC = ({ children }) => (
+
+ {children}
+
+);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx
new file mode 100644
index 0000000000000..2b7ca7510e8e1
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.test.tsx
@@ -0,0 +1,57 @@
+/*
+ * 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 { LogicMounter } from '../../../../__mocks__';
+import { mockApiLog } from '../__mocks__/api_log.mock';
+
+import { ApiLogLogic } from './';
+
+describe('ApiLogLogic', () => {
+ const { mount } = new LogicMounter(ApiLogLogic);
+
+ const DEFAULT_VALUES = {
+ isFlyoutOpen: false,
+ apiLog: null,
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('has expected default values', () => {
+ mount();
+ expect(ApiLogLogic.values).toEqual(DEFAULT_VALUES);
+ });
+
+ describe('actions', () => {
+ describe('openFlyout', () => {
+ it('sets isFlyoutOpen to true & sets the current apiLog', () => {
+ mount({ isFlyoutOpen: false, apiLog: null });
+ ApiLogLogic.actions.openFlyout(mockApiLog);
+
+ expect(ApiLogLogic.values).toEqual({
+ ...DEFAULT_VALUES,
+ isFlyoutOpen: true,
+ apiLog: mockApiLog,
+ });
+ });
+ });
+
+ describe('closeFlyout', () => {
+ it('sets isFlyoutOpen to false & resets the current apiLog', () => {
+ mount({ isFlyoutOpen: true, apiLog: mockApiLog });
+ ApiLogLogic.actions.closeFlyout();
+
+ expect(ApiLogLogic.values).toEqual({
+ ...DEFAULT_VALUES,
+ isFlyoutOpen: false,
+ apiLog: null,
+ });
+ });
+ });
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.ts
new file mode 100644
index 0000000000000..8b7c5f70f605c
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/api_log_logic.ts
@@ -0,0 +1,44 @@
+/*
+ * 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 { kea, MakeLogicType } from 'kea';
+
+import { ApiLog } from '../types';
+
+interface ApiLogValues {
+ isFlyoutOpen: boolean;
+ apiLog: ApiLog | null;
+}
+
+interface ApiLogActions {
+ openFlyout(apiLog: ApiLog): { apiLog: ApiLog };
+ closeFlyout(): void;
+}
+
+export const ApiLogLogic = kea>({
+ path: ['enterprise_search', 'app_search', 'api_log_logic'],
+ actions: () => ({
+ openFlyout: (apiLog) => ({ apiLog }),
+ closeFlyout: true,
+ }),
+ reducers: () => ({
+ isFlyoutOpen: [
+ false,
+ {
+ openFlyout: () => true,
+ closeFlyout: () => false,
+ },
+ ],
+ apiLog: [
+ null,
+ {
+ openFlyout: (_, { apiLog }) => apiLog,
+ closeFlyout: () => null,
+ },
+ ],
+ }),
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/index.ts
new file mode 100644
index 0000000000000..dcf949d9bf222
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_log/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 { ApiLogFlyout } from './api_log_flyout';
+export { ApiLogLogic } from './api_log_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.tsx
index 8ca15906783f9..4690911fad772 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs.tsx
@@ -26,6 +26,7 @@ import { Loading } from '../../../shared/loading';
import { LogRetentionCallout, LogRetentionTooltip, LogRetentionOptions } from '../log_retention';
+import { ApiLogFlyout } from './api_log';
import { ApiLogsTable, NewApiEventsPrompt } from './components';
import { API_LOGS_TITLE, RECENT_API_EVENTS } from './constants';
@@ -75,6 +76,7 @@ export const ApiLogs: React.FC = ({ engineBreadcrumb }) => {
+
>
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts
index 7b3ee80668ac7..2eda4c6323fa5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/api_logs_logic.test.ts
@@ -6,6 +6,7 @@
*/
import { LogicMounter, mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__';
+import { mockApiLog } from './__mocks__/api_log.mock';
import '../../__mocks__/engine_logic.mock';
import { nextTick } from '@kbn/test/jest';
@@ -29,17 +30,7 @@ describe('ApiLogsLogic', () => {
};
const MOCK_API_RESPONSE = {
- results: [
- {
- timestamp: '1970-01-01T12:00:00.000Z',
- http_method: 'POST',
- status: 200,
- user_agent: 'some browser agent string',
- full_request_path: '/api/as/v1/engines/national-parks-demo/search.json',
- request_body: '{"someMockRequest":"hello"}',
- response_body: '{"someMockResponse":"world"}',
- },
- ],
+ results: [mockApiLog, mockApiLog],
meta: {
page: {
current: 1,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx
index 99fce81ca348f..768295ec1389c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.test.tsx
@@ -53,6 +53,7 @@ describe('ApiLogsTable', () => {
};
const actions = {
onPaginate: jest.fn(),
+ openFlyout: jest.fn(),
};
beforeEach(() => {
@@ -86,7 +87,7 @@ describe('ApiLogsTable', () => {
expect(wrapper.find(EuiButtonEmpty)).toHaveLength(3);
wrapper.find('[data-test-subj="ApiLogsTableDetailsButton"]').first().simulate('click');
- // TODO: API log details flyout
+ expect(actions.openFlyout).toHaveBeenCalled();
});
it('renders an empty prompt if no items are passed', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx
index 8ebcc4350f7fc..5ecf8e1ba3330 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx
@@ -22,6 +22,7 @@ import { FormattedRelative } from '@kbn/i18n/react';
import { convertMetaToPagination, handlePageChange } from '../../../../shared/table_pagination';
+import { ApiLogLogic } from '../api_log';
import { ApiLogsLogic } from '../index';
import { ApiLog } from '../types';
import { getStatusColor } from '../utils';
@@ -34,6 +35,7 @@ interface Props {
export const ApiLogsTable: React.FC = ({ hasPagination }) => {
const { dataLoading, apiLogs, meta } = useValues(ApiLogsLogic);
const { onPaginate } = useActions(ApiLogsLogic);
+ const { openFlyout } = useActions(ApiLogLogic);
const columns: Array> = [
{
@@ -81,7 +83,7 @@ export const ApiLogsTable: React.FC = ({ hasPagination }) => {
size="s"
className="apiLogDetailButton"
data-test-subj="ApiLogsTableDetailsButton"
- // TODO: flyout onclick
+ onClick={() => openFlyout(apiLog)}
>
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.detailsButtonLabel', {
defaultMessage: 'Details',
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts
index 183956e51d8d4..568026dab231f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/index.ts
@@ -7,5 +7,6 @@
export { API_LOGS_TITLE } from './constants';
export { ApiLogsTable, NewApiEventsPrompt } from './components';
+export { ApiLogFlyout } from './api_log';
export { ApiLogs } from './api_logs';
export { ApiLogsLogic } from './api_logs_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts
index f9b6dcea2cbf3..ac464e2af353d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.test.ts
@@ -5,7 +5,9 @@
* 2.0.
*/
-import { getDateString, getStatusColor } from './utils';
+import dedent from 'dedent';
+
+import { getDateString, getStatusColor, attemptToFormatJson } from './utils';
describe('getDateString', () => {
const mockDate = jest
@@ -32,3 +34,20 @@ describe('getStatusColor', () => {
expect(getStatusColor(503)).toEqual('danger');
});
});
+
+describe('attemptToFormatJson', () => {
+ it('takes an unformatted JSON string and correctly newlines/indents it', () => {
+ expect(attemptToFormatJson('{"hello":"world","lorem":{"ipsum":"dolor","sit":"amet"}}'))
+ .toEqual(dedent`{
+ "hello": "world",
+ "lorem": {
+ "ipsum": "dolor",
+ "sit": "amet"
+ }
+ }`);
+ });
+
+ it('returns the original content if it is not properly formatted JSON', () => {
+ expect(attemptToFormatJson('{invalid json}')).toEqual('{invalid json}');
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts
index 3217a1561ce76..7e5f19686f13b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/utils.ts
@@ -19,3 +19,13 @@ export const getStatusColor = (status: number) => {
if (status >= 500) color = 'danger';
return color;
};
+
+export const attemptToFormatJson = (possibleJson: string) => {
+ try {
+ // it is JSON, we can format it with newlines/indentation
+ return JSON.stringify(JSON.parse(possibleJson), null, 2);
+ } catch {
+ // if it's not JSON, we return the original content
+ return possibleJson;
+ }
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx
index 3686f380407e2..18f27c3a1e834 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx
@@ -13,7 +13,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { EuiButtonEmptyTo } from '../../../../shared/react_router_helpers';
import { ENGINE_API_LOGS_PATH } from '../../../routes';
-import { ApiLogsLogic, ApiLogsTable, NewApiEventsPrompt } from '../../api_logs';
+import { ApiLogsLogic, ApiLogsTable, NewApiEventsPrompt, ApiLogFlyout } from '../../api_logs';
import { RECENT_API_EVENTS } from '../../api_logs/constants';
import { DataPanel } from '../../data_panel';
import { generateEnginePath } from '../../engine';
@@ -46,6 +46,7 @@ export const RecentApiLogs: React.FC = () => {
hasBorder
>
+
);
};
From 7da1b82b7ee07d94bee2dc2540a7161731e4c513 Mon Sep 17 00:00:00 2001
From: Rashmi Kulkarni
Date: Mon, 5 Apr 2021 15:24:22 -0700
Subject: [PATCH 014/131] fixes a skipped management x-pack test (#96178)
* fixes a skipped management x-pack test
* modified the test to incoroporate the review comments
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../management/users/edit_user/user_form.tsx | 5 ++++
.../functional/apps/security/management.js | 29 ++++++++++---------
.../functional/page_objects/security_page.ts | 5 ++++
3 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/x-pack/plugins/security/public/management/users/edit_user/user_form.tsx b/x-pack/plugins/security/public/management/users/edit_user/user_form.tsx
index 8433f54a73343..29d87e31797cc 100644
--- a/x-pack/plugins/security/public/management/users/edit_user/user_form.tsx
+++ b/x-pack/plugins/security/public/management/users/edit_user/user_form.tsx
@@ -262,6 +262,7 @@ export const UserForm: FunctionComponent = ({
>
= ({
>
= ({
>
= ({
>
= ({
>
{
- // await PageObjects.security.login('elastic', 'changeme');
await PageObjects.security.initTests();
await kibanaServer.uiSettings.update({
defaultIndex: 'logstash-*',
@@ -43,20 +44,26 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.settings.navigateTo();
});
+ after(async () => {
+ await security.role.delete('logstash-readonly');
+ await security.user.delete('dashuser', 'new-user');
+ await PageObjects.security.forceLogout();
+ });
+
describe('Security', () => {
describe('navigation', () => {
it('Can navigate to create user section', async () => {
await PageObjects.security.clickElasticsearchUsers();
await PageObjects.security.clickCreateNewUser();
const currentUrl = await browser.getCurrentUrl();
- expect(currentUrl).to.contain(EDIT_USERS_PATH);
+ expect(currentUrl).to.contain(CREATE_USERS_PATH);
});
it('Clicking cancel in create user section brings user back to listing', async () => {
await PageObjects.security.clickCancelEditUser();
const currentUrl = await browser.getCurrentUrl();
expect(currentUrl).to.contain(USERS_PATH);
- expect(currentUrl).to.not.contain(EDIT_USERS_PATH);
+ expect(currentUrl).to.not.contain(CREATE_USERS_PATH);
});
it('Clicking save in create user section brings user back to listing', async () => {
@@ -67,12 +74,11 @@ export default function ({ getService, getPageObjects }) {
await testSubjects.setValue('passwordConfirmationInput', '123456');
await testSubjects.setValue('userFormFullNameInput', 'Full User Name');
await testSubjects.setValue('userFormEmailInput', 'example@example.com');
-
- await PageObjects.security.clickSaveEditUser();
+ await PageObjects.security.clickSaveCreateUser();
const currentUrl = await browser.getCurrentUrl();
expect(currentUrl).to.contain(USERS_PATH);
- expect(currentUrl).to.not.contain(EDIT_USERS_PATH);
+ expect(currentUrl).to.not.contain(CREATE_USERS_PATH);
});
it('Can navigate to edit user section', async () => {
@@ -143,14 +149,11 @@ export default function ({ getService, getPageObjects }) {
await testSubjects.setValue('passwordConfirmationInput', '123456');
await testSubjects.setValue('userFormFullNameInput', 'dashuser');
await testSubjects.setValue('userFormEmailInput', 'example@example.com');
- await PageObjects.security.assignRoleToUser('kibana_dashboard_only_user');
await PageObjects.security.assignRoleToUser('logstash-readonly');
-
- await PageObjects.security.clickSaveEditUser();
-
+ await PageObjects.security.clickSaveCreateUser();
await PageObjects.settings.navigateTo();
await testSubjects.click('users');
- await PageObjects.settings.clickLinkText('kibana_dashboard_only_user');
+ await find.clickByButtonText('logstash-readonly');
const currentUrl = await browser.getCurrentUrl();
expect(currentUrl).to.contain(EDIT_ROLES_PATH);
});
diff --git a/x-pack/test/functional/page_objects/security_page.ts b/x-pack/test/functional/page_objects/security_page.ts
index f153050018609..97a5c517db794 100644
--- a/x-pack/test/functional/page_objects/security_page.ts
+++ b/x-pack/test/functional/page_objects/security_page.ts
@@ -290,6 +290,11 @@ export function SecurityPageProvider({ getService, getPageObjects }: FtrProvider
await PageObjects.header.waitUntilLoadingHasFinished();
}
+ async clickSaveCreateUser() {
+ await find.clickByButtonText('Create user');
+ await PageObjects.header.waitUntilLoadingHasFinished();
+ }
+
async clickSaveEditRole() {
const saveButton = await retry.try(() => testSubjects.find('roleFormSaveButton'));
await saveButton.moveMouseTo();
From d4b0f92c84ea44c2de3e95385f666ca4c9feb61f Mon Sep 17 00:00:00 2001
From: Nick Partridge
Date: Mon, 5 Apr 2021 18:02:13 -0500
Subject: [PATCH 015/131] [Dashboard] Fix Lens and TSVB chart tooltip
positioning relative to global headers (#94247)
---
src/core/public/rendering/_base.scss | 14 ++++++++++++++
src/core/public/rendering/rendering_service.tsx | 1 +
.../visualizations/views/timeseries/index.js | 1 +
.../vis_type_xy/public/components/xy_settings.tsx | 4 +++-
.../public/pie_visualization/render_function.tsx | 2 ++
.../__snapshots__/expression.test.tsx.snap | 7 +++++++
.../lens/public/xy_visualization/expression.tsx | 2 +-
7 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/src/core/public/rendering/_base.scss b/src/core/public/rendering/_base.scss
index de13785a17f5b..ed2d9bc0b3917 100644
--- a/src/core/public/rendering/_base.scss
+++ b/src/core/public/rendering/_base.scss
@@ -11,6 +11,16 @@
min-height: 100%;
}
+#app-fixed-viewport {
+ pointer-events: none;
+ visibility: hidden;
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+}
+
.app-wrapper {
display: flex;
flex-flow: column nowrap;
@@ -35,6 +45,10 @@
@mixin kbnAffordForHeader($headerHeight) {
padding-top: $headerHeight;
+ #app-fixed-viewport {
+ top: $headerHeight;
+ }
+
.euiFlyout,
.euiCollapsibleNav {
top: $headerHeight;
diff --git a/src/core/public/rendering/rendering_service.tsx b/src/core/public/rendering/rendering_service.tsx
index 843f2a253f33e..787fa475c7d5f 100644
--- a/src/core/public/rendering/rendering_service.tsx
+++ b/src/core/public/rendering/rendering_service.tsx
@@ -52,6 +52,7 @@ export class RenderingService {
{chromeHeader}
+
{bannerComponent}
{appComponent}
diff --git a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js
index a90faea50f22a..2911a9ee5d6e9 100644
--- a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js
+++ b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js
@@ -149,6 +149,7 @@ export const TimeSeries = ({
tooltip={{
snap: true,
type: tooltipMode === 'show_focused' ? TooltipType.Follow : TooltipType.VerticalCursor,
+ boundary: document.getElementById('app-fixed-viewport') ?? undefined,
headerFormatter: tooltipFormatter,
}}
externalPointerEvents={{ tooltip: { visible: false } }}
diff --git a/src/plugins/vis_type_xy/public/components/xy_settings.tsx b/src/plugins/vis_type_xy/public/components/xy_settings.tsx
index 59bed0060a6a6..8922f512522a0 100644
--- a/src/plugins/vis_type_xy/public/components/xy_settings.tsx
+++ b/src/plugins/vis_type_xy/public/components/xy_settings.tsx
@@ -148,13 +148,15 @@ export const XYSettings: FC = ({
: headerValueFormatter &&
(tooltip.detailedTooltip ? undefined : ({ value }: any) => headerValueFormatter(value));
+ const boundary = document.getElementById('app-fixed-viewport') ?? undefined;
const tooltipProps: TooltipProps = tooltip.detailedTooltip
? {
...tooltip,
+ boundary,
customTooltip: tooltip.detailedTooltip(headerFormatter),
headerFormatter: undefined,
}
- : { ...tooltip, headerFormatter };
+ : { ...tooltip, boundary, headerFormatter };
return (
safeXAccessorLabelRenderer(d.value),
}}
rotation={shouldRotate ? 90 : 0}
From d05d5634b350dee83b3e20424c2df697adc356bb Mon Sep 17 00:00:00 2001
From: Tiago Costa
Date: Tue, 6 Apr 2021 02:29:43 +0100
Subject: [PATCH 016/131] skip flaky suite (#95899)
---
.../plugins/canvas/shareable_runtime/components/app.test.tsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugins/canvas/shareable_runtime/components/app.test.tsx b/x-pack/plugins/canvas/shareable_runtime/components/app.test.tsx
index acf71cad3f3ba..b68642d184542 100644
--- a/x-pack/plugins/canvas/shareable_runtime/components/app.test.tsx
+++ b/x-pack/plugins/canvas/shareable_runtime/components/app.test.tsx
@@ -59,7 +59,8 @@ const getWrapper: (name?: WorkpadNames) => ReactWrapper = (name = 'hello') => {
return mount();
};
-describe('', () => {
+// FLAKY: https://github.com/elastic/kibana/issues/95899
+describe.skip('', () => {
test('App renders properly', () => {
expect(getWrapper().html()).toMatchSnapshot();
});
From 251bd9afc66f411cfe8bd51a04548b6b19084357 Mon Sep 17 00:00:00 2001
From: Pierre Gayvallet
Date: Tue, 6 Apr 2021 09:25:36 +0200
Subject: [PATCH 017/131] Remove /src/legacy (#95510)
* starting removing stuff
* fix jest config
* disable CLI mode until other PR is merged
* fix the schema
* add deprecation for maxPayloadBytes
* fix legacy start logic
* deletes `env` from unknown args
* fix FTR test config
* some legacy service deletion
* move config validation
* remove legacy exports from entrypoint
* preserve legacy logging in core logging config
* try to fix uiSettings integration tests
* fix legacy service tests
* more type fix
* use fromRoot from @kbn/utils
* cleanup kibana.d.ts
* fix unit tests
* remove src/core/server/utils
* fix server script
* add integration test for `/{path*}` route
* add unit tests on legacy config
* adapt uiSetting IT bis
* fix tests
* update generated doc
* address some review comments
* move review comments
* fix some stuff
* fix some stuff
* fix some stuff
* fix some stuff bis
* generated doc
* add test for ensureValidConfiguration
---
.eslintignore | 6 -
.eslintrc.js | 24 +-
.github/CODEOWNERS | 8 -
...lugin-core-server.kibanaresponsefactory.md | 4 +-
...core-server.legacyservicesetupdeps.core.md | 11 -
...ugin-core-server.legacyservicesetupdeps.md | 24 --
...e-server.legacyservicesetupdeps.plugins.md | 11 -
...server.legacyservicesetupdeps.uiplugins.md | 11 -
...core-server.legacyservicestartdeps.core.md | 11 -
...ugin-core-server.legacyservicestartdeps.md | 23 --
...e-server.legacyservicestartdeps.plugins.md | 11 -
.../core/server/kibana-plugin-core-server.md | 2 -
...plugin-plugins-data-server.plugin.start.md | 4 +-
jest.config.js | 1 -
kibana.d.ts | 15 -
.../src/get_server_watch_paths.test.ts | 2 -
...gacy_object_to_config_adapter.test.ts.snap | 68 +---
.../legacy_object_to_config_adapter.test.ts | 53 ---
.../legacy/legacy_object_to_config_adapter.ts | 48 +--
packages/kbn-legacy-logging/package.json | 3 +-
.../src/legacy_logging_server.ts | 2 +-
packages/kbn-legacy-logging/src/schema.ts | 104 ++---
packages/kbn-utils/src/package_json/index.ts | 4 +
src/cli/cli.js | 2 +-
src/cli/serve/serve.js | 10 +-
.../cli_encryption_keys.js | 3 +-
src/cli_keystore/cli_keystore.js | 2 +-
src/cli_plugin/cli.js | 2 +-
src/cli_plugin/install/index.js | 3 +-
src/cli_plugin/install/kibana.js | 2 +-
src/cli_plugin/install/settings.js | 4 +-
src/cli_plugin/install/settings.test.js | 2 +-
.../install}/utils/version.js | 0
src/cli_plugin/list/index.js | 2 +-
src/cli_plugin/remove/settings.js | 3 +-
.../config/ensure_valid_configuration.test.ts | 47 +++
.../config/ensure_valid_configuration.ts | 19 +-
src/core/server/config/index.ts | 1 +
.../bundle_routes/register_bundle_routes.ts | 2 +-
src/core/server/core_app/core_app.ts | 39 +-
.../integration_tests/core_app_routes.test.ts | 58 +++
src/core/server/http/http_config.ts | 249 ++++++------
.../integration_tests/core_services.test.ts | 178 ---------
.../i18n/get_kibana_translation_files.test.ts | 2 +-
.../i18n/get_kibana_translation_files.ts | 2 +-
src/core/server/index.ts | 2 -
.../__snapshots__/legacy_service.test.ts.snap | 27 --
.../config/ensure_valid_configuration.test.ts | 59 ---
.../config/get_unused_config_keys.test.ts | 163 --------
.../legacy/config/get_unused_config_keys.ts | 42 --
src/core/server/legacy/config/index.ts | 9 -
src/core/server/legacy/index.ts | 10 -
.../integration_tests/legacy_service.test.ts | 65 ---
src/core/server/legacy/legacy_service.mock.ts | 14 +-
.../legacy/legacy_service.test.mocks.ts | 18 +
src/core/server/legacy/legacy_service.test.ts | 372 +++++-------------
src/core/server/legacy/legacy_service.ts | 291 ++------------
.../logging/appenders/legacy_appender.ts | 7 +-
src/core/server/legacy/merge_vars.test.ts | 188 ---------
src/core/server/legacy/merge_vars.ts | 23 --
src/core/server/legacy/types.ts | 64 ---
.../__snapshots__/logging_config.test.ts.snap | 20 -
.../server/logging/logging_config.test.ts | 42 +-
src/core/server/logging/logging_config.ts | 6 +-
.../server/logging/logging_system.test.ts | 1 +
src/core/server/metrics/index.ts | 1 +
src/core/server/plugins/legacy_config.test.ts | 2 +-
.../server/plugins/plugin_context.test.ts | 2 +-
src/core/server/plugins/plugins_config.ts | 24 +-
src/core/server/server.api.md | 45 +--
src/core/server/server.test.mocks.ts | 2 +-
src/core/server/server.test.ts | 24 --
src/core/server/server.ts | 38 +-
src/core/server/types.ts | 1 -
.../integration_tests/doc_exists.ts | 102 ++---
.../integration_tests/doc_missing.ts | 61 ++-
.../doc_missing_and_index_read_only.ts | 145 -------
.../integration_tests/index.test.ts | 2 -
.../integration_tests/lib/servers.ts | 15 +-
src/core/server/utils/from_root.ts | 14 -
src/core/server/utils/index.ts | 10 -
src/core/server/utils/package_json.ts | 15 -
src/core/test_helpers/kbn_server.ts | 21 +-
.../config/__snapshots__/config.test.js.snap | 5 -
src/legacy/server/config/config.js | 207 ----------
src/legacy/server/config/config.test.js | 345 ----------------
src/legacy/server/config/index.js | 9 -
src/legacy/server/config/override.test.ts | 119 ------
src/legacy/server/config/override.ts | 41 --
src/legacy/server/config/schema.js | 95 -----
src/legacy/server/config/schema.test.js | 92 -----
src/legacy/server/core/index.ts | 20 -
src/legacy/server/http/index.js | 37 --
src/legacy/server/jest.config.js | 13 -
src/legacy/server/kbn_server.d.ts | 95 -----
src/legacy/server/kbn_server.js | 131 ------
src/legacy/server/logging/index.js | 17 -
src/legacy/utils/artifact_type.ts | 11 -
.../utils/deep_clone_with_buffers.test.ts | 68 ----
src/legacy/utils/deep_clone_with_buffers.ts | 22 --
src/legacy/utils/index.d.ts | 9 -
src/legacy/utils/index.js | 12 -
src/legacy/utils/jest.config.js | 13 -
src/legacy/utils/unset.js | 33 --
src/legacy/utils/unset.test.js | 90 -----
src/plugins/data/server/server.api.md | 4 +-
.../services/visual_testing/visual_testing.ts | 3 +-
x-pack/plugins/ml/server/lib/spaces_utils.ts | 17 +-
.../on_post_auth_interceptor.test.ts | 122 +-----
.../on_request_interceptor.test.ts | 164 ++------
x-pack/test/functional/config.js | 2 +-
111 files changed, 732 insertions(+), 4093 deletions(-)
delete mode 100644 docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.core.md
delete mode 100644 docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.md
delete mode 100644 docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.plugins.md
delete mode 100644 docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.uiplugins.md
delete mode 100644 docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.core.md
delete mode 100644 docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.md
delete mode 100644 docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.plugins.md
rename src/{legacy => cli_plugin/install}/utils/version.js (100%)
create mode 100644 src/core/server/config/ensure_valid_configuration.test.ts
rename src/core/server/{legacy => }/config/ensure_valid_configuration.ts (62%)
create mode 100644 src/core/server/core_app/integration_tests/core_app_routes.test.ts
delete mode 100644 src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap
delete mode 100644 src/core/server/legacy/config/ensure_valid_configuration.test.ts
delete mode 100644 src/core/server/legacy/config/get_unused_config_keys.test.ts
delete mode 100644 src/core/server/legacy/config/get_unused_config_keys.ts
delete mode 100644 src/core/server/legacy/config/index.ts
delete mode 100644 src/core/server/legacy/integration_tests/legacy_service.test.ts
create mode 100644 src/core/server/legacy/legacy_service.test.mocks.ts
delete mode 100644 src/core/server/legacy/merge_vars.test.ts
delete mode 100644 src/core/server/legacy/merge_vars.ts
delete mode 100644 src/core/server/legacy/types.ts
delete mode 100644 src/core/server/logging/__snapshots__/logging_config.test.ts.snap
delete mode 100644 src/core/server/ui_settings/integration_tests/doc_missing_and_index_read_only.ts
delete mode 100644 src/core/server/utils/from_root.ts
delete mode 100644 src/core/server/utils/index.ts
delete mode 100644 src/core/server/utils/package_json.ts
delete mode 100644 src/legacy/server/config/__snapshots__/config.test.js.snap
delete mode 100644 src/legacy/server/config/config.js
delete mode 100644 src/legacy/server/config/config.test.js
delete mode 100644 src/legacy/server/config/index.js
delete mode 100644 src/legacy/server/config/override.test.ts
delete mode 100644 src/legacy/server/config/override.ts
delete mode 100644 src/legacy/server/config/schema.js
delete mode 100644 src/legacy/server/config/schema.test.js
delete mode 100644 src/legacy/server/core/index.ts
delete mode 100644 src/legacy/server/http/index.js
delete mode 100644 src/legacy/server/jest.config.js
delete mode 100644 src/legacy/server/kbn_server.d.ts
delete mode 100644 src/legacy/server/kbn_server.js
delete mode 100644 src/legacy/server/logging/index.js
delete mode 100644 src/legacy/utils/artifact_type.ts
delete mode 100644 src/legacy/utils/deep_clone_with_buffers.test.ts
delete mode 100644 src/legacy/utils/deep_clone_with_buffers.ts
delete mode 100644 src/legacy/utils/index.d.ts
delete mode 100644 src/legacy/utils/index.js
delete mode 100644 src/legacy/utils/jest.config.js
delete mode 100644 src/legacy/utils/unset.js
delete mode 100644 src/legacy/utils/unset.test.js
diff --git a/.eslintignore b/.eslintignore
index bbd8e3f88a378..4058d971b7642 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -21,19 +21,13 @@ snapshots.js
# plugin overrides
/src/core/lib/kbn_internal_native_observable
-/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken
/src/plugins/data/common/es_query/kuery/ast/_generated_/**
/src/plugins/vis_type_timelion/common/_generated_/**
-/x-pack/legacy/plugins/**/__tests__/fixtures/**
/x-pack/plugins/apm/e2e/tmp/*
/x-pack/plugins/canvas/canvas_plugin
/x-pack/plugins/canvas/shareable_runtime/build
/x-pack/plugins/canvas/storybook/build
/x-pack/plugins/reporting/server/export_types/printable_pdf/server/lib/pdf/assets/**
-/x-pack/legacy/plugins/infra/common/graphql/types.ts
-/x-pack/legacy/plugins/infra/public/graphql/types.ts
-/x-pack/legacy/plugins/infra/server/graphql/types.ts
-/x-pack/legacy/plugins/maps/public/vendor/**
# package overrides
/packages/elastic-eslint-config-kibana
diff --git a/.eslintrc.js b/.eslintrc.js
index 65c8e8ee2e694..19ba7cacc3c44 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -410,11 +410,7 @@ module.exports = {
errorMessage: `Common code can not import from server or public, use a common directory.`,
},
{
- target: [
- 'src/legacy/**/*',
- '(src|x-pack)/plugins/**/(public|server)/**/*',
- 'examples/**/*',
- ],
+ target: ['(src|x-pack)/plugins/**/(public|server)/**/*', 'examples/**/*'],
from: [
'src/core/public/**/*',
'!src/core/public/index.ts', // relative import
@@ -428,8 +424,6 @@ module.exports = {
'!src/core/server/mocks{,.ts}',
'!src/core/server/types{,.ts}',
'!src/core/server/test_utils{,.ts}',
- '!src/core/server/utils', // ts alias
- '!src/core/server/utils/**/*',
// for absolute imports until fixed in
// https://github.com/elastic/kibana/issues/36096
'!src/core/server/*.test.mocks{,.ts}',
@@ -442,7 +436,6 @@ module.exports = {
},
{
target: [
- 'src/legacy/**/*',
'(src|x-pack)/plugins/**/(public|server)/**/*',
'examples/**/*',
'!(src|x-pack)/**/*.test.*',
@@ -482,7 +475,7 @@ module.exports = {
},
{
target: ['src/core/**/*'],
- from: ['plugins/**/*', 'src/plugins/**/*', 'src/legacy/ui/**/*'],
+ from: ['plugins/**/*', 'src/plugins/**/*'],
errorMessage: 'The core cannot depend on any plugins.',
},
{
@@ -490,19 +483,6 @@ module.exports = {
from: ['ui/**/*'],
errorMessage: 'Plugins cannot import legacy UI code.',
},
- {
- from: ['src/legacy/ui/**/*', 'ui/**/*'],
- target: [
- 'test/plugin_functional/plugins/**/public/np_ready/**/*',
- 'test/plugin_functional/plugins/**/server/np_ready/**/*',
- ],
- allowSameFolder: true,
- errorMessage:
- 'NP-ready code should not import from /src/legacy/ui/** folder. ' +
- 'Instead of importing from /src/legacy/ui/** deeply within a np_ready folder, ' +
- 'import those things once at the top level of your plugin and pass those down, just ' +
- 'like you pass down `core` and `plugins` objects.',
- },
],
},
],
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index b9afc197bac9c..a8dcafeb7753c 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -107,7 +107,6 @@
/x-pack/plugins/dashboard_enhanced/ @elastic/kibana-presentation
/x-pack/test/functional/apps/canvas/ @elastic/kibana-presentation
#CC# /src/plugins/kibana_react/public/code_editor/ @elastic/kibana-presentation
-#CC# /x-pack/legacy/plugins/canvas/ @elastic/kibana-presentation
#CC# /x-pack/plugins/dashboard_mode @elastic/kibana-presentation
@@ -164,7 +163,6 @@
/packages/kbn-utils/ @elastic/kibana-operations
/packages/kbn-cli-dev-mode/ @elastic/kibana-operations
/src/cli/keystore/ @elastic/kibana-operations
-/src/legacy/server/warnings/ @elastic/kibana-operations
/.ci/es-snapshots/ @elastic/kibana-operations
/.github/workflows/ @elastic/kibana-operations
/vars/ @elastic/kibana-operations
@@ -201,9 +199,6 @@
/packages/kbn-legacy-logging/ @elastic/kibana-core
/packages/kbn-crypto/ @elastic/kibana-core
/packages/kbn-http-tools/ @elastic/kibana-core
-/src/legacy/server/config/ @elastic/kibana-core
-/src/legacy/server/http/ @elastic/kibana-core
-/src/legacy/server/logging/ @elastic/kibana-core
/src/plugins/status_page/ @elastic/kibana-core
/src/plugins/saved_objects_management/ @elastic/kibana-core
/src/dev/run_check_published_api_changes.ts @elastic/kibana-core
@@ -213,9 +208,6 @@
/src/plugins/kibana_overview/ @elastic/kibana-core
/x-pack/plugins/global_search_bar/ @elastic/kibana-core
#CC# /src/core/server/csp/ @elastic/kibana-core
-#CC# /src/legacy/server/config/ @elastic/kibana-core
-#CC# /src/legacy/server/http/ @elastic/kibana-core
-#CC# /src/legacy/ui/public/documentation_links @elastic/kibana-core
#CC# /src/plugins/legacy_export/ @elastic/kibana-core
#CC# /src/plugins/xpack_legacy/ @elastic/kibana-core
#CC# /src/plugins/saved_objects/ @elastic/kibana-core
diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaresponsefactory.md b/docs/development/core/server/kibana-plugin-core-server.kibanaresponsefactory.md
index 395c26a6e4bf6..8ddc0da5f1b28 100644
--- a/docs/development/core/server/kibana-plugin-core-server.kibanaresponsefactory.md
+++ b/docs/development/core/server/kibana-plugin-core-server.kibanaresponsefactory.md
@@ -10,10 +10,10 @@ Set of helpers used to create `KibanaResponse` to form HTTP response on an incom
```typescript
kibanaResponseFactory: {
- custom: | Error | Buffer | {
+ custom: | Error | Buffer | Stream | {
message: string | Error;
attributes?: Record | undefined;
- } | Stream | undefined>(options: CustomHttpResponseOptions) => KibanaResponse;
+ } | undefined>(options: CustomHttpResponseOptions) => KibanaResponse;
badRequest: (options?: ErrorHttpResponseOptions) => KibanaResponse;
unauthorized: (options?: ErrorHttpResponseOptions) => KibanaResponse;
forbidden: (options?: ErrorHttpResponseOptions) => KibanaResponse;
diff --git a/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.core.md b/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.core.md
deleted file mode 100644
index 67f2cf0cdcc7c..0000000000000
--- a/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.core.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LegacyServiceSetupDeps](./kibana-plugin-core-server.legacyservicesetupdeps.md) > [core](./kibana-plugin-core-server.legacyservicesetupdeps.core.md)
-
-## LegacyServiceSetupDeps.core property
-
-Signature:
-
-```typescript
-core: LegacyCoreSetup;
-```
diff --git a/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.md b/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.md
deleted file mode 100644
index a5c1d59be06d3..0000000000000
--- a/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.md
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LegacyServiceSetupDeps](./kibana-plugin-core-server.legacyservicesetupdeps.md)
-
-## LegacyServiceSetupDeps interface
-
-> Warning: This API is now obsolete.
->
->
-
-Signature:
-
-```typescript
-export interface LegacyServiceSetupDeps
-```
-
-## Properties
-
-| Property | Type | Description |
-| --- | --- | --- |
-| [core](./kibana-plugin-core-server.legacyservicesetupdeps.core.md) | LegacyCoreSetup
| |
-| [plugins](./kibana-plugin-core-server.legacyservicesetupdeps.plugins.md) | Record<string, unknown>
| |
-| [uiPlugins](./kibana-plugin-core-server.legacyservicesetupdeps.uiplugins.md) | UiPlugins
| |
-
diff --git a/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.plugins.md b/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.plugins.md
deleted file mode 100644
index 032762904640b..0000000000000
--- a/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.plugins.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LegacyServiceSetupDeps](./kibana-plugin-core-server.legacyservicesetupdeps.md) > [plugins](./kibana-plugin-core-server.legacyservicesetupdeps.plugins.md)
-
-## LegacyServiceSetupDeps.plugins property
-
-Signature:
-
-```typescript
-plugins: Record;
-```
diff --git a/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.uiplugins.md b/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.uiplugins.md
deleted file mode 100644
index d19a7dfcbfcfa..0000000000000
--- a/docs/development/core/server/kibana-plugin-core-server.legacyservicesetupdeps.uiplugins.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LegacyServiceSetupDeps](./kibana-plugin-core-server.legacyservicesetupdeps.md) > [uiPlugins](./kibana-plugin-core-server.legacyservicesetupdeps.uiplugins.md)
-
-## LegacyServiceSetupDeps.uiPlugins property
-
-Signature:
-
-```typescript
-uiPlugins: UiPlugins;
-```
diff --git a/docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.core.md b/docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.core.md
deleted file mode 100644
index 17369e00a7068..0000000000000
--- a/docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.core.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LegacyServiceStartDeps](./kibana-plugin-core-server.legacyservicestartdeps.md) > [core](./kibana-plugin-core-server.legacyservicestartdeps.core.md)
-
-## LegacyServiceStartDeps.core property
-
-Signature:
-
-```typescript
-core: LegacyCoreStart;
-```
diff --git a/docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.md b/docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.md
deleted file mode 100644
index d6f6b38b79f84..0000000000000
--- a/docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.md
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LegacyServiceStartDeps](./kibana-plugin-core-server.legacyservicestartdeps.md)
-
-## LegacyServiceStartDeps interface
-
-> Warning: This API is now obsolete.
->
->
-
-Signature:
-
-```typescript
-export interface LegacyServiceStartDeps
-```
-
-## Properties
-
-| Property | Type | Description |
-| --- | --- | --- |
-| [core](./kibana-plugin-core-server.legacyservicestartdeps.core.md) | LegacyCoreStart
| |
-| [plugins](./kibana-plugin-core-server.legacyservicestartdeps.plugins.md) | Record<string, unknown>
| |
-
diff --git a/docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.plugins.md b/docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.plugins.md
deleted file mode 100644
index 4634bf21fb42c..0000000000000
--- a/docs/development/core/server/kibana-plugin-core-server.legacyservicestartdeps.plugins.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [LegacyServiceStartDeps](./kibana-plugin-core-server.legacyservicestartdeps.md) > [plugins](./kibana-plugin-core-server.legacyservicestartdeps.plugins.md)
-
-## LegacyServiceStartDeps.plugins property
-
-Signature:
-
-```typescript
-plugins: Record;
-```
diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md
index faac8108de825..3bbdf8c703ab1 100644
--- a/docs/development/core/server/kibana-plugin-core-server.md
+++ b/docs/development/core/server/kibana-plugin-core-server.md
@@ -110,8 +110,6 @@ The plugin integrates with the core system via lifecycle events: `setup`
| [LegacyCallAPIOptions](./kibana-plugin-core-server.legacycallapioptions.md) | The set of options that defines how API call should be made and result be processed. |
| [LegacyElasticsearchError](./kibana-plugin-core-server.legacyelasticsearcherror.md) | @deprecated. The new elasticsearch client doesn't wrap errors anymore. |
| [LegacyRequest](./kibana-plugin-core-server.legacyrequest.md) | |
-| [LegacyServiceSetupDeps](./kibana-plugin-core-server.legacyservicesetupdeps.md) | |
-| [LegacyServiceStartDeps](./kibana-plugin-core-server.legacyservicestartdeps.md) | |
| [LoggerContextConfigInput](./kibana-plugin-core-server.loggercontextconfiginput.md) | |
| [LoggingServiceSetup](./kibana-plugin-core-server.loggingservicesetup.md) | Provides APIs to plugins for customizing the plugin's logger. |
| [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) | APIs to retrieves metrics gathered and exposed by the core platform. |
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md
index 025cab9f48c1a..f4404521561d2 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md
@@ -12,7 +12,7 @@ start(core: CoreStart): {
fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise;
};
indexPatterns: {
- indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise;
+ indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise;
};
search: ISearchStart>;
};
@@ -31,7 +31,7 @@ start(core: CoreStart): {
fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise;
};
indexPatterns: {
- indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise;
+ indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise;
};
search: ISearchStart>;
}`
diff --git a/jest.config.js b/jest.config.js
index 03dc832ba170c..bd1e865a7e64a 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -12,7 +12,6 @@ module.exports = {
projects: [
'/packages/*/jest.config.js',
'/src/*/jest.config.js',
- '/src/legacy/*/jest.config.js',
'/src/plugins/*/jest.config.js',
'/test/*/jest.config.js',
'/x-pack/plugins/*/jest.config.js',
diff --git a/kibana.d.ts b/kibana.d.ts
index a2c670c96a699..8a7a531890057 100644
--- a/kibana.d.ts
+++ b/kibana.d.ts
@@ -13,18 +13,3 @@ import * as Public from 'src/core/public';
import * as Server from 'src/core/server';
export { Public, Server };
-
-/**
- * All exports from TS ambient definitions (where types are added for JS source in a .d.ts file).
- */
-import * as LegacyKibanaServer from './src/legacy/server/kbn_server';
-
-/**
- * Re-export legacy types under a namespace.
- */
-export namespace Legacy {
- export type KibanaConfig = LegacyKibanaServer.KibanaConfig;
- export type Request = LegacyKibanaServer.Request;
- export type ResponseToolkit = LegacyKibanaServer.ResponseToolkit;
- export type Server = LegacyKibanaServer.Server;
-}
diff --git a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts
index ab113b96a5f03..ff25f2a7bf55e 100644
--- a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts
+++ b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts
@@ -27,8 +27,6 @@ it('produces the right watch and ignore list', () => {
expect(watchPaths).toMatchInlineSnapshot(`
Array [
/src/core,
- /src/legacy/server,
- /src/legacy/utils,
/config,
/x-pack/test/plugin_functional/plugins/resolver_test,
/src/plugins,
diff --git a/packages/kbn-config/src/legacy/__snapshots__/legacy_object_to_config_adapter.test.ts.snap b/packages/kbn-config/src/legacy/__snapshots__/legacy_object_to_config_adapter.test.ts.snap
index 2801e0a0688cc..17ac75e9f3d9e 100644
--- a/packages/kbn-config/src/legacy/__snapshots__/legacy_object_to_config_adapter.test.ts.snap
+++ b/packages/kbn-config/src/legacy/__snapshots__/legacy_object_to_config_adapter.test.ts.snap
@@ -1,69 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`#get correctly handles server config.: default 1`] = `
-Object {
- "autoListen": true,
- "basePath": "/abc",
- "compression": Object {
- "enabled": true,
- },
- "cors": false,
- "customResponseHeaders": Object {
- "custom-header": "custom-value",
- },
- "host": "host",
- "keepaliveTimeout": 5000,
- "maxPayload": 1000,
- "name": "kibana-hostname",
- "port": 1234,
- "publicBaseUrl": "https://myhost.com/abc",
- "rewriteBasePath": false,
- "socketTimeout": 2000,
- "ssl": Object {
- "enabled": true,
- "keyPassphrase": "some-phrase",
- "someNewValue": "new",
- },
- "uuid": undefined,
- "xsrf": Object {
- "allowlist": Array [],
- "disableProtection": false,
- },
-}
-`;
-
-exports[`#get correctly handles server config.: disabled ssl 1`] = `
-Object {
- "autoListen": true,
- "basePath": "/abc",
- "compression": Object {
- "enabled": true,
- },
- "cors": false,
- "customResponseHeaders": Object {
- "custom-header": "custom-value",
- },
- "host": "host",
- "keepaliveTimeout": 5000,
- "maxPayload": 1000,
- "name": "kibana-hostname",
- "port": 1234,
- "publicBaseUrl": "http://myhost.com/abc",
- "rewriteBasePath": false,
- "socketTimeout": 2000,
- "ssl": Object {
- "certificate": "cert",
- "enabled": false,
- "key": "key",
- },
- "uuid": undefined,
- "xsrf": Object {
- "allowlist": Array [],
- "disableProtection": false,
- },
-}
-`;
-
exports[`#get correctly handles silent logging config. 1`] = `
Object {
"appenders": Object {
@@ -78,6 +14,7 @@ Object {
"root": Object {
"level": "off",
},
+ "silent": true,
}
`;
@@ -93,10 +30,13 @@ Object {
"type": "legacy-appender",
},
},
+ "dest": "/some/path.log",
+ "json": true,
"loggers": undefined,
"root": Object {
"level": "all",
},
+ "verbose": true,
}
`;
diff --git a/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.test.ts b/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.test.ts
index 5dd1941545708..47151503e1634 100644
--- a/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.test.ts
+++ b/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.test.ts
@@ -65,59 +65,6 @@ describe('#get', () => {
expect(configAdapter.get('logging')).toMatchSnapshot();
});
-
- test('correctly handles server config.', () => {
- const configAdapter = new LegacyObjectToConfigAdapter({
- server: {
- name: 'kibana-hostname',
- autoListen: true,
- basePath: '/abc',
- cors: false,
- customResponseHeaders: { 'custom-header': 'custom-value' },
- host: 'host',
- maxPayloadBytes: 1000,
- keepaliveTimeout: 5000,
- socketTimeout: 2000,
- port: 1234,
- publicBaseUrl: 'https://myhost.com/abc',
- rewriteBasePath: false,
- ssl: { enabled: true, keyPassphrase: 'some-phrase', someNewValue: 'new' },
- compression: { enabled: true },
- someNotSupportedValue: 'val',
- xsrf: {
- disableProtection: false,
- allowlist: [],
- },
- },
- });
-
- const configAdapterWithDisabledSSL = new LegacyObjectToConfigAdapter({
- server: {
- name: 'kibana-hostname',
- autoListen: true,
- basePath: '/abc',
- cors: false,
- customResponseHeaders: { 'custom-header': 'custom-value' },
- host: 'host',
- maxPayloadBytes: 1000,
- keepaliveTimeout: 5000,
- socketTimeout: 2000,
- port: 1234,
- publicBaseUrl: 'http://myhost.com/abc',
- rewriteBasePath: false,
- ssl: { enabled: false, certificate: 'cert', key: 'key' },
- compression: { enabled: true },
- someNotSupportedValue: 'val',
- xsrf: {
- disableProtection: false,
- allowlist: [],
- },
- },
- });
-
- expect(configAdapter.get('server')).toMatchSnapshot('default');
- expect(configAdapterWithDisabledSSL.get('server')).toMatchSnapshot('disabled ssl');
- });
});
describe('#set', () => {
diff --git a/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.ts b/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.ts
index 8ec26ff1f8e71..bc6fd49e2498a 100644
--- a/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.ts
+++ b/packages/kbn-config/src/legacy/legacy_object_to_config_adapter.ts
@@ -9,15 +9,6 @@
import { ConfigPath } from '../config';
import { ObjectToConfigAdapter } from '../object_to_config_adapter';
-// TODO: fix once core schemas are moved to this package
-type LoggingConfigType = any;
-
-/**
- * @internal
- * @deprecated
- */
-export type LegacyVars = Record;
-
/**
* Represents logging config supported by the legacy platform.
*/
@@ -30,7 +21,7 @@ export interface LegacyLoggingConfig {
events?: Record;
}
-type MixedLoggingConfig = LegacyLoggingConfig & Partial;
+type MixedLoggingConfig = LegacyLoggingConfig & Record;
/**
* Represents adapter between config provided by legacy platform and `Config`
@@ -48,6 +39,7 @@ export class LegacyObjectToConfigAdapter extends ObjectToConfigAdapter {
},
root: { level: 'info', ...root },
loggers,
+ ...legacyLoggingConfig,
};
if (configValue.silent) {
@@ -61,47 +53,11 @@ export class LegacyObjectToConfigAdapter extends ObjectToConfigAdapter {
return loggingConfig;
}
- private static transformServer(configValue: any = {}) {
- // TODO: New platform uses just a subset of `server` config from the legacy platform,
- // new values will be exposed once we need them
- return {
- autoListen: configValue.autoListen,
- basePath: configValue.basePath,
- cors: configValue.cors,
- customResponseHeaders: configValue.customResponseHeaders,
- host: configValue.host,
- maxPayload: configValue.maxPayloadBytes,
- name: configValue.name,
- port: configValue.port,
- publicBaseUrl: configValue.publicBaseUrl,
- rewriteBasePath: configValue.rewriteBasePath,
- ssl: configValue.ssl,
- keepaliveTimeout: configValue.keepaliveTimeout,
- socketTimeout: configValue.socketTimeout,
- compression: configValue.compression,
- uuid: configValue.uuid,
- xsrf: configValue.xsrf,
- };
- }
-
- private static transformPlugins(configValue: LegacyVars = {}) {
- // These properties are the only ones we use from the existing `plugins` config node
- // since `scanDirs` isn't respected by new platform plugin discovery.
- return {
- initialize: configValue.initialize,
- paths: configValue.paths,
- };
- }
-
public get(configPath: ConfigPath) {
const configValue = super.get(configPath);
switch (configPath) {
case 'logging':
return LegacyObjectToConfigAdapter.transformLogging(configValue as LegacyLoggingConfig);
- case 'server':
- return LegacyObjectToConfigAdapter.transformServer(configValue);
- case 'plugins':
- return LegacyObjectToConfigAdapter.transformPlugins(configValue as LegacyVars);
default:
return configValue;
}
diff --git a/packages/kbn-legacy-logging/package.json b/packages/kbn-legacy-logging/package.json
index 9450fd39607ea..96edeccad6658 100644
--- a/packages/kbn-legacy-logging/package.json
+++ b/packages/kbn-legacy-logging/package.json
@@ -11,6 +11,7 @@
"kbn:watch": "yarn build --watch"
},
"dependencies": {
- "@kbn/utils": "link:../kbn-utils"
+ "@kbn/utils": "link:../kbn-utils",
+ "@kbn/config-schema": "link:../kbn-config-schema"
}
}
diff --git a/packages/kbn-legacy-logging/src/legacy_logging_server.ts b/packages/kbn-legacy-logging/src/legacy_logging_server.ts
index e1edd06a4b4a2..3ece0f6f1ee47 100644
--- a/packages/kbn-legacy-logging/src/legacy_logging_server.ts
+++ b/packages/kbn-legacy-logging/src/legacy_logging_server.ts
@@ -88,7 +88,7 @@ export class LegacyLoggingServer {
// We set `ops.interval` to max allowed number and `ops` filter to value
// that doesn't exist to avoid logging of ops at all, if turned on it will be
// logged by the "legacy" Kibana.
- const { value: loggingConfig } = legacyLoggingConfigSchema.validate({
+ const loggingConfig = legacyLoggingConfigSchema.validate({
...legacyLoggingConfig,
events: {
...legacyLoggingConfig.events,
diff --git a/packages/kbn-legacy-logging/src/schema.ts b/packages/kbn-legacy-logging/src/schema.ts
index 76d7381ee8728..0330708e746c0 100644
--- a/packages/kbn-legacy-logging/src/schema.ts
+++ b/packages/kbn-legacy-logging/src/schema.ts
@@ -6,11 +6,8 @@
* Side Public License, v 1.
*/
-import Joi from 'joi';
+import { schema } from '@kbn/config-schema';
-const HANDLED_IN_KIBANA_PLATFORM = Joi.any().description(
- 'This key is handled in the new platform ONLY'
-);
/**
* @deprecated
*
@@ -36,46 +33,65 @@ export interface LegacyLoggingConfig {
};
}
-export const legacyLoggingConfigSchema = Joi.object()
- .keys({
- appenders: HANDLED_IN_KIBANA_PLATFORM,
- loggers: HANDLED_IN_KIBANA_PLATFORM,
- root: HANDLED_IN_KIBANA_PLATFORM,
-
- silent: Joi.boolean().default(false),
- quiet: Joi.boolean().when('silent', {
- is: true,
- then: Joi.boolean().default(true).valid(true),
- otherwise: Joi.boolean().default(false),
+export const legacyLoggingConfigSchema = schema.object({
+ silent: schema.boolean({ defaultValue: false }),
+ quiet: schema.conditional(
+ schema.siblingRef('silent'),
+ true,
+ schema.boolean({
+ defaultValue: true,
+ validate: (quiet) => {
+ if (!quiet) {
+ return 'must be true when `silent` is true';
+ }
+ },
+ }),
+ schema.boolean({ defaultValue: false })
+ ),
+ verbose: schema.conditional(
+ schema.siblingRef('quiet'),
+ true,
+ schema.boolean({
+ defaultValue: false,
+ validate: (verbose) => {
+ if (verbose) {
+ return 'must be false when `quiet` is true';
+ }
+ },
+ }),
+ schema.boolean({ defaultValue: false })
+ ),
+ events: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }),
+ dest: schema.string({ defaultValue: 'stdout' }),
+ filter: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }),
+ json: schema.conditional(
+ schema.siblingRef('dest'),
+ 'stdout',
+ schema.boolean({
+ defaultValue: !process.stdout.isTTY,
+ }),
+ schema.boolean({
+ defaultValue: true,
+ })
+ ),
+ timezone: schema.maybe(schema.string()),
+ rotate: schema.object({
+ enabled: schema.boolean({ defaultValue: false }),
+ everyBytes: schema.number({
+ min: 1048576, // > 1MB
+ max: 1073741825, // < 1GB
+ defaultValue: 10485760, // 10MB
}),
- verbose: Joi.boolean().when('quiet', {
- is: true,
- then: Joi.valid(false).default(false),
- otherwise: Joi.boolean().default(false),
+ keepFiles: schema.number({
+ min: 2,
+ max: 1024,
+ defaultValue: 7,
}),
- events: Joi.any().default({}),
- dest: Joi.string().default('stdout'),
- filter: Joi.any().default({}),
- json: Joi.boolean().when('dest', {
- is: 'stdout',
- then: Joi.boolean().default(!process.stdout.isTTY),
- otherwise: Joi.boolean().default(true),
+ pollingInterval: schema.number({
+ min: 5000,
+ max: 3600000,
+ defaultValue: 10000,
}),
- timezone: Joi.string(),
- rotate: Joi.object()
- .keys({
- enabled: Joi.boolean().default(false),
- everyBytes: Joi.number()
- // > 1MB
- .greater(1048576)
- // < 1GB
- .less(1073741825)
- // 10MB
- .default(10485760),
- keepFiles: Joi.number().greater(2).less(1024).default(7),
- pollingInterval: Joi.number().greater(5000).less(3600000).default(10000),
- usePolling: Joi.boolean().default(false),
- })
- .default(),
- })
- .default();
+ usePolling: schema.boolean({ defaultValue: false }),
+ }),
+});
diff --git a/packages/kbn-utils/src/package_json/index.ts b/packages/kbn-utils/src/package_json/index.ts
index 40ce353780749..d9304cee2ca38 100644
--- a/packages/kbn-utils/src/package_json/index.ts
+++ b/packages/kbn-utils/src/package_json/index.ts
@@ -14,3 +14,7 @@ export const kibanaPackageJson = {
__dirname: dirname(resolve(REPO_ROOT, 'package.json')),
...require(resolve(REPO_ROOT, 'package.json')),
};
+
+export const isKibanaDistributable = () => {
+ return kibanaPackageJson.build && kibanaPackageJson.build.distributable === true;
+};
diff --git a/src/cli/cli.js b/src/cli/cli.js
index 4540bf4a3f93c..d3bff4f492a80 100644
--- a/src/cli/cli.js
+++ b/src/cli/cli.js
@@ -7,7 +7,7 @@
*/
import _ from 'lodash';
-import { pkg } from '../core/server/utils';
+import { kibanaPackageJson as pkg } from '@kbn/utils';
import Command from './command';
import serveCommand from './serve/serve';
diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js
index a494e4538e79a..ad83965efde33 100644
--- a/src/cli/serve/serve.js
+++ b/src/cli/serve/serve.js
@@ -12,8 +12,7 @@ import { statSync } from 'fs';
import { resolve } from 'path';
import url from 'url';
-import { getConfigPath, fromRoot } from '@kbn/utils';
-import { IS_KIBANA_DISTRIBUTABLE } from '../../legacy/utils';
+import { getConfigPath, fromRoot, isKibanaDistributable } from '@kbn/utils';
import { readKeystore } from '../keystore/read_keystore';
function canRequire(path) {
@@ -65,9 +64,10 @@ function applyConfigOverrides(rawConfig, opts, extraCliOptions) {
delete rawConfig.xpack;
}
- if (opts.dev) {
- set('env', 'development');
+ // only used to set cliArgs.envName, we don't want to inject that into the config
+ delete extraCliOptions.env;
+ if (opts.dev) {
if (!has('elasticsearch.username')) {
set('elasticsearch.username', 'kibana_system');
}
@@ -184,7 +184,7 @@ export default function (program) {
.option('--plugins ', 'an alias for --plugin-dir', pluginDirCollector)
.option('--optimize', 'Deprecated, running the optimizer is no longer required');
- if (!IS_KIBANA_DISTRIBUTABLE) {
+ if (!isKibanaDistributable()) {
command
.option('--oss', 'Start Kibana without X-Pack')
.option(
diff --git a/src/cli_encryption_keys/cli_encryption_keys.js b/src/cli_encryption_keys/cli_encryption_keys.js
index e922b9354d291..acee81aabb706 100644
--- a/src/cli_encryption_keys/cli_encryption_keys.js
+++ b/src/cli_encryption_keys/cli_encryption_keys.js
@@ -6,7 +6,8 @@
* Side Public License, v 1.
*/
-import { pkg } from '../core/server/utils';
+import { kibanaPackageJson as pkg } from '@kbn/utils';
+
import Command from '../cli/command';
import { EncryptionConfig } from './encryption_config';
diff --git a/src/cli_keystore/cli_keystore.js b/src/cli_keystore/cli_keystore.js
index b325f685766aa..9f44e5d56e9d2 100644
--- a/src/cli_keystore/cli_keystore.js
+++ b/src/cli_keystore/cli_keystore.js
@@ -7,8 +7,8 @@
*/
import _ from 'lodash';
+import { kibanaPackageJson as pkg } from '@kbn/utils';
-import { pkg } from '../core/server/utils';
import Command from '../cli/command';
import { Keystore } from '../cli/keystore';
diff --git a/src/cli_plugin/cli.js b/src/cli_plugin/cli.js
index 24ccba6a23397..5ef142192c509 100644
--- a/src/cli_plugin/cli.js
+++ b/src/cli_plugin/cli.js
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { pkg } from '../core/server/utils';
+import { kibanaPackageJson as pkg } from '@kbn/utils';
import Command from '../cli/command';
import { listCommand } from './list';
import { installCommand } from './install';
diff --git a/src/cli_plugin/install/index.js b/src/cli_plugin/install/index.js
index c028facc28e2b..2683dd41d2bb3 100644
--- a/src/cli_plugin/install/index.js
+++ b/src/cli_plugin/install/index.js
@@ -6,8 +6,7 @@
* Side Public License, v 1.
*/
-import { getConfigPath } from '@kbn/utils';
-import { pkg } from '../../core/server/utils';
+import { getConfigPath, kibanaPackageJson as pkg } from '@kbn/utils';
import { install } from './install';
import { Logger } from '../lib/logger';
import { parse, parseMilliseconds } from './settings';
diff --git a/src/cli_plugin/install/kibana.js b/src/cli_plugin/install/kibana.js
index 29cb8df7401b6..1de157b951d03 100644
--- a/src/cli_plugin/install/kibana.js
+++ b/src/cli_plugin/install/kibana.js
@@ -9,7 +9,7 @@
import path from 'path';
import { statSync } from 'fs';
-import { versionSatisfies, cleanVersion } from '../../legacy/utils/version';
+import { versionSatisfies, cleanVersion } from './utils/version';
export function existingInstall(settings, logger) {
try {
diff --git a/src/cli_plugin/install/settings.js b/src/cli_plugin/install/settings.js
index 94473cc12aab2..e1536d66e0529 100644
--- a/src/cli_plugin/install/settings.js
+++ b/src/cli_plugin/install/settings.js
@@ -7,10 +7,8 @@
*/
import { resolve } from 'path';
-
import expiry from 'expiry-js';
-
-import { fromRoot } from '../../core/server/utils';
+import { fromRoot } from '@kbn/utils';
function generateUrls({ version, plugin }) {
return [
diff --git a/src/cli_plugin/install/settings.test.js b/src/cli_plugin/install/settings.test.js
index f06fd7eca7902..c7985763524ed 100644
--- a/src/cli_plugin/install/settings.test.js
+++ b/src/cli_plugin/install/settings.test.js
@@ -7,8 +7,8 @@
*/
import { createAbsolutePathSerializer } from '@kbn/dev-utils';
+import { fromRoot } from '@kbn/utils';
-import { fromRoot } from '../../core/server/utils';
import { parseMilliseconds, parse } from './settings';
const SECOND = 1000;
diff --git a/src/legacy/utils/version.js b/src/cli_plugin/install/utils/version.js
similarity index 100%
rename from src/legacy/utils/version.js
rename to src/cli_plugin/install/utils/version.js
diff --git a/src/cli_plugin/list/index.js b/src/cli_plugin/list/index.js
index ce55b939b8a4c..02d1ed19f8445 100644
--- a/src/cli_plugin/list/index.js
+++ b/src/cli_plugin/list/index.js
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { fromRoot } from '../../core/server/utils';
+import { fromRoot } from '@kbn/utils';
import { list } from './list';
import { Logger } from '../lib/logger';
import { logWarnings } from '../lib/log_warnings';
diff --git a/src/cli_plugin/remove/settings.js b/src/cli_plugin/remove/settings.js
index 333fa7cb0f2e1..2381770ee0a65 100644
--- a/src/cli_plugin/remove/settings.js
+++ b/src/cli_plugin/remove/settings.js
@@ -7,8 +7,7 @@
*/
import { resolve } from 'path';
-
-import { fromRoot } from '../../core/server/utils';
+import { fromRoot } from '@kbn/utils';
export function parse(command, options) {
const settings = {
diff --git a/src/core/server/config/ensure_valid_configuration.test.ts b/src/core/server/config/ensure_valid_configuration.test.ts
new file mode 100644
index 0000000000000..474e8dd59b4c4
--- /dev/null
+++ b/src/core/server/config/ensure_valid_configuration.test.ts
@@ -0,0 +1,47 @@
+/*
+ * 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 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { configServiceMock } from './mocks';
+import { ensureValidConfiguration } from './ensure_valid_configuration';
+import { CriticalError } from '../errors';
+
+describe('ensureValidConfiguration', () => {
+ let configService: ReturnType;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ configService = configServiceMock.create();
+ configService.getUsedPaths.mockReturnValue(Promise.resolve(['core', 'elastic']));
+ });
+
+ it('returns normally when there is no unused keys', async () => {
+ configService.getUnusedPaths.mockResolvedValue([]);
+ await expect(ensureValidConfiguration(configService as any)).resolves.toBeUndefined();
+ });
+
+ it('throws when there are some unused keys', async () => {
+ configService.getUnusedPaths.mockResolvedValue(['some.key', 'some.other.key']);
+
+ await expect(ensureValidConfiguration(configService as any)).rejects.toMatchInlineSnapshot(
+ `[Error: Unknown configuration key(s): "some.key", "some.other.key". Check for spelling errors and ensure that expected plugins are installed.]`
+ );
+ });
+
+ it('throws a `CriticalError` with the correct processExitCode value', async () => {
+ expect.assertions(2);
+
+ configService.getUnusedPaths.mockResolvedValue(['some.key', 'some.other.key']);
+
+ try {
+ await ensureValidConfiguration(configService as any);
+ } catch (e) {
+ expect(e).toBeInstanceOf(CriticalError);
+ expect(e.processExitCode).toEqual(64);
+ }
+ });
+});
diff --git a/src/core/server/legacy/config/ensure_valid_configuration.ts b/src/core/server/config/ensure_valid_configuration.ts
similarity index 62%
rename from src/core/server/legacy/config/ensure_valid_configuration.ts
rename to src/core/server/config/ensure_valid_configuration.ts
index fd3dd29e3d354..a33625cc0841d 100644
--- a/src/core/server/legacy/config/ensure_valid_configuration.ts
+++ b/src/core/server/config/ensure_valid_configuration.ts
@@ -6,20 +6,13 @@
* Side Public License, v 1.
*/
-import { getUnusedConfigKeys } from './get_unused_config_keys';
-import { ConfigService } from '../../config';
-import { CriticalError } from '../../errors';
-import { LegacyServiceSetupConfig } from '../types';
+import { ConfigService } from '@kbn/config';
+import { CriticalError } from '../errors';
-export async function ensureValidConfiguration(
- configService: ConfigService,
- { legacyConfig, settings }: LegacyServiceSetupConfig
-) {
- const unusedConfigKeys = await getUnusedConfigKeys({
- coreHandledConfigPaths: await configService.getUsedPaths(),
- settings,
- legacyConfig,
- });
+export async function ensureValidConfiguration(configService: ConfigService) {
+ await configService.validate();
+
+ const unusedConfigKeys = await configService.getUnusedPaths();
if (unusedConfigKeys.length > 0) {
const message = `Unknown configuration key(s): ${unusedConfigKeys
diff --git a/src/core/server/config/index.ts b/src/core/server/config/index.ts
index b1086d4470335..686564c6d678a 100644
--- a/src/core/server/config/index.ts
+++ b/src/core/server/config/index.ts
@@ -7,6 +7,7 @@
*/
export { coreDeprecationProvider } from './deprecation';
+export { ensureValidConfiguration } from './ensure_valid_configuration';
export {
ConfigService,
diff --git a/src/core/server/core_app/bundle_routes/register_bundle_routes.ts b/src/core/server/core_app/bundle_routes/register_bundle_routes.ts
index df46753747f5b..f313f10003631 100644
--- a/src/core/server/core_app/bundle_routes/register_bundle_routes.ts
+++ b/src/core/server/core_app/bundle_routes/register_bundle_routes.ts
@@ -8,10 +8,10 @@
import { join } from 'path';
import { PackageInfo } from '@kbn/config';
+import { fromRoot } from '@kbn/utils';
import { distDir as uiSharedDepsDistDir } from '@kbn/ui-shared-deps';
import { IRouter } from '../../http';
import { UiPlugins } from '../../plugins';
-import { fromRoot } from '../../utils';
import { FileHashCache } from './file_hash_cache';
import { registerRouteForBundle } from './bundles_route';
diff --git a/src/core/server/core_app/core_app.ts b/src/core/server/core_app/core_app.ts
index dac941767ebb5..bc1098832bac5 100644
--- a/src/core/server/core_app/core_app.ts
+++ b/src/core/server/core_app/core_app.ts
@@ -7,9 +7,11 @@
*/
import Path from 'path';
+import { stringify } from 'querystring';
import { Env } from '@kbn/config';
+import { schema } from '@kbn/config-schema';
+import { fromRoot } from '@kbn/utils';
-import { fromRoot } from '../utils';
import { InternalCoreSetup } from '../internal_types';
import { CoreContext } from '../core_context';
import { Logger } from '../logging';
@@ -49,6 +51,41 @@ export class CoreApp {
});
});
+ // remove trailing slash catch-all
+ router.get(
+ {
+ path: '/{path*}',
+ validate: {
+ params: schema.object({
+ path: schema.maybe(schema.string()),
+ }),
+ query: schema.maybe(schema.recordOf(schema.string(), schema.any())),
+ },
+ },
+ async (context, req, res) => {
+ const { query, params } = req;
+ const { path } = params;
+ if (!path || !path.endsWith('/')) {
+ return res.notFound();
+ }
+
+ const basePath = httpSetup.basePath.get(req);
+ let rewrittenPath = path.slice(0, -1);
+ if (`/${path}`.startsWith(basePath)) {
+ rewrittenPath = rewrittenPath.substring(basePath.length);
+ }
+
+ const querystring = query ? stringify(query) : undefined;
+ const url = `${basePath}/${rewrittenPath}${querystring ? `?${querystring}` : ''}`;
+
+ return res.redirected({
+ headers: {
+ location: url,
+ },
+ });
+ }
+ );
+
router.get({ path: '/core', validate: false }, async (context, req, res) =>
res.ok({ body: { version: '0.0.1' } })
);
diff --git a/src/core/server/core_app/integration_tests/core_app_routes.test.ts b/src/core/server/core_app/integration_tests/core_app_routes.test.ts
new file mode 100644
index 0000000000000..6b0643f7d1bc7
--- /dev/null
+++ b/src/core/server/core_app/integration_tests/core_app_routes.test.ts
@@ -0,0 +1,58 @@
+/*
+ * 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 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import * as kbnTestServer from '../../../test_helpers/kbn_server';
+import { Root } from '../../root';
+
+describe('Core app routes', () => {
+ let root: Root;
+
+ beforeAll(async function () {
+ root = kbnTestServer.createRoot({
+ plugins: { initialize: false },
+ server: {
+ basePath: '/base-path',
+ },
+ });
+
+ await root.setup();
+ await root.start();
+ });
+
+ afterAll(async function () {
+ await root.shutdown();
+ });
+
+ describe('`/{path*}` route', () => {
+ it('redirects requests to include the basePath', async () => {
+ const response = await kbnTestServer.request.get(root, '/some-path/').expect(302);
+ expect(response.get('location')).toEqual('/base-path/some-path');
+ });
+
+ it('includes the query in the redirect', async () => {
+ const response = await kbnTestServer.request.get(root, '/some-path/?foo=bar').expect(302);
+ expect(response.get('location')).toEqual('/base-path/some-path?foo=bar');
+ });
+
+ it('does not redirect if the path does not end with `/`', async () => {
+ await kbnTestServer.request.get(root, '/some-path').expect(404);
+ });
+
+ it('does not add the basePath if the path already contains it', async () => {
+ const response = await kbnTestServer.request.get(root, '/base-path/foo/').expect(302);
+ expect(response.get('location')).toEqual('/base-path/foo');
+ });
+ });
+
+ describe('`/` route', () => {
+ it('prevails on the `/{path*}` route', async () => {
+ const response = await kbnTestServer.request.get(root, '/').expect(302);
+ expect(response.get('location')).toEqual('/base-path/app/home');
+ });
+ });
+});
diff --git a/src/core/server/http/http_config.ts b/src/core/server/http/http_config.ts
index 356dad201ce95..daf7424b8f8bd 100644
--- a/src/core/server/http/http_config.ts
+++ b/src/core/server/http/http_config.ts
@@ -11,6 +11,7 @@ import { IHttpConfig, SslConfig, sslSchema } from '@kbn/server-http-tools';
import { hostname } from 'os';
import url from 'url';
+import { ServiceConfigDescriptor } from '../internal_types';
import { CspConfigType, CspConfig, ICspConfig } from '../csp';
import { ExternalUrlConfig, IExternalUrlConfig } from '../external_url';
@@ -20,141 +21,143 @@ const hostURISchema = schema.uri({ scheme: ['http', 'https'] });
const match = (regex: RegExp, errorMsg: string) => (str: string) =>
regex.test(str) ? undefined : errorMsg;
-// before update to make sure it's in sync with validation rules in Legacy
-// https://github.com/elastic/kibana/blob/master/src/legacy/server/config/schema.js
-export const config = {
- path: 'server' as const,
- schema: schema.object(
- {
- name: schema.string({ defaultValue: () => hostname() }),
- autoListen: schema.boolean({ defaultValue: true }),
- publicBaseUrl: schema.maybe(schema.uri({ scheme: ['http', 'https'] })),
- basePath: schema.maybe(
- schema.string({
- validate: match(validBasePathRegex, "must start with a slash, don't end with one"),
- })
- ),
- cors: schema.object(
- {
- enabled: schema.boolean({ defaultValue: false }),
- allowCredentials: schema.boolean({ defaultValue: false }),
- allowOrigin: schema.oneOf(
- [
- schema.arrayOf(hostURISchema, { minSize: 1 }),
- schema.arrayOf(schema.literal('*'), { minSize: 1, maxSize: 1 }),
- ],
- {
- defaultValue: ['*'],
- }
- ),
+const configSchema = schema.object(
+ {
+ name: schema.string({ defaultValue: () => hostname() }),
+ autoListen: schema.boolean({ defaultValue: true }),
+ publicBaseUrl: schema.maybe(schema.uri({ scheme: ['http', 'https'] })),
+ basePath: schema.maybe(
+ schema.string({
+ validate: match(validBasePathRegex, "must start with a slash, don't end with one"),
+ })
+ ),
+ cors: schema.object(
+ {
+ enabled: schema.boolean({ defaultValue: false }),
+ allowCredentials: schema.boolean({ defaultValue: false }),
+ allowOrigin: schema.oneOf(
+ [
+ schema.arrayOf(hostURISchema, { minSize: 1 }),
+ schema.arrayOf(schema.literal('*'), { minSize: 1, maxSize: 1 }),
+ ],
+ {
+ defaultValue: ['*'],
+ }
+ ),
+ },
+ {
+ validate(value) {
+ if (value.allowCredentials === true && value.allowOrigin.includes('*')) {
+ return 'Cannot specify wildcard origin "*" with "credentials: true". Please provide a list of allowed origins.';
+ }
},
- {
- validate(value) {
- if (value.allowCredentials === true && value.allowOrigin.includes('*')) {
- return 'Cannot specify wildcard origin "*" with "credentials: true". Please provide a list of allowed origins.';
- }
- },
+ }
+ ),
+ customResponseHeaders: schema.recordOf(schema.string(), schema.any(), {
+ defaultValue: {},
+ }),
+ host: schema.string({
+ defaultValue: 'localhost',
+ hostname: true,
+ validate(value) {
+ if (value === '0') {
+ return 'value 0 is not a valid hostname (use "0.0.0.0" to bind to all interfaces)';
}
+ },
+ }),
+ maxPayload: schema.byteSize({
+ defaultValue: '1048576b',
+ }),
+ port: schema.number({
+ defaultValue: 5601,
+ }),
+ rewriteBasePath: schema.boolean({ defaultValue: false }),
+ ssl: sslSchema,
+ keepaliveTimeout: schema.number({
+ defaultValue: 120000,
+ }),
+ socketTimeout: schema.number({
+ defaultValue: 120000,
+ }),
+ compression: schema.object({
+ enabled: schema.boolean({ defaultValue: true }),
+ referrerWhitelist: schema.maybe(
+ schema.arrayOf(
+ schema.string({
+ hostname: true,
+ }),
+ { minSize: 1 }
+ )
+ ),
+ }),
+ uuid: schema.maybe(
+ schema.string({
+ validate: match(uuidRegexp, 'must be a valid uuid'),
+ })
+ ),
+ xsrf: schema.object({
+ disableProtection: schema.boolean({ defaultValue: false }),
+ allowlist: schema.arrayOf(
+ schema.string({ validate: match(/^\//, 'must start with a slash') }),
+ { defaultValue: [] }
),
- customResponseHeaders: schema.recordOf(schema.string(), schema.any(), {
- defaultValue: {},
- }),
- host: schema.string({
- defaultValue: 'localhost',
- hostname: true,
+ }),
+ requestId: schema.object(
+ {
+ allowFromAnyIp: schema.boolean({ defaultValue: false }),
+ ipAllowlist: schema.arrayOf(schema.ip(), { defaultValue: [] }),
+ },
+ {
validate(value) {
- if (value === '0') {
- return 'value 0 is not a valid hostname (use "0.0.0.0" to bind to all interfaces)';
+ if (value.allowFromAnyIp === true && value.ipAllowlist?.length > 0) {
+ return `allowFromAnyIp must be set to 'false' if any values are specified in ipAllowlist`;
}
},
- }),
- maxPayload: schema.byteSize({
- defaultValue: '1048576b',
- }),
- port: schema.number({
- defaultValue: 5601,
- }),
- rewriteBasePath: schema.boolean({ defaultValue: false }),
- ssl: sslSchema,
- keepaliveTimeout: schema.number({
- defaultValue: 120000,
- }),
- socketTimeout: schema.number({
- defaultValue: 120000,
- }),
- compression: schema.object({
- enabled: schema.boolean({ defaultValue: true }),
- referrerWhitelist: schema.maybe(
- schema.arrayOf(
- schema.string({
- hostname: true,
- }),
- { minSize: 1 }
- )
- ),
- }),
- uuid: schema.maybe(
- schema.string({
- validate: match(uuidRegexp, 'must be a valid uuid'),
- })
- ),
- xsrf: schema.object({
- disableProtection: schema.boolean({ defaultValue: false }),
- allowlist: schema.arrayOf(
- schema.string({ validate: match(/^\//, 'must start with a slash') }),
- { defaultValue: [] }
- ),
- }),
- requestId: schema.object(
- {
- allowFromAnyIp: schema.boolean({ defaultValue: false }),
- ipAllowlist: schema.arrayOf(schema.ip(), { defaultValue: [] }),
- },
- {
- validate(value) {
- if (value.allowFromAnyIp === true && value.ipAllowlist?.length > 0) {
- return `allowFromAnyIp must be set to 'false' if any values are specified in ipAllowlist`;
- }
- },
+ }
+ ),
+ },
+ {
+ validate: (rawConfig) => {
+ if (!rawConfig.basePath && rawConfig.rewriteBasePath) {
+ return 'cannot use [rewriteBasePath] when [basePath] is not specified';
+ }
+
+ if (rawConfig.publicBaseUrl) {
+ const parsedUrl = url.parse(rawConfig.publicBaseUrl);
+ if (parsedUrl.query || parsedUrl.hash || parsedUrl.auth) {
+ return `[publicBaseUrl] may only contain a protocol, host, port, and pathname`;
}
- ),
- },
- {
- validate: (rawConfig) => {
- if (!rawConfig.basePath && rawConfig.rewriteBasePath) {
- return 'cannot use [rewriteBasePath] when [basePath] is not specified';
+ if (parsedUrl.path !== (rawConfig.basePath ?? '/')) {
+ return `[publicBaseUrl] must contain the [basePath]: ${parsedUrl.path} !== ${rawConfig.basePath}`;
}
+ }
- if (rawConfig.publicBaseUrl) {
- const parsedUrl = url.parse(rawConfig.publicBaseUrl);
- if (parsedUrl.query || parsedUrl.hash || parsedUrl.auth) {
- return `[publicBaseUrl] may only contain a protocol, host, port, and pathname`;
- }
- if (parsedUrl.path !== (rawConfig.basePath ?? '/')) {
- return `[publicBaseUrl] must contain the [basePath]: ${parsedUrl.path} !== ${rawConfig.basePath}`;
- }
- }
+ if (!rawConfig.compression.enabled && rawConfig.compression.referrerWhitelist) {
+ return 'cannot use [compression.referrerWhitelist] when [compression.enabled] is set to false';
+ }
- if (!rawConfig.compression.enabled && rawConfig.compression.referrerWhitelist) {
- return 'cannot use [compression.referrerWhitelist] when [compression.enabled] is set to false';
- }
+ if (
+ rawConfig.ssl.enabled &&
+ rawConfig.ssl.redirectHttpFromPort !== undefined &&
+ rawConfig.ssl.redirectHttpFromPort === rawConfig.port
+ ) {
+ return (
+ 'Kibana does not accept http traffic to [port] when ssl is ' +
+ 'enabled (only https is allowed), so [ssl.redirectHttpFromPort] ' +
+ `cannot be configured to the same value. Both are [${rawConfig.port}].`
+ );
+ }
+ },
+ }
+);
- if (
- rawConfig.ssl.enabled &&
- rawConfig.ssl.redirectHttpFromPort !== undefined &&
- rawConfig.ssl.redirectHttpFromPort === rawConfig.port
- ) {
- return (
- 'Kibana does not accept http traffic to [port] when ssl is ' +
- 'enabled (only https is allowed), so [ssl.redirectHttpFromPort] ' +
- `cannot be configured to the same value. Both are [${rawConfig.port}].`
- );
- }
- },
- }
- ),
+export type HttpConfigType = TypeOf;
+
+export const config: ServiceConfigDescriptor = {
+ path: 'server' as const,
+ schema: configSchema,
+ deprecations: ({ rename }) => [rename('maxPayloadBytes', 'maxPayload')],
};
-export type HttpConfigType = TypeOf;
export class HttpConfig implements IHttpConfig {
public name: string;
diff --git a/src/core/server/http/integration_tests/core_services.test.ts b/src/core/server/http/integration_tests/core_services.test.ts
index af358caae8bfc..5433f0d3c3e31 100644
--- a/src/core/server/http/integration_tests/core_services.test.ts
+++ b/src/core/server/http/integration_tests/core_services.test.ts
@@ -12,8 +12,6 @@ import {
legacyClusterClientInstanceMock,
} from './core_service.test.mocks';
-import Boom from '@hapi/boom';
-import { Request } from '@hapi/hapi';
import { errors as esErrors } from 'elasticsearch';
import { LegacyElasticsearchErrorHelpers } from '../../elasticsearch/legacy';
@@ -22,16 +20,6 @@ import { ResponseError } from '@elastic/elasticsearch/lib/errors';
import * as kbnTestServer from '../../../test_helpers/kbn_server';
import { InternalElasticsearchServiceStart } from '../../elasticsearch';
-interface User {
- id: string;
- roles?: string[];
-}
-
-interface StorageData {
- value: User;
- expires: number;
-}
-
const cookieOptions = {
name: 'sid',
encryptionKey: 'something_at_least_32_characters',
@@ -197,172 +185,6 @@ describe('http service', () => {
});
});
- describe('legacy server', () => {
- describe('#registerAuth()', () => {
- const sessionDurationMs = 1000;
-
- let root: ReturnType;
- beforeEach(async () => {
- root = kbnTestServer.createRoot({ plugins: { initialize: false } });
- }, 30000);
-
- afterEach(async () => {
- MockLegacyScopedClusterClient.mockClear();
- await root.shutdown();
- });
-
- it('runs auth for legacy routes and proxy request to legacy server route handlers', async () => {
- const { http } = await root.setup();
- const sessionStorageFactory = await http.createCookieSessionStorageFactory(
- cookieOptions
- );
- http.registerAuth((req, res, toolkit) => {
- if (req.headers.authorization) {
- const user = { id: '42' };
- const sessionStorage = sessionStorageFactory.asScoped(req);
- sessionStorage.set({ value: user, expires: Date.now() + sessionDurationMs });
- return toolkit.authenticated({ state: user });
- } else {
- return res.unauthorized();
- }
- });
- await root.start();
-
- const legacyUrl = '/legacy';
- const kbnServer = kbnTestServer.getKbnServer(root);
- kbnServer.server.route({
- method: 'GET',
- path: legacyUrl,
- handler: () => 'ok from legacy server',
- });
-
- const response = await kbnTestServer.request
- .get(root, legacyUrl)
- .expect(200, 'ok from legacy server');
-
- expect(response.header['set-cookie']).toHaveLength(1);
- });
-
- it('passes authHeaders as request headers to the legacy platform', async () => {
- const token = 'Basic: name:password';
- const { http } = await root.setup();
- const sessionStorageFactory = await http.createCookieSessionStorageFactory(
- cookieOptions
- );
- http.registerAuth((req, res, toolkit) => {
- if (req.headers.authorization) {
- const user = { id: '42' };
- const sessionStorage = sessionStorageFactory.asScoped(req);
- sessionStorage.set({ value: user, expires: Date.now() + sessionDurationMs });
- return toolkit.authenticated({
- state: user,
- requestHeaders: {
- authorization: token,
- },
- });
- } else {
- return res.unauthorized();
- }
- });
- await root.start();
-
- const legacyUrl = '/legacy';
- const kbnServer = kbnTestServer.getKbnServer(root);
- kbnServer.server.route({
- method: 'GET',
- path: legacyUrl,
- handler: (req: Request) => ({
- authorization: req.headers.authorization,
- custom: req.headers.custom,
- }),
- });
-
- await kbnTestServer.request
- .get(root, legacyUrl)
- .set({ custom: 'custom-header' })
- .expect(200, { authorization: token, custom: 'custom-header' });
- });
-
- it('attach security header to a successful response handled by Legacy platform', async () => {
- const authResponseHeader = {
- 'www-authenticate': 'Negotiate ade0234568a4209af8bc0280289eca',
- };
- const { http } = await root.setup();
- const { registerAuth } = http;
-
- registerAuth((req, res, toolkit) => {
- return toolkit.authenticated({ responseHeaders: authResponseHeader });
- });
-
- await root.start();
-
- const kbnServer = kbnTestServer.getKbnServer(root);
- kbnServer.server.route({
- method: 'GET',
- path: '/legacy',
- handler: () => 'ok',
- });
-
- const response = await kbnTestServer.request.get(root, '/legacy').expect(200);
- expect(response.header['www-authenticate']).toBe(authResponseHeader['www-authenticate']);
- });
-
- it('attach security header to an error response handled by Legacy platform', async () => {
- const authResponseHeader = {
- 'www-authenticate': 'Negotiate ade0234568a4209af8bc0280289eca',
- };
- const { http } = await root.setup();
- const { registerAuth } = http;
-
- registerAuth((req, res, toolkit) => {
- return toolkit.authenticated({ responseHeaders: authResponseHeader });
- });
-
- await root.start();
-
- const kbnServer = kbnTestServer.getKbnServer(root);
- kbnServer.server.route({
- method: 'GET',
- path: '/legacy',
- handler: () => {
- throw Boom.badRequest();
- },
- });
-
- const response = await kbnTestServer.request.get(root, '/legacy').expect(400);
- expect(response.header['www-authenticate']).toBe(authResponseHeader['www-authenticate']);
- });
- });
-
- describe('#basePath()', () => {
- let root: ReturnType;
- beforeEach(async () => {
- root = kbnTestServer.createRoot({ plugins: { initialize: false } });
- }, 30000);
-
- afterEach(async () => await root.shutdown());
- it('basePath information for an incoming request is available in legacy server', async () => {
- const reqBasePath = '/requests-specific-base-path';
- const { http } = await root.setup();
- http.registerOnPreRouting((req, res, toolkit) => {
- http.basePath.set(req, reqBasePath);
- return toolkit.next();
- });
-
- await root.start();
-
- const legacyUrl = '/legacy';
- const kbnServer = kbnTestServer.getKbnServer(root);
- kbnServer.server.route({
- method: 'GET',
- path: legacyUrl,
- handler: kbnServer.newPlatform.setup.core.http.basePath.get,
- });
-
- await kbnTestServer.request.get(root, legacyUrl).expect(200, reqBasePath);
- });
- });
- });
describe('legacy elasticsearch client', () => {
let root: ReturnType;
beforeEach(async () => {
diff --git a/src/core/server/i18n/get_kibana_translation_files.test.ts b/src/core/server/i18n/get_kibana_translation_files.test.ts
index 7ca0fe0e79337..45e1a8dfec9cb 100644
--- a/src/core/server/i18n/get_kibana_translation_files.test.ts
+++ b/src/core/server/i18n/get_kibana_translation_files.test.ts
@@ -14,7 +14,7 @@ const mockGetTranslationPaths = getTranslationPaths as jest.Mock;
jest.mock('./get_translation_paths', () => ({
getTranslationPaths: jest.fn().mockResolvedValue([]),
}));
-jest.mock('../utils', () => ({
+jest.mock('@kbn/utils', () => ({
fromRoot: jest.fn().mockImplementation((path: string) => path),
}));
diff --git a/src/core/server/i18n/get_kibana_translation_files.ts b/src/core/server/i18n/get_kibana_translation_files.ts
index 7b5ada2a25f4f..4e7ee718113ce 100644
--- a/src/core/server/i18n/get_kibana_translation_files.ts
+++ b/src/core/server/i18n/get_kibana_translation_files.ts
@@ -7,7 +7,7 @@
*/
import { basename } from 'path';
-import { fromRoot } from '../utils';
+import { fromRoot } from '@kbn/utils';
import { getTranslationPaths } from './get_translation_paths';
export const getKibanaTranslationFiles = async (
diff --git a/src/core/server/index.ts b/src/core/server/index.ts
index 963b69eac4f7f..2c6fa74cb54a0 100644
--- a/src/core/server/index.ts
+++ b/src/core/server/index.ts
@@ -406,8 +406,6 @@ export type {
SavedObjectsMigrationVersion,
} from './types';
-export type { LegacyServiceSetupDeps, LegacyServiceStartDeps, LegacyConfig } from './legacy';
-
export { ServiceStatusLevels } from './status';
export type { CoreStatus, ServiceStatus, ServiceStatusLevel, StatusServiceSetup } from './status';
diff --git a/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap b/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap
deleted file mode 100644
index 69b7f9fc78315..0000000000000
--- a/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap
+++ /dev/null
@@ -1,27 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`once LegacyService is set up with connection info reconfigures logging configuration if new config is received.: applyLoggingConfiguration params 1`] = `
-Array [
- Array [
- Object {
- "logging": Object {
- "verbose": true,
- },
- "path": Object {},
- },
- ],
-]
-`;
-
-exports[`once LegacyService is set up without connection info reconfigures logging configuration if new config is received.: applyLoggingConfiguration params 1`] = `
-Array [
- Array [
- Object {
- "logging": Object {
- "verbose": true,
- },
- "path": Object {},
- },
- ],
-]
-`;
diff --git a/src/core/server/legacy/config/ensure_valid_configuration.test.ts b/src/core/server/legacy/config/ensure_valid_configuration.test.ts
deleted file mode 100644
index febf91625378d..0000000000000
--- a/src/core/server/legacy/config/ensure_valid_configuration.test.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { ensureValidConfiguration } from './ensure_valid_configuration';
-import { getUnusedConfigKeys } from './get_unused_config_keys';
-import { configServiceMock } from '../../config/mocks';
-
-jest.mock('./get_unused_config_keys');
-
-describe('ensureValidConfiguration', () => {
- let configService: ReturnType;
-
- beforeEach(() => {
- jest.clearAllMocks();
- configService = configServiceMock.create();
- configService.getUsedPaths.mockReturnValue(Promise.resolve(['core', 'elastic']));
-
- (getUnusedConfigKeys as any).mockImplementation(() => []);
- });
-
- it('calls getUnusedConfigKeys with correct parameters', async () => {
- await ensureValidConfiguration(
- configService as any,
- {
- settings: 'settings',
- legacyConfig: 'pluginExtendedConfig',
- } as any
- );
- expect(getUnusedConfigKeys).toHaveBeenCalledTimes(1);
- expect(getUnusedConfigKeys).toHaveBeenCalledWith({
- coreHandledConfigPaths: ['core', 'elastic'],
- settings: 'settings',
- legacyConfig: 'pluginExtendedConfig',
- });
- });
-
- it('returns normally when there is no unused keys', async () => {
- await expect(
- ensureValidConfiguration(configService as any, {} as any)
- ).resolves.toBeUndefined();
-
- expect(getUnusedConfigKeys).toHaveBeenCalledTimes(1);
- });
-
- it('throws when there are some unused keys', async () => {
- (getUnusedConfigKeys as any).mockImplementation(() => ['some.key', 'some.other.key']);
-
- await expect(
- ensureValidConfiguration(configService as any, {} as any)
- ).rejects.toMatchInlineSnapshot(
- `[Error: Unknown configuration key(s): "some.key", "some.other.key". Check for spelling errors and ensure that expected plugins are installed.]`
- );
- });
-});
diff --git a/src/core/server/legacy/config/get_unused_config_keys.test.ts b/src/core/server/legacy/config/get_unused_config_keys.test.ts
deleted file mode 100644
index 86b4e0aeeea59..0000000000000
--- a/src/core/server/legacy/config/get_unused_config_keys.test.ts
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { LegacyConfig, LegacyVars } from '../types';
-import { getUnusedConfigKeys } from './get_unused_config_keys';
-
-describe('getUnusedConfigKeys', () => {
- beforeEach(() => {
- jest.resetAllMocks();
- });
-
- const getConfig = (values: LegacyVars = {}): LegacyConfig =>
- ({
- get: () => values as any,
- } as LegacyConfig);
-
- describe('not using core or plugin specs', () => {
- it('should return an empty list for empty parameters', async () => {
- expect(
- await getUnusedConfigKeys({
- coreHandledConfigPaths: [],
- settings: {},
- legacyConfig: getConfig(),
- })
- ).toEqual([]);
- });
-
- it('returns empty list when config and settings have the same properties', async () => {
- expect(
- await getUnusedConfigKeys({
- coreHandledConfigPaths: [],
- settings: {
- presentInBoth: true,
- alsoInBoth: 'someValue',
- },
- legacyConfig: getConfig({
- presentInBoth: true,
- alsoInBoth: 'someValue',
- }),
- })
- ).toEqual([]);
- });
-
- it('returns empty list when config has entries not present in settings', async () => {
- expect(
- await getUnusedConfigKeys({
- coreHandledConfigPaths: [],
- settings: {
- presentInBoth: true,
- },
- legacyConfig: getConfig({
- presentInBoth: true,
- onlyInConfig: 'someValue',
- }),
- })
- ).toEqual([]);
- });
-
- it('returns the list of properties from settings not present in config', async () => {
- expect(
- await getUnusedConfigKeys({
- coreHandledConfigPaths: [],
- settings: {
- presentInBoth: true,
- onlyInSetting: 'value',
- },
- legacyConfig: getConfig({
- presentInBoth: true,
- }),
- })
- ).toEqual(['onlyInSetting']);
- });
-
- it('correctly handle nested properties', async () => {
- expect(
- await getUnusedConfigKeys({
- coreHandledConfigPaths: [],
- settings: {
- elasticsearch: {
- username: 'foo',
- password: 'bar',
- },
- },
- legacyConfig: getConfig({
- elasticsearch: {
- username: 'foo',
- onlyInConfig: 'default',
- },
- }),
- })
- ).toEqual(['elasticsearch.password']);
- });
-
- it('correctly handle "env" specific case', async () => {
- expect(
- await getUnusedConfigKeys({
- coreHandledConfigPaths: [],
- settings: {
- env: 'development',
- },
- legacyConfig: getConfig({
- env: {
- name: 'development',
- },
- }),
- })
- ).toEqual([]);
- });
-
- it('correctly handle array properties', async () => {
- expect(
- await getUnusedConfigKeys({
- coreHandledConfigPaths: [],
- settings: {
- prop: ['a', 'b', 'c'],
- },
- legacyConfig: getConfig({
- prop: ['a'],
- }),
- })
- ).toEqual([]);
- });
- });
-
- it('ignores properties managed by the new platform', async () => {
- expect(
- await getUnusedConfigKeys({
- coreHandledConfigPaths: ['core', 'foo.bar'],
- settings: {
- core: {
- prop: 'value',
- },
- foo: {
- bar: true,
- dolly: true,
- },
- },
- legacyConfig: getConfig({}),
- })
- ).toEqual(['foo.dolly']);
- });
-
- it('handles array values', async () => {
- expect(
- await getUnusedConfigKeys({
- coreHandledConfigPaths: ['core', 'array'],
- settings: {
- core: {
- prop: 'value',
- array: [1, 2, 3],
- },
- array: ['some', 'values'],
- },
- legacyConfig: getConfig({}),
- })
- ).toEqual([]);
- });
-});
diff --git a/src/core/server/legacy/config/get_unused_config_keys.ts b/src/core/server/legacy/config/get_unused_config_keys.ts
deleted file mode 100644
index a2da6dc97225e..0000000000000
--- a/src/core/server/legacy/config/get_unused_config_keys.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { difference } from 'lodash';
-import { getFlattenedObject } from '@kbn/std';
-import { hasConfigPathIntersection } from '../../config';
-import { LegacyConfig, LegacyVars } from '../types';
-
-const getFlattenedKeys = (object: object) => Object.keys(getFlattenedObject(object));
-
-export async function getUnusedConfigKeys({
- coreHandledConfigPaths,
- settings,
- legacyConfig,
-}: {
- coreHandledConfigPaths: string[];
- settings: LegacyVars;
- legacyConfig: LegacyConfig;
-}) {
- const inputKeys = getFlattenedKeys(settings);
- const appliedKeys = getFlattenedKeys(legacyConfig.get());
-
- if (inputKeys.includes('env')) {
- // env is a special case key, see https://github.com/elastic/kibana/blob/848bf17b/src/legacy/server/config/config.js#L74
- // where it is deleted from the settings before being injected into the schema via context and
- // then renamed to `env.name` https://github.com/elastic/kibana/blob/848bf17/src/legacy/server/config/schema.js#L17
- inputKeys[inputKeys.indexOf('env')] = 'env.name';
- }
-
- // Filter out keys that are marked as used in the core (e.g. by new core plugins).
- return difference(inputKeys, appliedKeys).filter(
- (unusedConfigKey) =>
- !coreHandledConfigPaths.some((usedInCoreConfigKey) =>
- hasConfigPathIntersection(unusedConfigKey, usedInCoreConfigKey)
- )
- );
-}
diff --git a/src/core/server/legacy/config/index.ts b/src/core/server/legacy/config/index.ts
deleted file mode 100644
index b674b1386b786..0000000000000
--- a/src/core/server/legacy/config/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-export { ensureValidConfiguration } from './ensure_valid_configuration';
diff --git a/src/core/server/legacy/index.ts b/src/core/server/legacy/index.ts
index 8614265e4375d..39ffef501a9ec 100644
--- a/src/core/server/legacy/index.ts
+++ b/src/core/server/legacy/index.ts
@@ -6,16 +6,6 @@
* Side Public License, v 1.
*/
-/** @internal */
-export { ensureValidConfiguration } from './config';
/** @internal */
export type { ILegacyService } from './legacy_service';
export { LegacyService } from './legacy_service';
-/** @internal */
-export type {
- LegacyVars,
- LegacyConfig,
- LegacyServiceSetupDeps,
- LegacyServiceStartDeps,
- LegacyServiceSetupConfig,
-} from './types';
diff --git a/src/core/server/legacy/integration_tests/legacy_service.test.ts b/src/core/server/legacy/integration_tests/legacy_service.test.ts
deleted file mode 100644
index 715749c6ef0cb..0000000000000
--- a/src/core/server/legacy/integration_tests/legacy_service.test.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import * as kbnTestServer from '../../../test_helpers/kbn_server';
-
-describe('legacy service', () => {
- describe('http server', () => {
- let root: ReturnType;
- beforeEach(() => {
- root = kbnTestServer.createRoot({
- migrations: { skip: true },
- plugins: { initialize: false },
- });
- }, 30000);
-
- afterEach(async () => await root.shutdown());
-
- it("handles http request in Legacy platform if New platform doesn't handle it", async () => {
- const { http } = await root.setup();
- const rootUrl = '/route';
- const router = http.createRouter(rootUrl);
- router.get({ path: '/new-platform', validate: false }, (context, req, res) =>
- res.ok({ body: 'from-new-platform' })
- );
-
- await root.start();
-
- const legacyPlatformUrl = `${rootUrl}/legacy-platform`;
- const kbnServer = kbnTestServer.getKbnServer(root);
- kbnServer.server.route({
- method: 'GET',
- path: legacyPlatformUrl,
- handler: () => 'ok from legacy server',
- });
-
- await kbnTestServer.request.get(root, '/route/new-platform').expect(200, 'from-new-platform');
-
- await kbnTestServer.request.get(root, legacyPlatformUrl).expect(200, 'ok from legacy server');
- });
- it('throws error if Legacy and New platforms register handler for the same route', async () => {
- const { http } = await root.setup();
- const rootUrl = '/route';
- const router = http.createRouter(rootUrl);
- router.get({ path: '', validate: false }, (context, req, res) =>
- res.ok({ body: 'from-new-platform' })
- );
-
- await root.start();
-
- const kbnServer = kbnTestServer.getKbnServer(root);
- expect(() =>
- kbnServer.server.route({
- method: 'GET',
- path: rootUrl,
- handler: () => 'ok from legacy server',
- })
- ).toThrowErrorMatchingInlineSnapshot(`"New route /route conflicts with existing /route"`);
- });
- });
-});
diff --git a/src/core/server/legacy/legacy_service.mock.ts b/src/core/server/legacy/legacy_service.mock.ts
index 1f4c308be0107..0d72318a630e0 100644
--- a/src/core/server/legacy/legacy_service.mock.ts
+++ b/src/core/server/legacy/legacy_service.mock.ts
@@ -8,26 +8,14 @@
import type { PublicMethodsOf } from '@kbn/utility-types';
import { LegacyService } from './legacy_service';
-import { LegacyConfig, LegacyServiceSetupDeps } from './types';
-type LegacyServiceMock = jest.Mocked & { legacyId: symbol }>;
+type LegacyServiceMock = jest.Mocked>;
const createLegacyServiceMock = (): LegacyServiceMock => ({
- legacyId: Symbol(),
- setupLegacyConfig: jest.fn(),
setup: jest.fn(),
- start: jest.fn(),
stop: jest.fn(),
});
-const createLegacyConfigMock = (): jest.Mocked => ({
- get: jest.fn(),
- has: jest.fn(),
- set: jest.fn(),
-});
-
export const legacyServiceMock = {
create: createLegacyServiceMock,
- createSetupContract: (deps: LegacyServiceSetupDeps) => createLegacyServiceMock().setup(deps),
- createLegacyConfig: createLegacyConfigMock,
};
diff --git a/src/core/server/legacy/legacy_service.test.mocks.ts b/src/core/server/legacy/legacy_service.test.mocks.ts
new file mode 100644
index 0000000000000..506f0fd6f96d3
--- /dev/null
+++ b/src/core/server/legacy/legacy_service.test.mocks.ts
@@ -0,0 +1,18 @@
+/*
+ * 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 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export const reconfigureLoggingMock = jest.fn();
+export const setupLoggingMock = jest.fn();
+export const setupLoggingRotateMock = jest.fn();
+
+jest.doMock('@kbn/legacy-logging', () => ({
+ ...(jest.requireActual('@kbn/legacy-logging') as any),
+ reconfigureLogging: reconfigureLoggingMock,
+ setupLogging: setupLoggingMock,
+ setupLoggingRotate: setupLoggingRotateMock,
+}));
diff --git a/src/core/server/legacy/legacy_service.test.ts b/src/core/server/legacy/legacy_service.test.ts
index 67b5393f0b838..6b20bd7434baf 100644
--- a/src/core/server/legacy/legacy_service.test.ts
+++ b/src/core/server/legacy/legacy_service.test.ts
@@ -6,35 +6,22 @@
* Side Public License, v 1.
*/
-jest.mock('../../../legacy/server/kbn_server');
-
-import { BehaviorSubject, throwError } from 'rxjs';
+import {
+ setupLoggingMock,
+ setupLoggingRotateMock,
+ reconfigureLoggingMock,
+} from './legacy_service.test.mocks';
+
+import { BehaviorSubject } from 'rxjs';
+import moment from 'moment';
import { REPO_ROOT } from '@kbn/dev-utils';
-import KbnServer from '../../../legacy/server/kbn_server';
import { Config, Env, ObjectToConfigAdapter } from '../config';
-import { DiscoveredPlugin } from '../plugins';
import { getEnvOptions, configServiceMock } from '../config/mocks';
import { loggingSystemMock } from '../logging/logging_system.mock';
-import { contextServiceMock } from '../context/context_service.mock';
import { httpServiceMock } from '../http/http_service.mock';
-import { uiSettingsServiceMock } from '../ui_settings/ui_settings_service.mock';
-import { savedObjectsServiceMock } from '../saved_objects/saved_objects_service.mock';
-import { capabilitiesServiceMock } from '../capabilities/capabilities_service.mock';
-import { httpResourcesMock } from '../http_resources/http_resources_service.mock';
-import { setupMock as renderingServiceMock } from '../rendering/__mocks__/rendering_service';
-import { environmentServiceMock } from '../environment/environment_service.mock';
-import { LegacyServiceSetupDeps, LegacyServiceStartDeps } from './types';
-import { LegacyService } from './legacy_service';
-import { coreMock } from '../mocks';
-import { statusServiceMock } from '../status/status_service.mock';
-import { loggingServiceMock } from '../logging/logging_service.mock';
-import { metricsServiceMock } from '../metrics/metrics_service.mock';
-import { i18nServiceMock } from '../i18n/i18n_service.mock';
-import { deprecationsServiceMock } from '../deprecations/deprecations_service.mock';
-
-const MockKbnServer: jest.Mock = KbnServer as any;
+import { LegacyService, LegacyServiceSetupDeps } from './legacy_service';
let coreId: symbol;
let env: Env;
@@ -42,71 +29,16 @@ let config$: BehaviorSubject;
let setupDeps: LegacyServiceSetupDeps;
-let startDeps: LegacyServiceStartDeps;
-
const logger = loggingSystemMock.create();
let configService: ReturnType;
-let environmentSetup: ReturnType;
beforeEach(() => {
coreId = Symbol();
env = Env.createDefault(REPO_ROOT, getEnvOptions());
configService = configServiceMock.create();
- environmentSetup = environmentServiceMock.createSetupContract();
-
- MockKbnServer.prototype.ready = jest.fn().mockReturnValue(Promise.resolve());
- MockKbnServer.prototype.listen = jest.fn();
setupDeps = {
- core: {
- capabilities: capabilitiesServiceMock.createSetupContract(),
- context: contextServiceMock.createSetupContract(),
- elasticsearch: { legacy: {} } as any,
- i18n: i18nServiceMock.createSetupContract(),
- uiSettings: uiSettingsServiceMock.createSetupContract(),
- http: {
- ...httpServiceMock.createInternalSetupContract(),
- auth: {
- getAuthHeaders: () => undefined,
- } as any,
- },
- httpResources: httpResourcesMock.createSetupContract(),
- savedObjects: savedObjectsServiceMock.createInternalSetupContract(),
- plugins: {
- initialized: true,
- contracts: new Map([['plugin-id', 'plugin-value']]),
- },
- rendering: renderingServiceMock,
- environment: environmentSetup,
- status: statusServiceMock.createInternalSetupContract(),
- logging: loggingServiceMock.createInternalSetupContract(),
- metrics: metricsServiceMock.createInternalSetupContract(),
- deprecations: deprecationsServiceMock.createInternalSetupContract(),
- },
- plugins: { 'plugin-id': 'plugin-value' },
- uiPlugins: {
- public: new Map([['plugin-id', {} as DiscoveredPlugin]]),
- internal: new Map([
- [
- 'plugin-id',
- {
- requiredBundles: [],
- version: '8.0.0',
- publicTargetDir: 'path/to/target/public',
- publicAssetsDir: '/plugins/name/assets/',
- },
- ],
- ]),
- browserConfigs: new Map(),
- },
- };
-
- startDeps = {
- core: {
- ...coreMock.createInternalStart(),
- plugins: { contracts: new Map() },
- },
- plugins: {},
+ http: httpServiceMock.createInternalSetupContract(),
};
config$ = new BehaviorSubject(
@@ -117,98 +49,78 @@ beforeEach(() => {
);
configService.getConfig$.mockReturnValue(config$);
- configService.getUsedPaths.mockResolvedValue(['foo.bar']);
});
afterEach(() => {
jest.clearAllMocks();
+ setupLoggingMock.mockReset();
+ setupLoggingRotateMock.mockReset();
+ reconfigureLoggingMock.mockReset();
});
-describe('once LegacyService is set up with connection info', () => {
- test('creates legacy kbnServer and calls `listen`.', async () => {
- configService.atPath.mockReturnValue(new BehaviorSubject({ autoListen: true }));
- const legacyService = new LegacyService({
- coreId,
- env,
- logger,
- configService,
+describe('#setup', () => {
+ it('initializes legacy logging', async () => {
+ const opsConfig = {
+ interval: moment.duration(5, 'second'),
+ };
+ const opsConfig$ = new BehaviorSubject(opsConfig);
+
+ const loggingConfig = {
+ foo: 'bar',
+ };
+ const loggingConfig$ = new BehaviorSubject(loggingConfig);
+
+ configService.atPath.mockImplementation((path) => {
+ if (path === 'ops') {
+ return opsConfig$;
+ }
+ if (path === 'logging') {
+ return loggingConfig$;
+ }
+ return new BehaviorSubject({});
});
- await legacyService.setupLegacyConfig();
- await legacyService.setup(setupDeps);
- await legacyService.start(startDeps);
-
- expect(MockKbnServer).toHaveBeenCalledTimes(1);
- expect(MockKbnServer).toHaveBeenCalledWith(
- { path: { autoListen: true }, server: { autoListen: true } }, // Because of the mock, path also gets the value
- expect.objectContaining({ get: expect.any(Function) }),
- expect.any(Object)
- );
- expect(MockKbnServer.mock.calls[0][1].get()).toEqual(
- expect.objectContaining({
- path: expect.objectContaining({ autoListen: true }),
- server: expect.objectContaining({ autoListen: true }),
- })
- );
-
- const [mockKbnServer] = MockKbnServer.mock.instances;
- expect(mockKbnServer.listen).toHaveBeenCalledTimes(1);
- expect(mockKbnServer.close).not.toHaveBeenCalled();
- });
-
- test('creates legacy kbnServer but does not call `listen` if `autoListen: false`.', async () => {
- configService.atPath.mockReturnValue(new BehaviorSubject({ autoListen: false }));
-
const legacyService = new LegacyService({
coreId,
env,
logger,
configService: configService as any,
});
- await legacyService.setupLegacyConfig();
+
await legacyService.setup(setupDeps);
- await legacyService.start(startDeps);
- expect(MockKbnServer).toHaveBeenCalledTimes(1);
- expect(MockKbnServer).toHaveBeenCalledWith(
- { path: { autoListen: false }, server: { autoListen: true } },
- expect.objectContaining({ get: expect.any(Function) }),
- expect.any(Object)
+ expect(setupLoggingMock).toHaveBeenCalledTimes(1);
+ expect(setupLoggingMock).toHaveBeenCalledWith(
+ setupDeps.http.server,
+ loggingConfig,
+ opsConfig.interval.asMilliseconds()
);
- const legacyConfig = MockKbnServer.mock.calls[0][1].get();
- expect(legacyConfig.path.autoListen).toBe(false);
- expect(legacyConfig.server.autoListen).toBe(true);
-
- const [mockKbnServer] = MockKbnServer.mock.instances;
- expect(mockKbnServer.ready).toHaveBeenCalledTimes(1);
- expect(mockKbnServer.listen).not.toHaveBeenCalled();
- expect(mockKbnServer.close).not.toHaveBeenCalled();
+ expect(setupLoggingRotateMock).toHaveBeenCalledTimes(1);
+ expect(setupLoggingRotateMock).toHaveBeenCalledWith(setupDeps.http.server, loggingConfig);
});
- test('creates legacy kbnServer and closes it if `listen` fails.', async () => {
- configService.atPath.mockReturnValue(new BehaviorSubject({ autoListen: true }));
- MockKbnServer.prototype.listen.mockRejectedValue(new Error('something failed'));
- const legacyService = new LegacyService({
- coreId,
- env,
- logger,
- configService: configService as any,
+ it('reloads the logging config when the config changes', async () => {
+ const opsConfig = {
+ interval: moment.duration(5, 'second'),
+ };
+ const opsConfig$ = new BehaviorSubject(opsConfig);
+
+ const loggingConfig = {
+ foo: 'bar',
+ };
+ const loggingConfig$ = new BehaviorSubject(loggingConfig);
+
+ configService.atPath.mockImplementation((path) => {
+ if (path === 'ops') {
+ return opsConfig$;
+ }
+ if (path === 'logging') {
+ return loggingConfig$;
+ }
+ return new BehaviorSubject({});
});
- await legacyService.setupLegacyConfig();
- await legacyService.setup(setupDeps);
- await expect(legacyService.start(startDeps)).rejects.toThrowErrorMatchingInlineSnapshot(
- `"something failed"`
- );
-
- const [mockKbnServer] = MockKbnServer.mock.instances;
- expect(mockKbnServer.listen).toHaveBeenCalled();
- expect(mockKbnServer.close).toHaveBeenCalled();
- });
-
- test('throws if fails to retrieve initial config.', async () => {
- configService.getConfig$.mockReturnValue(throwError(new Error('something failed')));
const legacyService = new LegacyService({
coreId,
env,
@@ -216,150 +128,70 @@ describe('once LegacyService is set up with connection info', () => {
configService: configService as any,
});
- await expect(legacyService.setupLegacyConfig()).rejects.toThrowErrorMatchingInlineSnapshot(
- `"something failed"`
- );
- await expect(legacyService.setup(setupDeps)).rejects.toThrowErrorMatchingInlineSnapshot(
- `"Legacy config not initialized yet. Ensure LegacyService.setupLegacyConfig() is called before LegacyService.setup()"`
- );
- await expect(legacyService.start(startDeps)).rejects.toThrowErrorMatchingInlineSnapshot(
- `"Legacy service is not setup yet."`
- );
-
- expect(MockKbnServer).not.toHaveBeenCalled();
- });
-
- test('reconfigures logging configuration if new config is received.', async () => {
- const legacyService = new LegacyService({
- coreId,
- env,
- logger,
- configService: configService as any,
- });
- await legacyService.setupLegacyConfig();
await legacyService.setup(setupDeps);
- await legacyService.start(startDeps);
-
- const [mockKbnServer] = MockKbnServer.mock.instances as Array>;
- expect(mockKbnServer.applyLoggingConfiguration).not.toHaveBeenCalled();
-
- config$.next(new ObjectToConfigAdapter({ logging: { verbose: true } }));
- expect(mockKbnServer.applyLoggingConfiguration.mock.calls).toMatchSnapshot(
- `applyLoggingConfiguration params`
+ expect(reconfigureLoggingMock).toHaveBeenCalledTimes(1);
+ expect(reconfigureLoggingMock).toHaveBeenCalledWith(
+ setupDeps.http.server,
+ loggingConfig,
+ opsConfig.interval.asMilliseconds()
);
- });
- test('logs error if re-configuring fails.', async () => {
- const legacyService = new LegacyService({
- coreId,
- env,
- logger,
- configService: configService as any,
+ loggingConfig$.next({
+ foo: 'changed',
});
- await legacyService.setupLegacyConfig();
- await legacyService.setup(setupDeps);
- await legacyService.start(startDeps);
- const [mockKbnServer] = MockKbnServer.mock.instances as Array>;
- expect(mockKbnServer.applyLoggingConfiguration).not.toHaveBeenCalled();
- expect(loggingSystemMock.collect(logger).error).toEqual([]);
+ expect(reconfigureLoggingMock).toHaveBeenCalledTimes(2);
+ expect(reconfigureLoggingMock).toHaveBeenCalledWith(
+ setupDeps.http.server,
+ { foo: 'changed' },
+ opsConfig.interval.asMilliseconds()
+ );
+ });
- const configError = new Error('something went wrong');
- mockKbnServer.applyLoggingConfiguration.mockImplementation(() => {
- throw configError;
+ it('stops reloading logging config once the service is stopped', async () => {
+ const opsConfig = {
+ interval: moment.duration(5, 'second'),
+ };
+ const opsConfig$ = new BehaviorSubject(opsConfig);
+
+ const loggingConfig = {
+ foo: 'bar',
+ };
+ const loggingConfig$ = new BehaviorSubject(loggingConfig);
+
+ configService.atPath.mockImplementation((path) => {
+ if (path === 'ops') {
+ return opsConfig$;
+ }
+ if (path === 'logging') {
+ return loggingConfig$;
+ }
+ return new BehaviorSubject({});
});
- config$.next(new ObjectToConfigAdapter({ logging: { verbose: true } }));
-
- expect(loggingSystemMock.collect(logger).error).toEqual([[configError]]);
- });
-
- test('logs error if config service fails.', async () => {
const legacyService = new LegacyService({
coreId,
env,
logger,
configService: configService as any,
});
- await legacyService.setupLegacyConfig();
- await legacyService.setup(setupDeps);
- await legacyService.start(startDeps);
-
- const [mockKbnServer] = MockKbnServer.mock.instances;
- expect(mockKbnServer.applyLoggingConfiguration).not.toHaveBeenCalled();
- expect(loggingSystemMock.collect(logger).error).toEqual([]);
-
- const configError = new Error('something went wrong');
- config$.error(configError);
-
- expect(mockKbnServer.applyLoggingConfiguration).not.toHaveBeenCalled();
- expect(loggingSystemMock.collect(logger).error).toEqual([[configError]]);
- });
-});
-describe('once LegacyService is set up without connection info', () => {
- let legacyService: LegacyService;
- beforeEach(async () => {
- legacyService = new LegacyService({ coreId, env, logger, configService: configService as any });
- await legacyService.setupLegacyConfig();
await legacyService.setup(setupDeps);
- await legacyService.start(startDeps);
- });
- test('creates legacy kbnServer with `autoListen: false`.', () => {
- expect(MockKbnServer).toHaveBeenCalledTimes(1);
- expect(MockKbnServer).toHaveBeenCalledWith(
- { path: {}, server: { autoListen: true } },
- expect.objectContaining({ get: expect.any(Function) }),
- expect.any(Object)
- );
- expect(MockKbnServer.mock.calls[0][1].get()).toEqual(
- expect.objectContaining({
- server: expect.objectContaining({ autoListen: true }),
- })
+ expect(reconfigureLoggingMock).toHaveBeenCalledTimes(1);
+ expect(reconfigureLoggingMock).toHaveBeenCalledWith(
+ setupDeps.http.server,
+ loggingConfig,
+ opsConfig.interval.asMilliseconds()
);
- });
-
- test('reconfigures logging configuration if new config is received.', async () => {
- const [mockKbnServer] = MockKbnServer.mock.instances as Array>;
- expect(mockKbnServer.applyLoggingConfiguration).not.toHaveBeenCalled();
- config$.next(new ObjectToConfigAdapter({ logging: { verbose: true } }));
+ await legacyService.stop();
- expect(mockKbnServer.applyLoggingConfiguration.mock.calls).toMatchSnapshot(
- `applyLoggingConfiguration params`
- );
- });
-});
-
-describe('start', () => {
- test('Cannot start without setup phase', async () => {
- const legacyService = new LegacyService({
- coreId,
- env,
- logger,
- configService: configService as any,
+ loggingConfig$.next({
+ foo: 'changed',
});
- await expect(legacyService.start(startDeps)).rejects.toThrowErrorMatchingInlineSnapshot(
- `"Legacy service is not setup yet."`
- );
- });
-});
-test('Sets the server.uuid property on the legacy configuration', async () => {
- configService.atPath.mockReturnValue(new BehaviorSubject({ autoListen: true }));
- const legacyService = new LegacyService({
- coreId,
- env,
- logger,
- configService: configService as any,
+ expect(reconfigureLoggingMock).toHaveBeenCalledTimes(1);
});
-
- environmentSetup.instanceUuid = 'UUID_FROM_SERVICE';
-
- const { legacyConfig } = await legacyService.setupLegacyConfig();
- await legacyService.setup(setupDeps);
-
- expect(legacyConfig.get('server.uuid')).toBe('UUID_FROM_SERVICE');
});
diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts
index 43b348a5ff4a2..1d5343ff5311d 100644
--- a/src/core/server/legacy/legacy_service.ts
+++ b/src/core/server/legacy/legacy_service.ts
@@ -6,141 +6,61 @@
* Side Public License, v 1.
*/
-import { combineLatest, ConnectableObservable, Observable, Subscription } from 'rxjs';
-import { first, map, publishReplay, tap } from 'rxjs/operators';
+import { combineLatest, Observable, Subscription } from 'rxjs';
+import { first } from 'rxjs/operators';
+import { Server } from '@hapi/hapi';
import type { PublicMethodsOf } from '@kbn/utility-types';
-import { PathConfigType } from '@kbn/utils';
+import {
+ reconfigureLogging,
+ setupLogging,
+ setupLoggingRotate,
+ LegacyLoggingConfig,
+} from '@kbn/legacy-logging';
-import type { RequestHandlerContext } from 'src/core/server';
-// @ts-expect-error legacy config class
-import { Config as LegacyConfigClass } from '../../../legacy/server/config';
-import { CoreService } from '../../types';
-import { Config } from '../config';
import { CoreContext } from '../core_context';
-import { CspConfigType, config as cspConfig } from '../csp';
-import {
- HttpConfig,
- HttpConfigType,
- config as httpConfig,
- IRouter,
- RequestHandlerContextProvider,
-} from '../http';
+import { config as loggingConfig } from '../logging';
+import { opsConfig, OpsConfigType } from '../metrics';
import { Logger } from '../logging';
-import { LegacyServiceSetupDeps, LegacyServiceStartDeps, LegacyConfig, LegacyVars } from './types';
-import { ExternalUrlConfigType, config as externalUrlConfig } from '../external_url';
-import { CoreSetup, CoreStart } from '..';
-
-interface LegacyKbnServer {
- applyLoggingConfiguration: (settings: Readonly) => void;
- listen: () => Promise;
- ready: () => Promise;
- close: () => Promise;
-}
+import { InternalHttpServiceSetup } from '../http';
-function getLegacyRawConfig(config: Config, pathConfig: PathConfigType) {
- const rawConfig = config.toRaw();
-
- // Elasticsearch config is solely handled by the core and legacy platform
- // shouldn't have direct access to it.
- if (rawConfig.elasticsearch !== undefined) {
- delete rawConfig.elasticsearch;
- }
-
- return {
- ...rawConfig,
- // We rely heavily in the default value of 'path.data' in the legacy world and,
- // since it has been moved to NP, it won't show up in RawConfig.
- path: pathConfig,
- };
+export interface LegacyServiceSetupDeps {
+ http: InternalHttpServiceSetup;
}
/** @internal */
export type ILegacyService = PublicMethodsOf;
/** @internal */
-export class LegacyService implements CoreService {
- /** Symbol to represent the legacy platform as a fake "plugin". Used by the ContextService */
- public readonly legacyId = Symbol();
+export class LegacyService {
private readonly log: Logger;
- private readonly httpConfig$: Observable;
- private kbnServer?: LegacyKbnServer;
+ private readonly opsConfig$: Observable;
+ private readonly legacyLoggingConfig$: Observable;
private configSubscription?: Subscription;
- private setupDeps?: LegacyServiceSetupDeps;
- private update$?: ConnectableObservable<[Config, PathConfigType]>;
- private legacyRawConfig?: LegacyConfig;
- private settings?: LegacyVars;
- constructor(private readonly coreContext: CoreContext) {
+ constructor(coreContext: CoreContext) {
const { logger, configService } = coreContext;
this.log = logger.get('legacy-service');
- this.httpConfig$ = combineLatest(
- configService.atPath(httpConfig.path),
- configService.atPath(cspConfig.path),
- configService.atPath(externalUrlConfig.path)
- ).pipe(map(([http, csp, externalUrl]) => new HttpConfig(http, csp, externalUrl)));
- }
-
- public async setupLegacyConfig() {
- this.update$ = combineLatest([
- this.coreContext.configService.getConfig$(),
- this.coreContext.configService.atPath('path'),
- ]).pipe(
- tap(([config, pathConfig]) => {
- if (this.kbnServer !== undefined) {
- this.kbnServer.applyLoggingConfiguration(getLegacyRawConfig(config, pathConfig));
- }
- }),
- tap({ error: (err) => this.log.error(err) }),
- publishReplay(1)
- ) as ConnectableObservable<[Config, PathConfigType]>;
-
- this.configSubscription = this.update$.connect();
-
- this.settings = await this.update$
- .pipe(
- first(),
- map(([config, pathConfig]) => getLegacyRawConfig(config, pathConfig))
- )
- .toPromise();
-
- this.legacyRawConfig = LegacyConfigClass.withDefaultSchema(this.settings);
-
- return {
- settings: this.settings,
- legacyConfig: this.legacyRawConfig!,
- };
+ this.legacyLoggingConfig$ = configService.atPath(loggingConfig.path);
+ this.opsConfig$ = configService.atPath(opsConfig.path);
}
public async setup(setupDeps: LegacyServiceSetupDeps) {
this.log.debug('setting up legacy service');
-
- if (!this.legacyRawConfig) {
- throw new Error(
- 'Legacy config not initialized yet. Ensure LegacyService.setupLegacyConfig() is called before LegacyService.setup()'
- );
- }
-
- // propagate the instance uuid to the legacy config, as it was the legacy way to access it.
- this.legacyRawConfig!.set('server.uuid', setupDeps.core.environment.instanceUuid);
-
- this.setupDeps = setupDeps;
+ await this.setupLegacyLogging(setupDeps.http.server);
}
- public async start(startDeps: LegacyServiceStartDeps) {
- const { setupDeps } = this;
-
- if (!setupDeps || !this.legacyRawConfig) {
- throw new Error('Legacy service is not setup yet.');
- }
+ private async setupLegacyLogging(server: Server) {
+ const legacyLoggingConfig = await this.legacyLoggingConfig$.pipe(first()).toPromise();
+ const currentOpsConfig = await this.opsConfig$.pipe(first()).toPromise();
- this.log.debug('starting legacy service');
+ await setupLogging(server, legacyLoggingConfig, currentOpsConfig.interval.asMilliseconds());
+ await setupLoggingRotate(server, legacyLoggingConfig);
- this.kbnServer = await this.createKbnServer(
- this.settings!,
- this.legacyRawConfig!,
- setupDeps,
- startDeps
+ this.configSubscription = combineLatest([this.legacyLoggingConfig$, this.opsConfig$]).subscribe(
+ ([newLoggingConfig, newOpsConfig]) => {
+ reconfigureLogging(server, newLoggingConfig, newOpsConfig.interval.asMilliseconds());
+ }
);
}
@@ -151,156 +71,5 @@ export class LegacyService implements CoreService {
this.configSubscription.unsubscribe();
this.configSubscription = undefined;
}
-
- if (this.kbnServer !== undefined) {
- await this.kbnServer.close();
- this.kbnServer = undefined;
- }
- }
-
- private async createKbnServer(
- settings: LegacyVars,
- config: LegacyConfig,
- setupDeps: LegacyServiceSetupDeps,
- startDeps: LegacyServiceStartDeps
- ) {
- const coreStart: CoreStart = {
- capabilities: startDeps.core.capabilities,
- elasticsearch: startDeps.core.elasticsearch,
- http: {
- auth: startDeps.core.http.auth,
- basePath: startDeps.core.http.basePath,
- getServerInfo: startDeps.core.http.getServerInfo,
- },
- savedObjects: {
- getScopedClient: startDeps.core.savedObjects.getScopedClient,
- createScopedRepository: startDeps.core.savedObjects.createScopedRepository,
- createInternalRepository: startDeps.core.savedObjects.createInternalRepository,
- createSerializer: startDeps.core.savedObjects.createSerializer,
- createExporter: startDeps.core.savedObjects.createExporter,
- createImporter: startDeps.core.savedObjects.createImporter,
- getTypeRegistry: startDeps.core.savedObjects.getTypeRegistry,
- },
- metrics: {
- collectionInterval: startDeps.core.metrics.collectionInterval,
- getOpsMetrics$: startDeps.core.metrics.getOpsMetrics$,
- },
- uiSettings: { asScopedToClient: startDeps.core.uiSettings.asScopedToClient },
- coreUsageData: {
- getCoreUsageData: () => {
- throw new Error('core.start.coreUsageData.getCoreUsageData is unsupported in legacy');
- },
- },
- };
-
- const router = setupDeps.core.http.createRouter('', this.legacyId);
- const coreSetup: CoreSetup = {
- capabilities: setupDeps.core.capabilities,
- context: setupDeps.core.context,
- elasticsearch: {
- legacy: setupDeps.core.elasticsearch.legacy,
- },
- http: {
- createCookieSessionStorageFactory: setupDeps.core.http.createCookieSessionStorageFactory,
- registerRouteHandlerContext: <
- Context extends RequestHandlerContext,
- ContextName extends keyof Context
- >(
- contextName: ContextName,
- provider: RequestHandlerContextProvider
- ) => setupDeps.core.http.registerRouteHandlerContext(this.legacyId, contextName, provider),
- createRouter: () =>
- router as IRouter,
- resources: setupDeps.core.httpResources.createRegistrar(router),
- registerOnPreRouting: setupDeps.core.http.registerOnPreRouting,
- registerOnPreAuth: setupDeps.core.http.registerOnPreAuth,
- registerAuth: setupDeps.core.http.registerAuth,
- registerOnPostAuth: setupDeps.core.http.registerOnPostAuth,
- registerOnPreResponse: setupDeps.core.http.registerOnPreResponse,
- basePath: setupDeps.core.http.basePath,
- auth: {
- get: setupDeps.core.http.auth.get,
- isAuthenticated: setupDeps.core.http.auth.isAuthenticated,
- },
- csp: setupDeps.core.http.csp,
- getServerInfo: setupDeps.core.http.getServerInfo,
- },
- i18n: setupDeps.core.i18n,
- logging: {
- configure: (config$) => setupDeps.core.logging.configure([], config$),
- },
- metrics: {
- collectionInterval: setupDeps.core.metrics.collectionInterval,
- getOpsMetrics$: setupDeps.core.metrics.getOpsMetrics$,
- },
- savedObjects: {
- setClientFactoryProvider: setupDeps.core.savedObjects.setClientFactoryProvider,
- addClientWrapper: setupDeps.core.savedObjects.addClientWrapper,
- registerType: setupDeps.core.savedObjects.registerType,
- },
- status: {
- isStatusPageAnonymous: setupDeps.core.status.isStatusPageAnonymous,
- core$: setupDeps.core.status.core$,
- overall$: setupDeps.core.status.overall$,
- set: () => {
- throw new Error(`core.status.set is unsupported in legacy`);
- },
- // @ts-expect-error
- get dependencies$() {
- throw new Error(`core.status.dependencies$ is unsupported in legacy`);
- },
- // @ts-expect-error
- get derivedStatus$() {
- throw new Error(`core.status.derivedStatus$ is unsupported in legacy`);
- },
- },
- uiSettings: {
- register: setupDeps.core.uiSettings.register,
- },
- deprecations: {
- registerDeprecations: () => {
- throw new Error('core.setup.deprecations.registerDeprecations is unsupported in legacy');
- },
- },
- getStartServices: () => Promise.resolve([coreStart, startDeps.plugins, {}]),
- };
-
- // eslint-disable-next-line @typescript-eslint/no-var-requires
- const KbnServer = require('../../../legacy/server/kbn_server');
- const kbnServer: LegacyKbnServer = new KbnServer(settings, config, {
- env: {
- mode: this.coreContext.env.mode,
- packageInfo: this.coreContext.env.packageInfo,
- },
- setupDeps: {
- core: coreSetup,
- plugins: setupDeps.plugins,
- },
- startDeps: {
- core: coreStart,
- plugins: startDeps.plugins,
- },
- __internals: {
- hapiServer: setupDeps.core.http.server,
- uiPlugins: setupDeps.uiPlugins,
- rendering: setupDeps.core.rendering,
- },
- logger: this.coreContext.logger,
- });
-
- const { autoListen } = await this.httpConfig$.pipe(first()).toPromise();
-
- if (autoListen) {
- try {
- await kbnServer.listen();
- } catch (err) {
- await kbnServer.close();
- throw err;
- }
- } else {
- await kbnServer.ready();
- }
-
- return kbnServer;
}
}
diff --git a/src/core/server/legacy/logging/appenders/legacy_appender.ts b/src/core/server/legacy/logging/appenders/legacy_appender.ts
index a89441a5671b5..7e02d00c7b234 100644
--- a/src/core/server/legacy/logging/appenders/legacy_appender.ts
+++ b/src/core/server/legacy/logging/appenders/legacy_appender.ts
@@ -9,11 +9,10 @@
import { schema } from '@kbn/config-schema';
import { LegacyLoggingServer } from '@kbn/legacy-logging';
import { DisposableAppender, LogRecord } from '@kbn/logging';
-import { LegacyVars } from '../../types';
export interface LegacyAppenderConfig {
type: 'legacy-appender';
- legacyLoggingConfig?: any;
+ legacyLoggingConfig?: Record;
}
/**
@@ -23,7 +22,7 @@ export interface LegacyAppenderConfig {
export class LegacyAppender implements DisposableAppender {
public static configSchema = schema.object({
type: schema.literal('legacy-appender'),
- legacyLoggingConfig: schema.any(),
+ legacyLoggingConfig: schema.recordOf(schema.string(), schema.any()),
});
/**
@@ -34,7 +33,7 @@ export class LegacyAppender implements DisposableAppender {
private readonly loggingServer: LegacyLoggingServer;
- constructor(legacyLoggingConfig: Readonly) {
+ constructor(legacyLoggingConfig: any) {
this.loggingServer = new LegacyLoggingServer(legacyLoggingConfig);
}
diff --git a/src/core/server/legacy/merge_vars.test.ts b/src/core/server/legacy/merge_vars.test.ts
deleted file mode 100644
index e4268a52aa8ca..0000000000000
--- a/src/core/server/legacy/merge_vars.test.ts
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { mergeVars } from './merge_vars';
-
-describe('mergeVars', () => {
- it('merges two objects together', () => {
- const first = {
- otherName: 'value',
- otherCanFoo: true,
- otherNested: {
- otherAnotherVariable: 'ok',
- },
- };
- const second = {
- name: 'value',
- canFoo: true,
- nested: {
- anotherVariable: 'ok',
- },
- };
-
- expect(mergeVars(first, second)).toEqual({
- name: 'value',
- canFoo: true,
- nested: {
- anotherVariable: 'ok',
- },
- otherName: 'value',
- otherCanFoo: true,
- otherNested: {
- otherAnotherVariable: 'ok',
- },
- });
- });
-
- it('does not mutate the source objects', () => {
- const first = {
- var1: 'first',
- };
- const second = {
- var1: 'second',
- var2: 'second',
- };
- const third = {
- var1: 'third',
- var2: 'third',
- var3: 'third',
- };
- const fourth = {
- var1: 'fourth',
- var2: 'fourth',
- var3: 'fourth',
- var4: 'fourth',
- };
-
- mergeVars(first, second, third, fourth);
-
- expect(first).toEqual({ var1: 'first' });
- expect(second).toEqual({ var1: 'second', var2: 'second' });
- expect(third).toEqual({ var1: 'third', var2: 'third', var3: 'third' });
- expect(fourth).toEqual({ var1: 'fourth', var2: 'fourth', var3: 'fourth', var4: 'fourth' });
- });
-
- it('merges multiple objects together with precedence increasing from left-to-right', () => {
- const first = {
- var1: 'first',
- var2: 'first',
- var3: 'first',
- var4: 'first',
- };
- const second = {
- var1: 'second',
- var2: 'second',
- var3: 'second',
- };
- const third = {
- var1: 'third',
- var2: 'third',
- };
- const fourth = {
- var1: 'fourth',
- };
-
- expect(mergeVars(first, second, third, fourth)).toEqual({
- var1: 'fourth',
- var2: 'third',
- var3: 'second',
- var4: 'first',
- });
- });
-
- it('overwrites the original variable value if a duplicate entry is found', () => {
- const first = {
- nested: {
- otherAnotherVariable: 'ok',
- },
- };
- const second = {
- name: 'value',
- canFoo: true,
- nested: {
- anotherVariable: 'ok',
- },
- };
-
- expect(mergeVars(first, second)).toEqual({
- name: 'value',
- canFoo: true,
- nested: {
- anotherVariable: 'ok',
- },
- });
- });
-
- it('combines entries within "uiCapabilities"', () => {
- const first = {
- uiCapabilities: {
- firstCapability: 'ok',
- sharedCapability: 'shared',
- },
- };
- const second = {
- name: 'value',
- canFoo: true,
- uiCapabilities: {
- secondCapability: 'ok',
- },
- };
- const third = {
- name: 'value',
- canFoo: true,
- uiCapabilities: {
- thirdCapability: 'ok',
- sharedCapability: 'blocked',
- },
- };
-
- expect(mergeVars(first, second, third)).toEqual({
- name: 'value',
- canFoo: true,
- uiCapabilities: {
- firstCapability: 'ok',
- secondCapability: 'ok',
- thirdCapability: 'ok',
- sharedCapability: 'blocked',
- },
- });
- });
-
- it('does not deeply combine entries within "uiCapabilities"', () => {
- const first = {
- uiCapabilities: {
- firstCapability: 'ok',
- nestedCapability: {
- otherNestedProp: 'otherNestedValue',
- },
- },
- };
- const second = {
- name: 'value',
- canFoo: true,
- uiCapabilities: {
- secondCapability: 'ok',
- nestedCapability: {
- nestedProp: 'nestedValue',
- },
- },
- };
-
- expect(mergeVars(first, second)).toEqual({
- name: 'value',
- canFoo: true,
- uiCapabilities: {
- firstCapability: 'ok',
- secondCapability: 'ok',
- nestedCapability: {
- nestedProp: 'nestedValue',
- },
- },
- });
- });
-});
diff --git a/src/core/server/legacy/merge_vars.ts b/src/core/server/legacy/merge_vars.ts
deleted file mode 100644
index cd2cbb0d8cde2..0000000000000
--- a/src/core/server/legacy/merge_vars.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { LegacyVars } from './types';
-
-const ELIGIBLE_FLAT_MERGE_KEYS = ['uiCapabilities'];
-
-export function mergeVars(...sources: LegacyVars[]): LegacyVars {
- return Object.assign(
- {},
- ...sources,
- ...ELIGIBLE_FLAT_MERGE_KEYS.flatMap((key) =>
- sources.some((source) => key in source)
- ? [{ [key]: Object.assign({}, ...sources.map((source) => source[key] || {})) }]
- : []
- )
- );
-}
diff --git a/src/core/server/legacy/types.ts b/src/core/server/legacy/types.ts
deleted file mode 100644
index 9f562d3da3029..0000000000000
--- a/src/core/server/legacy/types.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { InternalCoreSetup, InternalCoreStart } from '../internal_types';
-import { PluginsServiceSetup, PluginsServiceStart, UiPlugins } from '../plugins';
-import { InternalRenderingServiceSetup } from '../rendering';
-
-/**
- * @internal
- * @deprecated
- */
-export type LegacyVars = Record;
-
-type LegacyCoreSetup = InternalCoreSetup & {
- plugins: PluginsServiceSetup;
- rendering: InternalRenderingServiceSetup;
-};
-type LegacyCoreStart = InternalCoreStart & { plugins: PluginsServiceStart };
-
-/**
- * New platform representation of the legacy configuration (KibanaConfig)
- *
- * @internal
- * @deprecated
- */
-export interface LegacyConfig {
- get(key?: string): T;
- has(key: string): boolean;
- set(key: string, value: any): void;
- set(config: LegacyVars): void;
-}
-
-/**
- * @public
- * @deprecated
- */
-export interface LegacyServiceSetupDeps {
- core: LegacyCoreSetup;
- plugins: Record;
- uiPlugins: UiPlugins;
-}
-
-/**
- * @public
- * @deprecated
- */
-export interface LegacyServiceStartDeps {
- core: LegacyCoreStart;
- plugins: Record;
-}
-
-/**
- * @internal
- * @deprecated
- */
-export interface LegacyServiceSetupConfig {
- legacyConfig: LegacyConfig;
- settings: LegacyVars;
-}
diff --git a/src/core/server/logging/__snapshots__/logging_config.test.ts.snap b/src/core/server/logging/__snapshots__/logging_config.test.ts.snap
deleted file mode 100644
index fe1407563a635..0000000000000
--- a/src/core/server/logging/__snapshots__/logging_config.test.ts.snap
+++ /dev/null
@@ -1,20 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`\`schema\` creates correct schema with defaults. 1`] = `
-Object {
- "appenders": Map {},
- "loggers": Array [],
- "root": Object {
- "appenders": Array [
- "default",
- ],
- "level": "info",
- },
-}
-`;
-
-exports[`\`schema\` throws if \`root\` logger does not have "default" appender configured. 1`] = `"[root]: \\"default\\" appender required for migration period till the next major release"`;
-
-exports[`\`schema\` throws if \`root\` logger does not have appenders configured. 1`] = `"[root.appenders]: array size is [0], but cannot be smaller than [1]"`;
-
-exports[`fails if loggers use unknown appenders. 1`] = `"Logger \\"some.nested.context\\" contains unsupported appender key \\"unknown\\"."`;
diff --git a/src/core/server/logging/logging_config.test.ts b/src/core/server/logging/logging_config.test.ts
index 83f3c139e371a..e0004ba992c17 100644
--- a/src/core/server/logging/logging_config.test.ts
+++ b/src/core/server/logging/logging_config.test.ts
@@ -9,7 +9,35 @@
import { LoggingConfig, config } from './logging_config';
test('`schema` creates correct schema with defaults.', () => {
- expect(config.schema.validate({})).toMatchSnapshot();
+ expect(config.schema.validate({})).toMatchInlineSnapshot(
+ { json: expect.any(Boolean) }, // default value depends on TTY
+ `
+ Object {
+ "appenders": Map {},
+ "dest": "stdout",
+ "events": Object {},
+ "filter": Object {},
+ "json": Any,
+ "loggers": Array [],
+ "quiet": false,
+ "root": Object {
+ "appenders": Array [
+ "default",
+ ],
+ "level": "info",
+ },
+ "rotate": Object {
+ "enabled": false,
+ "everyBytes": 10485760,
+ "keepFiles": 7,
+ "pollingInterval": 10000,
+ "usePolling": false,
+ },
+ "silent": false,
+ "verbose": false,
+ }
+ `
+ );
});
test('`schema` throws if `root` logger does not have appenders configured.', () => {
@@ -19,7 +47,9 @@ test('`schema` throws if `root` logger does not have appenders configured.', ()
appenders: [],
},
})
- ).toThrowErrorMatchingSnapshot();
+ ).toThrowErrorMatchingInlineSnapshot(
+ `"[root.appenders]: array size is [0], but cannot be smaller than [1]"`
+ );
});
test('`schema` throws if `root` logger does not have "default" appender configured.', () => {
@@ -29,7 +59,9 @@ test('`schema` throws if `root` logger does not have "default" appender configur
appenders: ['console'],
},
})
- ).toThrowErrorMatchingSnapshot();
+ ).toThrowErrorMatchingInlineSnapshot(
+ `"[root]: \\"default\\" appender required for migration period till the next major release"`
+ );
});
test('`getParentLoggerContext()` returns correct parent context name.', () => {
@@ -157,7 +189,9 @@ test('fails if loggers use unknown appenders.', () => {
],
});
- expect(() => new LoggingConfig(validateConfig)).toThrowErrorMatchingSnapshot();
+ expect(() => new LoggingConfig(validateConfig)).toThrowErrorMatchingInlineSnapshot(
+ `"Logger \\"some.nested.context\\" contains unsupported appender key \\"unknown\\"."`
+ );
});
describe('extend', () => {
diff --git a/src/core/server/logging/logging_config.ts b/src/core/server/logging/logging_config.ts
index 24496289fb4c8..f5b75d7bb739c 100644
--- a/src/core/server/logging/logging_config.ts
+++ b/src/core/server/logging/logging_config.ts
@@ -7,6 +7,7 @@
*/
import { schema, TypeOf } from '@kbn/config-schema';
+import { legacyLoggingConfigSchema } from '@kbn/legacy-logging';
import { AppenderConfigType, Appenders } from './appenders/appenders';
// We need this helper for the types to be correct
@@ -59,7 +60,7 @@ export const loggerSchema = schema.object({
export type LoggerConfigType = TypeOf;
export const config = {
path: 'logging',
- schema: schema.object({
+ schema: legacyLoggingConfigSchema.extends({
appenders: schema.mapOf(schema.string(), Appenders.configSchema, {
defaultValue: new Map(),
}),
@@ -85,7 +86,7 @@ export const config = {
}),
};
-export type LoggingConfigType = Omit, 'appenders'> & {
+export type LoggingConfigType = Pick, 'loggers' | 'root'> & {
appenders: Map;
};
@@ -105,6 +106,7 @@ export const loggerContextConfigSchema = schema.object({
/** @public */
export type LoggerContextConfigType = TypeOf;
+
/** @public */
export interface LoggerContextConfigInput {
// config-schema knows how to handle either Maps or Records
diff --git a/src/core/server/logging/logging_system.test.ts b/src/core/server/logging/logging_system.test.ts
index 8a6fe71bc6222..b67be384732cb 100644
--- a/src/core/server/logging/logging_system.test.ts
+++ b/src/core/server/logging/logging_system.test.ts
@@ -16,6 +16,7 @@ jest.mock('fs', () => ({
const dynamicProps = { process: { pid: expect.any(Number) } };
jest.mock('@kbn/legacy-logging', () => ({
+ ...(jest.requireActual('@kbn/legacy-logging') as any),
setupLoggingRotate: jest.fn().mockImplementation(() => Promise.resolve({})),
}));
diff --git a/src/core/server/metrics/index.ts b/src/core/server/metrics/index.ts
index 3e358edf3a01e..0631bb2b35801 100644
--- a/src/core/server/metrics/index.ts
+++ b/src/core/server/metrics/index.ts
@@ -16,3 +16,4 @@ export type {
export type { OpsProcessMetrics, OpsServerMetrics, OpsOsMetrics } from './collectors';
export { MetricsService } from './metrics_service';
export { opsConfig } from './ops_config';
+export type { OpsConfigType } from './ops_config';
diff --git a/src/core/server/plugins/legacy_config.test.ts b/src/core/server/plugins/legacy_config.test.ts
index 5687c2dd551d2..0ea26f2e0333e 100644
--- a/src/core/server/plugins/legacy_config.test.ts
+++ b/src/core/server/plugins/legacy_config.test.ts
@@ -13,7 +13,7 @@ import { getGlobalConfig, getGlobalConfig$ } from './legacy_config';
import { REPO_ROOT } from '@kbn/utils';
import { loggingSystemMock } from '../logging/logging_system.mock';
import { duration } from 'moment';
-import { fromRoot } from '../utils';
+import { fromRoot } from '@kbn/utils';
import { ByteSizeValue } from '@kbn/config-schema';
import { Server } from '../server';
diff --git a/src/core/server/plugins/plugin_context.test.ts b/src/core/server/plugins/plugin_context.test.ts
index b10bc47cb825b..e37d985d42321 100644
--- a/src/core/server/plugins/plugin_context.test.ts
+++ b/src/core/server/plugins/plugin_context.test.ts
@@ -9,6 +9,7 @@
import { duration } from 'moment';
import { first } from 'rxjs/operators';
import { REPO_ROOT } from '@kbn/dev-utils';
+import { fromRoot } from '@kbn/utils';
import { createPluginInitializerContext, InstanceInfo } from './plugin_context';
import { CoreContext } from '../core_context';
import { Env } from '../config';
@@ -16,7 +17,6 @@ import { loggingSystemMock } from '../logging/logging_system.mock';
import { rawConfigServiceMock, getEnvOptions } from '../config/mocks';
import { PluginManifest } from './types';
import { Server } from '../server';
-import { fromRoot } from '../utils';
import { schema, ByteSizeValue } from '@kbn/config-schema';
import { ConfigService } from '@kbn/config';
diff --git a/src/core/server/plugins/plugins_config.ts b/src/core/server/plugins/plugins_config.ts
index d565513ebb35b..45d80445f376e 100644
--- a/src/core/server/plugins/plugins_config.ts
+++ b/src/core/server/plugins/plugins_config.ts
@@ -7,20 +7,24 @@
*/
import { schema, TypeOf } from '@kbn/config-schema';
+import { ServiceConfigDescriptor } from '../internal_types';
import { Env } from '../config';
-export type PluginsConfigType = TypeOf;
+const configSchema = schema.object({
+ initialize: schema.boolean({ defaultValue: true }),
-export const config = {
+ /**
+ * Defines an array of directories where another plugin should be loaded from.
+ */
+ paths: schema.arrayOf(schema.string(), { defaultValue: [] }),
+});
+
+export type PluginsConfigType = TypeOf;
+
+export const config: ServiceConfigDescriptor = {
path: 'plugins',
- schema: schema.object({
- initialize: schema.boolean({ defaultValue: true }),
-
- /**
- * Defines an array of directories where another plugin should be loaded from.
- */
- paths: schema.arrayOf(schema.string(), { defaultValue: [] }),
- }),
+ schema: configSchema,
+ deprecations: ({ unusedFromRoot }) => [unusedFromRoot('plugins.scanDirs')],
};
/** @internal */
diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md
index fb5fe3efd3e06..53b2eb8610418 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -142,7 +142,6 @@ import { SearchParams } from 'elasticsearch';
import { SearchResponse as SearchResponse_2 } from 'elasticsearch';
import { SearchShardsParams } from 'elasticsearch';
import { SearchTemplateParams } from 'elasticsearch';
-import { Server } from '@hapi/hapi';
import { ShallowPromise } from '@kbn/utility-types';
import { SnapshotCreateParams } from 'elasticsearch';
import { SnapshotCreateRepositoryParams } from 'elasticsearch';
@@ -345,7 +344,7 @@ export const config: {
pingTimeout: Type;
logQueries: Type;
ssl: import("@kbn/config-schema").ObjectType<{
- verificationMode: Type<"certificate" | "none" | "full">;
+ verificationMode: Type<"none" | "certificate" | "full">;
certificateAuthorities: Type;
certificate: Type;
key: Type;
@@ -1305,10 +1304,10 @@ export type KibanaResponseFactory = typeof kibanaResponseFactory;
// @public
export const kibanaResponseFactory: {
- custom: | Error | Buffer | {
+ custom: | Error | Buffer | Stream | {
message: string | Error;
attributes?: Record | undefined;
- } | Stream | undefined>(options: CustomHttpResponseOptions) => KibanaResponse;
+ } | undefined>(options: CustomHttpResponseOptions) => KibanaResponse;
badRequest: (options?: ErrorHttpResponseOptions) => KibanaResponse;
unauthorized: (options?: ErrorHttpResponseOptions) => KibanaResponse;
forbidden: (options?: ErrorHttpResponseOptions) => KibanaResponse;
@@ -1585,20 +1584,6 @@ export class LegacyClusterClient implements ILegacyClusterClient {
close(): void;
}
-// @internal @deprecated
-export interface LegacyConfig {
- // (undocumented)
- get(key?: string): T;
- // (undocumented)
- has(key: string): boolean;
- // (undocumented)
- set(key: string, value: any): void;
- // Warning: (ae-forgotten-export) The symbol "LegacyVars" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
- set(config: LegacyVars): void;
-}
-
// @public @deprecated (undocumented)
export type LegacyElasticsearchClientConfig = Pick & Pick & {
pingTimeout?: ElasticsearchConfig['pingTimeout'] | ConfigOptions['pingTimeout'];
@@ -1634,30 +1619,6 @@ export class LegacyScopedClusterClient implements ILegacyScopedClusterClient {
callAsInternalUser(endpoint: string, clientParams?: Record, options?: LegacyCallAPIOptions): Promise;
}
-// @public @deprecated (undocumented)
-export interface LegacyServiceSetupDeps {
- // Warning: (ae-forgotten-export) The symbol "LegacyCoreSetup" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
- core: LegacyCoreSetup;
- // (undocumented)
- plugins: Record;
- // Warning: (ae-forgotten-export) The symbol "UiPlugins" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
- uiPlugins: UiPlugins;
-}
-
-// @public @deprecated (undocumented)
-export interface LegacyServiceStartDeps {
- // Warning: (ae-forgotten-export) The symbol "LegacyCoreStart" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
- core: LegacyCoreStart;
- // (undocumented)
- plugins: Record;
-}
-
// Warning: (ae-forgotten-export) The symbol "lifecycleResponseFactory" needs to be exported by the entry point index.d.ts
//
// @public
diff --git a/src/core/server/server.test.mocks.ts b/src/core/server/server.test.mocks.ts
index 96047dc6921ec..2bd3028b2f1b6 100644
--- a/src/core/server/server.test.mocks.ts
+++ b/src/core/server/server.test.mocks.ts
@@ -58,7 +58,7 @@ jest.doMock('./ui_settings/ui_settings_service', () => ({
}));
export const mockEnsureValidConfiguration = jest.fn();
-jest.doMock('./legacy/config/ensure_valid_configuration', () => ({
+jest.doMock('./config/ensure_valid_configuration', () => ({
ensureValidConfiguration: mockEnsureValidConfiguration,
}));
diff --git a/src/core/server/server.test.ts b/src/core/server/server.test.ts
index fcf09b0295bcb..534d7df9d9466 100644
--- a/src/core/server/server.test.ts
+++ b/src/core/server/server.test.ts
@@ -99,7 +99,6 @@ test('injects legacy dependency to context#setup()', async () => {
pluginDependencies: new Map([
[pluginA, []],
[pluginB, [pluginA]],
- [mockLegacyService.legacyId, [pluginA, pluginB]],
]),
});
});
@@ -108,12 +107,10 @@ test('runs services on "start"', async () => {
const server = new Server(rawConfigService, env, logger);
expect(mockHttpService.setup).not.toHaveBeenCalled();
- expect(mockLegacyService.start).not.toHaveBeenCalled();
await server.setup();
expect(mockHttpService.start).not.toHaveBeenCalled();
- expect(mockLegacyService.start).not.toHaveBeenCalled();
expect(mockSavedObjectsService.start).not.toHaveBeenCalled();
expect(mockUiSettingsService.start).not.toHaveBeenCalled();
expect(mockMetricsService.start).not.toHaveBeenCalled();
@@ -121,7 +118,6 @@ test('runs services on "start"', async () => {
await server.start();
expect(mockHttpService.start).toHaveBeenCalledTimes(1);
- expect(mockLegacyService.start).toHaveBeenCalledTimes(1);
expect(mockSavedObjectsService.start).toHaveBeenCalledTimes(1);
expect(mockUiSettingsService.start).toHaveBeenCalledTimes(1);
expect(mockMetricsService.start).toHaveBeenCalledTimes(1);
@@ -164,26 +160,6 @@ test('stops services on "stop"', async () => {
});
test(`doesn't setup core services if config validation fails`, async () => {
- mockConfigService.validate.mockImplementationOnce(() => {
- return Promise.reject(new Error('invalid config'));
- });
- const server = new Server(rawConfigService, env, logger);
- await expect(server.setup()).rejects.toThrowErrorMatchingInlineSnapshot(`"invalid config"`);
-
- expect(mockHttpService.setup).not.toHaveBeenCalled();
- expect(mockElasticsearchService.setup).not.toHaveBeenCalled();
- expect(mockPluginsService.setup).not.toHaveBeenCalled();
- expect(mockLegacyService.setup).not.toHaveBeenCalled();
- expect(mockSavedObjectsService.stop).not.toHaveBeenCalled();
- expect(mockUiSettingsService.setup).not.toHaveBeenCalled();
- expect(mockRenderingService.setup).not.toHaveBeenCalled();
- expect(mockMetricsService.setup).not.toHaveBeenCalled();
- expect(mockStatusService.setup).not.toHaveBeenCalled();
- expect(mockLoggingService.setup).not.toHaveBeenCalled();
- expect(mockI18nService.setup).not.toHaveBeenCalled();
-});
-
-test(`doesn't setup core services if legacy config validation fails`, async () => {
mockEnsureValidConfiguration.mockImplementation(() => {
throw new Error('Unknown configuration keys');
});
diff --git a/src/core/server/server.ts b/src/core/server/server.ts
index b575b2779082c..b34d7fec3dcbf 100644
--- a/src/core/server/server.ts
+++ b/src/core/server/server.ts
@@ -8,15 +8,20 @@
import apm from 'elastic-apm-node';
import { config as pathConfig } from '@kbn/utils';
-import { mapToObject } from '@kbn/std';
-import { ConfigService, Env, RawConfigurationProvider, coreDeprecationProvider } from './config';
+import {
+ ConfigService,
+ Env,
+ RawConfigurationProvider,
+ coreDeprecationProvider,
+ ensureValidConfiguration,
+} from './config';
import { CoreApp } from './core_app';
import { I18nService } from './i18n';
import { ElasticsearchService } from './elasticsearch';
import { HttpService } from './http';
import { HttpResourcesService } from './http_resources';
import { RenderingService } from './rendering';
-import { LegacyService, ensureValidConfiguration } from './legacy';
+import { LegacyService } from './legacy';
import { Logger, LoggerFactory, LoggingService, ILoggingSystem } from './logging';
import { UiSettingsService } from './ui_settings';
import { PluginsService, config as pluginsConfig } from './plugins';
@@ -121,22 +126,13 @@ export class Server {
const { pluginTree, pluginPaths, uiPlugins } = await this.plugins.discover({
environment: environmentSetup,
});
- const legacyConfigSetup = await this.legacy.setupLegacyConfig();
// Immediately terminate in case of invalid configuration
// This needs to be done after plugin discovery
- await this.configService.validate();
- await ensureValidConfiguration(this.configService, legacyConfigSetup);
+ await ensureValidConfiguration(this.configService);
const contextServiceSetup = this.context.setup({
- // We inject a fake "legacy plugin" with dependencies on every plugin so that legacy plugins:
- // 1) Can access context from any KP plugin
- // 2) Can register context providers that will only be available to other legacy plugins and will not leak into
- // New Platform plugins.
- pluginDependencies: new Map([
- ...pluginTree.asOpaqueIds,
- [this.legacy.legacyId, [...pluginTree.asOpaqueIds.keys()]],
- ]),
+ pluginDependencies: new Map([...pluginTree.asOpaqueIds]),
});
const httpSetup = await this.http.setup({
@@ -222,9 +218,7 @@ export class Server {
this.#pluginsInitialized = pluginsSetup.initialized;
await this.legacy.setup({
- core: { ...coreSetup, plugins: pluginsSetup, rendering: renderingSetup },
- plugins: mapToObject(pluginsSetup.contracts),
- uiPlugins,
+ http: httpSetup,
});
this.registerCoreContext(coreSetup);
@@ -266,15 +260,7 @@ export class Server {
coreUsageData: coreUsageDataStart,
};
- const pluginsStart = await this.plugins.start(this.coreStart);
-
- await this.legacy.start({
- core: {
- ...this.coreStart,
- plugins: pluginsStart,
- },
- plugins: mapToObject(pluginsStart.contracts),
- });
+ await this.plugins.start(this.coreStart);
await this.http.start();
diff --git a/src/core/server/types.ts b/src/core/server/types.ts
index ab1d6c6d95d0a..be07a3cfb1fd3 100644
--- a/src/core/server/types.ts
+++ b/src/core/server/types.ts
@@ -39,6 +39,5 @@ export type {
} from './saved_objects/types';
export type { DomainDeprecationDetails, DeprecationsGetResponse } from './deprecations/types';
export * from './ui_settings/types';
-export * from './legacy/types';
export type { EnvironmentMode, PackageInfo } from '@kbn/config';
export type { ExternalUrlConfig, IExternalUrlPolicy } from './external_url';
diff --git a/src/core/server/ui_settings/integration_tests/doc_exists.ts b/src/core/server/ui_settings/integration_tests/doc_exists.ts
index 86a9a24fab6de..59c27cc136174 100644
--- a/src/core/server/ui_settings/integration_tests/doc_exists.ts
+++ b/src/core/server/ui_settings/integration_tests/doc_exists.ts
@@ -9,10 +9,10 @@
import { getServices, chance } from './lib';
export const docExistsSuite = (savedObjectsIndex: string) => () => {
- async function setup(options: any = {}) {
+ async function setup(options: { initialSettings?: Record } = {}) {
const { initialSettings } = options;
- const { kbnServer, uiSettings, callCluster } = getServices();
+ const { uiSettings, callCluster, supertest } = getServices();
// delete the kibana index to ensure we start fresh
await callCluster('deleteByQuery', {
@@ -21,31 +21,30 @@ export const docExistsSuite = (savedObjectsIndex: string) => () => {
conflicts: 'proceed',
query: { match_all: {} },
},
+ refresh: true,
+ wait_for_completion: true,
});
if (initialSettings) {
await uiSettings.setMany(initialSettings);
}
- return { kbnServer, uiSettings };
+ return { uiSettings, supertest };
}
describe('get route', () => {
it('returns a 200 and includes userValues', async () => {
const defaultIndex = chance.word({ length: 10 });
- const { kbnServer } = await setup({
+
+ const { supertest } = await setup({
initialSettings: {
defaultIndex,
},
});
- const { statusCode, result } = await kbnServer.inject({
- method: 'GET',
- url: '/api/kibana/settings',
- });
+ const { body } = await supertest('get', '/api/kibana/settings').expect(200);
- expect(statusCode).toBe(200);
- expect(result).toMatchObject({
+ expect(body).toMatchObject({
settings: {
buildNum: {
userValue: expect.any(Number),
@@ -64,20 +63,17 @@ export const docExistsSuite = (savedObjectsIndex: string) => () => {
describe('set route', () => {
it('returns a 200 and all values including update', async () => {
- const { kbnServer } = await setup();
+ const { supertest } = await setup();
const defaultIndex = chance.word();
- const { statusCode, result } = await kbnServer.inject({
- method: 'POST',
- url: '/api/kibana/settings/defaultIndex',
- payload: {
- value: defaultIndex,
- },
- });
- expect(statusCode).toBe(200);
+ const { body } = await supertest('post', '/api/kibana/settings/defaultIndex')
+ .send({
+ value: defaultIndex,
+ })
+ .expect(200);
- expect(result).toMatchObject({
+ expect(body).toMatchObject({
settings: {
buildNum: {
userValue: expect.any(Number),
@@ -94,18 +90,15 @@ export const docExistsSuite = (savedObjectsIndex: string) => () => {
});
it('returns a 400 if trying to set overridden value', async () => {
- const { kbnServer } = await setup();
+ const { supertest } = await setup();
- const { statusCode, result } = await kbnServer.inject({
- method: 'POST',
- url: '/api/kibana/settings/foo',
- payload: {
+ const { body } = await supertest('delete', '/api/kibana/settings/foo')
+ .send({
value: 'baz',
- },
- });
+ })
+ .expect(400);
- expect(statusCode).toBe(400);
- expect(result).toEqual({
+ expect(body).toEqual({
error: 'Bad Request',
message: 'Unable to update "foo" because it is overridden',
statusCode: 400,
@@ -115,22 +108,18 @@ export const docExistsSuite = (savedObjectsIndex: string) => () => {
describe('setMany route', () => {
it('returns a 200 and all values including updates', async () => {
- const { kbnServer } = await setup();
+ const { supertest } = await setup();
const defaultIndex = chance.word();
- const { statusCode, result } = await kbnServer.inject({
- method: 'POST',
- url: '/api/kibana/settings',
- payload: {
+ const { body } = await supertest('post', '/api/kibana/settings')
+ .send({
changes: {
defaultIndex,
},
- },
- });
+ })
+ .expect(200);
- expect(statusCode).toBe(200);
-
- expect(result).toMatchObject({
+ expect(body).toMatchObject({
settings: {
buildNum: {
userValue: expect.any(Number),
@@ -147,20 +136,17 @@ export const docExistsSuite = (savedObjectsIndex: string) => () => {
});
it('returns a 400 if trying to set overridden value', async () => {
- const { kbnServer } = await setup();
+ const { supertest } = await setup();
- const { statusCode, result } = await kbnServer.inject({
- method: 'POST',
- url: '/api/kibana/settings',
- payload: {
+ const { body } = await supertest('post', '/api/kibana/settings')
+ .send({
changes: {
foo: 'baz',
},
- },
- });
+ })
+ .expect(400);
- expect(statusCode).toBe(400);
- expect(result).toEqual({
+ expect(body).toEqual({
error: 'Bad Request',
message: 'Unable to update "foo" because it is overridden',
statusCode: 400,
@@ -172,19 +158,15 @@ export const docExistsSuite = (savedObjectsIndex: string) => () => {
it('returns a 200 and deletes the setting', async () => {
const defaultIndex = chance.word({ length: 10 });
- const { kbnServer, uiSettings } = await setup({
+ const { uiSettings, supertest } = await setup({
initialSettings: { defaultIndex },
});
expect(await uiSettings.get('defaultIndex')).toBe(defaultIndex);
- const { statusCode, result } = await kbnServer.inject({
- method: 'DELETE',
- url: '/api/kibana/settings/defaultIndex',
- });
+ const { body } = await supertest('delete', '/api/kibana/settings/defaultIndex').expect(200);
- expect(statusCode).toBe(200);
- expect(result).toMatchObject({
+ expect(body).toMatchObject({
settings: {
buildNum: {
userValue: expect.any(Number),
@@ -197,15 +179,11 @@ export const docExistsSuite = (savedObjectsIndex: string) => () => {
});
});
it('returns a 400 if deleting overridden value', async () => {
- const { kbnServer } = await setup();
+ const { supertest } = await setup();
- const { statusCode, result } = await kbnServer.inject({
- method: 'DELETE',
- url: '/api/kibana/settings/foo',
- });
+ const { body } = await supertest('delete', '/api/kibana/settings/foo').expect(400);
- expect(statusCode).toBe(400);
- expect(result).toEqual({
+ expect(body).toEqual({
error: 'Bad Request',
message: 'Unable to update "foo" because it is overridden',
statusCode: 400,
diff --git a/src/core/server/ui_settings/integration_tests/doc_missing.ts b/src/core/server/ui_settings/integration_tests/doc_missing.ts
index 9fa3e4c1cfe78..29d1daf3b2032 100644
--- a/src/core/server/ui_settings/integration_tests/doc_missing.ts
+++ b/src/core/server/ui_settings/integration_tests/doc_missing.ts
@@ -11,14 +11,7 @@ import { getServices, chance } from './lib';
export const docMissingSuite = (savedObjectsIndex: string) => () => {
// ensure the kibana index has no documents
beforeEach(async () => {
- const { kbnServer, callCluster } = getServices();
-
- // write a setting to ensure kibana index is created
- await kbnServer.inject({
- method: 'POST',
- url: '/api/kibana/settings/defaultIndex',
- payload: { value: 'abc' },
- });
+ const { callCluster } = getServices();
// delete all docs from kibana index to ensure savedConfig is not found
await callCluster('deleteByQuery', {
@@ -31,15 +24,11 @@ export const docMissingSuite = (savedObjectsIndex: string) => () => {
describe('get route', () => {
it('creates doc, returns a 200 with settings', async () => {
- const { kbnServer } = getServices();
+ const { supertest } = getServices();
- const { statusCode, result } = await kbnServer.inject({
- method: 'GET',
- url: '/api/kibana/settings',
- });
+ const { body } = await supertest('get', '/api/kibana/settings').expect(200);
- expect(statusCode).toBe(200);
- expect(result).toMatchObject({
+ expect(body).toMatchObject({
settings: {
buildNum: {
userValue: expect.any(Number),
@@ -55,17 +44,17 @@ export const docMissingSuite = (savedObjectsIndex: string) => () => {
describe('set route', () => {
it('creates doc, returns a 200 with value set', async () => {
- const { kbnServer } = getServices();
+ const { supertest } = getServices();
const defaultIndex = chance.word();
- const { statusCode, result } = await kbnServer.inject({
- method: 'POST',
- url: '/api/kibana/settings/defaultIndex',
- payload: { value: defaultIndex },
- });
- expect(statusCode).toBe(200);
- expect(result).toMatchObject({
+ const { body } = await supertest('post', '/api/kibana/settings/defaultIndex')
+ .send({
+ value: defaultIndex,
+ })
+ .expect(200);
+
+ expect(body).toMatchObject({
settings: {
buildNum: {
userValue: expect.any(Number),
@@ -84,19 +73,17 @@ export const docMissingSuite = (savedObjectsIndex: string) => () => {
describe('setMany route', () => {
it('creates doc, returns 200 with updated values', async () => {
- const { kbnServer } = getServices();
+ const { supertest } = getServices();
const defaultIndex = chance.word();
- const { statusCode, result } = await kbnServer.inject({
- method: 'POST',
- url: '/api/kibana/settings',
- payload: {
+
+ const { body } = await supertest('post', '/api/kibana/settings')
+ .send({
changes: { defaultIndex },
- },
- });
+ })
+ .expect(200);
- expect(statusCode).toBe(200);
- expect(result).toMatchObject({
+ expect(body).toMatchObject({
settings: {
buildNum: {
userValue: expect.any(Number),
@@ -115,15 +102,11 @@ export const docMissingSuite = (savedObjectsIndex: string) => () => {
describe('delete route', () => {
it('creates doc, returns a 200 with just buildNum', async () => {
- const { kbnServer } = getServices();
+ const { supertest } = getServices();
- const { statusCode, result } = await kbnServer.inject({
- method: 'DELETE',
- url: '/api/kibana/settings/defaultIndex',
- });
+ const { body } = await supertest('delete', '/api/kibana/settings/defaultIndex').expect(200);
- expect(statusCode).toBe(200);
- expect(result).toMatchObject({
+ expect(body).toMatchObject({
settings: {
buildNum: {
userValue: expect.any(Number),
diff --git a/src/core/server/ui_settings/integration_tests/doc_missing_and_index_read_only.ts b/src/core/server/ui_settings/integration_tests/doc_missing_and_index_read_only.ts
deleted file mode 100644
index 78fdab7eb8c5d..0000000000000
--- a/src/core/server/ui_settings/integration_tests/doc_missing_and_index_read_only.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { getServices, chance } from './lib';
-
-export const docMissingAndIndexReadOnlySuite = (savedObjectsIndex: string) => () => {
- // ensure the kibana index has no documents
- beforeEach(async () => {
- const { kbnServer, callCluster } = getServices();
-
- // write a setting to ensure kibana index is created
- await kbnServer.inject({
- method: 'POST',
- url: '/api/kibana/settings/defaultIndex',
- payload: { value: 'abc' },
- });
-
- // delete all docs from kibana index to ensure savedConfig is not found
- await callCluster('deleteByQuery', {
- index: savedObjectsIndex,
- body: {
- query: { match_all: {} },
- },
- });
-
- // set the index to read only
- await callCluster('indices.putSettings', {
- index: savedObjectsIndex,
- body: {
- index: {
- blocks: {
- read_only: true,
- },
- },
- },
- });
- });
-
- afterEach(async () => {
- const { callCluster } = getServices();
-
- // disable the read only block
- await callCluster('indices.putSettings', {
- index: savedObjectsIndex,
- body: {
- index: {
- blocks: {
- read_only: false,
- },
- },
- },
- });
- });
-
- describe('get route', () => {
- it('returns simulated doc with buildNum', async () => {
- const { kbnServer } = getServices();
-
- const { statusCode, result } = await kbnServer.inject({
- method: 'GET',
- url: '/api/kibana/settings',
- });
-
- expect(statusCode).toBe(200);
-
- expect(result).toMatchObject({
- settings: {
- buildNum: {
- userValue: expect.any(Number),
- },
- foo: {
- userValue: 'bar',
- isOverridden: true,
- },
- },
- });
- });
- });
-
- describe('set route', () => {
- it('fails with 403 forbidden', async () => {
- const { kbnServer } = getServices();
-
- const defaultIndex = chance.word();
- const { statusCode, result } = await kbnServer.inject({
- method: 'POST',
- url: '/api/kibana/settings/defaultIndex',
- payload: { value: defaultIndex },
- });
-
- expect(statusCode).toBe(403);
-
- expect(result).toEqual({
- error: 'Forbidden',
- message: expect.stringContaining('index read-only'),
- statusCode: 403,
- });
- });
- });
-
- describe('setMany route', () => {
- it('fails with 403 forbidden', async () => {
- const { kbnServer } = getServices();
-
- const defaultIndex = chance.word();
- const { statusCode, result } = await kbnServer.inject({
- method: 'POST',
- url: '/api/kibana/settings',
- payload: {
- changes: { defaultIndex },
- },
- });
-
- expect(statusCode).toBe(403);
- expect(result).toEqual({
- error: 'Forbidden',
- message: expect.stringContaining('index read-only'),
- statusCode: 403,
- });
- });
- });
-
- describe('delete route', () => {
- it('fails with 403 forbidden', async () => {
- const { kbnServer } = getServices();
-
- const { statusCode, result } = await kbnServer.inject({
- method: 'DELETE',
- url: '/api/kibana/settings/defaultIndex',
- });
-
- expect(statusCode).toBe(403);
- expect(result).toEqual({
- error: 'Forbidden',
- message: expect.stringContaining('index read-only'),
- statusCode: 403,
- });
- });
- });
-};
diff --git a/src/core/server/ui_settings/integration_tests/index.test.ts b/src/core/server/ui_settings/integration_tests/index.test.ts
index 6e6c357e6cccc..6c7cdfa43cf57 100644
--- a/src/core/server/ui_settings/integration_tests/index.test.ts
+++ b/src/core/server/ui_settings/integration_tests/index.test.ts
@@ -12,7 +12,6 @@ import { getEnvOptions } from '@kbn/config/target/mocks';
import { startServers, stopServers } from './lib';
import { docExistsSuite } from './doc_exists';
import { docMissingSuite } from './doc_missing';
-import { docMissingAndIndexReadOnlySuite } from './doc_missing_and_index_read_only';
const kibanaVersion = Env.createDefault(REPO_ROOT, getEnvOptions()).packageInfo.version;
const savedObjectIndex = `.kibana_${kibanaVersion}_001`;
@@ -23,7 +22,6 @@ describe('uiSettings/routes', function () {
beforeAll(startServers);
/* eslint-disable jest/valid-describe */
describe('doc missing', docMissingSuite(savedObjectIndex));
- describe('doc missing and index readonly', docMissingAndIndexReadOnlySuite(savedObjectIndex));
describe('doc exists', docExistsSuite(savedObjectIndex));
/* eslint-enable jest/valid-describe */
afterAll(stopServers);
diff --git a/src/core/server/ui_settings/integration_tests/lib/servers.ts b/src/core/server/ui_settings/integration_tests/lib/servers.ts
index 87176bed5de11..d019dc640f385 100644
--- a/src/core/server/ui_settings/integration_tests/lib/servers.ts
+++ b/src/core/server/ui_settings/integration_tests/lib/servers.ts
@@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
+import type supertest from 'supertest';
import { SavedObjectsClientContract, IUiSettingsClient } from 'src/core/server';
import {
@@ -13,6 +14,8 @@ import {
TestElasticsearchUtils,
TestKibanaUtils,
TestUtils,
+ HttpMethod,
+ getSupertest,
} from '../../../../test_helpers/kbn_server';
import { LegacyAPICaller } from '../../../elasticsearch/';
import { httpServerMock } from '../../../http/http_server.mocks';
@@ -21,13 +24,11 @@ let servers: TestUtils;
let esServer: TestElasticsearchUtils;
let kbn: TestKibanaUtils;
-let kbnServer: TestKibanaUtils['kbnServer'];
-
interface AllServices {
- kbnServer: TestKibanaUtils['kbnServer'];
savedObjectsClient: SavedObjectsClientContract;
callCluster: LegacyAPICaller;
uiSettings: IUiSettingsClient;
+ supertest: (method: HttpMethod, path: string) => supertest.Test;
}
let services: AllServices;
@@ -47,7 +48,6 @@ export async function startServers() {
});
esServer = await servers.startES();
kbn = await servers.startKibana();
- kbnServer = kbn.kbnServer;
}
export function getServices() {
@@ -61,12 +61,10 @@ export function getServices() {
httpServerMock.createKibanaRequest()
);
- const uiSettings = kbnServer.newPlatform.start.core.uiSettings.asScopedToClient(
- savedObjectsClient
- );
+ const uiSettings = kbn.coreStart.uiSettings.asScopedToClient(savedObjectsClient);
services = {
- kbnServer,
+ supertest: (method: HttpMethod, path: string) => getSupertest(kbn.root, method, path),
callCluster,
savedObjectsClient,
uiSettings,
@@ -77,7 +75,6 @@ export function getServices() {
export async function stopServers() {
services = null!;
- kbnServer = null!;
if (servers) {
await esServer.stop();
await kbn.stop();
diff --git a/src/core/server/utils/from_root.ts b/src/core/server/utils/from_root.ts
deleted file mode 100644
index 377f4d0e29ca5..0000000000000
--- a/src/core/server/utils/from_root.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { resolve } from 'path';
-import { pkg } from './package_json';
-
-export function fromRoot(...args: string[]) {
- return resolve(pkg.__dirname, ...args);
-}
diff --git a/src/core/server/utils/index.ts b/src/core/server/utils/index.ts
deleted file mode 100644
index b0776c48f3bed..0000000000000
--- a/src/core/server/utils/index.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-export * from './from_root';
-export * from './package_json';
diff --git a/src/core/server/utils/package_json.ts b/src/core/server/utils/package_json.ts
deleted file mode 100644
index 57ca781d7d78e..0000000000000
--- a/src/core/server/utils/package_json.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { dirname } from 'path';
-
-export const pkg = {
- __filename: require.resolve('../../../../package.json'),
- __dirname: dirname(require.resolve('../../../../package.json')),
- ...require('../../../../package.json'),
-};
diff --git a/src/core/test_helpers/kbn_server.ts b/src/core/test_helpers/kbn_server.ts
index 1844b5de3dc35..950ab5f4392e1 100644
--- a/src/core/test_helpers/kbn_server.ts
+++ b/src/core/test_helpers/kbn_server.ts
@@ -29,11 +29,10 @@ import { resolve } from 'path';
import { BehaviorSubject } from 'rxjs';
import supertest from 'supertest';
-import { CoreStart } from 'src/core/server';
+import { InternalCoreSetup, InternalCoreStart } from '../server/internal_types';
import { LegacyAPICaller } from '../server/elasticsearch';
import { CliArgs, Env } from '../server/config';
import { Root } from '../server/root';
-import KbnServer from '../../legacy/server/kbn_server';
export type HttpMethod = 'delete' | 'get' | 'head' | 'post' | 'put';
@@ -125,14 +124,6 @@ export function createRootWithCorePlugins(settings = {}, cliArgs: Partial ReturnType
@@ -164,8 +155,8 @@ export interface TestElasticsearchUtils {
export interface TestKibanaUtils {
root: Root;
- coreStart: CoreStart;
- kbnServer: KbnServer;
+ coreSetup: InternalCoreSetup;
+ coreStart: InternalCoreStart;
stop: () => Promise;
}
@@ -283,14 +274,12 @@ export function createTestServers({
startKibana: async () => {
const root = createRootWithCorePlugins(kbnSettings);
- await root.setup();
+ const coreSetup = await root.setup();
const coreStart = await root.start();
- const kbnServer = getKbnServer(root);
-
return {
root,
- kbnServer,
+ coreSetup,
coreStart,
stop: async () => await root.shutdown(),
};
diff --git a/src/legacy/server/config/__snapshots__/config.test.js.snap b/src/legacy/server/config/__snapshots__/config.test.js.snap
deleted file mode 100644
index 3bf471f8aba20..0000000000000
--- a/src/legacy/server/config/__snapshots__/config.test.js.snap
+++ /dev/null
@@ -1,5 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`lib/config/config class Config() #getDefault(key) array key should throw exception for unknown key 1`] = `"Unknown config key: foo,bar."`;
-
-exports[`lib/config/config class Config() #getDefault(key) dot notation key should throw exception for unknown key 1`] = `"Unknown config key: foo.bar."`;
diff --git a/src/legacy/server/config/config.js b/src/legacy/server/config/config.js
deleted file mode 100644
index 81cb0a36333bd..0000000000000
--- a/src/legacy/server/config/config.js
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import Joi from 'joi';
-import { set } from '@elastic/safer-lodash-set';
-import _ from 'lodash';
-import { override } from './override';
-import createDefaultSchema from './schema';
-import { unset, deepCloneWithBuffers as clone, IS_KIBANA_DISTRIBUTABLE } from '../../utils';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { pkg } from '../../../core/server/utils';
-const schema = Symbol('Joi Schema');
-const schemaExts = Symbol('Schema Extensions');
-const vals = Symbol('config values');
-
-export class Config {
- static withDefaultSchema(settings = {}) {
- const defaultSchema = createDefaultSchema();
- return new Config(defaultSchema, settings);
- }
-
- constructor(initialSchema, initialSettings) {
- this[schemaExts] = Object.create(null);
- this[vals] = Object.create(null);
-
- this.extendSchema(initialSchema, initialSettings);
- }
-
- extendSchema(extension, settings, key) {
- if (!extension) {
- return;
- }
-
- if (!key) {
- return _.each(extension._inner.children, (child) => {
- this.extendSchema(child.schema, _.get(settings, child.key), child.key);
- });
- }
-
- if (this.has(key)) {
- throw new Error(`Config schema already has key: ${key}`);
- }
-
- set(this[schemaExts], key, extension);
- this[schema] = null;
-
- this.set(key, settings);
- }
-
- removeSchema(key) {
- if (!_.has(this[schemaExts], key)) {
- throw new TypeError(`Unknown schema key: ${key}`);
- }
-
- this[schema] = null;
- unset(this[schemaExts], key);
- unset(this[vals], key);
- }
-
- resetTo(obj) {
- this._commit(obj);
- }
-
- set(key, value) {
- // clone and modify the config
- let config = clone(this[vals]);
- if (_.isPlainObject(key)) {
- config = override(config, key);
- } else {
- set(config, key, value);
- }
-
- // attempt to validate the config value
- this._commit(config);
- }
-
- _commit(newVals) {
- // resolve the current environment
- let env = newVals.env;
- delete newVals.env;
- if (_.isObject(env)) env = env.name;
- if (!env) env = 'production';
-
- const dev = env === 'development';
- const prod = env === 'production';
-
- // pass the environment as context so that it can be refed in config
- const context = {
- env: env,
- prod: prod,
- dev: dev,
- notProd: !prod,
- notDev: !dev,
- version: _.get(pkg, 'version'),
- branch: _.get(pkg, 'branch'),
- buildNum: IS_KIBANA_DISTRIBUTABLE ? pkg.build.number : Number.MAX_SAFE_INTEGER,
- buildSha: IS_KIBANA_DISTRIBUTABLE
- ? pkg.build.sha
- : 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
- dist: IS_KIBANA_DISTRIBUTABLE,
- };
-
- if (!context.dev && !context.prod) {
- throw new TypeError(
- `Unexpected environment "${env}", expected one of "development" or "production"`
- );
- }
-
- const results = Joi.validate(newVals, this.getSchema(), {
- context,
- abortEarly: false,
- });
-
- if (results.error) {
- const error = new Error(results.error.message);
- error.name = results.error.name;
- error.stack = results.error.stack;
- throw error;
- }
-
- this[vals] = results.value;
- }
-
- get(key) {
- if (!key) {
- return clone(this[vals]);
- }
-
- const value = _.get(this[vals], key);
- if (value === undefined) {
- if (!this.has(key)) {
- throw new Error('Unknown config key: ' + key);
- }
- }
- return clone(value);
- }
-
- getDefault(key) {
- const schemaKey = Array.isArray(key) ? key.join('.') : key;
-
- const subSchema = Joi.reach(this.getSchema(), schemaKey);
- if (!subSchema) {
- throw new Error(`Unknown config key: ${key}.`);
- }
-
- return clone(_.get(Joi.describe(subSchema), 'flags.default'));
- }
-
- has(key) {
- function has(key, schema, path) {
- path = path || [];
- // Catch the partial paths
- if (path.join('.') === key) return true;
- // Only go deep on inner objects with children
- if (_.size(schema._inner.children)) {
- for (let i = 0; i < schema._inner.children.length; i++) {
- const child = schema._inner.children[i];
- // If the child is an object recurse through it's children and return
- // true if there's a match
- if (child.schema._type === 'object') {
- if (has(key, child.schema, path.concat([child.key]))) return true;
- // if the child matches, return true
- } else if (path.concat([child.key]).join('.') === key) {
- return true;
- }
- }
- }
- }
-
- if (Array.isArray(key)) {
- // TODO: add .has() support for array keys
- key = key.join('.');
- }
-
- return !!has(key, this.getSchema());
- }
-
- getSchema() {
- if (!this[schema]) {
- this[schema] = (function convertToSchema(children) {
- let schema = Joi.object().keys({}).default();
-
- for (const key of Object.keys(children)) {
- const child = children[key];
- const childSchema = _.isPlainObject(child) ? convertToSchema(child) : child;
-
- if (!childSchema || !childSchema.isJoi) {
- throw new TypeError(
- 'Unable to convert configuration definition value to Joi schema: ' + childSchema
- );
- }
-
- schema = schema.keys({ [key]: childSchema });
- }
-
- return schema;
- })(this[schemaExts]);
- }
-
- return this[schema];
- }
-}
diff --git a/src/legacy/server/config/config.test.js b/src/legacy/server/config/config.test.js
deleted file mode 100644
index b617babb8262d..0000000000000
--- a/src/legacy/server/config/config.test.js
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { Config } from './config';
-import _ from 'lodash';
-import Joi from 'joi';
-
-/**
- * Plugins should defined a config method that takes a joi object. By default
- * it should return a way to disallow config
- *
- * Config should be newed up with a joi schema (containing defaults via joi)
- *
- * let schema = { ... }
- * new Config(schema);
- *
- */
-
-const data = {
- test: {
- hosts: ['host-01', 'host-02'],
- client: {
- type: 'datastore',
- host: 'store-01',
- port: 5050,
- },
- },
-};
-
-const schema = Joi.object({
- test: Joi.object({
- enable: Joi.boolean().default(true),
- hosts: Joi.array().items(Joi.string()),
- client: Joi.object({
- type: Joi.string().default('datastore'),
- host: Joi.string(),
- port: Joi.number(),
- }).default(),
- undefValue: Joi.string(),
- }).default(),
-}).default();
-
-describe('lib/config/config', function () {
- describe('class Config()', function () {
- describe('constructor', function () {
- it('should not allow any config if the schema is not passed', function () {
- const config = new Config();
- const run = function () {
- config.set('something.enable', true);
- };
- expect(run).toThrow();
- });
-
- it('should allow keys in the schema', function () {
- const config = new Config(schema);
- const run = function () {
- config.set('test.client.host', 'http://localhost');
- };
- expect(run).not.toThrow();
- });
-
- it('should not allow keys not in the schema', function () {
- const config = new Config(schema);
- const run = function () {
- config.set('paramNotDefinedInTheSchema', true);
- };
- expect(run).toThrow();
- });
-
- it('should not allow child keys not in the schema', function () {
- const config = new Config(schema);
- const run = function () {
- config.set('test.client.paramNotDefinedInTheSchema', true);
- };
- expect(run).toThrow();
- });
-
- it('should set defaults', function () {
- const config = new Config(schema);
- expect(config.get('test.enable')).toBe(true);
- expect(config.get('test.client.type')).toBe('datastore');
- });
- });
-
- describe('#resetTo(object)', function () {
- let config;
- beforeEach(function () {
- config = new Config(schema);
- });
-
- it('should reset the config object with new values', function () {
- config.set(data);
- const newData = config.get();
- newData.test.enable = false;
- config.resetTo(newData);
- expect(config.get()).toEqual(newData);
- });
- });
-
- describe('#has(key)', function () {
- let config;
- beforeEach(function () {
- config = new Config(schema);
- });
-
- it('should return true for fields that exist in the schema', function () {
- expect(config.has('test.undefValue')).toBe(true);
- });
-
- it('should return true for partial objects that exist in the schema', function () {
- expect(config.has('test.client')).toBe(true);
- });
-
- it('should return false for fields that do not exist in the schema', function () {
- expect(config.has('test.client.pool')).toBe(false);
- });
- });
-
- describe('#set(key, value)', function () {
- let config;
-
- beforeEach(function () {
- config = new Config(schema);
- });
-
- it('should use a key and value to set a config value', function () {
- config.set('test.enable', false);
- expect(config.get('test.enable')).toBe(false);
- });
-
- it('should use an object to set config values', function () {
- const hosts = ['host-01', 'host-02'];
- config.set({ test: { enable: false, hosts: hosts } });
- expect(config.get('test.enable')).toBe(false);
- expect(config.get('test.hosts')).toEqual(hosts);
- });
-
- it('should use a flatten object to set config values', function () {
- const hosts = ['host-01', 'host-02'];
- config.set({ 'test.enable': false, 'test.hosts': hosts });
- expect(config.get('test.enable')).toBe(false);
- expect(config.get('test.hosts')).toEqual(hosts);
- });
-
- it('should override values with just the values present', function () {
- const newData = _.cloneDeep(data);
- config.set(data);
- newData.test.enable = false;
- config.set({ test: { enable: false } });
- expect(config.get()).toEqual(newData);
- });
-
- it('should thow an exception when setting a value with the wrong type', function (done) {
- expect.assertions(4);
-
- const run = function () {
- config.set('test.enable', 'something');
- };
-
- try {
- run();
- } catch (err) {
- expect(err).toHaveProperty('name', 'ValidationError');
- expect(err).toHaveProperty(
- 'message',
- 'child "test" fails because [child "enable" fails because ["enable" must be a boolean]]'
- );
- expect(err).not.toHaveProperty('details');
- expect(err).not.toHaveProperty('_object');
- }
-
- done();
- });
- });
-
- describe('#get(key)', function () {
- let config;
-
- beforeEach(function () {
- config = new Config(schema);
- config.set(data);
- });
-
- it('should return the whole config object when called without a key', function () {
- const newData = _.cloneDeep(data);
- newData.test.enable = true;
- expect(config.get()).toEqual(newData);
- });
-
- it('should return the value using dot notation', function () {
- expect(config.get('test.enable')).toBe(true);
- });
-
- it('should return the clone of partial object using dot notation', function () {
- expect(config.get('test.client')).not.toBe(data.test.client);
- expect(config.get('test.client')).toEqual(data.test.client);
- });
-
- it('should throw exception for unknown config values', function () {
- const run = function () {
- config.get('test.does.not.exist');
- };
- expect(run).toThrowError(/Unknown config key: test.does.not.exist/);
- });
-
- it('should not throw exception for undefined known config values', function () {
- const run = function getUndefValue() {
- config.get('test.undefValue');
- };
- expect(run).not.toThrow();
- });
- });
-
- describe('#getDefault(key)', function () {
- let config;
-
- beforeEach(function () {
- config = new Config(schema);
- config.set(data);
- });
-
- describe('dot notation key', function () {
- it('should return undefined if there is no default', function () {
- const hostDefault = config.getDefault('test.client.host');
- expect(hostDefault).toBeUndefined();
- });
-
- it('should return default if specified', function () {
- const typeDefault = config.getDefault('test.client.type');
- expect(typeDefault).toBe('datastore');
- });
-
- it('should throw exception for unknown key', function () {
- expect(() => {
- config.getDefault('foo.bar');
- }).toThrowErrorMatchingSnapshot();
- });
- });
-
- describe('array key', function () {
- it('should return undefined if there is no default', function () {
- const hostDefault = config.getDefault(['test', 'client', 'host']);
- expect(hostDefault).toBeUndefined();
- });
-
- it('should return default if specified', function () {
- const typeDefault = config.getDefault(['test', 'client', 'type']);
- expect(typeDefault).toBe('datastore');
- });
-
- it('should throw exception for unknown key', function () {
- expect(() => {
- config.getDefault(['foo', 'bar']);
- }).toThrowErrorMatchingSnapshot();
- });
- });
-
- it('object schema with no default should return default value for property', function () {
- const noDefaultSchema = Joi.object()
- .keys({
- foo: Joi.array().items(Joi.string().min(1)).default(['bar']),
- })
- .required();
-
- const config = new Config(noDefaultSchema);
- config.set({
- foo: ['baz'],
- });
-
- const fooDefault = config.getDefault('foo');
- expect(fooDefault).toEqual(['bar']);
- });
-
- it('should return clone of the default', function () {
- const schemaWithArrayDefault = Joi.object()
- .keys({
- foo: Joi.array().items(Joi.string().min(1)).default(['bar']),
- })
- .default();
-
- const config = new Config(schemaWithArrayDefault);
- config.set({
- foo: ['baz'],
- });
-
- expect(config.getDefault('foo')).not.toBe(config.getDefault('foo'));
- expect(config.getDefault('foo')).toEqual(config.getDefault('foo'));
- });
- });
-
- describe('#extendSchema(key, schema)', function () {
- let config;
- beforeEach(function () {
- config = new Config(schema);
- });
-
- it('should allow you to extend the schema at the top level', function () {
- const newSchema = Joi.object({ test: Joi.boolean().default(true) }).default();
- config.extendSchema(newSchema, {}, 'myTest');
- expect(config.get('myTest.test')).toBe(true);
- });
-
- it('should allow you to extend the schema with a prefix', function () {
- const newSchema = Joi.object({ test: Joi.boolean().default(true) }).default();
- config.extendSchema(newSchema, {}, 'prefix.myTest');
- expect(config.get('prefix')).toEqual({ myTest: { test: true } });
- expect(config.get('prefix.myTest')).toEqual({ test: true });
- expect(config.get('prefix.myTest.test')).toBe(true);
- });
-
- it('should NOT allow you to extend the schema if something else is there', function () {
- const newSchema = Joi.object({ test: Joi.boolean().default(true) }).default();
- const run = function () {
- config.extendSchema('test', newSchema);
- };
- expect(run).toThrow();
- });
- });
-
- describe('#removeSchema(key)', function () {
- it('should completely remove the key', function () {
- const config = new Config(
- Joi.object().keys({
- a: Joi.number().default(1),
- })
- );
-
- expect(config.get('a')).toBe(1);
- config.removeSchema('a');
- expect(() => config.get('a')).toThrowError('Unknown config key');
- });
-
- it('only removes existing keys', function () {
- const config = new Config(Joi.object());
-
- expect(() => config.removeSchema('b')).toThrowError('Unknown schema');
- });
- });
- });
-});
diff --git a/src/legacy/server/config/index.js b/src/legacy/server/config/index.js
deleted file mode 100644
index 6fb77eb2a3777..0000000000000
--- a/src/legacy/server/config/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-export { Config } from './config';
diff --git a/src/legacy/server/config/override.test.ts b/src/legacy/server/config/override.test.ts
deleted file mode 100644
index d3046eb7bc8af..0000000000000
--- a/src/legacy/server/config/override.test.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { override } from './override';
-
-describe('override(target, source)', function () {
- it('should override the values form source to target', function () {
- const target = {
- test: {
- enable: true,
- host: ['something else'],
- client: {
- type: 'sql',
- },
- },
- };
-
- const source = {
- test: {
- host: ['host-01', 'host-02'],
- client: {
- type: 'nosql',
- },
- foo: {
- bar: {
- baz: 1,
- },
- },
- },
- };
-
- expect(override(target, source)).toMatchInlineSnapshot(`
- Object {
- "test": Object {
- "client": Object {
- "type": "nosql",
- },
- "enable": true,
- "foo": Object {
- "bar": Object {
- "baz": 1,
- },
- },
- "host": Array [
- "host-01",
- "host-02",
- ],
- },
- }
- `);
- });
-
- it('does not mutate arguments', () => {
- const target = {
- foo: {
- bar: 1,
- baz: 1,
- },
- };
-
- const source = {
- foo: {
- bar: 2,
- },
- box: 2,
- };
-
- expect(override(target, source)).toMatchInlineSnapshot(`
- Object {
- "box": 2,
- "foo": Object {
- "bar": 2,
- "baz": 1,
- },
- }
- `);
- expect(target).not.toHaveProperty('box');
- expect(source.foo).not.toHaveProperty('baz');
- });
-
- it('explodes keys with dots in them', () => {
- const target = {
- foo: {
- bar: 1,
- },
- 'baz.box.boot.bar.bar': 20,
- };
-
- const source = {
- 'foo.bar': 2,
- 'baz.box.boot': {
- 'bar.foo': 10,
- },
- };
-
- expect(override(target, source)).toMatchInlineSnapshot(`
- Object {
- "baz": Object {
- "box": Object {
- "boot": Object {
- "bar": Object {
- "bar": 20,
- "foo": 10,
- },
- },
- },
- },
- "foo": Object {
- "bar": 2,
- },
- }
- `);
- });
-});
diff --git a/src/legacy/server/config/override.ts b/src/legacy/server/config/override.ts
deleted file mode 100644
index 55147c955539e..0000000000000
--- a/src/legacy/server/config/override.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-const isObject = (v: any): v is Record =>
- typeof v === 'object' && v !== null && !Array.isArray(v);
-
-const assignDeep = (target: Record, source: Record) => {
- for (let [key, value] of Object.entries(source)) {
- // unwrap dot-separated keys
- if (key.includes('.')) {
- const [first, ...others] = key.split('.');
- key = first;
- value = { [others.join('.')]: value };
- }
-
- if (isObject(value)) {
- if (!target.hasOwnProperty(key)) {
- target[key] = {};
- }
-
- assignDeep(target[key], value);
- } else {
- target[key] = value;
- }
- }
-};
-
-export const override = (...sources: Array>): Record => {
- const result = {};
-
- for (const object of sources) {
- assignDeep(result, object);
- }
-
- return result;
-};
diff --git a/src/legacy/server/config/schema.js b/src/legacy/server/config/schema.js
deleted file mode 100644
index 81fdfe04290d5..0000000000000
--- a/src/legacy/server/config/schema.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import Joi from 'joi';
-import os from 'os';
-import { legacyLoggingConfigSchema } from '@kbn/legacy-logging';
-
-const HANDLED_IN_NEW_PLATFORM = Joi.any().description(
- 'This key is handled in the new platform ONLY'
-);
-export default () =>
- Joi.object({
- elastic: Joi.object({
- apm: HANDLED_IN_NEW_PLATFORM,
- }).default(),
-
- pkg: Joi.object({
- version: Joi.string().default(Joi.ref('$version')),
- branch: Joi.string().default(Joi.ref('$branch')),
- buildNum: Joi.number().default(Joi.ref('$buildNum')),
- buildSha: Joi.string().default(Joi.ref('$buildSha')),
- }).default(),
-
- env: Joi.object({
- name: Joi.string().default(Joi.ref('$env')),
- dev: Joi.boolean().default(Joi.ref('$dev')),
- prod: Joi.boolean().default(Joi.ref('$prod')),
- }).default(),
-
- dev: HANDLED_IN_NEW_PLATFORM,
- pid: HANDLED_IN_NEW_PLATFORM,
- csp: HANDLED_IN_NEW_PLATFORM,
-
- server: Joi.object({
- name: Joi.string().default(os.hostname()),
- // keep them for BWC, remove when not used in Legacy.
- // validation should be in sync with one in New platform.
- // https://github.com/elastic/kibana/blob/master/src/core/server/http/http_config.ts
- basePath: Joi.string()
- .default('')
- .allow('')
- .regex(/(^$|^\/.*[^\/]$)/, `start with a slash, don't end with one`),
- host: Joi.string().hostname().default('localhost'),
- port: Joi.number().default(5601),
- rewriteBasePath: Joi.boolean().when('basePath', {
- is: '',
- then: Joi.default(false).valid(false),
- otherwise: Joi.default(false),
- }),
-
- autoListen: HANDLED_IN_NEW_PLATFORM,
- cors: HANDLED_IN_NEW_PLATFORM,
- customResponseHeaders: HANDLED_IN_NEW_PLATFORM,
- keepaliveTimeout: HANDLED_IN_NEW_PLATFORM,
- maxPayloadBytes: HANDLED_IN_NEW_PLATFORM,
- publicBaseUrl: HANDLED_IN_NEW_PLATFORM,
- socketTimeout: HANDLED_IN_NEW_PLATFORM,
- ssl: HANDLED_IN_NEW_PLATFORM,
- compression: HANDLED_IN_NEW_PLATFORM,
- uuid: HANDLED_IN_NEW_PLATFORM,
- xsrf: HANDLED_IN_NEW_PLATFORM,
- }).default(),
-
- uiSettings: HANDLED_IN_NEW_PLATFORM,
-
- logging: legacyLoggingConfigSchema,
-
- ops: Joi.object({
- interval: Joi.number().default(5000),
- cGroupOverrides: HANDLED_IN_NEW_PLATFORM,
- }).default(),
-
- plugins: HANDLED_IN_NEW_PLATFORM,
- path: HANDLED_IN_NEW_PLATFORM,
- stats: HANDLED_IN_NEW_PLATFORM,
- status: HANDLED_IN_NEW_PLATFORM,
- map: HANDLED_IN_NEW_PLATFORM,
- i18n: HANDLED_IN_NEW_PLATFORM,
-
- // temporarily moved here from the (now deleted) kibana legacy plugin
- kibana: Joi.object({
- enabled: Joi.boolean().default(true),
- index: Joi.string().default('.kibana'),
- autocompleteTerminateAfter: Joi.number().integer().min(1).default(100000),
- // TODO Also allow units here like in elasticsearch config once this is moved to the new platform
- autocompleteTimeout: Joi.number().integer().min(1).default(1000),
- }).default(),
-
- savedObjects: HANDLED_IN_NEW_PLATFORM,
- }).default();
diff --git a/src/legacy/server/config/schema.test.js b/src/legacy/server/config/schema.test.js
deleted file mode 100644
index c57e6cf9a933a..0000000000000
--- a/src/legacy/server/config/schema.test.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import schemaProvider from './schema';
-import Joi from 'joi';
-
-describe('Config schema', function () {
- let schema;
- beforeEach(async () => (schema = await schemaProvider()));
-
- function validate(data, options) {
- return Joi.validate(data, schema, options);
- }
-
- describe('server', function () {
- it('everything is optional', function () {
- const { error } = validate({});
- expect(error).toBe(null);
- });
-
- describe('basePath', function () {
- it('accepts empty strings', function () {
- const { error, value } = validate({ server: { basePath: '' } });
- expect(error).toBe(null);
- expect(value.server.basePath).toBe('');
- });
-
- it('accepts strings with leading slashes', function () {
- const { error, value } = validate({ server: { basePath: '/path' } });
- expect(error).toBe(null);
- expect(value.server.basePath).toBe('/path');
- });
-
- it('rejects strings with trailing slashes', function () {
- const { error } = validate({ server: { basePath: '/path/' } });
- expect(error).toHaveProperty('details');
- expect(error.details[0]).toHaveProperty('path', ['server', 'basePath']);
- });
-
- it('rejects strings without leading slashes', function () {
- const { error } = validate({ server: { basePath: 'path' } });
- expect(error).toHaveProperty('details');
- expect(error.details[0]).toHaveProperty('path', ['server', 'basePath']);
- });
-
- it('rejects things that are not strings', function () {
- for (const value of [1, true, {}, [], /foo/]) {
- const { error } = validate({ server: { basePath: value } });
- expect(error).toHaveProperty('details');
- expect(error.details[0]).toHaveProperty('path', ['server', 'basePath']);
- }
- });
- });
-
- describe('rewriteBasePath', function () {
- it('defaults to false', () => {
- const { error, value } = validate({});
- expect(error).toBe(null);
- expect(value.server.rewriteBasePath).toBe(false);
- });
-
- it('accepts false', function () {
- const { error, value } = validate({ server: { rewriteBasePath: false } });
- expect(error).toBe(null);
- expect(value.server.rewriteBasePath).toBe(false);
- });
-
- it('accepts true if basePath set', function () {
- const { error, value } = validate({ server: { basePath: '/foo', rewriteBasePath: true } });
- expect(error).toBe(null);
- expect(value.server.rewriteBasePath).toBe(true);
- });
-
- it('rejects true if basePath not set', function () {
- const { error } = validate({ server: { rewriteBasePath: true } });
- expect(error).toHaveProperty('details');
- expect(error.details[0]).toHaveProperty('path', ['server', 'rewriteBasePath']);
- });
-
- it('rejects strings', function () {
- const { error } = validate({ server: { rewriteBasePath: 'foo' } });
- expect(error).toHaveProperty('details');
- expect(error.details[0]).toHaveProperty('path', ['server', 'rewriteBasePath']);
- });
- });
- });
-});
diff --git a/src/legacy/server/core/index.ts b/src/legacy/server/core/index.ts
deleted file mode 100644
index 2bdd9f26b2c22..0000000000000
--- a/src/legacy/server/core/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { Server } from '@hapi/hapi';
-import KbnServer from '../kbn_server';
-
-/**
- * Exposes `kbnServer.newPlatform` through Hapi API.
- * @param kbnServer KbnServer singleton instance.
- * @param server Hapi server instance to expose `core` on.
- */
-export function coreMixin(kbnServer: KbnServer, server: Server) {
- // we suppress type error because hapi expect a function here not an object
- server.decorate('server', 'newPlatform', kbnServer.newPlatform as any);
-}
diff --git a/src/legacy/server/http/index.js b/src/legacy/server/http/index.js
deleted file mode 100644
index 0fb51b341c3dd..0000000000000
--- a/src/legacy/server/http/index.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { format } from 'url';
-import Boom from '@hapi/boom';
-
-export default async function (kbnServer, server) {
- server = kbnServer.server;
-
- const getBasePath = (request) => kbnServer.newPlatform.setup.core.http.basePath.get(request);
-
- server.route({
- method: 'GET',
- path: '/{p*}',
- handler: function (req, h) {
- const path = req.path;
- if (path === '/' || path.charAt(path.length - 1) !== '/') {
- throw Boom.notFound();
- }
- const basePath = getBasePath(req);
- const pathPrefix = basePath ? `${basePath}/` : '';
- return h
- .redirect(
- format({
- search: req.url.search,
- pathname: pathPrefix + path.slice(0, -1),
- })
- )
- .permanent(true);
- },
- });
-}
diff --git a/src/legacy/server/jest.config.js b/src/legacy/server/jest.config.js
deleted file mode 100644
index 0a7322d2985fa..0000000000000
--- a/src/legacy/server/jest.config.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-module.exports = {
- preset: '@kbn/test',
- rootDir: '../../..',
- roots: ['/src/legacy/server'],
-};
diff --git a/src/legacy/server/kbn_server.d.ts b/src/legacy/server/kbn_server.d.ts
deleted file mode 100644
index 3fe0f5899668f..0000000000000
--- a/src/legacy/server/kbn_server.d.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { Server } from '@hapi/hapi';
-
-import {
- CoreSetup,
- CoreStart,
- EnvironmentMode,
- LoggerFactory,
- PackageInfo,
- LegacyServiceSetupDeps,
-} from '../../core/server';
-
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { LegacyConfig } from '../../core/server/legacy';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { UiPlugins } from '../../core/server/plugins';
-
-// lot of legacy code was assuming this type only had these two methods
-export type KibanaConfig = Pick;
-
-// Extend the defaults with the plugins and server methods we need.
-declare module 'hapi' {
- interface PluginProperties {
- spaces: any;
- }
-
- interface Server {
- config: () => KibanaConfig;
- newPlatform: KbnServer['newPlatform'];
- }
-}
-
-type KbnMixinFunc = (kbnServer: KbnServer, server: Server, config: any) => Promise | void;
-
-export interface PluginsSetup {
- [key: string]: object;
-}
-
-export interface KibanaCore {
- __internals: {
- hapiServer: LegacyServiceSetupDeps['core']['http']['server'];
- rendering: LegacyServiceSetupDeps['core']['rendering'];
- uiPlugins: UiPlugins;
- };
- env: {
- mode: Readonly;
- packageInfo: Readonly;
- };
- setupDeps: {
- core: CoreSetup;
- plugins: PluginsSetup;
- };
- startDeps: {
- core: CoreStart;
- plugins: Record;
- };
- logger: LoggerFactory;
-}
-
-export interface NewPlatform {
- __internals: KibanaCore['__internals'];
- env: KibanaCore['env'];
- coreContext: {
- logger: KibanaCore['logger'];
- };
- setup: KibanaCore['setupDeps'];
- start: KibanaCore['startDeps'];
- stop: null;
-}
-
-// eslint-disable-next-line import/no-default-export
-export default class KbnServer {
- public readonly newPlatform: NewPlatform;
- public server: Server;
- public inject: Server['inject'];
-
- constructor(settings: Record, config: KibanaConfig, core: KibanaCore);
-
- public ready(): Promise;
- public mixin(...fns: KbnMixinFunc[]): Promise;
- public listen(): Promise;
- public close(): Promise;
- public applyLoggingConfiguration(settings: any): void;
- public config: KibanaConfig;
-}
-
-// Re-export commonly used hapi types.
-export { Server, Request, ResponseToolkit } from '@hapi/hapi';
diff --git a/src/legacy/server/kbn_server.js b/src/legacy/server/kbn_server.js
deleted file mode 100644
index 4bc76b6a7706f..0000000000000
--- a/src/legacy/server/kbn_server.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { constant, once, compact, flatten } from 'lodash';
-import { reconfigureLogging } from '@kbn/legacy-logging';
-
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { fromRoot, pkg } from '../../core/server/utils';
-import { Config } from './config';
-import httpMixin from './http';
-import { coreMixin } from './core';
-import { loggingMixin } from './logging';
-
-/**
- * @typedef {import('./kbn_server').KibanaConfig} KibanaConfig
- * @typedef {import('./kbn_server').KibanaCore} KibanaCore
- * @typedef {import('./kbn_server').LegacyPlugins} LegacyPlugins
- */
-
-const rootDir = fromRoot('.');
-
-export default class KbnServer {
- /**
- * @param {Record} settings
- * @param {KibanaConfig} config
- * @param {KibanaCore} core
- */
- constructor(settings, config, core) {
- this.name = pkg.name;
- this.version = pkg.version;
- this.build = pkg.build || false;
- this.rootDir = rootDir;
- this.settings = settings || {};
- this.config = config;
-
- const { setupDeps, startDeps, logger, __internals, env } = core;
-
- this.server = __internals.hapiServer;
- this.newPlatform = {
- env: {
- mode: env.mode,
- packageInfo: env.packageInfo,
- },
- __internals,
- coreContext: {
- logger,
- },
- setup: setupDeps,
- start: startDeps,
- stop: null,
- };
-
- this.ready = constant(
- this.mixin(
- // Sets global HTTP behaviors
- httpMixin,
-
- coreMixin,
-
- loggingMixin
- )
- );
-
- this.listen = once(this.listen);
- }
-
- /**
- * Extend the KbnServer outside of the constraints of a plugin. This allows access
- * to APIs that are not exposed (intentionally) to the plugins and should only
- * be used when the code will be kept up to date with Kibana.
- *
- * @param {...function} - functions that should be called to mixin functionality.
- * They are called with the arguments (kibana, server, config)
- * and can return a promise to delay execution of the next mixin
- * @return {Promise} - promise that is resolved when the final mixin completes.
- */
- async mixin(...fns) {
- for (const fn of compact(flatten(fns))) {
- await fn.call(this, this, this.server, this.config);
- }
- }
-
- /**
- * Tell the server to listen for incoming requests, or get
- * a promise that will be resolved once the server is listening.
- *
- * @return undefined
- */
- async listen() {
- await this.ready();
-
- const { server } = this;
-
- if (process.env.isDevCliChild) {
- // help parent process know when we are ready
- process.send(['SERVER_LISTENING']);
- }
-
- return server;
- }
-
- async close() {
- if (!this.server) {
- return;
- }
-
- await this.server.stop();
- }
-
- async inject(opts) {
- if (!this.server) {
- await this.ready();
- }
-
- return await this.server.inject(opts);
- }
-
- applyLoggingConfiguration(settings) {
- const config = Config.withDefaultSchema(settings);
-
- const loggingConfig = config.get('logging');
- const opsConfig = config.get('ops');
-
- reconfigureLogging(this.server, loggingConfig, opsConfig.interval);
- }
-}
diff --git a/src/legacy/server/logging/index.js b/src/legacy/server/logging/index.js
deleted file mode 100644
index 1b2ae59f4aa00..0000000000000
--- a/src/legacy/server/logging/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { setupLogging, setupLoggingRotate } from '@kbn/legacy-logging';
-
-export async function loggingMixin(kbnServer, server, config) {
- const loggingConfig = config.get('logging');
- const opsInterval = config.get('ops.interval');
-
- await setupLogging(server, loggingConfig, opsInterval);
- await setupLoggingRotate(server, loggingConfig);
-}
diff --git a/src/legacy/utils/artifact_type.ts b/src/legacy/utils/artifact_type.ts
deleted file mode 100644
index 8243b78b15025..0000000000000
--- a/src/legacy/utils/artifact_type.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { pkg } from '../../core/server/utils';
-export const IS_KIBANA_DISTRIBUTABLE = pkg.build && pkg.build.distributable === true;
-export const IS_KIBANA_RELEASE = pkg.build && pkg.build.release === true;
diff --git a/src/legacy/utils/deep_clone_with_buffers.test.ts b/src/legacy/utils/deep_clone_with_buffers.test.ts
deleted file mode 100644
index f23e0c8496490..0000000000000
--- a/src/legacy/utils/deep_clone_with_buffers.test.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { deepCloneWithBuffers } from './deep_clone_with_buffers';
-
-describe('deepCloneWithBuffers()', () => {
- it('deep clones objects', () => {
- const source = {
- a: {
- b: {},
- c: {},
- d: [
- {
- e: 'f',
- },
- ],
- },
- };
-
- const output = deepCloneWithBuffers(source);
-
- expect(source.a).toEqual(output.a);
- expect(source.a).not.toBe(output.a);
-
- expect(source.a.b).toEqual(output.a.b);
- expect(source.a.b).not.toBe(output.a.b);
-
- expect(source.a.c).toEqual(output.a.c);
- expect(source.a.c).not.toBe(output.a.c);
-
- expect(source.a.d).toEqual(output.a.d);
- expect(source.a.d).not.toBe(output.a.d);
-
- expect(source.a.d[0]).toEqual(output.a.d[0]);
- expect(source.a.d[0]).not.toBe(output.a.d[0]);
- });
-
- it('copies buffers but keeps them buffers', () => {
- const input = Buffer.from('i am a teapot', 'utf8');
- const output = deepCloneWithBuffers(input);
-
- expect(Buffer.isBuffer(input)).toBe(true);
- expect(Buffer.isBuffer(output)).toBe(true);
- expect(Buffer.compare(output, input));
- expect(output).not.toBe(input);
- });
-
- it('copies buffers that are deep', () => {
- const input = {
- a: {
- b: {
- c: Buffer.from('i am a teapot', 'utf8'),
- },
- },
- };
- const output = deepCloneWithBuffers(input);
-
- expect(Buffer.isBuffer(input.a.b.c)).toBe(true);
- expect(Buffer.isBuffer(output.a.b.c)).toBe(true);
- expect(Buffer.compare(output.a.b.c, input.a.b.c));
- expect(output.a.b.c).not.toBe(input.a.b.c);
- });
-});
diff --git a/src/legacy/utils/deep_clone_with_buffers.ts b/src/legacy/utils/deep_clone_with_buffers.ts
deleted file mode 100644
index c81a572326e7c..0000000000000
--- a/src/legacy/utils/deep_clone_with_buffers.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { cloneDeepWith } from 'lodash';
-
-// We should add `any` return type to overcome bug in lodash types, customizer
-// in lodash 3.* can return `undefined` if cloning is handled by the lodash, but
-// type of the customizer function doesn't expect that.
-function cloneBuffersCustomizer(val: unknown): any {
- if (Buffer.isBuffer(val)) {
- return Buffer.from(val);
- }
-}
-
-export function deepCloneWithBuffers(val: T): T {
- return cloneDeepWith(val, cloneBuffersCustomizer);
-}
diff --git a/src/legacy/utils/index.d.ts b/src/legacy/utils/index.d.ts
deleted file mode 100644
index 92fbd6ce715a4..0000000000000
--- a/src/legacy/utils/index.d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-export function unset(object: object, rawPath: string): void;
diff --git a/src/legacy/utils/index.js b/src/legacy/utils/index.js
deleted file mode 100644
index a96caeb93aaa6..0000000000000
--- a/src/legacy/utils/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-export { deepCloneWithBuffers } from './deep_clone_with_buffers';
-export { unset } from './unset';
-export { IS_KIBANA_DISTRIBUTABLE } from './artifact_type';
-export { IS_KIBANA_RELEASE } from './artifact_type';
diff --git a/src/legacy/utils/jest.config.js b/src/legacy/utils/jest.config.js
deleted file mode 100644
index 593c3aec9d0b0..0000000000000
--- a/src/legacy/utils/jest.config.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-module.exports = {
- preset: '@kbn/test',
- rootDir: '../../..',
- roots: ['/src/legacy/utils'],
-};
diff --git a/src/legacy/utils/unset.js b/src/legacy/utils/unset.js
deleted file mode 100644
index fa9a9cee77a13..0000000000000
--- a/src/legacy/utils/unset.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import _ from 'lodash';
-
-export function unset(object, rawPath) {
- if (!object) return;
- const path = _.toPath(rawPath);
-
- switch (path.length) {
- case 0:
- return;
-
- case 1:
- delete object[rawPath];
- break;
-
- default:
- const leaf = path.pop();
- const parentPath = path.slice();
- const parent = _.get(object, parentPath);
- unset(parent, leaf);
- if (!_.size(parent)) {
- unset(object, parentPath);
- }
- break;
- }
-}
diff --git a/src/legacy/utils/unset.test.js b/src/legacy/utils/unset.test.js
deleted file mode 100644
index 0c521ae046124..0000000000000
--- a/src/legacy/utils/unset.test.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { unset } from './unset';
-
-describe('unset(obj, key)', function () {
- describe('invalid input', function () {
- it('should do nothing if not given an object', function () {
- const obj = 'hello';
- unset(obj, 'e');
- expect(obj).toBe('hello');
- });
-
- it('should do nothing if not given a key', function () {
- const obj = { one: 1 };
- unset(obj);
- expect(obj).toEqual({ one: 1 });
- });
-
- it('should do nothing if given an empty string as a key', function () {
- const obj = { one: 1 };
- unset(obj, '');
- expect(obj).toEqual({ one: 1 });
- });
- });
-
- describe('shallow removal', function () {
- let obj;
-
- beforeEach(function () {
- obj = { one: 1, two: 2, deep: { three: 3, four: 4 } };
- });
-
- it('should remove the param using a string key', function () {
- unset(obj, 'two');
- expect(obj).toEqual({ one: 1, deep: { three: 3, four: 4 } });
- });
-
- it('should remove the param using an array key', function () {
- unset(obj, ['two']);
- expect(obj).toEqual({ one: 1, deep: { three: 3, four: 4 } });
- });
- });
-
- describe('deep removal', function () {
- let obj;
-
- beforeEach(function () {
- obj = { one: 1, two: 2, deep: { three: 3, four: 4 } };
- });
-
- it('should remove the param using a string key', function () {
- unset(obj, 'deep.three');
- expect(obj).toEqual({ one: 1, two: 2, deep: { four: 4 } });
- });
-
- it('should remove the param using an array key', function () {
- unset(obj, ['deep', 'three']);
- expect(obj).toEqual({ one: 1, two: 2, deep: { four: 4 } });
- });
- });
-
- describe('recursive removal', function () {
- it('should clear object if only value is removed', function () {
- const obj = { one: { two: { three: 3 } } };
- unset(obj, 'one.two.three');
- expect(obj).toEqual({});
- });
-
- it('should clear object if no props are left', function () {
- const obj = { one: { two: { three: 3 } } };
- unset(obj, 'one.two');
- expect(obj).toEqual({});
- });
-
- it('should remove deep property, then clear the object', function () {
- const obj = { one: { two: { three: 3, four: 4 } } };
- unset(obj, 'one.two.three');
- expect(obj).toEqual({ one: { two: { four: 4 } } });
-
- unset(obj, 'one.two.four');
- expect(obj).toEqual({});
- });
- });
-});
diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md
index 29a5a67239171..9fff4ac95c87e 100644
--- a/src/plugins/data/server/server.api.md
+++ b/src/plugins/data/server/server.api.md
@@ -966,7 +966,7 @@ export class IndexPatternsServiceProvider implements Plugin_3, { expressions, usageCollection }: IndexPatternsServiceSetupDeps): void;
// (undocumented)
start(core: CoreStart, { fieldFormats, logger }: IndexPatternsServiceStartDeps): {
- indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: ElasticsearchClient_2) => Promise;
+ indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: ElasticsearchClient_2) => Promise;
};
}
@@ -1232,7 +1232,7 @@ export class Plugin implements Plugin_2 Promise;
};
indexPatterns: {
- indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise;
+ indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: import("../../../core/server").ElasticsearchClient) => Promise;
};
search: ISearchStart