diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency.tsx
index a682e10269e6c..db4f80dc37f4b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/frequency.tsx
@@ -26,10 +26,10 @@ import { ViewContentHeader } from '../../../../components/shared/view_content_he
import { NAV, RESET_BUTTON } from '../../../../constants';
import { DIFFERENT_SYNC_TYPES_DOCS_URL } from '../../../../routes';
import {
+ LEARN_MORE_LINK,
SOURCE_FREQUENCY_DESCRIPTION,
SOURCE_SYNC_FREQUENCY_TITLE,
BLOCKED_TIME_WINDOWS_TITLE,
- SYNC_FREQUENCY_LINK_LABEL,
SYNC_UNSAVED_CHANGES_MESSAGE,
} from '../../constants';
import { SourceLogic } from '../../source_logic';
@@ -84,16 +84,6 @@ export const Frequency: React.FC = ({ tabId }) => {
);
- const docsLinks = (
-
-
-
- {SYNC_FREQUENCY_LINK_LABEL}
-
-
-
- );
-
return (
= ({ tabId }) => {
/>
+ {SOURCE_FREQUENCY_DESCRIPTION}{' '}
+
+ {LEARN_MORE_LINK}
+
+ >
+ }
action={actions}
/>
- {docsLinks}
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.tsx
index 54ce0563ddeb3..2dfa2a6420f7f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/objects_and_assets.tsx
@@ -27,11 +27,11 @@ import { ViewContentHeader } from '../../../../components/shared/view_content_he
import { NAV, RESET_BUTTON } from '../../../../constants';
import { OBJECTS_AND_ASSETS_DOCS_URL } from '../../../../routes';
import {
+ LEARN_MORE_LINK,
SYNC_MANAGEMENT_CONTENT_EXTRACTION_LABEL,
SYNC_MANAGEMENT_THUMBNAILS_LABEL,
SYNC_MANAGEMENT_THUMBNAILS_GLOBAL_CONFIG_LABEL,
SOURCE_OBJECTS_AND_ASSETS_DESCRIPTION,
- OBJECTS_AND_ASSETS_LINK_LABEL,
SOURCE_OBJECTS_AND_ASSETS_LABEL,
SYNC_UNSAVED_CHANGES_MESSAGE,
} from '../../constants';
@@ -84,12 +84,16 @@ export const ObjectsAndAssets: React.FC = () => {
/>
+ {SOURCE_OBJECTS_AND_ASSETS_DESCRIPTION}{' '}
+
+ {LEARN_MORE_LINK}
+
+ >
+ }
action={actions}
/>
-
- {OBJECTS_AND_ASSETS_LINK_LABEL}
-
{SOURCE_OBJECTS_AND_ASSETS_LABEL}
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.test.tsx
index fb9cdc6916fa9..2d1e8105c12b2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.test.tsx
@@ -12,7 +12,7 @@ import React from 'react';
import { shallow } from 'enzyme';
-import { EuiLink, EuiCallOut, EuiSwitch } from '@elastic/eui';
+import { EuiCallOut, EuiSwitch } from '@elastic/eui';
import { Synchronization } from './synchronization';
@@ -28,7 +28,6 @@ describe('Synchronization', () => {
it('renders when config enabled', () => {
const wrapper = shallow( );
- expect(wrapper.find(EuiLink)).toHaveLength(1);
expect(wrapper.find(EuiSwitch)).toHaveLength(1);
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.tsx
index e88d4d251fa54..dec275adb3c50 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/synchronization/synchronization.tsx
@@ -15,12 +15,12 @@ import { ViewContentHeader } from '../../../../components/shared/view_content_he
import { NAV } from '../../../../constants';
import { SYNCHRONIZATION_DOCS_URL } from '../../../../routes';
import {
+ LEARN_MORE_LINK,
SOURCE_SYNCHRONIZATION_DESCRIPTION,
SYNCHRONIZATION_DISABLED_TITLE,
SYNCHRONIZATION_DISABLED_DESCRIPTION,
SOURCE_SYNCHRONIZATION_TOGGLE_LABEL,
SOURCE_SYNCHRONIZATION_TOGGLE_DESCRIPTION,
- SYNCHRONIZATION_LINK_LABEL,
} from '../../constants';
import { SourceLogic } from '../../source_logic';
import { SourceLayout } from '../source_layout';
@@ -65,11 +65,15 @@ export const Synchronization: React.FC = () => {
>
+ {SOURCE_SYNCHRONIZATION_DESCRIPTION}{' '}
+
+ {LEARN_MORE_LINK}
+
+ >
+ }
/>
-
- {SYNCHRONIZATION_LINK_LABEL}
-
{isSyncConfigEnabled ? syncToggle : syncDisabledCallout}
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/constants.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/constants.ts
index f44dbae0608ea..087716e565ad0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/constants.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/constants.ts
@@ -531,7 +531,7 @@ export const SOURCE_SYNCHRONIZATION_DESCRIPTION = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.sources.sourceSynchronizationDescription',
{
defaultMessage:
- 'Synchronization provides control over data being indexed from the content source. Enable synchronization of data from the content source to Workplace Search.',
+ 'Enable or disable synchronization of data from this content source to Workplace Search.',
}
);
@@ -539,7 +539,7 @@ export const SOURCE_FREQUENCY_DESCRIPTION = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.sources.sourceFrequencyDescription',
{
defaultMessage:
- 'Schedule the frequency of data synchronization between Workplace search and the content source. Indexing schedules that occur less frequently lower the burden on third-party servers, while more frequent will ensure your data is up-to-date.',
+ 'Manage the frequency of data synchronization from Workplace search to this content source. Sync more frequently to ensure your data is up to date. Sync less frequently to reduce the burden on third party servers.',
}
);
@@ -547,7 +547,7 @@ export const SOURCE_OBJECTS_AND_ASSETS_DESCRIPTION = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.sources.sourceObjectsAndAssetsDescription',
{
defaultMessage:
- 'Customize the indexing rules that determine what data is synchronized from this content source to Workplace Search.',
+ 'Customize the indexing rules that determine which objects and assets are synchronized from this content source to Workplace Search.',
}
);
@@ -636,13 +636,6 @@ export const BLOCKED_TIME_WINDOWS_TITLE = i18n.translate(
}
);
-export const SYNCHRONIZATION_LINK_LABEL = i18n.translate(
- 'xpack.enterpriseSearch.workplaceSearch.sources.synchronizationLinkLabel',
- {
- defaultMessage: 'Learn more about synchronization',
- }
-);
-
export const SYNCHRONIZATION_DISABLED_TITLE = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.sources.synchronizationDisabledTitle',
{
@@ -657,20 +650,6 @@ export const SYNCHRONIZATION_DISABLED_DESCRIPTION = i18n.translate(
}
);
-export const SYNC_FREQUENCY_LINK_LABEL = i18n.translate(
- 'xpack.enterpriseSearch.workplaceSearch.sources.syncFrequencyLinkLabel',
- {
- defaultMessage: 'Learn more about synchronization frequency',
- }
-);
-
-export const OBJECTS_AND_ASSETS_LINK_LABEL = i18n.translate(
- 'xpack.enterpriseSearch.workplaceSearch.sources.objectsAndAssetsLinkLabel',
- {
- defaultMessage: 'Learn more about Objects and assets',
- }
-);
-
export const FULL_SYNC_LABEL = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.sources.fullSyncLabel',
{
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/box.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/box.svg
new file mode 100644
index 0000000000000..b1b542eadd59c
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/box.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/confluence_cloud.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/confluence_cloud.svg
new file mode 100644
index 0000000000000..7aac36a6fe3c5
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/confluence_cloud.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/confluence_server.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/confluence_server.svg
new file mode 100644
index 0000000000000..7aac36a6fe3c5
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/confluence_server.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/custom_api_source.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/custom_api_source.svg
new file mode 100644
index 0000000000000..cc07fbbc50877
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/custom_api_source.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/dropbox.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/dropbox.svg
new file mode 100644
index 0000000000000..01e5a7735de12
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/dropbox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/github.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/github.svg
new file mode 100644
index 0000000000000..aa9c3e5b45146
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/github.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/github_enterprise_server.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/github_enterprise_server.svg
new file mode 100644
index 0000000000000..aa9c3e5b45146
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/github_enterprise_server.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/gmail.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/gmail.svg
new file mode 100644
index 0000000000000..31fe60c6a63f9
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/gmail.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/google_drive.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/google_drive.svg
new file mode 100644
index 0000000000000..f3fe82cd3cd98
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/google_drive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/jira_cloud.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/jira_cloud.svg
new file mode 100644
index 0000000000000..c12e55798d889
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/jira_cloud.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/jira_server.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/jira_server.svg
new file mode 100644
index 0000000000000..4dfd0fd910079
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/jira_server.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/onedrive.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/onedrive.svg
new file mode 100644
index 0000000000000..c390dff1e418f
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/onedrive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/salesforce.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/salesforce.svg
new file mode 100644
index 0000000000000..ef6d552949424
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/salesforce.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/salesforce_sandbox.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/salesforce_sandbox.svg
new file mode 100644
index 0000000000000..ef6d552949424
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/salesforce_sandbox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/servicenow.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/servicenow.svg
new file mode 100644
index 0000000000000..6388ec44d21d7
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/servicenow.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/sharepoint_online.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/sharepoint_online.svg
new file mode 100644
index 0000000000000..aebfd7a8e49c0
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/sharepoint_online.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/slack.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/slack.svg
new file mode 100644
index 0000000000000..8f6fc0c987eaa
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/slack.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/public/assets/source_icons/zendesk.svg b/x-pack/plugins/enterprise_search/public/assets/source_icons/zendesk.svg
new file mode 100644
index 0000000000000..8afd143dd9a7c
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/assets/source_icons/zendesk.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/x-pack/plugins/enterprise_search/server/integrations.ts b/x-pack/plugins/enterprise_search/server/integrations.ts
new file mode 100644
index 0000000000000..48909261243e8
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/server/integrations.ts
@@ -0,0 +1,304 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { i18n } from '@kbn/i18n';
+import type { HttpServiceSetup } from 'src/core/server';
+
+import type { IntegrationCategory } from '../../../../src/plugins/custom_integrations/common';
+import type { CustomIntegrationsPluginSetup } from '../../../../src/plugins/custom_integrations/server';
+
+interface WorkplaceSearchIntegration {
+ id: string;
+ title: string;
+ description: string;
+ categories: IntegrationCategory[];
+ uiInternalPath?: string;
+}
+
+const workplaceSearchIntegrations: WorkplaceSearchIntegration[] = [
+ {
+ id: 'box',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.boxName', {
+ defaultMessage: 'Box',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.boxDescription',
+ {
+ defaultMessage: 'Search over your files and folders stored on Box with Workplace Search.',
+ }
+ ),
+ categories: ['document_storage'],
+ },
+ {
+ id: 'confluence_cloud',
+ title: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.confluenceCloudName',
+ {
+ defaultMessage: 'Confluence Cloud',
+ }
+ ),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.confluenceCloudDescription',
+ {
+ defaultMessage:
+ 'Search over your organizational content on Confluence Cloud with Workplace Search.',
+ }
+ ),
+ categories: ['knowledge_platform'],
+ },
+ {
+ id: 'confluence_server',
+ title: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.confluenceServerName',
+ {
+ defaultMessage: 'Confluence Server',
+ }
+ ),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.confluenceServerDescription',
+ {
+ defaultMessage:
+ 'Search over your organizational content on Confluence Server with Workplace Search.',
+ }
+ ),
+ categories: ['knowledge_platform'],
+ },
+ {
+ id: 'dropbox',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.dropboxName', {
+ defaultMessage: 'Dropbox',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.dropboxDescription',
+ {
+ defaultMessage:
+ 'Search over your files and folders stored on Dropbox with Workplace Search.',
+ }
+ ),
+ categories: ['document_storage'],
+ },
+ {
+ id: 'github',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.githubName', {
+ defaultMessage: 'GitHub',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.githubDescription',
+ {
+ defaultMessage: 'Search over your projects and repos on GitHub with Workplace Search.',
+ }
+ ),
+ categories: ['software_development'],
+ },
+ {
+ id: 'github_enterprise_server',
+ title: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.githubEnterpriseServerName',
+ {
+ defaultMessage: 'GitHub Enterprise Server',
+ }
+ ),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.githubEnterpriseServerDescription',
+ {
+ defaultMessage:
+ 'Search over your projects and repos on GitHub Enterprise Server with Workplace Search.',
+ }
+ ),
+ categories: ['software_development'],
+ },
+ {
+ id: 'gmail',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.gmailName', {
+ defaultMessage: 'Gmail',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.gmailDescription',
+ {
+ defaultMessage: 'Search over your emails managed by Gmail with Workplace Search.',
+ }
+ ),
+ categories: ['communication'],
+ },
+ {
+ id: 'google_drive',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.googleDriveName', {
+ defaultMessage: 'Google Drive',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.googleDriveDescription',
+ {
+ defaultMessage: 'Search over your documents on Google Drive with Workplace Search.',
+ }
+ ),
+ categories: ['document_storage'],
+ },
+ {
+ id: 'jira_cloud',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.jiraCloudName', {
+ defaultMessage: 'Jira Cloud',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.jiraCloudDescription',
+ {
+ defaultMessage: 'Search over your project workflow on Jira Cloud with Workplace Search.',
+ }
+ ),
+ categories: ['project_management'],
+ },
+ {
+ id: 'jira_server',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.jiraServerName', {
+ defaultMessage: 'Jira Server',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.jiraServerDescription',
+ {
+ defaultMessage: 'Search over your project workflow on Jira Server with Workplace Search.',
+ }
+ ),
+ categories: ['project_management'],
+ },
+ {
+ id: 'onedrive',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.onedriveName', {
+ defaultMessage: 'OneDrive',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.onedriveDescription',
+ {
+ defaultMessage: 'Search over your files stored on OneDrive with Workplace Search.',
+ }
+ ),
+ categories: ['document_storage'],
+ uiInternalPath: '/app/enterprise_search/workplace_search/sources/add/one_drive',
+ },
+ {
+ id: 'salesforce',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.salesforceName', {
+ defaultMessage: 'Salesforce',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.salesforceDescription',
+ {
+ defaultMessage: 'Search over your content on Salesforce with Workplace Search.',
+ }
+ ),
+ categories: ['crm'],
+ },
+ {
+ id: 'salesforce_sandbox',
+ title: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.salesforceSandboxName',
+ {
+ defaultMessage: 'Salesforce Sandbox',
+ }
+ ),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.salesforceSandboxDescription',
+ {
+ defaultMessage: 'Search over your content on Salesforce Sandbox with Workplace Search.',
+ }
+ ),
+ categories: ['crm'],
+ },
+ {
+ id: 'servicenow',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.servicenowName', {
+ defaultMessage: 'ServiceNow',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.servicenowDescription',
+ {
+ defaultMessage: 'Search over your content on ServiceNow with Workplace Search.',
+ }
+ ),
+ categories: ['enterprise_management'],
+ },
+ {
+ id: 'sharepoint_online',
+ title: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.sharepointOnlineName',
+ {
+ defaultMessage: 'SharePoint Online',
+ }
+ ),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.sharepointOnlineDescription',
+ {
+ defaultMessage: 'Search over your files stored on SharePoint Online with Workplace Search.',
+ }
+ ),
+ categories: ['document_storage'],
+ uiInternalPath: '/app/enterprise_search/workplace_search/sources/add/share_point',
+ },
+ {
+ id: 'slack',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.slackName', {
+ defaultMessage: 'Slack',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.slackDescription',
+ {
+ defaultMessage: 'Search over your messages on Slack with Workplace Search.',
+ }
+ ),
+ categories: ['communication'],
+ },
+ {
+ id: 'zendesk',
+ title: i18n.translate('xpack.enterpriseSearch.workplaceSearch.integrations.zendeskName', {
+ defaultMessage: 'Zendesk',
+ }),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.zendeskDescription',
+ {
+ defaultMessage: 'Search over your tickets on Zendesk with Workplace Search.',
+ }
+ ),
+ categories: ['customer_support'],
+ },
+ {
+ id: 'custom_api_source',
+ title: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.customApiSourceName',
+ {
+ defaultMessage: 'Custom API Source',
+ }
+ ),
+ description: i18n.translate(
+ 'xpack.enterpriseSearch.workplaceSearch.integrations.customApiSourceDescription',
+ {
+ defaultMessage:
+ 'Search over anything by building your own integration with Workplace Search.',
+ }
+ ),
+ categories: ['custom'],
+ uiInternalPath: '/app/enterprise_search/workplace_search/sources/add/custom',
+ },
+];
+
+export const registerEnterpriseSearchIntegrations = (
+ http: HttpServiceSetup,
+ customIntegrations: CustomIntegrationsPluginSetup
+) => {
+ workplaceSearchIntegrations.forEach((integration) => {
+ customIntegrations.registerCustomIntegration({
+ uiInternalPath: `/app/enterprise_search/workplace_search/sources/add/${integration.id}`,
+ icons: [
+ {
+ type: 'svg',
+ src: http.basePath.prepend(
+ `/plugins/enterpriseSearch/assets/source_icons/${integration.id}.svg`
+ ),
+ },
+ ],
+ isBeta: false,
+ shipper: 'enterprise_search',
+ ...integration,
+ });
+ });
+};
diff --git a/x-pack/plugins/enterprise_search/server/plugin.ts b/x-pack/plugins/enterprise_search/server/plugin.ts
index 26572134aa31c..1d58da5bbdd2b 100644
--- a/x-pack/plugins/enterprise_search/server/plugin.ts
+++ b/x-pack/plugins/enterprise_search/server/plugin.ts
@@ -15,6 +15,7 @@ import {
KibanaRequest,
DEFAULT_APP_CATEGORIES,
} from '../../../../src/core/server';
+import { CustomIntegrationsPluginSetup } from '../../../../src/plugins/custom_integrations/server';
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
import { InfraPluginSetup } from '../../infra/server';
@@ -31,6 +32,7 @@ import {
import { registerTelemetryUsageCollector as registerASTelemetryUsageCollector } from './collectors/app_search/telemetry';
import { registerTelemetryUsageCollector as registerESTelemetryUsageCollector } from './collectors/enterprise_search/telemetry';
import { registerTelemetryUsageCollector as registerWSTelemetryUsageCollector } from './collectors/workplace_search/telemetry';
+import { registerEnterpriseSearchIntegrations } from './integrations';
import { checkAccess } from './lib/check_access';
import { entSearchHttpAgent } from './lib/enterprise_search_http_agent';
@@ -55,6 +57,7 @@ interface PluginsSetup {
security?: SecurityPluginSetup;
features: FeaturesPluginSetup;
infra: InfraPluginSetup;
+ customIntegrations?: CustomIntegrationsPluginSetup;
}
interface PluginsStart {
@@ -80,11 +83,15 @@ export class EnterpriseSearchPlugin implements Plugin {
public setup(
{ capabilities, http, savedObjects, getStartServices }: CoreSetup,
- { usageCollection, security, features, infra }: PluginsSetup
+ { usageCollection, security, features, infra, customIntegrations }: PluginsSetup
) {
const config = this.config;
const log = this.logger;
+ if (customIntegrations) {
+ registerEnterpriseSearchIntegrations(http, customIntegrations);
+ }
+
/*
* Initialize config.ssl.certificateAuthorities file(s) - required for all API calls (+ access checks)
*/
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/settings.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/settings.test.ts
index aff9cd17dd001..d8ff7f1815a62 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/settings.test.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/settings.test.ts
@@ -57,13 +57,21 @@ describe('log settings routes', () => {
describe('validates', () => {
it('validates good data', () => {
- const request = {
+ mockRouter.shouldValidate({
body: {
analytics: { enabled: true },
+ },
+ });
+ mockRouter.shouldValidate({
+ body: {
api: { enabled: true },
},
- };
- mockRouter.shouldValidate(request);
+ });
+ mockRouter.shouldValidate({
+ body: {
+ crawler: { enabled: true },
+ },
+ });
});
it('rejects bad data', () => {
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/settings.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/settings.ts
index b83dfd9d9ef15..2d0ce1411761a 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/settings.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/settings.ts
@@ -38,6 +38,11 @@ export function registerSettingsRoutes({
enabled: schema.boolean(),
})
),
+ crawler: schema.maybe(
+ schema.object({
+ enabled: schema.boolean(),
+ })
+ ),
}),
},
},
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/source_engines.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/source_engines.test.ts
index 67edcc356e902..4374bbe88e183 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/source_engines.test.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/source_engines.test.ts
@@ -92,6 +92,7 @@ describe('source engine routes', () => {
it('creates a request to enterprise search', () => {
expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
path: '/as/engines/:name/source_engines/bulk_create',
+ hasJsonResponse: false,
});
});
});
@@ -145,6 +146,7 @@ describe('source engine routes', () => {
it('creates a request to enterprise search', () => {
expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
path: '/as/engines/:name/source_engines/:source_engine_name',
+ hasJsonResponse: false,
});
});
});
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/source_engines.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/source_engines.ts
index 1d41a82287b0e..79be0c9c29322 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/source_engines.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/source_engines.ts
@@ -45,6 +45,7 @@ export function registerSourceEnginesRoutes({
},
enterpriseSearchRequestHandler.createRequest({
path: '/as/engines/:name/source_engines/bulk_create',
+ hasJsonResponse: false,
})
);
@@ -60,6 +61,7 @@ export function registerSourceEnginesRoutes({
},
enterpriseSearchRequestHandler.createRequest({
path: '/as/engines/:name/source_engines/:source_engine_name',
+ hasJsonResponse: false,
})
);
}
diff --git a/x-pack/plugins/event_log/server/index.ts b/x-pack/plugins/event_log/server/index.ts
index deeee970ce68a..b643060415b19 100644
--- a/x-pack/plugins/event_log/server/index.ts
+++ b/x-pack/plugins/event_log/server/index.ts
@@ -33,6 +33,7 @@ export const config: PluginConfigDescriptor = {
settings?.xpack?.eventLog?.enabled === true
) {
addDeprecation({
+ configPath: 'xpack.eventLog.enabled',
message: `"xpack.eventLog.enabled" is deprecated. The ability to disable this plugin will be removed in 8.0.0.`,
correctiveActions: {
manualSteps: [`Remove "xpack.eventLog.enabled" from your kibana configs.`],
diff --git a/x-pack/plugins/fleet/public/applications/integrations/layouts/default.tsx b/x-pack/plugins/fleet/public/applications/integrations/layouts/default.tsx
index 8ced172e696aa..0c46e1af301cf 100644
--- a/x-pack/plugins/fleet/public/applications/integrations/layouts/default.tsx
+++ b/x-pack/plugins/fleet/public/applications/integrations/layouts/default.tsx
@@ -5,20 +5,12 @@
* 2.0.
*/
import React, { memo } from 'react';
-import { EuiFlexGroup, EuiFlexItem, EuiImage, EuiSpacer, EuiText, EuiLink } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
-import { i18n } from '@kbn/i18n';
-
-import styled, { useTheme } from 'styled-components';
-
-import type { EuiTheme } from 'src/plugins/kibana_react/common';
-
import { useLink } from '../../../hooks';
import type { Section } from '../sections';
-import { useLinks, useStartServices } from '../hooks';
-
import { WithHeaderLayout } from './';
interface Props {
@@ -26,45 +18,11 @@ interface Props {
children?: React.ReactNode;
}
-const Illustration = styled(EuiImage)`
- margin-bottom: -77px;
- position: relative;
- top: -16px;
- width: 395px;
-`;
-
-const Hero = styled.div`
- text-align: right;
-`;
-
-const HeroImage = memo(() => {
- const { toSharedAssets } = useLinks();
- const theme = useTheme() as EuiTheme;
- const IS_DARK_THEME = theme.darkMode;
-
- return (
-
-
-
- );
-});
-
export const DefaultLayout: React.FunctionComponent = memo(({ section, children }) => {
const { getHref } = useLink();
- const { docLinks } = useStartServices();
return (
}
leftColumn={
@@ -79,20 +37,11 @@ export const DefaultLayout: React.FunctionComponent = memo(({ section, ch
-
+
- {i18n.translate('xpack.fleet.epm.pageSubtitleLinkText', {
- defaultMessage: 'Getting started with Elastic Stack',
- })}
-
- ),
- }}
+ defaultMessage="Choose an integration to start collecting and analyzing your data"
/>
diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.stories.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.stories.tsx
index 94370587ddec8..86bac94bc50cd 100644
--- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.stories.tsx
+++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.stories.tsx
@@ -22,7 +22,7 @@ export default {
type Args = Omit & { width: number };
const args: Args = {
- width: 250,
+ width: 280,
title: 'Title',
description: 'Description',
name: 'beats',
diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.tsx
index a68499dbd8dd0..091eb4c97183d 100644
--- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.tsx
+++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_card.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import styled from 'styled-components';
-import { EuiCard } from '@elastic/eui';
+import { EuiCard, EuiFlexItem, EuiBadge, EuiToolTip, EuiSpacer } from '@elastic/eui';
import { CardIcon } from '../../../../../components/package_icon';
import type { IntegrationCardItem } from '../../../../../../common/types/models/epm';
@@ -16,10 +16,10 @@ import { RELEASE_BADGE_DESCRIPTION, RELEASE_BADGE_LABEL } from './release_badge'
export type PackageCardProps = IntegrationCardItem;
-// adding the `href` causes EuiCard to use a `a` instead of a `button`
-// `a` tags use `euiLinkColor` which results in blueish Badge text
+// Min-height is roughly 3 lines of content.
+// This keeps the cards from looking overly unbalanced because of content differences.
const Card = styled(EuiCard)`
- color: inherit;
+ min-height: 127px;
`;
export function PackageCard({
@@ -32,14 +32,28 @@ export function PackageCard({
url,
release,
}: PackageCardProps) {
- const betaBadgeLabel = release && release !== 'ga' ? RELEASE_BADGE_LABEL[release] : undefined;
- const betaBadgeLabelTooltipContent =
- release && release !== 'ga' ? RELEASE_BADGE_DESCRIPTION[release] : undefined;
+ let releaseBadge: React.ReactNode | null = null;
+
+ if (release && release !== 'ga') {
+ releaseBadge = (
+
+
+
+
+ {RELEASE_BADGE_LABEL[release]}
+
+
+
+ );
+ }
return (
}
href={url}
- betaBadgeLabel={betaBadgeLabel}
- betaBadgeTooltipContent={betaBadgeLabelTooltipContent}
target={url.startsWith('http') || url.startsWith('https') ? '_blank' : undefined}
- />
+ >
+ {releaseBadge}
+
);
}
diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx
index 2a4cb84f1e6ce..00adb2a7b4ffb 100644
--- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx
+++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx
@@ -5,8 +5,8 @@
* 2.0.
*/
-import type { ReactNode } from 'react';
-import React, { Fragment, useCallback, useState } from 'react';
+import type { ReactNode, FunctionComponent } from 'react';
+import React, { useCallback, useState, useRef, useEffect } from 'react';
import {
EuiFlexGrid,
EuiFlexGroup,
@@ -20,7 +20,6 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
-import { useStartServices } from '../../../../../hooks';
import { Loading } from '../../../components';
import { useLocalSearch, searchIdField } from '../../../hooks';
@@ -31,7 +30,7 @@ import { PackageCard } from './package_card';
export interface Props {
isLoading?: boolean;
controls?: ReactNode | ReactNode[];
- title: string;
+ title?: string;
list: IntegrationCardItem[];
initialSearch?: string;
setSelectedCategory: (category: string) => void;
@@ -40,7 +39,7 @@ export interface Props {
callout?: JSX.Element | null;
}
-export function PackageListGrid({
+export const PackageListGrid: FunctionComponent = ({
isLoading,
controls,
title,
@@ -50,9 +49,23 @@ export function PackageListGrid({
setSelectedCategory,
showMissingIntegrationMessage = false,
callout,
-}: Props) {
+}) => {
const [searchTerm, setSearchTerm] = useState(initialSearch || '');
const localSearchRef = useLocalSearch(list);
+ const menuRef = useRef(null);
+ const [isSticky, setIsSticky] = useState(false);
+ const [windowScrollY] = useState(window.scrollY);
+
+ useEffect(() => {
+ const menuRefCurrent = menuRef.current;
+ const onScroll = () => {
+ if (menuRefCurrent) {
+ setIsSticky(menuRefCurrent?.getBoundingClientRect().top < 110);
+ }
+ };
+ window.addEventListener('scroll', onScroll);
+ return () => window.removeEventListener('scroll', onScroll);
+ }, [windowScrollY, isSticky]);
const onQueryChange = ({
queryText: userInput,
@@ -71,7 +84,7 @@ export function PackageListGrid({
setSearchTerm('');
};
- const controlsContent = ;
+ const controlsContent = ;
let gridContent: JSX.Element;
if (isLoading || !localSearchRef.current) {
@@ -93,58 +106,68 @@ export function PackageListGrid({
}
return (
-
- {controlsContent}
-
-
- {callout ? (
- <>
-
- {callout}
- >
- ) : null}
-
- {gridContent}
- {showMissingIntegrationMessage && (
- <>
-
-
- >
- )}
-
-
+
+
+
+ {controlsContent}
+
+
+
+ {callout ? (
+ <>
+
+ {callout}
+ >
+ ) : null}
+
+ {gridContent}
+ {showMissingIntegrationMessage && (
+ <>
+
+
+ >
+ )}
+
+
+
);
-}
+};
interface ControlsColumnProps {
controls: ReactNode;
- title: string;
+ title: string | undefined;
+ sticky: boolean;
}
-function ControlsColumn({ controls, title }: ControlsColumnProps) {
+function ControlsColumn({ controls, title, sticky }: ControlsColumnProps) {
+ let titleContent;
+ if (title) {
+ titleContent = (
+ <>
+
+ {title}
+
+
+ >
+ );
+ }
return (
-
-
- {title}
-
-
-
- {controls}
-
-
-
+
+ {titleContent}
+ {controls}
+
);
}
@@ -196,20 +219,17 @@ function MissingIntegrationContent({
resetQuery,
setSelectedCategory,
}: MissingIntegrationContentProps) {
- const {
- application: { getUrlForApp },
- } = useStartServices();
const handleCustomInputsLinkClick = useCallback(() => {
resetQuery();
setSelectedCategory('custom');
}, [resetQuery, setSelectedCategory]);
return (
-
+
@@ -227,14 +247,6 @@ function MissingIntegrationContent({
/>
),
- beatsTutorialLink: (
-
-
-
- ),
}}
/>
diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx
index 40f89346c25bf..91b557d0db5b6 100644
--- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx
+++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx
@@ -7,9 +7,8 @@
import React, { memo, useMemo, useState } from 'react';
import { useLocation, useHistory, useParams } from 'react-router-dom';
-import { i18n } from '@kbn/i18n';
import _ from 'lodash';
-import { EuiHorizontalRule } from '@elastic/eui';
+import { EuiHorizontalRule, EuiFlexItem } from '@elastic/eui';
import { pagePathGetters } from '../../../../constants';
import {
@@ -93,10 +92,6 @@ const packageListToIntegrationsList = (packages: PackageList): PackageList => {
}, []);
};
-const title = i18n.translate('xpack.fleet.epmList.allTitle', {
- defaultMessage: 'Browse by category',
-});
-
// TODO: clintandrewhall - this component is hard to test due to the hooks, particularly those that use `http`
// or `location` to load data. Ideally, we'll split this into "connected" and "pure" components.
export const AvailablePackages: React.FC = memo(() => {
@@ -121,9 +116,7 @@ export const AvailablePackages: React.FC = memo(() => {
function setSearchTerm(search: string) {
// Use .replace so the browser's back button is not tied to single keystroke
- history.replace(
- pagePathGetters.integrations_all({ category: selectedCategory, searchTerm: search })[1]
- );
+ history.replace(pagePathGetters.integrations_all({ searchTerm: search })[1]);
}
const { data: eprPackages, isLoading: isLoadingAllPackages } = useGetPackages({
@@ -186,20 +179,26 @@ export const AvailablePackages: React.FC = memo(() => {
}
let controls = [
- ,
- ,
+
+
+ ,
+ ,
];
if (categories) {
controls = [
- {
- setSelectedCategory(id);
- }}
- />,
+
+ {
+ setSelectedCategory(id);
+ }}
+ />
+ ,
...controls,
];
}
@@ -214,7 +213,6 @@ export const AvailablePackages: React.FC = memo(() => {
return (
{
const { icons } = props;
if (icons && icons.length === 1 && icons[0].type === 'eui') {
- return ;
+ return ;
} else if (icons && icons.length === 1 && icons[0].type === 'svg') {
- return ;
+ return ;
} else {
return ;
}
diff --git a/x-pack/plugins/fleet/server/index.ts b/x-pack/plugins/fleet/server/index.ts
index 897f160810e29..cc754b87686e6 100644
--- a/x-pack/plugins/fleet/server/index.ts
+++ b/x-pack/plugins/fleet/server/index.ts
@@ -89,6 +89,7 @@ export const config: PluginConfigDescriptor = {
delete fullConfig.xpack.fleet.agents.elasticsearch.host;
fullConfig.xpack.fleet.agents.elasticsearch.hosts = [oldValue];
addDeprecation({
+ configPath: 'xpack.fleet.agents.elasticsearch.host',
message: `Config key [xpack.fleet.agents.elasticsearch.host] is deprecated and replaced by [xpack.fleet.agents.elasticsearch.hosts]`,
correctiveActions: {
manualSteps: [
diff --git a/x-pack/plugins/fleet/server/plugin.ts b/x-pack/plugins/fleet/server/plugin.ts
index a706ca6a54fdc..697ea0fa30d69 100644
--- a/x-pack/plugins/fleet/server/plugin.ts
+++ b/x-pack/plugins/fleet/server/plugin.ts
@@ -57,7 +57,7 @@ import {
registerPreconfigurationRoutes,
} from './routes';
-import type { ExternalCallback } from './types';
+import type { ExternalCallback, FleetRequestHandlerContext } from './types';
import type {
ESIndexPatternService,
AgentService,
@@ -231,7 +231,21 @@ export class FleetPlugin
});
}
- const router = core.http.createRouter();
+ core.http.registerRouteHandlerContext(
+ 'fleet',
+ (coreContext, request) => ({
+ epm: {
+ // Use a lazy getter to avoid constructing this client when not used by a request handler
+ get internalSoClient() {
+ return appContextService
+ .getSavedObjects()
+ .getScopedClient(request, { excludedWrappers: ['security'] });
+ },
+ },
+ })
+ );
+
+ const router = core.http.createRouter();
// Register usage collection
registerFleetUsageCollector(core, config, deps.usageCollection);
diff --git a/x-pack/plugins/fleet/server/routes/epm/handlers.ts b/x-pack/plugins/fleet/server/routes/epm/handlers.ts
index 2324d1a423bfc..c98038427cafc 100644
--- a/x-pack/plugins/fleet/server/routes/epm/handlers.ts
+++ b/x-pack/plugins/fleet/server/routes/epm/handlers.ts
@@ -9,7 +9,7 @@ import path from 'path';
import type { TypeOf } from '@kbn/config-schema';
import mime from 'mime-types';
-import type { RequestHandler, ResponseHeaders, KnownHeaders } from 'src/core/server';
+import type { ResponseHeaders, KnownHeaders } from 'src/core/server';
import type {
GetInfoResponse,
@@ -34,6 +34,7 @@ import type {
DeletePackageRequestSchema,
BulkUpgradePackagesFromRegistryRequestSchema,
GetStatsRequestSchema,
+ FleetRequestHandler,
UpdatePackageRequestSchema,
} from '../../types';
import {
@@ -57,7 +58,7 @@ import { getAsset } from '../../services/epm/archive/storage';
import { getPackageUsageStats } from '../../services/epm/packages/get';
import { updatePackage } from '../../services/epm/packages/update';
-export const getCategoriesHandler: RequestHandler<
+export const getCategoriesHandler: FleetRequestHandler<
undefined,
TypeOf
> = async (context, request, response) => {
@@ -72,12 +73,12 @@ export const getCategoriesHandler: RequestHandler<
}
};
-export const getListHandler: RequestHandler<
+export const getListHandler: FleetRequestHandler<
undefined,
TypeOf
> = async (context, request, response) => {
try {
- const savedObjectsClient = context.core.savedObjects.client;
+ const savedObjectsClient = context.fleet.epm.internalSoClient;
const res = await getPackages({
savedObjectsClient,
...request.query,
@@ -93,9 +94,9 @@ export const getListHandler: RequestHandler<
}
};
-export const getLimitedListHandler: RequestHandler = async (context, request, response) => {
+export const getLimitedListHandler: FleetRequestHandler = async (context, request, response) => {
try {
- const savedObjectsClient = context.core.savedObjects.client;
+ const savedObjectsClient = context.fleet.epm.internalSoClient;
const res = await getLimitedPackages({ savedObjectsClient });
const body: GetLimitedPackagesResponse = {
response: res,
@@ -108,110 +109,105 @@ export const getLimitedListHandler: RequestHandler = async (context, request, re
}
};
-export const getFileHandler: RequestHandler> = async (
- context,
- request,
- response
-) => {
- try {
- const { pkgName, pkgVersion, filePath } = request.params;
- const savedObjectsClient = context.core.savedObjects.client;
- const installation = await getInstallation({ savedObjectsClient, pkgName });
- const useLocalFile = pkgVersion === installation?.version;
+export const getFileHandler: FleetRequestHandler> =
+ async (context, request, response) => {
+ try {
+ const { pkgName, pkgVersion, filePath } = request.params;
+ const savedObjectsClient = context.fleet.epm.internalSoClient;
+ const installation = await getInstallation({ savedObjectsClient, pkgName });
+ const useLocalFile = pkgVersion === installation?.version;
+
+ if (useLocalFile) {
+ const assetPath = `${pkgName}-${pkgVersion}/${filePath}`;
+ const fileBuffer = getArchiveEntry(assetPath);
+ // only pull local installation if we don't have it cached
+ const storedAsset =
+ !fileBuffer && (await getAsset({ savedObjectsClient, path: assetPath }));
- if (useLocalFile) {
- const assetPath = `${pkgName}-${pkgVersion}/${filePath}`;
- const fileBuffer = getArchiveEntry(assetPath);
- // only pull local installation if we don't have it cached
- const storedAsset = !fileBuffer && (await getAsset({ savedObjectsClient, path: assetPath }));
+ // error, if neither is available
+ if (!fileBuffer && !storedAsset) {
+ return response.custom({
+ body: `installed package file not found: ${filePath}`,
+ statusCode: 404,
+ });
+ }
+
+ // if storedAsset is not available, fileBuffer *must* be
+ // b/c we error if we don't have at least one, and storedAsset is the least likely
+ const { buffer, contentType } = storedAsset
+ ? {
+ contentType: storedAsset.media_type,
+ buffer: storedAsset.data_utf8
+ ? Buffer.from(storedAsset.data_utf8, 'utf8')
+ : Buffer.from(storedAsset.data_base64, 'base64'),
+ }
+ : {
+ contentType: mime.contentType(path.extname(assetPath)),
+ buffer: fileBuffer,
+ };
+
+ if (!contentType) {
+ return response.custom({
+ body: `unknown content type for file: ${filePath}`,
+ statusCode: 400,
+ });
+ }
- // error, if neither is available
- if (!fileBuffer && !storedAsset) {
return response.custom({
- body: `installed package file not found: ${filePath}`,
- statusCode: 404,
+ body: buffer,
+ statusCode: 200,
+ headers: {
+ 'cache-control': 'max-age=10, public',
+ 'content-type': contentType,
+ },
});
- }
-
- // if storedAsset is not available, fileBuffer *must* be
- // b/c we error if we don't have at least one, and storedAsset is the least likely
- const { buffer, contentType } = storedAsset
- ? {
- contentType: storedAsset.media_type,
- buffer: storedAsset.data_utf8
- ? Buffer.from(storedAsset.data_utf8, 'utf8')
- : Buffer.from(storedAsset.data_base64, 'base64'),
+ } else {
+ const registryResponse = await getFile(pkgName, pkgVersion, filePath);
+ const headersToProxy: KnownHeaders[] = ['content-type', 'cache-control'];
+ const proxiedHeaders = headersToProxy.reduce((headers, knownHeader) => {
+ const value = registryResponse.headers.get(knownHeader);
+ if (value !== null) {
+ headers[knownHeader] = value;
}
- : {
- contentType: mime.contentType(path.extname(assetPath)),
- buffer: fileBuffer,
- };
+ return headers;
+ }, {} as ResponseHeaders);
- if (!contentType) {
return response.custom({
- body: `unknown content type for file: ${filePath}`,
- statusCode: 400,
+ body: registryResponse.body,
+ statusCode: registryResponse.status,
+ headers: proxiedHeaders,
});
}
-
- return response.custom({
- body: buffer,
- statusCode: 200,
- headers: {
- 'cache-control': 'max-age=10, public',
- 'content-type': contentType,
- },
- });
- } else {
- const registryResponse = await getFile(pkgName, pkgVersion, filePath);
- const headersToProxy: KnownHeaders[] = ['content-type', 'cache-control'];
- const proxiedHeaders = headersToProxy.reduce((headers, knownHeader) => {
- const value = registryResponse.headers.get(knownHeader);
- if (value !== null) {
- headers[knownHeader] = value;
- }
- return headers;
- }, {} as ResponseHeaders);
-
- return response.custom({
- body: registryResponse.body,
- statusCode: registryResponse.status,
- headers: proxiedHeaders,
- });
+ } catch (error) {
+ return defaultIngestErrorHandler({ error, response });
}
- } catch (error) {
- return defaultIngestErrorHandler({ error, response });
- }
-};
+ };
-export const getInfoHandler: RequestHandler> = async (
- context,
- request,
- response
-) => {
- try {
- const { pkgkey } = request.params;
- const savedObjectsClient = context.core.savedObjects.client;
- // TODO: change epm API to /packageName/version so we don't need to do this
- const { pkgName, pkgVersion } = splitPkgKey(pkgkey);
- const res = await getPackageInfo({ savedObjectsClient, pkgName, pkgVersion });
- const body: GetInfoResponse = {
- response: res,
- };
- return response.ok({ body });
- } catch (error) {
- return defaultIngestErrorHandler({ error, response });
- }
-};
+export const getInfoHandler: FleetRequestHandler> =
+ async (context, request, response) => {
+ try {
+ const { pkgkey } = request.params;
+ const savedObjectsClient = context.fleet.epm.internalSoClient;
+ // TODO: change epm API to /packageName/version so we don't need to do this
+ const { pkgName, pkgVersion } = splitPkgKey(pkgkey);
+ const res = await getPackageInfo({ savedObjectsClient, pkgName, pkgVersion });
+ const body: GetInfoResponse = {
+ response: res,
+ };
+ return response.ok({ body });
+ } catch (error) {
+ return defaultIngestErrorHandler({ error, response });
+ }
+ };
-export const updatePackageHandler: RequestHandler<
+export const updatePackageHandler: FleetRequestHandler<
TypeOf,
unknown,
TypeOf
> = async (context, request, response) => {
try {
const { pkgkey } = request.params;
- const savedObjectsClient = context.core.savedObjects.client;
+ const savedObjectsClient = context.fleet.epm.internalSoClient;
const { pkgName } = splitPkgKey(pkgkey);
@@ -226,30 +222,27 @@ export const updatePackageHandler: RequestHandler<
}
};
-export const getStatsHandler: RequestHandler> = async (
- context,
- request,
- response
-) => {
- try {
- const { pkgName } = request.params;
- const savedObjectsClient = context.core.savedObjects.client;
- const body: GetStatsResponse = {
- response: await getPackageUsageStats({ savedObjectsClient, pkgName }),
- };
- return response.ok({ body });
- } catch (error) {
- return defaultIngestErrorHandler({ error, response });
- }
-};
+export const getStatsHandler: FleetRequestHandler> =
+ async (context, request, response) => {
+ try {
+ const { pkgName } = request.params;
+ const savedObjectsClient = context.fleet.epm.internalSoClient;
+ const body: GetStatsResponse = {
+ response: await getPackageUsageStats({ savedObjectsClient, pkgName }),
+ };
+ return response.ok({ body });
+ } catch (error) {
+ return defaultIngestErrorHandler({ error, response });
+ }
+ };
-export const installPackageFromRegistryHandler: RequestHandler<
+export const installPackageFromRegistryHandler: FleetRequestHandler<
TypeOf,
undefined,
TypeOf
> = async (context, request, response) => {
- const savedObjectsClient = context.core.savedObjects.client;
- const esClient = context.core.elasticsearch.client.asCurrentUser;
+ const savedObjectsClient = context.fleet.epm.internalSoClient;
+ const esClient = context.core.elasticsearch.client.asInternalUser;
const { pkgkey } = request.params;
const res = await installPackage({
@@ -284,13 +277,13 @@ const bulkInstallServiceResponseToHttpEntry = (
}
};
-export const bulkInstallPackagesFromRegistryHandler: RequestHandler<
+export const bulkInstallPackagesFromRegistryHandler: FleetRequestHandler<
undefined,
undefined,
TypeOf
> = async (context, request, response) => {
- const savedObjectsClient = context.core.savedObjects.client;
- const esClient = context.core.elasticsearch.client.asCurrentUser;
+ const savedObjectsClient = context.fleet.epm.internalSoClient;
+ const esClient = context.core.elasticsearch.client.asInternalUser;
const bulkInstalledResponses = await bulkInstallPackages({
savedObjectsClient,
esClient,
@@ -303,7 +296,7 @@ export const bulkInstallPackagesFromRegistryHandler: RequestHandler<
return response.ok({ body });
};
-export const installPackageByUploadHandler: RequestHandler<
+export const installPackageByUploadHandler: FleetRequestHandler<
undefined,
undefined,
TypeOf
@@ -314,8 +307,8 @@ export const installPackageByUploadHandler: RequestHandler<
body: { message: 'Requires Enterprise license' },
});
}
- const savedObjectsClient = context.core.savedObjects.client;
- const esClient = context.core.elasticsearch.client.asCurrentUser;
+ const savedObjectsClient = context.fleet.epm.internalSoClient;
+ const esClient = context.core.elasticsearch.client.asInternalUser;
const contentType = request.headers['content-type'] as string; // from types it could also be string[] or undefined but this is checked later
const archiveBuffer = Buffer.from(request.body);
@@ -336,15 +329,15 @@ export const installPackageByUploadHandler: RequestHandler<
}
};
-export const deletePackageHandler: RequestHandler<
+export const deletePackageHandler: FleetRequestHandler<
TypeOf,
undefined,
TypeOf
> = async (context, request, response) => {
try {
const { pkgkey } = request.params;
- const savedObjectsClient = context.core.savedObjects.client;
- const esClient = context.core.elasticsearch.client.asCurrentUser;
+ const savedObjectsClient = context.fleet.epm.internalSoClient;
+ const esClient = context.core.elasticsearch.client.asInternalUser;
const res = await removeInstallation({
savedObjectsClient,
pkgkey,
diff --git a/x-pack/plugins/fleet/server/routes/epm/index.ts b/x-pack/plugins/fleet/server/routes/epm/index.ts
index 0f49b3cfa772d..360f2ec1d446e 100644
--- a/x-pack/plugins/fleet/server/routes/epm/index.ts
+++ b/x-pack/plugins/fleet/server/routes/epm/index.ts
@@ -8,6 +8,7 @@
import type { IRouter } from 'src/core/server';
import { PLUGIN_ID, EPM_API_ROUTES } from '../../constants';
+import type { FleetRequestHandlerContext } from '../../types';
import {
GetCategoriesRequestSchema,
GetPackagesRequestSchema,
@@ -38,7 +39,7 @@ import {
const MAX_FILE_SIZE_BYTES = 104857600; // 100MB
-export const registerRoutes = (router: IRouter) => {
+export const registerRoutes = (router: IRouter) => {
router.get(
{
path: EPM_API_ROUTES.CATEGORIES_PATTERN,
diff --git a/x-pack/plugins/fleet/server/routes/security.ts b/x-pack/plugins/fleet/server/routes/security.ts
index 8efea34ed8164..33a510c27f04e 100644
--- a/x-pack/plugins/fleet/server/routes/security.ts
+++ b/x-pack/plugins/fleet/server/routes/security.ts
@@ -5,13 +5,13 @@
* 2.0.
*/
-import type { IRouter, RequestHandler } from 'src/core/server';
+import type { IRouter, RequestHandler, RequestHandlerContext } from 'src/core/server';
import { appContextService } from '../services';
-export function enforceSuperUser(
- handler: RequestHandler
-): RequestHandler {
+export function enforceSuperUser(
+ handler: RequestHandler
+): RequestHandler {
return function enforceSuperHandler(context, req, res) {
if (!appContextService.hasSecurity() || !appContextService.getSecurityLicense().isEnabled()) {
return res.forbidden({
@@ -44,7 +44,9 @@ export function enforceSuperUser(
};
}
-export function makeRouterEnforcingSuperuser(router: IRouter): IRouter {
+export function makeRouterEnforcingSuperuser(
+ router: IRouter
+): IRouter {
return {
get: (options, handler) => router.get(options, enforceSuperUser(handler)),
delete: (options, handler) => router.delete(options, enforceSuperUser(handler)),
diff --git a/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts b/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts
index c196054faf08c..b39c6e7686110 100644
--- a/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts
+++ b/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts
@@ -5,13 +5,14 @@
* 2.0.
*/
-import { httpServerMock } from 'src/core/server/mocks';
+import { httpServerMock, savedObjectsClientMock } from 'src/core/server/mocks';
import type { PostFleetSetupResponse } from '../../../common';
import { RegistryError } from '../../errors';
import { createAppContextStartContractMock, xpackMocks } from '../../mocks';
import { appContextService } from '../../services/app_context';
import { setupFleet } from '../../services/setup';
+import type { FleetRequestHandlerContext } from '../../types';
import { fleetSetupHandler } from './handlers';
@@ -24,12 +25,19 @@ jest.mock('../../services/setup', () => {
const mockSetupFleet = setupFleet as jest.MockedFunction;
describe('FleetSetupHandler', () => {
- let context: ReturnType;
+ let context: FleetRequestHandlerContext;
let response: ReturnType;
let request: ReturnType;
beforeEach(async () => {
- context = xpackMocks.createRequestHandlerContext();
+ context = {
+ ...xpackMocks.createRequestHandlerContext(),
+ fleet: {
+ epm: {
+ internalSoClient: savedObjectsClientMock.create(),
+ },
+ },
+ };
response = httpServerMock.createResponseFactory();
request = httpServerMock.createKibanaRequest({
method: 'post',
diff --git a/x-pack/plugins/fleet/server/routes/setup/handlers.ts b/x-pack/plugins/fleet/server/routes/setup/handlers.ts
index d24db96667d52..c5b2ef0ade26f 100644
--- a/x-pack/plugins/fleet/server/routes/setup/handlers.ts
+++ b/x-pack/plugins/fleet/server/routes/setup/handlers.ts
@@ -12,6 +12,7 @@ import type { GetFleetStatusResponse, PostFleetSetupResponse } from '../../../co
import { setupFleet } from '../../services/setup';
import { hasFleetServers } from '../../services/fleet_server';
import { defaultIngestErrorHandler } from '../../errors';
+import type { FleetRequestHandler } from '../../types';
export const getFleetStatusHandler: RequestHandler = async (context, request, response) => {
try {
@@ -42,10 +43,10 @@ export const getFleetStatusHandler: RequestHandler = async (context, request, re
}
};
-export const fleetSetupHandler: RequestHandler = async (context, request, response) => {
+export const fleetSetupHandler: FleetRequestHandler = async (context, request, response) => {
try {
- const soClient = context.core.savedObjects.client;
- const esClient = context.core.elasticsearch.client.asCurrentUser;
+ const soClient = context.fleet.epm.internalSoClient;
+ const esClient = context.core.elasticsearch.client.asInternalUser;
const setupStatus = await setupFleet(soClient, esClient);
const body: PostFleetSetupResponse = {
...setupStatus,
diff --git a/x-pack/plugins/fleet/server/routes/setup/index.ts b/x-pack/plugins/fleet/server/routes/setup/index.ts
index d64c9f24f2610..591b9c832172d 100644
--- a/x-pack/plugins/fleet/server/routes/setup/index.ts
+++ b/x-pack/plugins/fleet/server/routes/setup/index.ts
@@ -10,9 +10,11 @@ import type { IRouter } from 'src/core/server';
import { PLUGIN_ID, AGENTS_SETUP_API_ROUTES, SETUP_API_ROUTE } from '../../constants';
import type { FleetConfigType } from '../../../common';
+import type { FleetRequestHandlerContext } from '../../types/request_context';
+
import { getFleetStatusHandler, fleetSetupHandler } from './handlers';
-export const registerFleetSetupRoute = (router: IRouter) => {
+export const registerFleetSetupRoute = (router: IRouter) => {
router.post(
{
path: SETUP_API_ROUTE,
@@ -26,7 +28,7 @@ export const registerFleetSetupRoute = (router: IRouter) => {
};
// That route is used by agent to setup Fleet
-export const registerCreateFleetSetupRoute = (router: IRouter) => {
+export const registerCreateFleetSetupRoute = (router: IRouter) => {
router.post(
{
path: AGENTS_SETUP_API_ROUTES.CREATE_PATTERN,
@@ -37,7 +39,7 @@ export const registerCreateFleetSetupRoute = (router: IRouter) => {
);
};
-export const registerGetFleetStatusRoute = (router: IRouter) => {
+export const registerGetFleetStatusRoute = (router: IRouter) => {
router.get(
{
path: AGENTS_SETUP_API_ROUTES.INFO_PATTERN,
@@ -48,7 +50,10 @@ export const registerGetFleetStatusRoute = (router: IRouter) => {
);
};
-export const registerRoutes = (router: IRouter, config: FleetConfigType) => {
+export const registerRoutes = (
+ router: IRouter,
+ config: FleetConfigType
+) => {
// Ingest manager setup
registerFleetSetupRoute(router);
diff --git a/x-pack/plugins/fleet/server/types/index.tsx b/x-pack/plugins/fleet/server/types/index.tsx
index 63e6c277ed710..5bdd95ef0b874 100644
--- a/x-pack/plugins/fleet/server/types/index.tsx
+++ b/x-pack/plugins/fleet/server/types/index.tsx
@@ -96,3 +96,4 @@ export interface BulkActionResult {
export * from './models';
export * from './rest_spec';
export * from './extensions';
+export { FleetRequestHandler, FleetRequestHandlerContext } from './request_context';
diff --git a/x-pack/plugins/fleet/server/types/request_context.ts b/x-pack/plugins/fleet/server/types/request_context.ts
new file mode 100644
index 0000000000000..a3b414119b685
--- /dev/null
+++ b/x-pack/plugins/fleet/server/types/request_context.ts
@@ -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 type {
+ KibanaResponseFactory,
+ RequestHandler,
+ RequestHandlerContext,
+ RouteMethod,
+ SavedObjectsClientContract,
+} from '../../../../../src/core/server';
+
+/** @internal */
+export interface FleetRequestHandlerContext extends RequestHandlerContext {
+ fleet: {
+ epm: {
+ /**
+ * Saved Objects client configured to use kibana_system privileges instead of end-user privileges. Should only be
+ * used by routes that have additional privilege checks for authorization (such as requiring superuser).
+ */
+ readonly internalSoClient: SavedObjectsClientContract;
+ };
+ };
+}
+
+/**
+ * Convenience type for request handlers in Fleet that includes the FleetRequestHandlerContext type
+ * @internal
+ */
+export type FleetRequestHandler<
+ P = unknown,
+ Q = unknown,
+ B = unknown,
+ Method extends RouteMethod = any,
+ ResponseFactory extends KibanaResponseFactory = KibanaResponseFactory
+> = RequestHandler;
diff --git a/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx b/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx
index 0e5ef1ca78033..2b0aaf5175b88 100644
--- a/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx
+++ b/x-pack/plugins/infra/public/containers/with_kuery_autocompletion.tsx
@@ -83,7 +83,6 @@ class WithKueryAutocompletionComponent extends React.Component<
query: expression,
selectionStart: cursorPosition,
selectionEnd: cursorPosition,
- // @ts-expect-error (until data service updates to new types)
indexPatterns: [indexPattern],
boolFilter: [],
})) || [];
diff --git a/x-pack/plugins/maps/server/index.ts b/x-pack/plugins/maps/server/index.ts
index 4e5dfcf1f94c4..6a846bc245824 100644
--- a/x-pack/plugins/maps/server/index.ts
+++ b/x-pack/plugins/maps/server/index.ts
@@ -34,6 +34,7 @@ export const config: PluginConfigDescriptor = {
return completeConfig;
}
addDeprecation({
+ configPath: 'xpack.maps.showMapVisualizationTypes',
message: i18n.translate('xpack.maps.deprecation.showMapVisualizationTypes.message', {
defaultMessage:
'xpack.maps.showMapVisualizationTypes is deprecated and is no longer used',
@@ -59,6 +60,7 @@ export const config: PluginConfigDescriptor = {
return completeConfig;
}
addDeprecation({
+ configPath: 'map.proxyElasticMapsServiceInMaps',
documentationUrl: `https://www.elastic.co/guide/en/kibana/${branch}/maps-connect-to-ems.html#elastic-maps-server`,
message: i18n.translate('xpack.maps.deprecation.proxyEMS.message', {
defaultMessage: 'map.proxyElasticMapsServiceInMaps is deprecated and is no longer used',
@@ -86,6 +88,7 @@ export const config: PluginConfigDescriptor = {
return completeConfig;
}
addDeprecation({
+ configPath: 'map.regionmap',
message: i18n.translate('xpack.maps.deprecation.regionmap.message', {
defaultMessage: 'map.regionmap is deprecated and is no longer used',
}),
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json
index 123232935df05..f8feaef3be5f8 100644
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json
@@ -1,29 +1,29 @@
{
"id": "apm_transaction",
"title": "APM",
- "description": "Detect anomalies in transactions from your APM services for metric data.",
+ "description": "Detect anomalies in transactions from your APM services.",
"type": "Transaction data",
"logoFile": "logo.json",
- "defaultIndexPattern": "apm-*-metric,metrics-apm*",
+ "defaultIndexPattern": "apm-*-transaction",
"query": {
"bool": {
"filter": [
- { "term": { "processor.event": "metric" } },
- { "term": { "metricset.name": "transaction" } }
+ { "term": { "processor.event": "transaction" } },
+ { "exists": { "field": "transaction.duration" } }
]
}
},
"jobs": [
{
- "id": "apm_metrics",
- "file": "apm_metrics.json"
+ "id": "high_mean_transaction_duration",
+ "file": "high_mean_transaction_duration.json"
}
],
"datafeeds": [
{
- "id": "datafeed-apm_metrics",
- "file": "datafeed_apm_metrics.json",
- "job_id": "apm_metrics"
+ "id": "datafeed-high_mean_transaction_duration",
+ "file": "datafeed_high_mean_transaction_duration.json",
+ "job_id": "high_mean_transaction_duration"
}
]
}
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/apm_metrics.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/apm_metrics.json
deleted file mode 100644
index d5092f3ffc553..0000000000000
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/apm_metrics.json
+++ /dev/null
@@ -1,53 +0,0 @@
-{
- "job_type": "anomaly_detector",
- "groups": [
- "apm"
- ],
- "description": "Detects anomalies in transaction duration, throughput and error percentage for metric data.",
- "analysis_config": {
- "bucket_span": "15m",
- "summary_count_field_name" : "doc_count",
- "detectors" : [
- {
- "detector_description" : "high duration by transaction type for an APM service",
- "function" : "high_mean",
- "field_name" : "transaction_duration",
- "by_field_name" : "transaction.type",
- "partition_field_name" : "service.name"
- },
- {
- "detector_description" : "transactions per minute for an APM service",
- "function" : "mean",
- "field_name" : "transactions_per_min",
- "by_field_name" : "transaction.type",
- "partition_field_name" : "service.name"
- },
- {
- "detector_description" : "percent failed for an APM service",
- "function" : "high_mean",
- "field_name" : "transaction_failure_percentage",
- "by_field_name" : "transaction.type",
- "partition_field_name" : "service.name"
- }
- ],
- "influencers" : [
- "transaction.type",
- "service.name"
- ]
- },
- "analysis_limits": {
- "model_memory_limit": "32mb"
- },
- "data_description": {
- "time_field" : "@timestamp",
- "time_format" : "epoch_ms"
- },
- "model_plot_config": {
- "enabled" : true,
- "annotations_enabled" : true
- },
- "results_index_name" : "custom-apm",
- "custom_settings": {
- "created_by": "ml-module-apm-transaction"
- }
-}
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/datafeed_apm_metrics.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/datafeed_apm_metrics.json
deleted file mode 100644
index ba45582252cd7..0000000000000
--- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/datafeed_apm_metrics.json
+++ /dev/null
@@ -1,95 +0,0 @@
-{
- "job_id": "JOB_ID",
- "indices": [
- "INDEX_PATTERN_NAME"
- ],
- "chunking_config" : {
- "mode" : "off"
- },
- "query": {
- "bool": {
- "filter": [
- { "term": { "processor.event": "metric" } },
- { "term": { "metricset.name": "transaction" } }
- ]
- }
- },
- "aggregations" : {
- "buckets" : {
- "composite" : {
- "size" : 5000,
- "sources" : [
- {
- "date" : {
- "date_histogram" : {
- "field" : "@timestamp",
- "fixed_interval" : "90s"
- }
- }
- },
- {
- "transaction.type" : {
- "terms" : {
- "field" : "transaction.type"
- }
- }
- },
- {
- "service.name" : {
- "terms" : {
- "field" : "service.name"
- }
- }
- }
- ]
- },
- "aggs" : {
- "@timestamp" : {
- "max" : {
- "field" : "@timestamp"
- }
- },
- "transactions_per_min" : {
- "rate" : {
- "unit" : "minute"
- }
- },
- "transaction_duration" : {
- "avg" : {
- "field" : "transaction.duration.histogram"
- }
- },
- "error_count" : {
- "filter" : {
- "term" : {
- "event.outcome" : "failure"
- }
- },
- "aggs" : {
- "actual_error_count" : {
- "value_count" : {
- "field" : "event.outcome"
- }
- }
- }
- },
- "success_count" : {
- "filter" : {
- "term" : {
- "event.outcome" : "success"
- }
- }
- },
- "transaction_failure_percentage" : {
- "bucket_script" : {
- "buckets_path" : {
- "failure_count" : "error_count>_count",
- "success_count" : "success_count>_count"
- },
- "script" : "if ((params.failure_count + params.success_count)==0){return 0;}else{return params.failure_count/(params.failure_count + params.success_count);}"
- }
- }
- }
- }
- }
-}
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/datafeed_high_mean_transaction_duration.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/datafeed_high_mean_transaction_duration.json
new file mode 100644
index 0000000000000..d312577902f51
--- /dev/null
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/datafeed_high_mean_transaction_duration.json
@@ -0,0 +1,14 @@
+{
+ "job_id": "JOB_ID",
+ "indices": [
+ "INDEX_PATTERN_NAME"
+ ],
+ "query": {
+ "bool": {
+ "filter": [
+ { "term": { "processor.event": "transaction" } },
+ { "exists": { "field": "transaction.duration.us" } }
+ ]
+ }
+ }
+}
diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/high_mean_transaction_duration.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/high_mean_transaction_duration.json
new file mode 100644
index 0000000000000..77284cb275cd8
--- /dev/null
+++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/ml/high_mean_transaction_duration.json
@@ -0,0 +1,35 @@
+{
+ "job_type": "anomaly_detector",
+ "groups": [
+ "apm"
+ ],
+ "description": "Detect transaction duration anomalies across transaction types for your APM services.",
+ "analysis_config": {
+ "bucket_span": "15m",
+ "detectors": [
+ {
+ "detector_description": "high duration by transaction type for an APM service",
+ "function": "high_mean",
+ "field_name": "transaction.duration.us",
+ "by_field_name": "transaction.type",
+ "partition_field_name": "service.name"
+ }
+ ],
+ "influencers": [
+ "transaction.type",
+ "service.name"
+ ]
+ },
+ "analysis_limits": {
+ "model_memory_limit": "32mb"
+ },
+ "data_description": {
+ "time_field": "@timestamp"
+ },
+ "model_plot_config": {
+ "enabled": true
+ },
+ "custom_settings": {
+ "created_by": "ml-module-apm-transaction"
+ }
+}
diff --git a/x-pack/plugins/monitoring/public/application/pages/beats/beats_template.tsx b/x-pack/plugins/monitoring/public/application/pages/beats/beats_template.tsx
index 3bab01af8ceb7..7a070c735bbea 100644
--- a/x-pack/plugins/monitoring/public/application/pages/beats/beats_template.tsx
+++ b/x-pack/plugins/monitoring/public/application/pages/beats/beats_template.tsx
@@ -23,6 +23,7 @@ export const BeatsTemplate: React.FC = ({ instance, ...props
defaultMessage: 'Overview',
}),
route: '/beats',
+ testSubj: 'beatsOverviewPage',
});
tabs.push({
id: 'instances',
@@ -30,6 +31,7 @@ export const BeatsTemplate: React.FC = ({ instance, ...props
defaultMessage: 'Instances',
}),
route: '/beats/beats',
+ testSubj: 'beatsListingPage',
});
} else {
tabs.push({
diff --git a/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx b/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx
index 489ad110c40fd..4611f17159621 100644
--- a/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx
+++ b/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx
@@ -71,12 +71,7 @@ export const BeatsInstancesPage: React.FC = ({ clusters }) => {
]);
return (
-
+
= ({ clusters }) => {
};
return (
-
- {renderOverview(data)}
+
+ {renderOverview(data)}
);
};
diff --git a/x-pack/plugins/monitoring/public/application/pages/kibana/instance.tsx b/x-pack/plugins/monitoring/public/application/pages/kibana/instance.tsx
index 444794d118b0f..2d2fe99758ff7 100644
--- a/x-pack/plugins/monitoring/public/application/pages/kibana/instance.tsx
+++ b/x-pack/plugins/monitoring/public/application/pages/kibana/instance.tsx
@@ -164,13 +164,8 @@ export const KibanaInstancePage: React.FC = ({ clusters }) => {
}, [ccs, clusterUuid, instance, services.data?.query.timefilter.timefilter, services.http]);
return (
-
-
+
+
diff --git a/x-pack/plugins/monitoring/public/application/pages/kibana/instances.tsx b/x-pack/plugins/monitoring/public/application/pages/kibana/instances.tsx
index ae0237ea40472..076e9413216fb 100644
--- a/x-pack/plugins/monitoring/public/application/pages/kibana/instances.tsx
+++ b/x-pack/plugins/monitoring/public/application/pages/kibana/instances.tsx
@@ -87,12 +87,7 @@ export const KibanaInstancesPage: React.FC
= ({ clusters }) => {
]);
return (
-
+
= ({ ...props }) => {
defaultMessage: 'Overview',
}),
route: '/kibana',
+ testSubj: 'kibanaOverviewPage',
},
{
id: 'instances',
@@ -23,6 +24,7 @@ export const KibanaTemplate: React.FC = ({ ...props }) => {
defaultMessage: 'Instances',
}),
route: '/kibana/instances',
+ testSubj: 'kibanaInstancesPage',
},
];
diff --git a/x-pack/plugins/monitoring/public/application/pages/kibana/overview.tsx b/x-pack/plugins/monitoring/public/application/pages/kibana/overview.tsx
index a47da048e1936..4c480bf1fbb33 100644
--- a/x-pack/plugins/monitoring/public/application/pages/kibana/overview.tsx
+++ b/x-pack/plugins/monitoring/public/application/pages/kibana/overview.tsx
@@ -107,12 +107,7 @@ export const KibanaOverviewPage: React.FC = ({ clusters }) => {
}, [ccs, clusterUuid, services.data?.query.timefilter.timefilter, services.http]);
return (
-
+
);
diff --git a/x-pack/plugins/monitoring/public/application/pages/no_data/no_data_page.tsx b/x-pack/plugins/monitoring/public/application/pages/no_data/no_data_page.tsx
index 26072f53f4752..e798e7d74ad38 100644
--- a/x-pack/plugins/monitoring/public/application/pages/no_data/no_data_page.tsx
+++ b/x-pack/plugins/monitoring/public/application/pages/no_data/no_data_page.tsx
@@ -220,12 +220,10 @@ async function executeCheck(checker: SettingsChecker, http: { fetch: any }): Pro
return { found, reason };
} catch (err: any) {
- const { data } = err;
-
return {
error: true,
found: false,
- errorReason: data,
+ errorReason: err.body,
};
}
}
diff --git a/x-pack/plugins/monitoring/public/application/pages/page_template.tsx b/x-pack/plugins/monitoring/public/application/pages/page_template.tsx
index 5c030814d9cdf..23eeb2c034a80 100644
--- a/x-pack/plugins/monitoring/public/application/pages/page_template.tsx
+++ b/x-pack/plugins/monitoring/public/application/pages/page_template.tsx
@@ -92,7 +92,7 @@ export const PageTemplate: React.FC = ({
};
return (
-
+
diff --git a/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap b/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap
index b6d117fb3269c..8852d104fe00a 100644
--- a/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap
+++ b/x-pack/plugins/monitoring/public/components/no_data/__snapshots__/no_data.test.js.snap
@@ -3,7 +3,13 @@
exports[`NoData should show a default message if reason is unknown 1`] = `
+
+ No monitoring data found.
+
+
+ No monitoring data found.
+
{
+ return
{children} ;
+ };
+
if (isCloudEnabled) {
return (
-
+
-
+
);
}
if (useInternalCollection) {
return (
-
+
+
+
+
+
+
-
+
);
}
return (
-
+
+
+
+
+
+
-
+
);
}
diff --git a/x-pack/plugins/monitoring/public/components/no_data/reasons/__snapshots__/we_tried.test.js.snap b/x-pack/plugins/monitoring/public/components/no_data/reasons/__snapshots__/we_tried.test.js.snap
index 482e6e97115b7..4e1209a5fd2aa 100644
--- a/x-pack/plugins/monitoring/public/components/no_data/reasons/__snapshots__/we_tried.test.js.snap
+++ b/x-pack/plugins/monitoring/public/components/no_data/reasons/__snapshots__/we_tried.test.js.snap
@@ -1,15 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`WeTried should render "we tried" message 1`] = `
-Array [
+
We couldn't activate monitoring
- ,
+
,
+ />
@@ -19,6 +21,6 @@ Array [
If data is in your cluster, your monitoring dashboards will show up here.
-
,
-]
+
+
`;
diff --git a/x-pack/plugins/monitoring/public/components/no_data/reasons/we_tried.js b/x-pack/plugins/monitoring/public/components/no_data/reasons/we_tried.js
index 17e171451e3a3..37504f5842a74 100644
--- a/x-pack/plugins/monitoring/public/components/no_data/reasons/we_tried.js
+++ b/x-pack/plugins/monitoring/public/components/no_data/reasons/we_tried.js
@@ -5,13 +5,13 @@
* 2.0.
*/
-import React, { Fragment } from 'react';
+import React from 'react';
import { EuiText, EuiHorizontalRule, EuiTitle } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
export function WeTried() {
return (
-
+
-
+
);
}
diff --git a/x-pack/plugins/monitoring/public/directives/main/index.html b/x-pack/plugins/monitoring/public/directives/main/index.html
index c479b282cd778..fd14120e1db2f 100644
--- a/x-pack/plugins/monitoring/public/directives/main/index.html
+++ b/x-pack/plugins/monitoring/public/directives/main/index.html
@@ -1,4 +1,4 @@
-
+
diff --git a/x-pack/plugins/monitoring/server/config.test.ts b/x-pack/plugins/monitoring/server/config.test.ts
index 5e02767fea98a..4fe5d9c765734 100644
--- a/x-pack/plugins/monitoring/server/config.test.ts
+++ b/x-pack/plugins/monitoring/server/config.test.ts
@@ -107,7 +107,7 @@ describe('config schema', () => {
"index": "metricbeat-*",
},
"min_interval_seconds": 10,
- "render_react_app": false,
+ "render_react_app": true,
"show_license_expiration": true,
},
}
diff --git a/x-pack/plugins/monitoring/server/config.ts b/x-pack/plugins/monitoring/server/config.ts
index 5c2bdc1424f93..ddbfd480a9f4e 100644
--- a/x-pack/plugins/monitoring/server/config.ts
+++ b/x-pack/plugins/monitoring/server/config.ts
@@ -51,7 +51,7 @@ export const configSchema = schema.object({
}),
min_interval_seconds: schema.number({ defaultValue: 10 }),
show_license_expiration: schema.boolean({ defaultValue: true }),
- render_react_app: schema.boolean({ defaultValue: false }),
+ render_react_app: schema.boolean({ defaultValue: true }),
}),
kibana: schema.object({
collection: schema.object({
diff --git a/x-pack/plugins/monitoring/server/deprecations.ts b/x-pack/plugins/monitoring/server/deprecations.ts
index 3554abd569581..9dec7b105f2f6 100644
--- a/x-pack/plugins/monitoring/server/deprecations.ts
+++ b/x-pack/plugins/monitoring/server/deprecations.ts
@@ -55,6 +55,7 @@ export const deprecations = ({
const legacyKey = get(config, `xpack.monitoring.${CLUSTER_ALERTS_ADDRESS_CONFIG_KEY}`);
if (emailNotificationsEnabled && !updatedKey && !legacyKey) {
addDeprecation({
+ configPath: `cluster_alerts.email_notifications.enabled`,
message: `Config key [${fromPath}.${CLUSTER_ALERTS_ADDRESS_CONFIG_KEY}] will be required for email notifications to work in 8.0."`,
correctiveActions: {
manualSteps: [
@@ -70,6 +71,7 @@ export const deprecations = ({
if (es) {
if (es.username === 'elastic') {
addDeprecation({
+ configPath: 'elasticsearch.username',
message: `Setting [${fromPath}.username] to "elastic" is deprecated. You should use the "kibana_system" user instead.`,
correctiveActions: {
manualSteps: [`Replace [${fromPath}.username] from "elastic" to "kibana_system".`],
@@ -77,6 +79,7 @@ export const deprecations = ({
});
} else if (es.username === 'kibana') {
addDeprecation({
+ configPath: 'elasticsearch.username',
message: `Setting [${fromPath}.username] to "kibana" is deprecated. You should use the "kibana_system" user instead.`,
correctiveActions: {
manualSteps: [`Replace [${fromPath}.username] from "kibana" to "kibana_system".`],
@@ -91,6 +94,7 @@ export const deprecations = ({
if (ssl) {
if (ssl.key !== undefined && ssl.certificate === undefined) {
addDeprecation({
+ configPath: 'elasticsearch.ssl.key',
message: `Setting [${fromPath}.key] without [${fromPath}.certificate] is deprecated. This has no effect, you should use both settings to enable TLS client authentication to Elasticsearch.`,
correctiveActions: {
manualSteps: [
@@ -100,6 +104,7 @@ export const deprecations = ({
});
} else if (ssl.certificate !== undefined && ssl.key === undefined) {
addDeprecation({
+ configPath: 'elasticsearch.ssl.certificate',
message: `Setting [${fromPath}.certificate] without [${fromPath}.key] is deprecated. This has no effect, you should use both settings to enable TLS client authentication to Elasticsearch.`,
correctiveActions: {
manualSteps: [
diff --git a/x-pack/plugins/osquery/public/scheduled_query_groups/queries/ecs_mapping_editor_field.tsx b/x-pack/plugins/osquery/public/scheduled_query_groups/queries/ecs_mapping_editor_field.tsx
index 34d7dd755e2b9..8a5fa0e2066f2 100644
--- a/x-pack/plugins/osquery/public/scheduled_query_groups/queries/ecs_mapping_editor_field.tsx
+++ b/x-pack/plugins/osquery/public/scheduled_query_groups/queries/ecs_mapping_editor_field.tsx
@@ -6,7 +6,7 @@
*/
import { produce } from 'immer';
-import { isEmpty, find, orderBy, sortedUniqBy, isArray, map } from 'lodash';
+import { each, isEmpty, find, orderBy, sortedUniqBy, isArray, map, reduce, get } from 'lodash';
import React, {
forwardRef,
useCallback,
@@ -624,30 +624,47 @@ export const ECSMappingEditorField = ({ field, query, fieldRef }: ECSMappingEdit
return currentValue;
}
- const tablesOrderMap =
- ast?.from?.value?.reduce(
- (
- acc: { [x: string]: number },
- table: { value: { alias?: { value: string }; value: { value: string } } },
- index: number
- ) => {
- acc[table.value.alias?.value ?? table.value.value.value] = index;
- return acc;
- },
- {}
- ) ?? {};
-
- const astOsqueryTables: Record
=
+ const astOsqueryTables: Record<
+ string,
+ {
+ columns: OsqueryColumn[];
+ order: number;
+ }
+ > =
ast?.from?.value?.reduce(
(
- acc: { [x: string]: OsqueryColumn[] },
- table: { value: { alias?: { value: string }; value: { value: string } } }
- ) => {
- const osqueryTable = find(osquerySchema, ['name', table.value.value.value]);
-
- if (osqueryTable) {
- acc[table.value.alias?.value ?? table.value.value.value] = osqueryTable.columns;
+ acc: {
+ [x: string]: {
+ columns: OsqueryColumn[];
+ order: number;
+ };
+ },
+ table: {
+ value: {
+ left?: { value: { value: string }; alias?: { value: string } };
+ right?: { value: { value: string }; alias?: { value: string } };
+ value?: { value: string };
+ alias?: { value: string };
+ };
}
+ ) => {
+ each(['value.left', 'value.right', 'value'], (valueKey) => {
+ if (valueKey) {
+ const osqueryTable = find(osquerySchema, [
+ 'name',
+ get(table, `${valueKey}.value.value`),
+ ]);
+
+ if (osqueryTable) {
+ acc[
+ get(table, `${valueKey}.alias.value`) ?? get(table, `${valueKey}.value.value`)
+ ] = {
+ columns: osqueryTable.columns,
+ order: Object.keys(acc).length,
+ };
+ }
+ }
+ });
return acc;
},
@@ -659,75 +676,107 @@ export const ECSMappingEditorField = ({ field, query, fieldRef }: ECSMappingEdit
return currentValue;
}
- /*
- Simple query
- select * from users;
- */
- if (
- ast?.selectItems?.value?.length &&
- ast?.selectItems?.value[0].value === '*' &&
- ast.from?.value?.length &&
- ast?.from.value[0].value?.value?.value &&
- astOsqueryTables[ast.from.value[0].value.value.value]
- ) {
- const tableName =
- ast.from.value[0].value.alias?.value ?? ast.from.value[0].value.value.value;
-
- return astOsqueryTables[ast.from.value[0].value.value.value].map((osqueryColumn) => ({
- label: osqueryColumn.name,
- value: {
- name: osqueryColumn.name,
- description: osqueryColumn.description,
- table: tableName,
- tableOrder: tablesOrderMap[tableName],
- suggestion_label: osqueryColumn.name,
- },
- }));
- }
-
- /*
- Advanced query
- select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;
- */
const suggestions =
isArray(ast?.selectItems?.value) &&
ast?.selectItems?.value
- // @ts-expect-error update types
- ?.map((selectItem) => {
- const [table, column] = selectItem.value?.split('.');
-
- if (column === '*' && astOsqueryTables[table]) {
- return astOsqueryTables[table].map((osqueryColumn) => ({
- label: osqueryColumn.name,
- value: {
- name: osqueryColumn.name,
- description: osqueryColumn.description,
- table,
- tableOrder: tablesOrderMap[table],
- suggestion_label: `${osqueryColumn.name}`,
- },
- }));
- }
+ ?.map((selectItem: { type: string; value: string; hasAs: boolean; alias?: string }) => {
+ if (selectItem.type === 'Identifier') {
+ /*
+ select * from routes, uptime;
+ */
+ if (ast?.selectItems?.value.length === 1 && selectItem.value === '*') {
+ return reduce(
+ astOsqueryTables,
+ (acc, { columns: osqueryColumns, order: tableOrder }, table) => {
+ acc.push(
+ ...osqueryColumns.map((osqueryColumn) => ({
+ label: osqueryColumn.name,
+ value: {
+ name: osqueryColumn.name,
+ description: osqueryColumn.description,
+ table,
+ tableOrder,
+ suggestion_label: osqueryColumn.name,
+ },
+ }))
+ );
+ return acc;
+ },
+ [] as OsquerySchemaOption[]
+ );
+ }
- if (astOsqueryTables && astOsqueryTables[table]) {
- const osqueryColumn = find(astOsqueryTables[table], ['name', column]);
-
- if (osqueryColumn) {
- const label = selectItem.hasAs ? selectItem.alias : column;
-
- return [
- {
- label,
- value: {
- name: osqueryColumn.name,
- description: osqueryColumn.description,
- table,
- tableOrder: tablesOrderMap[table],
- suggestion_label: `${label}`,
- },
+ /*
+ select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;
+ */
+
+ const [table, column] = selectItem.value.includes('.')
+ ? selectItem.value?.split('.')
+ : [Object.keys(astOsqueryTables)[0], selectItem.value];
+
+ if (column === '*' && astOsqueryTables[table]) {
+ const { columns: osqueryColumns, order: tableOrder } = astOsqueryTables[table];
+ return osqueryColumns.map((osqueryColumn) => ({
+ label: osqueryColumn.name,
+ value: {
+ name: osqueryColumn.name,
+ description: osqueryColumn.description,
+ table,
+ tableOrder,
+ suggestion_label: `${osqueryColumn.name}`,
},
- ];
+ }));
}
+
+ if (astOsqueryTables[table]) {
+ const osqueryColumn = find(astOsqueryTables[table].columns, ['name', column]);
+
+ if (osqueryColumn) {
+ const label = selectItem.hasAs ? selectItem.alias : column;
+
+ return [
+ {
+ label,
+ value: {
+ name: osqueryColumn.name,
+ description: osqueryColumn.description,
+ table,
+ tableOrder: astOsqueryTables[table].order,
+ suggestion_label: `${label}`,
+ },
+ },
+ ];
+ }
+ }
+ }
+
+ /*
+ SELECT pid, uid, name, ROUND((
+ (user_time + system_time) / (cpu_time.tsb - cpu_time.itsb)
+ ) * 100, 2) AS percentage
+ FROM processes, (
+ SELECT (
+ SUM(user) + SUM(nice) + SUM(system) + SUM(idle) * 1.0) AS tsb,
+ SUM(COALESCE(idle, 0)) + SUM(COALESCE(iowait, 0)) AS itsb
+ FROM cpu_time
+ ) AS cpu_time
+ ORDER BY user_time+system_time DESC
+ LIMIT 5;
+ */
+
+ if (selectItem.type === 'FunctionCall' && selectItem.hasAs) {
+ return [
+ {
+ label: selectItem.alias,
+ value: {
+ name: selectItem.alias,
+ description: '',
+ table: '',
+ tableOrder: -1,
+ suggestion_label: selectItem.alias,
+ },
+ },
+ ];
}
return [];
diff --git a/x-pack/plugins/reporting/server/config/index.ts b/x-pack/plugins/reporting/server/config/index.ts
index a45c084131a4d..1eeafb4e0c513 100644
--- a/x-pack/plugins/reporting/server/config/index.ts
+++ b/x-pack/plugins/reporting/server/config/index.ts
@@ -25,6 +25,7 @@ export const config: PluginConfigDescriptor = {
const reporting = get(settings, fromPath);
if (reporting?.index) {
addDeprecation({
+ configPath: `${fromPath}.index`,
title: i18n.translate('xpack.reporting.deprecations.reportingIndex.title', {
defaultMessage: 'Setting "{fromPath}.index" is deprecated',
values: { fromPath },
@@ -51,6 +52,7 @@ export const config: PluginConfigDescriptor = {
if (reporting?.roles?.enabled !== false) {
addDeprecation({
+ configPath: `${fromPath}.roles.enabled`,
level: 'warning',
title: i18n.translate('xpack.reporting.deprecations.reportingRoles.title', {
defaultMessage: 'Setting "{fromPath}.roles" is deprecated',
diff --git a/x-pack/plugins/security/server/config_deprecations.test.ts b/x-pack/plugins/security/server/config_deprecations.test.ts
index 634df081d77d7..d4b18a2e1b296 100644
--- a/x-pack/plugins/security/server/config_deprecations.test.ts
+++ b/x-pack/plugins/security/server/config_deprecations.test.ts
@@ -17,6 +17,7 @@ const deprecationContext = configDeprecationsMock.createContext();
const applyConfigDeprecations = (settings: Record = {}) => {
const deprecations = securityConfigDeprecationProvider(configDeprecationFactory);
const deprecationMessages: string[] = [];
+ const configPaths: string[] = [];
const { config: migrated } = applyDeprecations(
settings,
deprecations.map((deprecation) => ({
@@ -25,10 +26,13 @@ const applyConfigDeprecations = (settings: Record = {}) => {
context: deprecationContext,
})),
() =>
- ({ message }) =>
- deprecationMessages.push(message)
+ ({ message, configPath }) => {
+ deprecationMessages.push(message);
+ configPaths.push(configPath);
+ }
);
return {
+ configPaths,
messages: deprecationMessages,
migrated,
};
@@ -356,12 +360,14 @@ describe('Config Deprecations', () => {
},
},
};
- const { messages } = applyConfigDeprecations(cloneDeep(config));
+ const { messages, configPaths } = applyConfigDeprecations(cloneDeep(config));
expect(messages).toMatchInlineSnapshot(`
Array [
"\\"xpack.security.authc.providers.saml..maxRedirectURLSize\\" is no longer used.",
]
`);
+
+ expect(configPaths).toEqual(['xpack.security.authc.providers.saml.saml1.maxRedirectURLSize']);
});
it(`warns when 'xpack.security.authc.providers' is an array of strings`, () => {
diff --git a/x-pack/plugins/security/server/config_deprecations.ts b/x-pack/plugins/security/server/config_deprecations.ts
index ce9eb76fb1dc8..c8c8e64648c4b 100644
--- a/x-pack/plugins/security/server/config_deprecations.ts
+++ b/x-pack/plugins/security/server/config_deprecations.ts
@@ -35,6 +35,7 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({
const legacyAuditLoggerEnabled = !settings?.xpack?.security?.audit?.appender;
if (auditLoggingEnabled && legacyAuditLoggerEnabled) {
addDeprecation({
+ configPath: 'xpack.security.audit.appender',
title: i18n.translate('xpack.security.deprecations.auditLoggerTitle', {
defaultMessage: 'The legacy audit logger is deprecated',
}),
@@ -59,6 +60,7 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({
(settings, fromPath, addDeprecation) => {
if (Array.isArray(settings?.xpack?.security?.authc?.providers)) {
addDeprecation({
+ configPath: 'xpack.security.authc.providers',
title: i18n.translate('xpack.security.deprecations.authcProvidersTitle', {
defaultMessage:
'Defining "xpack.security.authc.providers" as an array of provider types is deprecated',
@@ -92,6 +94,7 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({
if (hasProviderType('basic') && hasProviderType('token')) {
addDeprecation({
+ configPath: 'xpack.security.authc.providers',
title: i18n.translate('xpack.security.deprecations.basicAndTokenProvidersTitle', {
defaultMessage:
'Both "basic" and "token" authentication providers are enabled in "xpack.security.authc.providers"',
@@ -119,8 +122,13 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({
string,
any
>;
- if (Object.values(samlProviders).find((provider) => !!provider.maxRedirectURLSize)) {
+
+ const foundProvider = Object.entries(samlProviders).find(
+ ([_, provider]) => !!provider.maxRedirectURLSize
+ );
+ if (foundProvider) {
addDeprecation({
+ configPath: `xpack.security.authc.providers.saml.${foundProvider[0]}.maxRedirectURLSize`,
title: i18n.translate('xpack.security.deprecations.maxRedirectURLSizeTitle', {
defaultMessage:
'"xpack.security.authc.providers.saml..maxRedirectURLSize" is deprecated',
@@ -143,6 +151,7 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({
(settings, fromPath, addDeprecation, { branch }) => {
if ('enabled' in (settings?.xpack?.security || {})) {
addDeprecation({
+ configPath: 'xpack.security.enabled',
title: i18n.translate('xpack.security.deprecations.enabledTitle', {
defaultMessage: 'Setting "xpack.security.enabled" is deprecated',
}),
@@ -169,6 +178,7 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({
(settings, fromPath, addDeprecation, { branch }) => {
if (settings?.xpack?.security?.session?.idleTimeout === undefined) {
addDeprecation({
+ configPath: 'xpack.security.session.idleTimeout',
level: 'warning',
title: i18n.translate('xpack.security.deprecations.idleTimeoutTitle', {
defaultMessage: 'The "xpack.security.session.idleTimeout" default is changing',
@@ -192,6 +202,7 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({
if (settings?.xpack?.security?.session?.lifespan === undefined) {
addDeprecation({
+ configPath: 'xpack.security.session.lifespan',
level: 'warning',
title: i18n.translate('xpack.security.deprecations.lifespanTitle', {
defaultMessage: 'The "xpack.security.session.lifespan" default is changing',
diff --git a/x-pack/plugins/security_solution/common/detection_engine/utils.ts b/x-pack/plugins/security_solution/common/detection_engine/utils.ts
index 28749e0400bbb..7d4badcd3507c 100644
--- a/x-pack/plugins/security_solution/common/detection_engine/utils.ts
+++ b/x-pack/plugins/security_solution/common/detection_engine/utils.ts
@@ -51,7 +51,8 @@ export const normalizeThresholdField = (
? thresholdField
: isEmpty(thresholdField)
? []
- : [thresholdField!];
+ : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ [thresholdField!];
};
export const normalizeThresholdObject = (threshold: Threshold): ThresholdNormalized => {
diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts
index d7ab014c3b445..fdb8416de2ed8 100644
--- a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts
+++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts
@@ -161,7 +161,7 @@ export async function indexEndpointHostDocs({
const indexedAgentResponse = await indexFleetAgentForHost(
client,
kbnClient,
- hostMetadata!,
+ hostMetadata,
realPolicies[appliedPolicyId].policy_id,
kibanaVersion
);
diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts
index b792b34dd510f..67a261d088f86 100644
--- a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts
+++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts
@@ -73,7 +73,7 @@ export const indexFleetAgentForHost = async (
.index({
index: agentDoc._index,
id: agentDoc._id,
- body: agentDoc._source!,
+ body: agentDoc._source,
op_type: 'create',
})
.catch(wrapErrorAndRejectPromise);
diff --git a/x-pack/plugins/security_solution/cypress/integration/cases/connectors.spec.ts b/x-pack/plugins/security_solution/cypress/integration/cases/connectors.spec.ts
index a53e37f363d05..287d86c6fba9e 100644
--- a/x-pack/plugins/security_solution/cypress/integration/cases/connectors.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/cases/connectors.spec.ts
@@ -89,11 +89,11 @@ describe('Cases connectors', () => {
addServiceNowConnector(snConnector);
cy.wait('@createConnector').then(({ response }) => {
- cy.wrap(response!.statusCode).should('eql', 200);
+ cy.wrap(response?.statusCode).should('eql', 200);
cy.get(TOASTER).should('have.text', "Created 'New connector'");
cy.get(TOASTER).should('not.exist');
- selectLastConnectorCreated(response!.body.id);
+ selectLastConnectorCreated(response?.body.id);
cy.wait('@saveConnector', { timeout: 10000 }).its('response.statusCode').should('eql', 200);
cy.get(SERVICE_NOW_MAPPING).first().should('have.text', 'short_description');
diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/custom_query_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/custom_query_rule.spec.ts
index a9a592c7803fe..79b053874f212 100644
--- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/custom_query_rule.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/custom_query_rule.spec.ts
@@ -351,10 +351,10 @@ describe('Custom detection rules deletion and edition', () => {
goToRuleDetails();
cy.wait('@fetchRuleDetails').then(({ response }) => {
- cy.wrap(response!.statusCode).should('eql', 200);
+ cy.wrap(response?.statusCode).should('eql', 200);
- cy.wrap(response!.body.max_signals).should('eql', getExistingRule().maxSignals);
- cy.wrap(response!.body.enabled).should('eql', false);
+ cy.wrap(response?.body.max_signals).should('eql', getExistingRule().maxSignals);
+ cy.wrap(response?.body.enabled).should('eql', false);
});
});
@@ -415,9 +415,9 @@ describe('Custom detection rules deletion and edition', () => {
saveEditedRule();
cy.wait('@getRule').then(({ response }) => {
- cy.wrap(response!.statusCode).should('eql', 200);
+ cy.wrap(response?.statusCode).should('eql', 200);
// ensure that editing rule does not modify max_signals
- cy.wrap(response!.body.max_signals).should('eql', getExistingRule().maxSignals);
+ cy.wrap(response?.body.max_signals).should('eql', getExistingRule().maxSignals);
});
cy.get(RULE_NAME_HEADER).should('contain', `${getEditedRule().name}`);
diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/export_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/export_rule.spec.ts
index 03086810a8435..18b7b122f0967 100644
--- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/export_rule.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/export_rule.spec.ts
@@ -35,7 +35,7 @@ describe('Export rules', () => {
goToManageAlertsDetectionRules();
exportFirstRule();
cy.wait('@export').then(({ response }) => {
- cy.wrap(response!.body).should('eql', expectedExportedRule(this.ruleResponse));
+ cy.wrap(response?.body).should('eql', expectedExportedRule(this.ruleResponse));
});
});
});
diff --git a/x-pack/plugins/security_solution/cypress/integration/timeline_templates/creation.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timeline_templates/creation.spec.ts
index 48269677466b6..71bbea673e5c8 100644
--- a/x-pack/plugins/security_solution/cypress/integration/timeline_templates/creation.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/timeline_templates/creation.spec.ts
@@ -70,7 +70,7 @@ describe('Timeline Templates', () => {
addNameToTimeline(getTimeline().title);
cy.wait('@timeline').then(({ response }) => {
- const timelineId = response!.body.data.persistTimeline.timeline.savedObjectId;
+ const timelineId = response?.body.data.persistTimeline.timeline.savedObjectId;
addDescriptionToTimeline(getTimeline().description);
addNotesToTimeline(getTimeline().notes);
diff --git a/x-pack/plugins/security_solution/cypress/integration/timeline_templates/export.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timeline_templates/export.spec.ts
index a20baffeadc7e..638a70df35850 100644
--- a/x-pack/plugins/security_solution/cypress/integration/timeline_templates/export.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/timeline_templates/export.spec.ts
@@ -35,9 +35,9 @@ describe('Export timelines', () => {
exportTimeline(this.templateId);
cy.wait('@export').then(({ response }) => {
- cy.wrap(response!.statusCode).should('eql', 200);
+ cy.wrap(response?.statusCode).should('eql', 200);
- cy.wrap(response!.body).should(
+ cy.wrap(response?.body).should(
'eql',
expectedExportedTimelineTemplate(this.templateResponse)
);
diff --git a/x-pack/plugins/security_solution/cypress/integration/timelines/export.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timelines/export.spec.ts
index 029216f701ae0..29d1cb588f1a2 100644
--- a/x-pack/plugins/security_solution/cypress/integration/timelines/export.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/timelines/export.spec.ts
@@ -33,9 +33,9 @@ describe('Export timelines', () => {
exportTimeline(this.timelineId);
cy.wait('@export').then(({ response }) => {
- cy.wrap(response!.statusCode).should('eql', 200);
+ cy.wrap(response?.statusCode).should('eql', 200);
- cy.wrap(response!.body).should('eql', expectedExportedTimeline(this.timelineResponse));
+ cy.wrap(response?.body).should('eql', expectedExportedTimeline(this.timelineResponse));
});
});
});
diff --git a/x-pack/plugins/security_solution/cypress/integration/timelines/search_or_filter.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timelines/search_or_filter.spec.ts
index 9d019cf23ebb1..b42bdcdd6fb8d 100644
--- a/x-pack/plugins/security_solution/cypress/integration/timelines/search_or_filter.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/timelines/search_or_filter.spec.ts
@@ -54,8 +54,8 @@ describe('Update kqlMode for timeline', () => {
it('should be able to update timeline kqlMode with filter', () => {
cy.get(TIMELINE_KQLMODE_FILTER).click();
cy.wait('@update').then(({ response }) => {
- cy.wrap(response!.statusCode).should('eql', 200);
- cy.wrap(response!.body.data.persistTimeline.timeline.kqlMode).should('eql', 'filter');
+ cy.wrap(response?.statusCode).should('eql', 200);
+ cy.wrap(response?.body.data.persistTimeline.timeline.kqlMode).should('eql', 'filter');
cy.get(ADD_FILTER).should('exist');
});
});
@@ -63,8 +63,8 @@ describe('Update kqlMode for timeline', () => {
it('should be able to update timeline kqlMode with search', () => {
cy.get(TIMELINE_KQLMODE_SEARCH).click();
cy.wait('@update').then(({ response }) => {
- cy.wrap(response!.statusCode).should('eql', 200);
- cy.wrap(response!.body.data.persistTimeline.timeline.kqlMode).should('eql', 'search');
+ cy.wrap(response?.statusCode).should('eql', 200);
+ cy.wrap(response?.body.data.persistTimeline.timeline.kqlMode).should('eql', 'search');
cy.get(ADD_FILTER).should('not.exist');
});
});
diff --git a/x-pack/plugins/security_solution/cypress/integration/urls/state.spec.ts b/x-pack/plugins/security_solution/cypress/integration/urls/state.spec.ts
index 47e6b0d34e3c5..73eb141f1ce3d 100644
--- a/x-pack/plugins/security_solution/cypress/integration/urls/state.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/urls/state.spec.ts
@@ -250,8 +250,8 @@ describe('url state', () => {
cy.wait('@timeline').then(({ response }) => {
closeTimeline();
- cy.wrap(response!.statusCode).should('eql', 200);
- const timelineId = response!.body.data.persistTimeline.timeline.savedObjectId;
+ cy.wrap(response?.statusCode).should('eql', 200);
+ const timelineId = response?.body.data.persistTimeline.timeline.savedObjectId;
cy.visit('/app/home');
cy.visit(`/app/security/timelines?timeline=(id:'${timelineId}',isOpen:!t)`);
cy.get(DATE_PICKER_APPLY_BUTTON_TIMELINE).should('exist');
diff --git a/x-pack/plugins/security_solution/cypress/integration/value_lists/value_lists.spec.ts b/x-pack/plugins/security_solution/cypress/integration/value_lists/value_lists.spec.ts
index a7cc412a920c0..f2b87e42685e7 100644
--- a/x-pack/plugins/security_solution/cypress/integration/value_lists/value_lists.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/value_lists/value_lists.spec.ts
@@ -174,8 +174,8 @@ describe('value lists', () => {
cy.wait('@exportList').then(({ response }) => {
cy.fixture(listName).then((list: string) => {
const [lineOne, lineTwo] = list.split('\n');
- expect(response!.body).to.contain(lineOne);
- expect(response!.body).to.contain(lineTwo);
+ expect(response?.body).to.contain(lineOne);
+ expect(response?.body).to.contain(lineTwo);
});
});
});
@@ -189,8 +189,8 @@ describe('value lists', () => {
cy.wait('@exportList').then(({ response }) => {
cy.fixture(listName).then((list: string) => {
const [lineOne, lineTwo] = list.split('\n');
- expect(response!.body).to.contain(lineOne);
- expect(response!.body).to.contain(lineTwo);
+ expect(response?.body).to.contain(lineOne);
+ expect(response?.body).to.contain(lineTwo);
});
});
});
@@ -204,8 +204,8 @@ describe('value lists', () => {
cy.wait('@exportList').then(({ response }) => {
cy.fixture(listName).then((list: string) => {
const [lineOne, lineTwo] = list.split('\n');
- expect(response!.body).to.contain(lineOne);
- expect(response!.body).to.contain(lineTwo);
+ expect(response?.body).to.contain(lineOne);
+ expect(response?.body).to.contain(lineTwo);
});
});
});
@@ -219,7 +219,7 @@ describe('value lists', () => {
cy.wait('@exportList').then(({ response }) => {
cy.fixture(listName).then((list: string) => {
const [lineOne] = list.split('\n');
- expect(response!.body).to.contain(lineOne);
+ expect(response?.body).to.contain(lineOne);
});
});
});
diff --git a/x-pack/plugins/security_solution/cypress/screens/timelines.ts b/x-pack/plugins/security_solution/cypress/screens/timelines.ts
index ca60250330f83..92522c44dd8e4 100644
--- a/x-pack/plugins/security_solution/cypress/screens/timelines.ts
+++ b/x-pack/plugins/security_solution/cypress/screens/timelines.ts
@@ -9,7 +9,10 @@ export const BULK_ACTIONS = '[data-test-subj="utility-bar-action-button"]';
export const EXPORT_TIMELINE_ACTION = '[data-test-subj="export-timeline-action"]';
-export const TIMELINE = (id: string) => {
+export const TIMELINE = (id: string | undefined) => {
+ if (id == null) {
+ throw new TypeError('id should never be null or undefined');
+ }
return `[data-test-subj="title-${id}"]`;
};
diff --git a/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts
index 591be21b5682b..b9323fee44d5c 100644
--- a/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts
+++ b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts
@@ -254,7 +254,7 @@ export const fillDefineCustomRuleWithImportedQueryAndContinue = (
rule: CustomRule | OverrideRule
) => {
cy.get(IMPORT_QUERY_FROM_SAVED_TIMELINE_LINK).click();
- cy.get(TIMELINE(rule.timeline.id!)).click();
+ cy.get(TIMELINE(rule.timeline.id)).click();
cy.get(CUSTOM_QUERY_INPUT).should('have.value', rule.customQuery);
cy.get(DEFINE_CONTINUE_BUTTON).should('exist').click({ force: true });
@@ -273,7 +273,7 @@ export const fillDefineThresholdRule = (rule: ThresholdRule) => {
const threshold = 1;
cy.get(IMPORT_QUERY_FROM_SAVED_TIMELINE_LINK).click();
- cy.get(TIMELINE(rule.timeline.id!)).click();
+ cy.get(TIMELINE(rule.timeline.id)).click();
cy.get(COMBO_BOX_CLEAR_BTN).first().click();
rule.index.forEach((index) => {
@@ -298,7 +298,7 @@ export const fillDefineThresholdRuleAndContinue = (rule: ThresholdRule) => {
cy.wrap($el).type(rule.thresholdField, { delay: 35 });
cy.get(IMPORT_QUERY_FROM_SAVED_TIMELINE_LINK).click();
- cy.get(TIMELINE(rule.timeline.id!)).click();
+ cy.get(TIMELINE(rule.timeline.id)).click();
cy.get(CUSTOM_QUERY_INPUT).should('have.value', rule.customQuery);
cy.get(THRESHOLD_INPUT_AREA)
.find(INPUT)
@@ -314,9 +314,12 @@ export const fillDefineThresholdRuleAndContinue = (rule: ThresholdRule) => {
};
export const fillDefineEqlRuleAndContinue = (rule: CustomRule) => {
+ if (rule.customQuery == null) {
+ throw new TypeError('The rule custom query should never be undefined or null ');
+ }
cy.get(RULES_CREATION_FORM).find(EQL_QUERY_INPUT).should('exist');
cy.get(RULES_CREATION_FORM).find(EQL_QUERY_INPUT).should('be.visible');
- cy.get(RULES_CREATION_FORM).find(EQL_QUERY_INPUT).type(rule.customQuery!);
+ cy.get(RULES_CREATION_FORM).find(EQL_QUERY_INPUT).type(rule.customQuery);
cy.get(RULES_CREATION_FORM).find(EQL_QUERY_VALIDATION_SPINNER).should('not.exist');
cy.get(RULES_CREATION_PREVIEW)
.find(QUERY_PREVIEW_BUTTON)
diff --git a/x-pack/plugins/security_solution/cypress/tasks/login.ts b/x-pack/plugins/security_solution/cypress/tasks/login.ts
index 5a935702131d6..96d37d2d9214a 100644
--- a/x-pack/plugins/security_solution/cypress/tasks/login.ts
+++ b/x-pack/plugins/security_solution/cypress/tasks/login.ts
@@ -57,7 +57,7 @@ const LOGIN_API_ENDPOINT = '/internal/security/login';
*/
export const getUrlWithRoute = (role: ROLES, route: string) => {
const url = Cypress.config().baseUrl;
- const kibana = new URL(url!);
+ const kibana = new URL(String(url));
const theUrl = `${Url.format({
auth: `${role}:changeme`,
username: role,
@@ -83,7 +83,7 @@ interface User {
*/
export const constructUrlWithUser = (user: User, route: string) => {
const url = Cypress.config().baseUrl;
- const kibana = new URL(url!);
+ const kibana = new URL(String(url));
const hostname = kibana.hostname;
const username = user.username;
const password = user.password;
diff --git a/x-pack/plugins/security_solution/cypress/tasks/rule_details.ts b/x-pack/plugins/security_solution/cypress/tasks/rule_details.ts
index 37968e700fb39..f001af9df62d2 100644
--- a/x-pack/plugins/security_solution/cypress/tasks/rule_details.ts
+++ b/x-pack/plugins/security_solution/cypress/tasks/rule_details.ts
@@ -32,7 +32,7 @@ export const activatesRule = () => {
cy.get(RULE_SWITCH).should('be.visible');
cy.get(RULE_SWITCH).click();
cy.wait('@bulk_update').then(({ response }) => {
- cy.wrap(response!.statusCode).should('eql', 200);
+ cy.wrap(response?.statusCode).should('eql', 200);
});
};
diff --git a/x-pack/plugins/security_solution/public/common/components/charts/barchart.tsx b/x-pack/plugins/security_solution/public/common/components/charts/barchart.tsx
index 527ef2721ab86..20ab5cca89a76 100644
--- a/x-pack/plugins/security_solution/public/common/components/charts/barchart.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/charts/barchart.tsx
@@ -94,7 +94,7 @@ export const BarChartBaseComponent = ({
yAccessors={yAccessors}
timeZone={timeZone}
splitSeriesAccessors={splitSeriesAccessors}
- data={series.value!}
+ data={series.value ?? []}
stackAccessors={get('configs.series.stackAccessors', chartConfigs)}
color={series.color ? series.color : undefined}
/>
diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/helpers.test.tsx
index d164d1f8f0ba0..bcdec78fe0614 100644
--- a/x-pack/plugins/security_solution/public/common/components/event_details/helpers.test.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/event_details/helpers.test.tsx
@@ -12,7 +12,7 @@ import { mockBrowserFields } from '../../containers/source/mock';
const aField = {
...mockDetailItemData[4],
- ...mockBrowserFields.base.fields!['@timestamp'],
+ ...mockBrowserFields.base.fields?.['@timestamp'],
};
describe('helpers', () => {
diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx
index a1c74a603fbc3..47d0ccf5ba3b2 100644
--- a/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx
@@ -127,7 +127,7 @@ export const getColumnsWithTimestamp = ({
export const getExampleText = (example: string | number | null | undefined): string =>
!isEmpty(example) ? `Example: ${example}` : '';
-export const getIconFromType = (type: string | null) => {
+export const getIconFromType = (type: string | null | undefined) => {
switch (type) {
case 'string': // fall through
case 'keyword':
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 632197aa6b219..fd644d1380ddb 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
@@ -236,7 +236,7 @@ const EventsViewerComponent: React.FC = ({
useTimelineEvents({
docValueFields,
fields,
- filterQuery: combinedQueries!.filterQuery,
+ filterQuery: combinedQueries?.filterQuery,
id,
indexNames,
limit: itemsPerPage,
@@ -300,7 +300,7 @@ const EventsViewerComponent: React.FC = ({
height={headerFilterGroup ? COMPACT_HEADER_HEIGHT : EVENTS_VIEWER_HEADER_HEIGHT}
subtitle={utilityBar ? undefined : subtitle}
title={globalFullScreen ? titleWithExitFullScreen : justTitle}
- isInspectDisabled={combinedQueries!.filterQuery === undefined}
+ isInspectDisabled={combinedQueries?.filterQuery === undefined}
>
{HeaderSectionContent}
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 d60db8a4bc461..1e61e69180f91 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
@@ -181,7 +181,7 @@ const StatefulEventsViewerComponent: React.FC = ({
browserFields,
bulkActions,
columns,
- dataProviders: dataProviders!,
+ dataProviders,
defaultCellActions,
deletedEventIds,
docValueFields,
@@ -199,7 +199,7 @@ const StatefulEventsViewerComponent: React.FC = ({
isLive,
isLoadingIndexPattern,
itemsPerPage,
- itemsPerPageOptions: itemsPerPageOptions!,
+ itemsPerPageOptions,
kqlMode,
leadingControlColumns,
onRuleChange,
@@ -220,7 +220,7 @@ const StatefulEventsViewerComponent: React.FC = ({
columns={columns}
docValueFields={docValueFields}
id={id}
- dataProviders={dataProviders!}
+ dataProviders={dataProviders}
deletedEventIds={deletedEventIds}
end={end}
isLoadingIndexPattern={isLoadingIndexPattern}
@@ -228,8 +228,8 @@ const StatefulEventsViewerComponent: React.FC = ({
indexNames={selectedPatterns}
indexPattern={indexPattern}
isLive={isLive}
- itemsPerPage={itemsPerPage!}
- itemsPerPageOptions={itemsPerPageOptions!}
+ itemsPerPage={itemsPerPage}
+ itemsPerPageOptions={itemsPerPageOptions}
kqlMode={kqlMode}
query={query}
onRuleChange={onRuleChange}
diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts
index f4e3814738f92..7262264d72103 100644
--- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts
+++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts
@@ -54,6 +54,7 @@ export const useSetBreadcrumbs = () => {
dispatch(timelineActions.showTimeline({ id: TimelineId.active, show: false }));
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
navigateToUrl(breadcrumb.href!);
},
}
diff --git a/x-pack/plugins/security_solution/public/common/components/utils.ts b/x-pack/plugins/security_solution/public/common/components/utils.ts
index fc27578487ca7..da92c94d3c1cd 100644
--- a/x-pack/plugins/security_solution/public/common/components/utils.ts
+++ b/x-pack/plugins/security_solution/public/common/components/utils.ts
@@ -22,6 +22,7 @@ export const getDaysDiff = (minDate: moment.Moment, maxDate: moment.Moment) => {
};
export const histogramDateTimeFormatter = (domain: [string, string] | null, fixedDiff?: number) => {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const diff = fixedDiff ?? getDaysDiff(moment(domain![0]), moment(domain![1]));
const format = niceTimeFormatByDay(diff);
return timeFormatter(format);
diff --git a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx
index 20d411a0437c2..ed2a2252bd0d2 100644
--- a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx
+++ b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx
@@ -78,7 +78,7 @@ const experimentalFeaturesReducer: Reducer {
...mockEcsDataWithAlert,
signal: {
rule: {
- ...mockEcsDataWithAlert.signal?.rule!,
+ ...mockEcsDataWithAlert.signal?.rule,
// @ts-expect-error
timeline_id: null,
},
@@ -317,7 +317,7 @@ describe('alert actions', () => {
...mockEcsDataWithAlert,
signal: {
rule: {
- ...mockEcsDataWithAlert.signal?.rule!,
+ ...mockEcsDataWithAlert.signal?.rule,
timeline_id: [''],
},
},
@@ -343,7 +343,7 @@ describe('alert actions', () => {
...mockEcsDataWithAlert,
signal: {
rule: {
- ...mockEcsDataWithAlert.signal?.rule!,
+ ...mockEcsDataWithAlert.signal?.rule,
type: ['eql'],
timeline_id: [''],
},
@@ -387,7 +387,7 @@ describe('alert actions', () => {
...mockEcsDataWithAlert,
signal: {
rule: {
- ...mockEcsDataWithAlert.signal?.rule!,
+ ...mockEcsDataWithAlert.signal?.rule,
type: ['eql'],
timeline_id: [''],
},
diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx
index d48bc95f5d480..fb958c775e68c 100644
--- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx
@@ -192,8 +192,10 @@ export const getThresholdAggregationData = (
};
}
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const originalTime = moment(thresholdData.signal?.original_time![0]);
const now = moment();
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const ruleFrom = dateMath.parse(thresholdData.signal?.rule?.from![0]!);
const ruleInterval = moment.duration(now.diff(ruleFrom));
const fromOriginalTime = originalTime.clone().subtract(ruleInterval); // This is the default... can overshoot
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 d7c48c4f18bc8..4bd516d0b1338 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
@@ -142,14 +142,14 @@ export const AlertsTableComponent: React.FC = ({
const setEventsLoadingCallback = useCallback(
({ eventIds, isLoading }: SetEventsLoadingProps) => {
- setEventsLoading!({ id: timelineId, eventIds, isLoading });
+ setEventsLoading({ id: timelineId, eventIds, isLoading });
},
[setEventsLoading, timelineId]
);
const setEventsDeletedCallback = useCallback(
({ eventIds, isDeleted }: SetEventsDeletedProps) => {
- setEventsDeleted!({ id: timelineId, eventIds, isDeleted });
+ setEventsDeleted({ id: timelineId, eventIds, isDeleted });
},
[setEventsDeleted, timelineId]
);
@@ -216,7 +216,7 @@ export const AlertsTableComponent: React.FC = ({
// Callback for clearing entire selection from utility bar
const clearSelectionCallback = useCallback(() => {
- clearSelected!({ id: timelineId });
+ clearSelected({ id: timelineId });
dispatch(
timelineActions.setTGridSelectAll({
id: timelineId,
diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx
index 6d7b5d4acc5b8..f785ec43a8b31 100644
--- a/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx
@@ -59,6 +59,7 @@ interface MlJobSelectProps {
}
const renderJobOption = (option: MlJobOption) => (
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
);
@@ -69,6 +70,7 @@ export const MlJobSelect: React.FC = ({ describedByIds = [], f
const mlUrl = useKibana().services.application.getUrlForApp('ml');
const handleJobSelect = useCallback(
(selectedJobOptions: MlJobOption[]): void => {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const selectedJobIds = selectedJobOptions.map((option) => option.value!.id);
field.setValue(selectedJobIds);
},
diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx
index dc20dd1aa9ca4..dd836a04f8263 100644
--- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx
@@ -61,9 +61,9 @@ export const RuleSwitchComponent = ({
async (event: EuiSwitchEvent) => {
setMyIsLoading(true);
if (dispatch != null) {
- await enableRulesAction([id], event.target.checked!, dispatch, dispatchToaster);
+ await enableRulesAction([id], event.target.checked, dispatch, dispatchToaster);
} else {
- const enabling = event.target.checked!;
+ const enabling = event.target.checked;
const title = enabling
? i18n.BATCH_ACTION_ACTIVATE_SELECTED_ERROR(1)
: i18n.BATCH_ACTION_DEACTIVATE_SELECTED_ERROR(1);
diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx
index 848bdd7f8ef71..ebda4f2b4232f 100644
--- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx
+++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx
@@ -176,8 +176,8 @@ const DetectionEnginePageComponent: React.FC = ({
const onFilterGroupChangedCallback = useCallback(
(newFilterGroup: Status) => {
const timelineId = TimelineId.detectionsPage;
- clearEventsLoading!({ id: timelineId });
- clearEventsDeleted!({ id: timelineId });
+ clearEventsLoading({ id: timelineId });
+ clearEventsDeleted({ id: timelineId });
setFilterGroup(newFilterGroup);
},
[clearEventsLoading, clearEventsDeleted, setFilterGroup]
diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx
index 492b8e461fb60..7167b07c7da5d 100644
--- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx
+++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx
@@ -302,6 +302,7 @@ const RuleDetailsPageComponent: React.FC = ({
const getLegacyUrlConflictCallout = useMemo(() => {
const outcome = rule?.outcome;
if (rule != null && spacesApi && outcome === 'conflict') {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const aliasTargetId = rule?.alias_target_id!; // This is always defined if outcome === 'conflict'
// We have resolved to one rule, but there is another one with a legacy URL associated with this page. Display a
// callout with a warning for the user, and provide a way for them to navigate to the other rule.
@@ -401,9 +402,9 @@ const RuleDetailsPageComponent: React.FC = ({
const onFilterGroupChangedCallback = useCallback(
(newFilterGroup: Status) => {
const timelineId = TimelineId.detectionsRulesDetailsPage;
- clearEventsLoading!({ id: timelineId });
- clearEventsDeleted!({ id: timelineId });
- clearSelected!({ id: timelineId });
+ clearEventsLoading({ id: timelineId });
+ clearEventsDeleted({ id: timelineId });
+ clearSelected({ id: timelineId });
setFilterGroup(newFilterGroup);
},
[clearEventsLoading, clearEventsDeleted, clearSelected, setFilterGroup]
diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx
index 0f109214c6bf3..18b5d74516199 100644
--- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx
+++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx
@@ -174,6 +174,7 @@ export const getAboutStepsData = (rule: Rule, detailsView: boolean): AboutStepRu
timestampOverride: timestampOverride ?? '',
name,
description,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
note: note!,
references,
severity: {
diff --git a/x-pack/plugins/security_solution/public/hosts/components/authentications_table/index.tsx b/x-pack/plugins/security_solution/public/hosts/components/authentications_table/index.tsx
index b83853eec69a1..23e5da28a3559 100644
--- a/x-pack/plugins/security_solution/public/hosts/components/authentications_table/index.tsx
+++ b/x-pack/plugins/security_solution/public/hosts/components/authentications_table/index.tsx
@@ -229,8 +229,8 @@ const getAuthenticationColumns = (): AuthTableColumns => [
truncateText: false,
hideForMobile: false,
render: ({ node }) =>
- has('lastSuccess.timestamp', node) && node.lastSuccess!.timestamp != null ? (
-
+ has('lastSuccess.timestamp', node) && node.lastSuccess?.timestamp != null ? (
+
) : (
getEmptyTagValue()
),
@@ -264,8 +264,8 @@ const getAuthenticationColumns = (): AuthTableColumns => [
truncateText: false,
hideForMobile: false,
render: ({ node }) =>
- has('lastFailure.timestamp', node) && node.lastFailure!.timestamp != null ? (
-
+ has('lastFailure.timestamp', node) && node.lastFailure?.timestamp != null ? (
+
) : (
getEmptyTagValue()
),
diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_card_grid/artifact_card_grid.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_card_grid/artifact_card_grid.tsx
index 9e9082ccc54e7..0218b83288d84 100644
--- a/x-pack/plugins/security_solution/public/management/components/artifact_card_grid/artifact_card_grid.tsx
+++ b/x-pack/plugins/security_solution/public/management/components/artifact_card_grid/artifact_card_grid.tsx
@@ -119,6 +119,7 @@ export const ArtifactCardGrid = memo(
const handleItemComponentProps = useCallback(
(item: AnyArtifact): ArtifactEntryCollapsibleCardProps => {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return fullCardProps.get(item)!;
},
[fullCardProps]
diff --git a/x-pack/plugins/security_solution/public/management/components/back_to_external_app_button/back_to_external_app_button.tsx b/x-pack/plugins/security_solution/public/management/components/back_to_external_app_button/back_to_external_app_button.tsx
index c71eea2aaf9db..47242ed7d1edc 100644
--- a/x-pack/plugins/security_solution/public/management/components/back_to_external_app_button/back_to_external_app_button.tsx
+++ b/x-pack/plugins/security_solution/public/management/components/back_to_external_app_button/back_to_external_app_button.tsx
@@ -31,7 +31,7 @@ const EuiButtonEmptyStyled = styled(EuiButtonEmpty)`
export type BackToExternalAppButtonProps = CommonProps & ListPageRouteState;
export const BackToExternalAppButton = memo(
({ backButtonLabel, backButtonUrl, onBackButtonNavigateTo, ...commonProps }) => {
- const handleBackOnClick = useNavigateToAppEventHandler(...onBackButtonNavigateTo!);
+ const handleBackOnClick = useNavigateToAppEventHandler(...onBackButtonNavigateTo);
return (
(
flush="left"
size="xs"
iconType="arrowLeft"
- href={backButtonUrl!}
+ href={backButtonUrl}
onClick={handleBackOnClick}
textProps={{ className: 'text' }}
>
diff --git a/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.tsx b/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.tsx
index 41abb0309a7d1..6e33ad9218bb6 100644
--- a/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.tsx
+++ b/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.tsx
@@ -75,6 +75,7 @@ export const ContextMenuWithRouterSupport = memo {
+ let appTestContext: AppContextTestRender;
+ let renderResult: ReturnType;
+ let render: (
+ props?: Partial
+ ) => ReturnType;
+
+ const loadedUserEndpointPrivilegesState = (
+ endpointOverrides: Partial = {}
+ ): EndpointPrivileges => ({
+ loading: false,
+ canAccessFleet: true,
+ canAccessEndpointManagement: true,
+ isPlatinumPlus: false,
+ ...endpointOverrides,
+ });
+
beforeEach(() => {
onSearchMock = jest.fn();
+ appTestContext = createAppRootMockRenderer();
+
+ render = (overrideProps = {}) => {
+ const props: SearchExceptionsProps = {
+ placeholder: 'search test',
+ onSearch: onSearchMock,
+ ...overrideProps,
+ };
+
+ renderResult = appTestContext.render( );
+ return renderResult;
+ };
+
+ mockUseEndpointPrivileges.mockReturnValue(loadedUserEndpointPrivilegesState());
});
- const getElement = (defaultValue: string = '') => (
-
- );
+ afterAll(() => {
+ mockUseEndpointPrivileges.mockReset();
+ });
it('should have a default value', () => {
const expectedDefaultValue = 'this is a default value';
- const element = mount(getElement(expectedDefaultValue));
- const defaultValue = element
- .find('[data-test-subj="searchField"]')
- .first()
- .props().defaultValue;
- expect(defaultValue).toBe(expectedDefaultValue);
+ const element = render({ defaultValue: expectedDefaultValue });
+
+ expect(element.getByDisplayValue(expectedDefaultValue)).not.toBeNull();
});
it('should dispatch search action when submit search field', () => {
const expectedDefaultValue = 'this is a default value';
- const element = mount(getElement());
+ const element = render();
expect(onSearchMock).toHaveBeenCalledTimes(0);
- const searchFieldProps = element
- .find('[data-test-subj="searchField"]')
- .first()
- .props() as EuiFieldSearchPropsFake;
- searchFieldProps.onSearch(expectedDefaultValue);
+ act(() => {
+ fireEvent.change(element.getByTestId('searchField'), {
+ target: { value: expectedDefaultValue },
+ });
+ });
expect(onSearchMock).toHaveBeenCalledTimes(1);
expect(onSearchMock).toHaveBeenCalledWith(expectedDefaultValue, '', '');
@@ -56,11 +83,42 @@ describe('Search exceptions', () => {
it('should dispatch search action when click on button', () => {
const expectedDefaultValue = 'this is a default value';
- const element = mount(getElement(expectedDefaultValue));
+ const element = render({ defaultValue: expectedDefaultValue });
expect(onSearchMock).toHaveBeenCalledTimes(0);
- element.find('[data-test-subj="searchButton"]').first().simulate('click');
+ act(() => {
+ fireEvent.click(element.getByTestId('searchButton'));
+ });
+
expect(onSearchMock).toHaveBeenCalledTimes(1);
expect(onSearchMock).toHaveBeenCalledWith(expectedDefaultValue, '', '');
});
+
+ it('should hide refresh button', () => {
+ const element = render({ hideRefreshButton: true });
+
+ expect(element.queryByTestId('searchButton')).toBeNull();
+ });
+
+ it('should hide policies selector when no license', () => {
+ const generator = new EndpointDocGenerator('policy-list');
+ const policy = generator.generatePolicyPackagePolicy();
+ mockUseEndpointPrivileges.mockReturnValue(
+ loadedUserEndpointPrivilegesState({ isPlatinumPlus: false })
+ );
+ const element = render({ policyList: [policy], hasPolicyFilter: true });
+
+ expect(element.queryByTestId('policiesSelectorButton')).toBeNull();
+ });
+
+ it('should display policies selector when right license', () => {
+ const generator = new EndpointDocGenerator('policy-list');
+ const policy = generator.generatePolicyPackagePolicy();
+ mockUseEndpointPrivileges.mockReturnValue(
+ loadedUserEndpointPrivilegesState({ isPlatinumPlus: true })
+ );
+ const element = render({ policyList: [policy], hasPolicyFilter: true });
+
+ expect(element.queryByTestId('policiesSelectorButton')).not.toBeNull();
+ });
});
diff --git a/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx b/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx
index 2b7b2e6b66884..1f3eab5db2947 100644
--- a/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx
+++ b/x-pack/plugins/security_solution/public/management/components/search_exceptions/search_exceptions.tsx
@@ -19,6 +19,7 @@ export interface SearchExceptionsProps {
policyList?: ImmutableArray;
defaultExcludedPolicies?: string;
defaultIncludedPolicies?: string;
+ hideRefreshButton?: boolean;
onSearch(query: string, includedPolicies?: string, excludedPolicies?: string): void;
}
@@ -31,6 +32,7 @@ export const SearchExceptions = memo(
policyList,
defaultIncludedPolicies,
defaultExcludedPolicies,
+ hideRefreshButton = false,
}) => {
const { isPlatinumPlus } = useEndpointPrivileges();
const [query, setQuery] = useState(defaultValue);
@@ -101,13 +103,15 @@ export const SearchExceptions = memo(
) : null}
-
-
- {i18n.translate('xpack.securitySolution.management.search.button', {
- defaultMessage: 'Refresh',
- })}
-
-
+ {!hideRefreshButton ? (
+
+
+ {i18n.translate('xpack.securitySolution.management.search.button', {
+ defaultMessage: 'Refresh',
+ })}
+
+
+ ) : null}
);
}
diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts
index b16caf00b4e28..d9407e310639e 100644
--- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts
+++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts
@@ -50,9 +50,9 @@ const handleEndpointDetailsActivityLogChanged: CaseReducer = (state, action) => {
return {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
...state!,
isolationRequestState: action.payload,
};
diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/event_filter_delete_modal.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/event_filter_delete_modal.test.tsx
index ed18c084c2a05..108e3d06affa6 100644
--- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/event_filter_delete_modal.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/event_filter_delete_modal.test.tsx
@@ -30,12 +30,12 @@ describe('When event filters delete modal is shown', () => {
const getConfirmButton = () =>
renderResult.baseElement.querySelector(
'[data-test-subj="eventFilterDeleteModalConfirmButton"]'
- )! as HTMLButtonElement;
+ ) as HTMLButtonElement;
const getCancelButton = () =>
renderResult.baseElement.querySelector(
'[data-test-subj="eventFilterDeleteModalCancelButton"]'
- )! as HTMLButtonElement;
+ ) as HTMLButtonElement;
const getCurrentState = () => store.getState().management.eventFilters;
diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.test.tsx
index d5a1c6624923b..83b4f005135ba 100644
--- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/flyout/index.test.tsx
@@ -80,7 +80,7 @@ describe('Event filter flyout', () => {
});
expect(getFormEntryState(getState())).not.toBeUndefined();
- expect(getFormEntryState(getState())!.entries[0].field).toBe('');
+ expect(getFormEntryState(getState())?.entries[0].field).toBe('');
});
it('should confirm form when button is disabled', () => {
@@ -98,7 +98,7 @@ describe('Event filter flyout', () => {
type: 'eventFiltersChangeForm',
payload: {
entry: {
- ...(getState().form!.entry as CreateExceptionListItemSchema),
+ ...(getState().form?.entry as CreateExceptionListItemSchema),
name: 'test',
os_types: ['windows'],
},
@@ -125,7 +125,7 @@ describe('Event filter flyout', () => {
type: 'eventFiltersFormStateChanged',
payload: {
type: 'LoadedResourceState',
- data: getState().form!.entry as ExceptionListItemSchema,
+ data: getState().form?.entry as ExceptionListItemSchema,
},
});
});
@@ -193,6 +193,6 @@ describe('Event filter flyout', () => {
});
expect(getFormEntryState(getState())).not.toBeUndefined();
- expect(getFormEntryState(getState())!.item_id).toBe(createdEventFilterEntryMock().item_id);
+ expect(getFormEntryState(getState())?.item_id).toBe(createdEventFilterEntryMock().item_id);
});
});
diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx
index 3934e3a389c36..f8dd9ac632cd0 100644
--- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/form/index.test.tsx
@@ -99,7 +99,7 @@ describe('Event filter form', () => {
});
});
- expect(getState().form.entry!.name).toBe('Exception name');
+ expect(getState().form.entry?.name).toBe('Exception name');
expect(getState().form.hasNameError).toBeFalsy();
});
@@ -116,7 +116,7 @@ describe('Event filter form', () => {
});
});
- expect(getState().form.entry!.name).toBe('');
+ expect(getState().form.entry?.name).toBe('');
expect(getState().form.hasNameError).toBeTruthy();
});
diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/modal/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/modal/index.test.tsx
index c77188694f507..8ea50ecd460e4 100644
--- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/modal/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/components/modal/index.test.tsx
@@ -81,7 +81,7 @@ describe('Event filter modal', () => {
await waitForAction('eventFiltersInitForm');
});
- expect(getState().form!.entry).not.toBeUndefined();
+ expect(getState().form?.entry).not.toBeUndefined();
});
it('should set OS with the enriched data', async () => {
@@ -90,7 +90,7 @@ describe('Event filter modal', () => {
await waitForAction('eventFiltersInitForm');
});
- expect(getState().form!.entry?.os_types).toContain('linux');
+ expect(getState().form?.entry?.os_types).toContain('linux');
});
it('should confirm form when button is disabled', async () => {
@@ -103,7 +103,7 @@ describe('Event filter modal', () => {
act(() => {
fireEvent.click(confirmButton);
});
- expect(getState().form!.submissionResourceState.type).toBe('UninitialisedResourceState');
+ expect(getState().form?.submissionResourceState.type).toBe('UninitialisedResourceState');
});
it('should confirm form when button is enabled', async () => {
@@ -116,7 +116,7 @@ describe('Event filter modal', () => {
type: 'eventFiltersChangeForm',
payload: {
entry: {
- ...(getState().form!.entry as CreateExceptionListItemSchema),
+ ...(getState().form?.entry as CreateExceptionListItemSchema),
name: 'test',
},
hasNameError: false,
@@ -126,7 +126,7 @@ describe('Event filter modal', () => {
act(() => {
fireEvent.click(confirmButton);
});
- expect(getState().form!.submissionResourceState.type).toBe('LoadingResourceState');
+ expect(getState().form?.submissionResourceState.type).toBe('LoadingResourceState');
expect(confirmButton.hasAttribute('disabled')).toBeTruthy();
});
@@ -143,7 +143,7 @@ describe('Event filter modal', () => {
type: 'eventFiltersFormStateChanged',
payload: {
type: 'LoadedResourceState',
- data: getState().form!.entry as ExceptionListItemSchema,
+ data: getState().form?.entry as ExceptionListItemSchema,
},
});
});
diff --git a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/use_event_filters_notification.test.tsx b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/use_event_filters_notification.test.tsx
index 039aeb9f8e596..82fe231505ad5 100644
--- a/x-pack/plugins/security_solution/public/management/pages/event_filters/view/use_event_filters_notification.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/event_filters/view/use_event_filters_notification.test.tsx
@@ -79,14 +79,14 @@ describe('EventFiltersNotification', () => {
type: 'eventFiltersFormStateChanged',
payload: {
type: 'LoadedResourceState',
- data: store.getState()!.management!.eventFilters!.form!.entry as ExceptionListItemSchema,
+ data: store.getState().management.eventFilters.form.entry as ExceptionListItemSchema,
},
});
});
expect(notifications.toasts.addSuccess).toBeCalledWith(
getCreationSuccessMessage(
- store.getState()!.management!.eventFilters!.form!.entry as CreateExceptionListItemSchema
+ store.getState().management.eventFilters.form.entry as CreateExceptionListItemSchema
)
);
expect(notifications.toasts.addDanger).not.toBeCalled();
@@ -110,14 +110,14 @@ describe('EventFiltersNotification', () => {
type: 'eventFiltersFormStateChanged',
payload: {
type: 'LoadedResourceState',
- data: store.getState()!.management!.eventFilters!.form!.entry as ExceptionListItemSchema,
+ data: store.getState().management.eventFilters.form.entry as ExceptionListItemSchema,
},
});
});
expect(notifications.toasts.addSuccess).toBeCalledWith(
getUpdateSuccessMessage(
- store.getState()!.management!.eventFilters!.form!.entry as CreateExceptionListItemSchema
+ store.getState().management.eventFilters.form.entry as CreateExceptionListItemSchema
)
);
expect(notifications.toasts.addDanger).not.toBeCalled();
@@ -144,7 +144,7 @@ describe('EventFiltersNotification', () => {
type: 'FailedResourceState',
error: { message: 'error message', statusCode: 500, error: 'error' },
lastLoadedState: getLastLoadedResourceState(
- store.getState()!.management!.eventFilters!.form!.submissionResourceState
+ store.getState().management.eventFilters.form.submissionResourceState
),
},
});
@@ -154,7 +154,7 @@ describe('EventFiltersNotification', () => {
expect(notifications.toasts.addDanger).toBeCalledWith(
getCreationErrorMessage(
(
- store.getState()!.management!.eventFilters!.form!
+ store.getState().management.eventFilters.form
.submissionResourceState as FailedResourceState
).error
)
@@ -181,7 +181,7 @@ describe('EventFiltersNotification', () => {
type: 'FailedResourceState',
error: { message: 'error message', statusCode: 500, error: 'error' },
lastLoadedState: getLastLoadedResourceState(
- store.getState()!.management!.eventFilters!.form!.submissionResourceState
+ store.getState().management.eventFilters.form.submissionResourceState
),
},
});
@@ -191,7 +191,7 @@ describe('EventFiltersNotification', () => {
expect(notifications.toasts.addDanger).toBeCalledWith(
getUpdateErrorMessage(
(
- store.getState()!.management!.eventFilters!.form!
+ store.getState().management.eventFilters.form
.submissionResourceState as FailedResourceState
).error
)
@@ -211,7 +211,7 @@ describe('EventFiltersNotification', () => {
type: 'FailedResourceState',
error: { message: 'error message', statusCode: 500, error: 'error' },
lastLoadedState: getLastLoadedResourceState(
- store.getState()!.management!.eventFilters!.form!.submissionResourceState
+ store.getState().management.eventFilters.form.submissionResourceState
),
},
});
@@ -221,7 +221,7 @@ describe('EventFiltersNotification', () => {
expect(notifications.toasts.addWarning).toBeCalledWith(
getGetErrorMessage(
(
- store.getState()!.management!.eventFilters!.form!
+ store.getState().management.eventFilters.form
.submissionResourceState as FailedResourceState
).error
)
diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/delete_modal.test.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/delete_modal.test.tsx
index 2a75ab0622128..2118a8de9b9ed 100644
--- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/delete_modal.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/delete_modal.test.tsx
@@ -53,11 +53,11 @@ describe('When on the host isolation exceptions delete modal', () => {
const submitButton = renderResult.baseElement.querySelector(
'[data-test-subj="hostIsolationExceptionsDeleteModalConfirmButton"]'
- )! as HTMLButtonElement;
+ ) as HTMLButtonElement;
const cancelButton = renderResult.baseElement.querySelector(
'[data-test-subj="hostIsolationExceptionsDeleteModalConfirmButton"]'
- )! as HTMLButtonElement;
+ ) as HTMLButtonElement;
act(() => {
fireEvent.click(submitButton);
@@ -72,7 +72,7 @@ describe('When on the host isolation exceptions delete modal', () => {
render();
const cancelButton = renderResult.baseElement.querySelector(
'[data-test-subj="hostIsolationExceptionsDeleteModalConfirmButton"]'
- )! as HTMLButtonElement;
+ ) as HTMLButtonElement;
const waiter = waitForAction('hostIsolationExceptionsMarkToDelete', {
validate: ({ payload }) => {
@@ -96,7 +96,7 @@ describe('When on the host isolation exceptions delete modal', () => {
const submitButton = renderResult.baseElement.querySelector(
'[data-test-subj="hostIsolationExceptionsDeleteModalConfirmButton"]'
- )! as HTMLButtonElement;
+ ) as HTMLButtonElement;
await act(async () => {
fireEvent.click(submitButton);
@@ -121,7 +121,7 @@ describe('When on the host isolation exceptions delete modal', () => {
const submitButton = renderResult.baseElement.querySelector(
'[data-test-subj="hostIsolationExceptionsDeleteModalConfirmButton"]'
- )! as HTMLButtonElement;
+ ) as HTMLButtonElement;
await act(async () => {
fireEvent.click(submitButton);
diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.tsx
index de12616c67a3c..799e327a3fb4c 100644
--- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form_flyout.tsx
@@ -97,7 +97,7 @@ export const HostIsolationExceptionsFormFlyout: React.FC<{}> = memo(() => {
if (!exceptionToEdit || location.id !== exceptionToEdit.id) {
dispatch({
type: 'hostIsolationExceptionsMarkToEdit',
- payload: { id: location.id! },
+ payload: { id: location.id },
});
} else {
setException(exceptionToEdit);
diff --git a/x-pack/plugins/security_solution/public/management/pages/mocks/trusted_apps_http_mocks.ts b/x-pack/plugins/security_solution/public/management/pages/mocks/trusted_apps_http_mocks.ts
index 6f90fcd629485..0a440afcb2c30 100644
--- a/x-pack/plugins/security_solution/public/management/pages/mocks/trusted_apps_http_mocks.ts
+++ b/x-pack/plugins/security_solution/public/management/pages/mocks/trusted_apps_http_mocks.ts
@@ -75,6 +75,7 @@ export const trustedAppPutHttpMocks = httpHandlerMockFactory {
it('windows process events is enabled', () => {
const config = policyConfig(getState());
- expect(config!.windows.events.process).toEqual(true);
+ expect(config.windows.events.process).toEqual(true);
});
});
@@ -128,7 +128,7 @@ describe('policy details: ', () => {
it('mac file events is enabled', () => {
const config = policyConfig(getState());
- expect(config!.mac.events.file).toEqual(true);
+ expect(config.mac.events.file).toEqual(true);
});
});
@@ -150,7 +150,7 @@ describe('policy details: ', () => {
it('linux file events is enabled', () => {
const config = policyConfig(getState());
- expect(config!.linux.events.file).toEqual(true);
+ expect(config.linux.events.file).toEqual(true);
});
});
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/exception_items_summary.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/exception_items_summary.test.tsx
index 1d9edbe66fc78..b348a99d223b8 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/exception_items_summary.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_package_custom_extension/components/exception_items_summary.test.tsx
@@ -20,7 +20,7 @@ const mockTheme = getMockTheme({
});
const getStatValue = (el: reactTestingLibrary.RenderResult, stat: string) => {
- return el.getByText(stat)!.nextSibling?.lastChild?.textContent;
+ return el.getByText(stat).nextSibling?.lastChild?.textContent;
};
describe('Fleet event filters card', () => {
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx
index a4a2ee65c84e7..4573b15b8fabc 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx
@@ -101,6 +101,7 @@ export const PolicyFormLayout = React.memo(() => {
title: i18n.translate('xpack.securitySolution.endpoint.policy.details.updateErrorTitle', {
defaultMessage: 'Failed!',
}),
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
text: policyUpdateStatus.error!.message,
});
}
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts
index c6b89b4137cc4..9e53eb9cfc40f 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts
@@ -93,7 +93,7 @@ export const usePolicyTrustedAppsNotification = () => {
'xpack.securitySolution.endpoint.policy.trustedApps.layout.flyout.toastSuccess.textSingle',
{
defaultMessage: '"{name}" has been added to your trusted applications list.',
- values: { name: updatedArtifacts[0]!.data.name },
+ values: { name: updatedArtifacts[0].data.name },
}
),
});
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.tsx
index 8728104aee637..bbf2f3b208754 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/flyout/policy_trusted_apps_flyout.tsx
@@ -91,6 +91,7 @@ export const PolicyTrustedAppsFlyout = React.memo(() => {
payload: {
action: 'assign',
artifacts: selectedArtifactIds.map>((selectedId) => {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return assignableArtifactsList?.data?.find((trustedApp) => trustedApp.id === selectedId)!;
}),
},
@@ -182,6 +183,7 @@ export const PolicyTrustedAppsFlyout = React.memo(() => {
defaultMessage: 'Search trusted applications',
}
)}
+ hideRefreshButton
/>
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx
index cb29d0ff868ac..5d6c9731c7070 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx
@@ -181,6 +181,7 @@ export const PolicyTrustedAppsList = memo(() => {
const provideCardProps = useCallback['cardComponentProps']>(
(item) => {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return cardProps.get(item as Immutable)!;
},
[cardProps]
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/remove_trusted_app_from_policy_modal.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/remove_trusted_app_from_policy_modal.test.tsx
index 0411751685a90..917ffe49c6090 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/remove_trusted_app_from_policy_modal.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/remove_trusted_app_from_policy_modal.test.tsx
@@ -25,7 +25,8 @@ import {
import { Immutable } from '../../../../../../../common/endpoint/types';
import { HttpFetchOptionsWithPath } from 'kibana/public';
-describe('When using the RemoveTrustedAppFromPolicyModal component', () => {
+// FLAKY https://github.com/elastic/kibana/issues/115100
+describe.skip('When using the RemoveTrustedAppFromPolicyModal component', () => {
let appTestContext: AppContextTestRender;
let renderResult: ReturnType;
let render: (waitForLoadedState?: boolean) => Promise>;
diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts
index 0ff6282f8a018..0de5761ccf074 100644
--- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts
+++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts
@@ -191,6 +191,7 @@ const submitCreationIfNeeded = async (
if (editMode) {
responseTrustedApp = (
await trustedAppsService.updateTrustedApp(
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
{ id: editItemId(currentState)! },
// TODO: try to remove the cast
entry as PostTrustedAppCreateRequest
@@ -414,6 +415,7 @@ const fetchEditTrustedAppIfNeeded = async (
payload: {
// @ts-expect-error-next-line will be fixed with when AsyncResourceState is refactored (#830)
type: 'LoadingResourceState',
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
previousState: editItemState(currentState)!,
},
});
diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx
index 50485ccde00ad..d4f456ab8e039 100644
--- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx
@@ -86,7 +86,9 @@ const addResultToValidation = (
};
}
const errorMarkup: React.ReactNode = type === 'warnings' ? {resultValue}
: resultValue;
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
validation.result[field]![type].push(errorMarkup);
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
validation.result[field]!.isInvalid = true;
};
diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.tsx
index e247602060384..07de303c155aa 100644
--- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/effected_policy_select/effected_policy_select.tsx
@@ -143,7 +143,7 @@ export const EffectedPolicySelect = memo(
});
},
[isGlobal, onChange]
- )!;
+ );
const handleGlobalButtonChange = useCallback(
(selectedId) => {
diff --git a/x-pack/plugins/security_solution/public/network/components/details/index.tsx b/x-pack/plugins/security_solution/public/network/components/details/index.tsx
index 7658a6a76230c..0b53a4bfb3fe2 100644
--- a/x-pack/plugins/security_solution/public/network/components/details/index.tsx
+++ b/x-pack/plugins/security_solution/public/network/components/details/index.tsx
@@ -71,7 +71,7 @@ export const IpOverview = React.memo(
const capabilities = useMlCapabilities();
const userPermissions = hasMlUserPermissions(capabilities);
const [darkMode] = useUiSetting$(DEFAULT_DARK_MODE);
- const typeData = data[flowTarget]!;
+ const typeData = data[flowTarget];
const column: DescriptionList[] = [
{
title: i18n.LOCATION,
diff --git a/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.test.tsx
index a811f5c92c37a..fc28067866146 100644
--- a/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.test.tsx
@@ -78,7 +78,7 @@ describe('NetworkTopNFlow Table Component', () => {
);
- expect(store.getState().network.page.queries!.dns.sort).toEqual({
+ expect(store.getState().network.page.queries?.dns.sort).toEqual({
direction: 'desc',
field: 'queryCount',
});
@@ -87,7 +87,7 @@ describe('NetworkTopNFlow Table Component', () => {
wrapper.update();
- expect(store.getState().network.page.queries!.dns.sort).toEqual({
+ expect(store.getState().network.page.queries?.dns.sort).toEqual({
direction: 'asc',
field: 'dnsName',
});
diff --git a/x-pack/plugins/security_solution/public/network/components/network_http_table/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/network_http_table/index.test.tsx
index f05372c76b36f..2a85b31791f5a 100644
--- a/x-pack/plugins/security_solution/public/network/components/network_http_table/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/network/components/network_http_table/index.test.tsx
@@ -80,7 +80,7 @@ describe('NetworkHttp Table Component', () => {
);
- expect(store.getState().network.page.queries!.http.sort).toEqual({
+ expect(store.getState().network.page.queries?.http.sort).toEqual({
direction: 'desc',
});
@@ -88,7 +88,7 @@ describe('NetworkHttp Table Component', () => {
wrapper.update();
- expect(store.getState().network.page.queries!.http.sort).toEqual({
+ expect(store.getState().network.page.queries?.http.sort).toEqual({
direction: 'asc',
});
expect(wrapper.find('.euiTable thead tr th button').first().find('svg')).toBeTruthy();
diff --git a/x-pack/plugins/security_solution/public/network/components/tls_table/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/tls_table/index.test.tsx
index 8f2c7a098a045..3a1a5efef6b89 100644
--- a/x-pack/plugins/security_solution/public/network/components/tls_table/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/network/components/tls_table/index.test.tsx
@@ -77,7 +77,7 @@ describe('Tls Table Component', () => {
/>
);
- expect(store.getState().network.details.queries!.tls.sort).toEqual({
+ expect(store.getState().network.details.queries?.tls.sort).toEqual({
direction: 'desc',
field: '_id',
});
@@ -86,7 +86,7 @@ describe('Tls Table Component', () => {
wrapper.update();
- expect(store.getState().network.details.queries!.tls.sort).toEqual({
+ expect(store.getState().network.details.queries?.tls.sort).toEqual({
direction: 'asc',
field: '_id',
});
diff --git a/x-pack/plugins/security_solution/public/network/components/users_table/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/users_table/index.test.tsx
index 69027ad9bd9f8..3861433b4dcb0 100644
--- a/x-pack/plugins/security_solution/public/network/components/users_table/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/network/components/users_table/index.test.tsx
@@ -81,7 +81,7 @@ describe('Users Table Component', () => {
/>
);
- expect(store.getState().network.details.queries!.users.sort).toEqual({
+ expect(store.getState().network.details.queries?.users.sort).toEqual({
direction: 'asc',
field: 'name',
});
@@ -90,7 +90,7 @@ describe('Users Table Component', () => {
wrapper.update();
- expect(store.getState().network.details.queries!.users.sort).toEqual({
+ expect(store.getState().network.details.queries?.users.sort).toEqual({
direction: 'desc',
field: 'name',
});
diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx
index 718487ccf7fc6..371b68e9bec8e 100644
--- a/x-pack/plugins/security_solution/public/plugin.tsx
+++ b/x-pack/plugins/security_solution/public/plugin.tsx
@@ -371,16 +371,23 @@ export class Plugin implements IPlugin node.id === originID)!
);
const relatedEvents = [
diff --git a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts
index 3a8bf76e732a9..6dfeaa9723a33 100644
--- a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts
+++ b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/index.ts
@@ -162,6 +162,7 @@ export function root(tree: IndexedProcessTree) {
// iteratively swap current w/ its parent
while (parent(tree, current) !== undefined) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
current = parent(tree, current)!;
}
return current;
diff --git a/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts b/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts
index 110ea476f5fb2..26cf874edda00 100644
--- a/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts
+++ b/x-pack/plugins/security_solution/public/resolver/store/selectors.test.ts
@@ -145,7 +145,7 @@ describe('resolver selectors', () => {
});
});
it('the origin should be in view', () => {
- const origin = selectors.graphNodeForID(state())(originID)!;
+ const origin = selectors.graphNodeForID(state())(originID);
expect(
selectors
.visibleNodesAndEdgeLines(state())(0)
@@ -153,7 +153,7 @@ describe('resolver selectors', () => {
).toBe(true);
});
it('the first child should be in view', () => {
- const firstChild = selectors.graphNodeForID(state())(firstChildID)!;
+ const firstChild = selectors.graphNodeForID(state())(firstChildID);
expect(
selectors
.visibleNodesAndEdgeLines(state())(0)
@@ -161,7 +161,7 @@ describe('resolver selectors', () => {
).toBe(true);
});
it('the second child should not be in view', () => {
- const secondChild = selectors.graphNodeForID(state())(secondChildID)!;
+ const secondChild = selectors.graphNodeForID(state())(secondChildID);
expect(
selectors
.visibleNodesAndEdgeLines(state())(0)
diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts b/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts
index 145e54dbbb7b2..7bb7180712c99 100644
--- a/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts
+++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts
@@ -67,7 +67,7 @@ expect.extend({
? () =>
`${this.utils.matcherHint(matcherName, undefined, undefined, options)}\n\n` +
`Expected: not ${this.utils.printExpected(expected)}\n${
- this.utils.stringify(expected) !== this.utils.stringify(received[received.length - 1]!)
+ this.utils.stringify(expected) !== this.utils.stringify(received[received.length - 1])
? `Received: ${this.utils.printReceived(received[received.length - 1])}`
: ''
}`
@@ -131,7 +131,7 @@ expect.extend({
? () =>
`${this.utils.matcherHint(matcherName, undefined, undefined, options)}\n\n` +
`Expected: not ${this.utils.printExpected(expected)}\n${
- this.utils.stringify(expected) !== this.utils.stringify(received[received.length - 1]!)
+ this.utils.stringify(expected) !== this.utils.stringify(received[received.length - 1])
? `Received: ${this.utils.printReceived(received[received.length - 1])}`
: ''
}`
diff --git a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx
index 1a7477af3b3cf..6a146882fbab5 100644
--- a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx
+++ b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx
@@ -104,7 +104,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the user clicks the west panning button', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:west-button'))!.simulate('click');
+ (await simulator.resolve('resolver:graph-controls:west-button'))?.simulate('click');
simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration);
});
@@ -118,7 +118,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the user clicks the south panning button', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:south-button'))!.simulate('click');
+ (await simulator.resolve('resolver:graph-controls:south-button'))?.simulate('click');
simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration);
});
@@ -132,7 +132,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the user clicks the east panning button', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:east-button'))!.simulate('click');
+ (await simulator.resolve('resolver:graph-controls:east-button'))?.simulate('click');
simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration);
});
@@ -146,7 +146,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the user clicks the north panning button', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:north-button'))!.simulate('click');
+ (await simulator.resolve('resolver:graph-controls:north-button'))?.simulate('click');
simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration);
});
@@ -160,9 +160,9 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the user clicks the center panning button', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:north-button'))!.simulate('click');
+ (await simulator.resolve('resolver:graph-controls:north-button'))?.simulate('click');
simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration);
- (await simulator.resolve('resolver:graph-controls:center-button'))!.simulate('click');
+ (await simulator.resolve('resolver:graph-controls:center-button'))?.simulate('click');
simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration);
});
@@ -177,7 +177,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the zoom in button is clicked', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:zoom-in'))!.simulate('click');
+ (await simulator.resolve('resolver:graph-controls:zoom-in'))?.simulate('click');
simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration);
});
@@ -191,7 +191,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the zoom out button is clicked', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:zoom-out'))!.simulate('click');
+ (await simulator.resolve('resolver:graph-controls:zoom-out'))?.simulate('click');
simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration);
});
@@ -207,7 +207,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
beforeEach(async () => {
await expect(originNodeStyle()).toYieldObjectEqualTo(originalSizeStyle);
- (await simulator.resolve('resolver:graph-controls:zoom-slider'))!.simulate('change', {
+ (await simulator.resolve('resolver:graph-controls:zoom-slider'))?.simulate('change', {
target: { value: 0.8 },
});
simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration);
@@ -223,7 +223,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the slider is moved downwards', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:zoom-slider'))!.simulate('change', {
+ (await simulator.resolve('resolver:graph-controls:zoom-slider'))?.simulate('change', {
target: { value: 0.2 },
});
simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration);
@@ -239,7 +239,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the schema information button is clicked', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:schema-info-button'))!.simulate('click', {
+ (await simulator.resolve('resolver:graph-controls:schema-info-button'))?.simulate('click', {
button: 0,
});
});
@@ -257,7 +257,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the node legend button is clicked', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:node-legend-button'))!.simulate('click', {
+ (await simulator.resolve('resolver:graph-controls:node-legend-button'))?.simulate('click', {
button: 0,
});
});
@@ -275,7 +275,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
describe('when the node legend button is clicked while the schema info button is open', () => {
beforeEach(async () => {
- (await simulator.resolve('resolver:graph-controls:schema-info-button'))!.simulate('click', {
+ (await simulator.resolve('resolver:graph-controls:schema-info-button'))?.simulate('click', {
button: 0,
});
});
@@ -284,8 +284,8 @@ describe('graph controls: when relsover is loaded with an origin node', () => {
expect(simulator.testSubject('resolver:graph-controls:schema-info').length).toBe(1);
await simulator
- .testSubject('resolver:graph-controls:node-legend-button')!
- .simulate('click', { button: 0 });
+ .testSubject('resolver:graph-controls:node-legend-button')
+ ?.simulate('click', { button: 0 });
await expect(
simulator.map(() => ({
diff --git a/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx
index 3b2d222ac3812..72db334e17c2c 100644
--- a/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx
+++ b/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx
@@ -150,13 +150,13 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children and
.filterWhere(Simulator.isDOM);
expect(copyableFieldHoverArea).toHaveLength(1);
- copyableFieldHoverArea!.simulate('mouseenter');
+ copyableFieldHoverArea?.simulate('mouseenter');
});
describe('and when they click the copy-to-clipboard button', () => {
beforeEach(async () => {
const copyButton = await simulator().resolve('resolver:panel:clipboard');
expect(copyButton).toHaveLength(1);
- copyButton!.simulate('click');
+ copyButton?.simulate('click');
simulator().confirmTextWrittenToClipboard();
});
it(`should write ${value} to the clipboard`, async () => {
@@ -232,11 +232,11 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children and
.filterWhere(Simulator.isDOM)
);
});
- cExtHoverArea!.simulate('mouseenter');
+ cExtHoverArea?.simulate('mouseenter');
});
describe('and when the user clicks the copy-to-clipboard button', () => {
beforeEach(async () => {
- (await simulator().resolve('resolver:panel:clipboard'))!.simulate('click');
+ (await simulator().resolve('resolver:panel:clipboard'))?.simulate('click');
simulator().confirmTextWrittenToClipboard();
});
const expected = 'Sep 23, 2020 @ 08:25:32.316';
@@ -369,7 +369,7 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children and
beforeEach(async () => {
const button = await simulator().resolve('resolver:panel:clipboard');
expect(button).toBeTruthy();
- button!.simulate('click');
+ button?.simulate('click');
simulator().confirmTextWrittenToClipboard();
});
it(`should write ${expectedValue} to the clipboard`, async () => {
diff --git a/x-pack/plugins/security_solution/public/resolver/view/side_effect_simulator_factory.ts b/x-pack/plugins/security_solution/public/resolver/view/side_effect_simulator_factory.ts
index 8c3caf16eadd7..b3289a510deef 100644
--- a/x-pack/plugins/security_solution/public/resolver/view/side_effect_simulator_factory.ts
+++ b/x-pack/plugins/security_solution/public/resolver/view/side_effect_simulator_factory.ts
@@ -41,6 +41,7 @@ export const sideEffectSimulatorFactory: () => SideEffectSimulator = () => {
*/
const getBoundingClientRect: (target: Element) => DOMRect = (target) => {
if (contentRects.has(target)) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return contentRects.get(target)!;
}
const domRect: DOMRect = {
diff --git a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx
index 9851f11d9adba..e76e2800908c2 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx
@@ -70,7 +70,7 @@ describe('Field Renderers', () => {
describe('#dateRenderer', () => {
test('it renders correctly against snapshot', () => {
- const wrapper = shallow(dateRenderer(mockData.complete.source!.firstSeen));
+ const wrapper = shallow(dateRenderer(mockData.complete.source?.firstSeen));
expect(wrapper).toMatchSnapshot();
});
@@ -307,7 +307,7 @@ describe('Field Renderers', () => {
);
expect(
- wrapper.find('[data-test-subj="more-container"]').first().props().style!.overflow
+ wrapper.find('[data-test-subj="more-container"]').first().props().style?.overflow
).toEqual('auto');
});
@@ -322,7 +322,7 @@ describe('Field Renderers', () => {
);
expect(
- wrapper.find('[data-test-subj="more-container"]').first().props().style!.maxHeight
+ wrapper.find('[data-test-subj="more-container"]').first().props().style?.maxHeight
).toEqual(DEFAULT_MORE_MAX_HEIGHT);
});
diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/active_timelines.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/active_timelines.tsx
index 4eb91ca8ee272..639bc1ac6b57f 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/active_timelines.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/active_timelines.tsx
@@ -77,6 +77,7 @@ const ActiveTimelinesComponent: React.FC = ({
>
diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx
index 9f1730c367a81..1fdfb744f3071 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/header/index.tsx
@@ -113,6 +113,7 @@ const FlyoutHeaderPanelComponent: React.FC = ({ timeline
[dataProviders, kqlQuery]
);
const getKqlQueryTimeline = useMemo(() => timelineSelectors.getKqlFilterQuerySelector(), []);
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const kqlQueryTimeline = useSelector((state: State) => getKqlQueryTimeline(state, timelineId)!);
const kqlQueryExpression =
@@ -333,6 +334,7 @@ const TimelineStatusInfoComponent: React.FC = ({ timelineId }
@@ -372,6 +374,7 @@ const FlyoutHeaderComponent: React.FC = ({ timelineId }) => {
);
const { dataProviders, filters, timelineType, kqlMode, activeTab } = timeline;
const getKqlQueryTimeline = useMemo(() => timelineSelectors.getKqlFilterQuerySelector(), []);
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const kqlQueryTimeline = useSelector((state: State) => getKqlQueryTimeline(state, timelineId)!);
const kqlQueryExpression =
diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts
index 2a3b49517b456..1fbddf61f8cd3 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts
+++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts
@@ -205,9 +205,11 @@ const convertToDefaultField = ({ and, ...dataProvider }: DataProviderResult) =>
if (dataProvider.type === DataProviderType.template) {
return deepMerge(dataProvider, {
type: DataProviderType.default,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
enabled: dataProvider.queryMatch!.operator !== IS_OPERATOR,
queryMatch: {
value:
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
dataProvider.queryMatch!.operator === IS_OPERATOR ? '' : dataProvider.queryMatch!.value,
},
});
diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx
index d59b75fcfb506..f3ec55ea0ddef 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx
@@ -318,7 +318,7 @@ describe('StatefulOpenTimeline', () => {
await waitFor(() => {
expect(
wrapper.find(`.${OPEN_TIMELINE_CLASS_NAME} input`).first().getDOMNode().id ===
- document.activeElement!.id
+ document.activeElement?.id
).toBe(true);
});
});
diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.test.tsx
index 1cca5a3999b81..607bccdbc039d 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/note_previews/index.test.tsx
@@ -44,7 +44,7 @@ describe('NotePreviews', () => {
const wrapper = mountWithIntl( );
- hasNotes[0].notes!.forEach(({ savedObjectId }) => {
+ hasNotes[0].notes?.forEach(({ savedObjectId }) => {
expect(wrapper.find(`[data-test-subj="note-preview-${savedObjectId}"]`).exists()).toBe(true);
});
});
@@ -54,7 +54,7 @@ describe('NotePreviews', () => {
const wrapper = mountWithIntl( );
- hasNotes[0].notes!.forEach(({ savedObjectId }) => {
+ hasNotes[0].notes?.forEach(({ savedObjectId }) => {
expect(wrapper.find(`[data-test-subj="note-preview-${savedObjectId}"]`).exists()).toBe(true);
});
});
diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.tsx
index b3cd5eedd19c3..a7953d60ba767 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/timelines_table/actions_columns.tsx
@@ -40,6 +40,7 @@ export const getActionsColumns = ({
onOpenTimeline({
duplicate: true,
timelineType: TimelineType.default,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
timelineId: savedObjectId!,
});
},
@@ -58,6 +59,7 @@ export const getActionsColumns = ({
onOpenTimeline({
duplicate: true,
timelineType: TimelineType.template,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
timelineId: savedObjectId!,
});
},
diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/expandable_event.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/expandable_event.tsx
index 53382fe8fa21d..17d43d80a5a9a 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/expandable_event.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/expandable_event.tsx
@@ -108,7 +108,7 @@ export const ExpandableEvent = React.memo(
(
{':'}
-
+
{header.type}
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 a7c989bfab64e..1473de5472b3e 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
@@ -187,6 +187,7 @@ const StatefulEventComponent: React.FC = ({
const handleOnEventDetailPanelOpened = useCallback(() => {
const eventId = event._id;
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const indexName = event._index!;
const updatedExpandedDetail: TimelineExpandedDetailType = {
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 fc8bf2086471c..3ee0ef8804e89 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
@@ -111,7 +111,7 @@ export const BodyComponent = React.memo(
const onRowSelected: OnRowSelected = useCallback(
({ eventIds, isSelected }: { eventIds: string[]; isSelected: boolean }) => {
- setSelected!({
+ setSelected({
id,
eventIds: getEventIdToDataMapping(data, eventIds, queryFields),
isSelected,
@@ -125,7 +125,7 @@ export const BodyComponent = React.memo(
const onSelectAll: OnSelectAll = useCallback(
({ isSelected }: { isSelected: boolean }) =>
isSelected
- ? setSelected!({
+ ? setSelected({
id,
eventIds: getEventIdToDataMapping(
data,
@@ -135,7 +135,7 @@ export const BodyComponent = React.memo(
isSelected,
isSelectAllChecked: isSelected,
})
- : clearSelected!({ id }),
+ : clearSelected({ id }),
[setSelected, clearSelected, id, data, queryFields]
);
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx
index 3703d6fe441c0..61ea659964e4d 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/suricata/suricata_row_renderer.test.tsx
@@ -78,7 +78,7 @@ describe('suricata_row_renderer', () => {
});
test('should render a suricata row even if it does not have a suricata signature', () => {
- delete suricata!.suricata!.eve!.alert!.signature;
+ delete suricata?.suricata?.eve?.alert?.signature;
const children = suricataRowRenderer.renderRow({
browserFields: mockBrowserFields,
data: suricata,
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.tsx
index 41f35e7c50e30..7c010795682ac 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/zeek/zeek_signature.tsx
@@ -76,12 +76,12 @@ export const DraggableZeekElement = React.memo<{
and: [],
enabled: true,
id: escapeDataProviderId(`draggable-zeek-element-draggable-wrapper-${id}-${field}-${value}`),
- name: value!,
+ name: String(value),
excluded: false,
kqlQuery: '',
queryMatch: {
field,
- value: value!,
+ value: String(value),
operator: IS_OPERATOR as QueryOperator,
},
}),
@@ -97,7 +97,7 @@ export const DraggableZeekElement = React.memo<{
) : (
- {stringRenderer(value!)}
+ {stringRenderer(String(value))}
),
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx
index 84f286b435a48..52443cf92a9cb 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/data_providers/add_data_provider_popover.tsx
@@ -113,7 +113,7 @@ const AddDataProviderPopoverComponent: React.FC = (
width: 400,
content: (
= (
width: 400,
content: (
= (
return (
= ({ users }) => {
const List = useMemo(
() =>
users.map((user) => (
-
-
+
+
)),
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 d2cf158818f75..2082e7f5b69bb 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
@@ -463,7 +463,7 @@ const makeMapStateToProps = () => {
status,
timelineType,
} = timeline;
- const kqlQueryTimeline = getKqlQueryTimeline(state, timelineId)!;
+ const kqlQueryTimeline = getKqlQueryTimeline(state, timelineId);
const timelineFilter = kqlMode === 'filter' ? filters || [] : [];
// return events on empty search
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/index.tsx
index 33ab2e0049828..96ca26a099d2f 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/index.tsx
@@ -74,7 +74,7 @@ const StatefulSearchOrFilterComponent = React.memo(
from={from}
fromStr={fromStr}
isRefreshPaused={isRefreshPaused}
- kqlMode={kqlMode!}
+ kqlMode={kqlMode}
refreshInterval={refreshInterval}
savedQueryId={savedQueryId}
setFilters={setFiltersInTimeline}
@@ -82,7 +82,7 @@ const StatefulSearchOrFilterComponent = React.memo(
timelineId={timelineId}
to={to}
toStr={toStr}
- updateKqlMode={updateKqlMode!}
+ updateKqlMode={updateKqlMode}
updateReduxTime={updateReduxTime}
/>
);
@@ -119,15 +119,19 @@ const makeMapStateToProps = () => {
const policy: inputsModel.Policy = getInputsPolicy(state);
return {
dataProviders: timeline.dataProviders,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
filterQuery: getKqlFilterQuery(state, timelineId)!,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
filters: timeline.filters!,
from: input.timerange.from,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
fromStr: input.timerange.fromStr!,
isRefreshPaused: policy.kind === 'manual',
kqlMode: getOr('filter', 'kqlMode', timeline),
refreshInterval: policy.duration,
savedQueryId: getOr(null, 'savedQueryId', timeline),
to: input.timerange.to,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
toStr: input.timerange.toStr!,
};
};
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.test.tsx
index 44174009d0198..7269c005e9af5 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.test.tsx
@@ -47,7 +47,7 @@ describe('SelectableTimeline', () => {
const searchProps: EuiSelectableProps['searchProps'] = wrapper
.find('[data-test-subj="selectable-input"]')
.prop('searchProps');
- expect(searchProps!.placeholder).toEqual('e.g. Timeline name or description');
+ expect(searchProps?.placeholder).toEqual('e.g. Timeline name or description');
});
});
@@ -65,7 +65,7 @@ describe('SelectableTimeline', () => {
const searchProps: EuiSelectableProps['searchProps'] = wrapper
.find('[data-test-subj="selectable-input"]')
.prop('searchProps');
- expect(searchProps!.placeholder).toEqual('e.g. Timeline template name or description');
+ expect(searchProps?.placeholder).toEqual('e.g. Timeline template name or description');
});
});
});
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx
index 9d10584130194..e4070a051af46 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx
@@ -110,8 +110,8 @@ const SelectableTimelineComponent: React.FC = ({
selectableListOuterRef.current &&
selectableListInnerRef.current
) {
- const clientHeight = selectableListOuterRef.current!.clientHeight;
- const scrollHeight = selectableListInnerRef.current!.clientHeight;
+ const clientHeight = selectableListOuterRef.current.clientHeight;
+ const scrollHeight = selectableListInnerRef.current.clientHeight;
const clientHeightTrigger = clientHeight * 1.2;
if (
scrollOffset > 10 &&
diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx
index 3514766b334a0..af05198ef9974 100644
--- a/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx
+++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/styles.tsx
@@ -271,13 +271,13 @@ export const EventsTrData = styled.div.attrs(({ className = '' }) => ({
const TIMELINE_EVENT_DETAILS_OFFSET = 40;
interface WidthProp {
- width?: number;
+ width: number;
}
export const EventsTrSupplementContainer = styled.div.attrs(({ width }) => ({
role: 'dialog',
style: {
- width: `${width! - TIMELINE_EVENT_DETAILS_OFFSET}px`,
+ width: `${width - TIMELINE_EVENT_DETAILS_OFFSET}px`,
},
}))``;
diff --git a/x-pack/plugins/security_solution/public/timelines/containers/api.ts b/x-pack/plugins/security_solution/public/timelines/containers/api.ts
index 789c942d0e29a..7f74912be09b4 100644
--- a/x-pack/plugins/security_solution/public/timelines/containers/api.ts
+++ b/x-pack/plugins/security_solution/public/timelines/containers/api.ts
@@ -156,6 +156,7 @@ export const persistTimeline = async ({
try {
if (isEmpty(timelineId) && timeline.status === TimelineStatus.draft && timeline) {
const temp: TimelineResponse | TimelineErrorResponse = await cleanDraftTimeline({
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
timelineType: timeline.timelineType!,
templateTimelineId: timeline.templateTimelineId ?? undefined,
templateTimelineVersion: timeline.templateTimelineVersion ?? undefined,
@@ -163,7 +164,7 @@ export const persistTimeline = async ({
const draftTimeline = decodeTimelineResponse(temp);
const templateTimelineInfo =
- timeline.timelineType! === TimelineType.template
+ timeline.timelineType === TimelineType.template
? {
templateTimelineId:
draftTimeline.data.persistTimeline.timeline.templateTimelineId ??
diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts
index 9d95036cb6076..164f293edee65 100644
--- a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts
+++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts
@@ -235,7 +235,7 @@ export const createTimelineEpic =
mergeMap(([result, recentTimeline, allTimelineQuery, kibana]) => {
const error = result as TimelineErrorResponse;
if (error.status_code != null && error.status_code === 405) {
- kibana.notifications!.toasts.addDanger({
+ kibana.notifications.toasts.addDanger({
title: i18n.UPDATE_TIMELINE_ERROR_TITLE,
text: error.message ?? i18n.UPDATE_TIMELINE_ERROR_TEXT,
});
diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts
index eceafb9b56cdd..639d1b1e4f489 100644
--- a/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts
+++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts
@@ -1126,8 +1126,8 @@ describe('Timeline', () => {
const newAndProvider = update.foo.dataProviders[indexProvider].and.find(
(i) => i.id === '456'
);
- expect(oldAndProvider!.enabled).toEqual(false);
- expect(newAndProvider!.enabled).toEqual(true);
+ expect(oldAndProvider?.enabled).toEqual(false);
+ expect(newAndProvider?.enabled).toEqual(true);
});
});
@@ -1386,8 +1386,8 @@ describe('Timeline', () => {
const newAndProvider = update.foo.dataProviders[indexProvider].and.find(
(i) => i.id === '456'
);
- expect(oldAndProvider!.excluded).toEqual(true);
- expect(newAndProvider!.excluded).toEqual(false);
+ expect(oldAndProvider?.excluded).toEqual(true);
+ expect(newAndProvider?.excluded).toEqual(false);
});
});
diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts
index a116311becfe5..cf6665a5dde2b 100644
--- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts
@@ -135,6 +135,7 @@ export class ManifestTask {
}
}
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (oldManifest! == null) {
this.logger.debug('Last computed manifest not available yet');
return;
diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts b/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts
index a1b93b5bd59f7..32d5806a4b47a 100644
--- a/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts
@@ -130,7 +130,7 @@ describe('Policy-Changing license watcher', () => {
expect(packagePolicySvcMock.update).toHaveBeenCalled();
expect(
- packagePolicySvcMock.update.mock.calls[0][3].inputs[0].config!.policy.value.windows.popup
+ packagePolicySvcMock.update.mock.calls[0][3].inputs[0].config?.policy.value.windows.popup
.malware.message
).not.toEqual(CustomMessage);
});
diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts
index 4652630649ffc..e12299bedbb34 100644
--- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts
@@ -189,6 +189,7 @@ export const isolationRequestHandler = function (
},
} as Omit,
user: {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
id: user!.username,
},
};
diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts
index 39aa0bf2d8cf7..9b454a266834c 100644
--- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts
@@ -114,8 +114,8 @@ describe('test document enrichment', () => {
const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx);
expect(enrichedHostList.policy_info).toBeDefined();
- expect(enrichedHostList.policy_info!.agent.applied.id).toEqual(policyID);
- expect(enrichedHostList.policy_info!.agent.applied.revision).toEqual(policyRev);
+ expect(enrichedHostList.policy_info?.agent.applied.id).toEqual(policyID);
+ expect(enrichedHostList.policy_info?.agent.applied.revision).toEqual(policyRev);
});
it('reflects current fleet agent info', async () => {
@@ -130,8 +130,8 @@ describe('test document enrichment', () => {
const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx);
expect(enrichedHostList.policy_info).toBeDefined();
- expect(enrichedHostList.policy_info!.agent.configured.id).toEqual(policyID);
- expect(enrichedHostList.policy_info!.agent.configured.revision).toEqual(policyRev);
+ expect(enrichedHostList.policy_info?.agent.configured.id).toEqual(policyID);
+ expect(enrichedHostList.policy_info?.agent.configured.revision).toEqual(policyRev);
});
it('reflects current endpoint policy info', async () => {
@@ -151,8 +151,8 @@ describe('test document enrichment', () => {
const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx);
expect(enrichedHostList.policy_info).toBeDefined();
- expect(enrichedHostList.policy_info!.endpoint.id).toEqual(policyID);
- expect(enrichedHostList.policy_info!.endpoint.revision).toEqual(policyRev);
+ expect(enrichedHostList.policy_info?.endpoint.id).toEqual(policyID);
+ expect(enrichedHostList.policy_info?.endpoint.revision).toEqual(policyRev);
});
});
});
diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts
index 5c06dbd3db14c..027107bcf1a59 100644
--- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts
@@ -114,6 +114,7 @@ export const getMetadataListRequestHandler = function (
}
const endpointPolicies = await getAllEndpointPackagePolicies(
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
endpointAppContext.service.getPackagePolicyService()!,
context.core.savedObjects.client
);
@@ -344,6 +345,7 @@ export async function enrichHostMetadata(
const status = await metadataRequestContext.endpointAppContextService
?.getAgentService()
?.getAgentStatusById(esClient.asCurrentUser, elasticAgentId);
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
hostStatus = fleetAgentStatusToEndpointHostStatus(status!);
} catch (e) {
if (e instanceof AgentNotFoundError) {
@@ -361,6 +363,7 @@ export async function enrichHostMetadata(
?.getAgent(esClient.asCurrentUser, elasticAgentId);
const agentPolicy = await metadataRequestContext.endpointAppContextService
.getAgentPolicyService()
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
?.get(esSavedObjectClient, agent?.policy_id!, true);
const endpointPolicy = ((agentPolicy?.package_policies || []) as PackagePolicy[]).find(
(policy: PackagePolicy) => policy.package?.name === 'endpoint'
@@ -404,6 +407,7 @@ async function legacyListMetadataQuery(
logger: Logger,
endpointPolicies: PackagePolicy[]
): Promise {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const agentService = endpointAppContext.service.getAgentService()!;
const metadataRequestContext: MetadataRequestContext = {
@@ -512,11 +516,15 @@ async function queryUnitedIndex(
return metadata && agent;
})
.map((doc) => {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const { endpoint: metadata, agent } = doc!._source!.united!;
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const agentPolicy = agentPoliciesMap[agent.policy_id!];
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const endpointPolicy = endpointPoliciesMap[agent.policy_id!];
return {
metadata,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
host_status: fleetAgentStatusToEndpointHostStatus(agent.last_checkin_status!),
policy_info: {
agent: {
diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts
index d9016e7a9c7cb..3e5050c05814a 100644
--- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts
@@ -171,8 +171,8 @@ describe('test endpoint route', () => {
const esSearchMock = mockScopedClient.asCurrentUser.search;
// should be called twice, united index first, then legacy index
expect(esSearchMock).toHaveBeenCalledTimes(2);
- expect(esSearchMock.mock.calls[0][0]!.index).toEqual(METADATA_UNITED_INDEX);
- expect(esSearchMock.mock.calls[1][0]!.index).toEqual(metadataCurrentIndexPattern);
+ expect(esSearchMock.mock.calls[0][0]?.index).toEqual(METADATA_UNITED_INDEX);
+ expect(esSearchMock.mock.calls[1][0]?.index).toEqual(metadataCurrentIndexPattern);
expect(routeConfig.options).toEqual({
authRequired: true,
tags: ['access:securitySolution'],
@@ -224,7 +224,7 @@ describe('test endpoint route', () => {
);
expect(esSearchMock).toHaveBeenCalledTimes(1);
- expect(esSearchMock.mock.calls[0][0]!.index).toEqual(METADATA_UNITED_INDEX);
+ expect(esSearchMock.mock.calls[0][0]?.index).toEqual(METADATA_UNITED_INDEX);
expect(esSearchMock.mock.calls[0][0]?.body?.query).toEqual({
bool: {
must: [
diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts
index 448496671b4f9..7b09013496c6d 100644
--- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts
@@ -53,8 +53,8 @@ export async function kibanaRequestToMetadataListESQuery(
body: {
query: buildQueryBody(
request,
- queryBuilderOptions?.unenrolledAgentIds!,
- queryBuilderOptions?.statusAgentIds!
+ queryBuilderOptions?.unenrolledAgentIds,
+ queryBuilderOptions?.statusAgentIds
),
track_total_hits: true,
sort: MetadataSortMethod,
diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts
index 987bef15afe98..ce46395a1f09f 100644
--- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts
@@ -120,12 +120,14 @@ export async function agentVersionsMap(
const result: Map = new Map();
let hasMore = true;
while (hasMore) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const queryResult = await endpointAppContext.service
.getAgentService()!
.listAgents(esClient, searchOptions(page++));
queryResult.agents.forEach((agent: Agent) => {
const agentVersion = agent.local_metadata?.elastic?.agent?.version;
if (result.has(agentVersion)) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
result.set(agentVersion, result.get(agentVersion)! + 1);
} else {
result.set(agentVersion, 1);
diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/service.ts b/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/service.ts
index 9cefc55eddec4..856a615c1ffa2 100644
--- a/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/service.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/service.ts
@@ -142,6 +142,7 @@ export const getTrustedAppsList = async (
data: results?.data.map(exceptionListItemToTrustedApp) ?? [],
total: results?.total ?? 0,
page: results?.page ?? 1,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
per_page: results?.per_page ?? perPage!,
};
};
@@ -262,6 +263,7 @@ export const getTrustedAppsSummary = async (
let page = 1;
while (paging) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const { data, total } = (await exceptionsListClient.findExceptionListItem({
listId: ENDPOINT_TRUSTED_APPS_LIST_ID,
page,
diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions.ts
index a04a6eea5ab65..711d78ba51b59 100644
--- a/x-pack/plugins/security_solution/server/endpoint/services/actions.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/services/actions.ts
@@ -200,6 +200,7 @@ export const getPendingActionCounts = async (
},
{ ignore: [404] }
)
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.then((result) => result.body?.hits?.hits?.map((a) => a._source!) || [])
.catch(catchAndWrapError);
@@ -272,6 +273,7 @@ const fetchActionResponseIds = async (
},
{ ignore: [404] }
)
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.then((result) => result.body?.hits?.hits?.map((a) => a._source!) || [])
.catch(catchAndWrapError);
diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/artifact_client.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/artifact_client.ts
index ac19757e037b2..062702bb14a49 100644
--- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/artifact_client.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/artifact_client.ts
@@ -37,6 +37,7 @@ export class EndpointArtifactClient implements EndpointArtifactClientInterface {
return {
type: idPieces[1],
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
decodedSha256: idPieces.pop()!,
identifier: idPieces.join('-'),
};
@@ -74,7 +75,7 @@ export class EndpointArtifactClient implements EndpointArtifactClientInterface {
async deleteArtifact(id: string) {
// Ignoring the `id` not being in the type until we can refactor the types in endpoint.
- // @ts-ignore
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const artifactId = (await this.getArtifact(id))?.id!;
return this.fleetArtifacts.deleteArtifact(artifactId);
}
diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.mock.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.mock.ts
index 87a73e0130113..a7fb5dc23877c 100644
--- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.mock.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.mock.ts
@@ -42,14 +42,14 @@ export const mockFindExceptionListItemResponses = (
responses: Record>
) => {
return jest.fn().mockImplementation((options: FindExceptionListItemOptions) => {
- const matches = options.filter!.match(FILTER_REGEXP) || [];
+ const matches = options.filter?.match(FILTER_REGEXP) || [];
- if (matches[4] && responses[options.listId]?.[`${matches![1]}-${matches[4]}`]) {
+ if (matches[4] && responses[options.listId]?.[`${matches?.[1]}-${matches[4]}`]) {
return createExceptionListResponse(
- responses[options.listId]?.[`${matches![1]}-${matches[4]}`] || []
+ responses[options.listId]?.[`${matches?.[1]}-${matches[4]}`] || []
);
} else {
- return createExceptionListResponse(responses[options.listId]?.[matches![1] || ''] || []);
+ return createExceptionListResponse(responses[options.listId]?.[matches?.[1] || ''] || []);
}
});
};
diff --git a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts
index 5e2f46aa4c285..23c21e431a344 100644
--- a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts
@@ -171,6 +171,7 @@ export class EndpointMetadataService {
// Get Agent Policy and Endpoint Package Policy
if (fleetAgent) {
try {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
fleetAgentPolicy = await this.getFleetAgentPolicy(fleetAgent.policy_id!);
endpointPackagePolicy = fleetAgentPolicy.package_policies.find(
(policy) => policy.package?.name === 'endpoint'
@@ -183,7 +184,8 @@ export class EndpointMetadataService {
return {
metadata: endpointMetadata,
host_status: fleetAgent
- ? fleetAgentStatusToEndpointHostStatus(fleetAgent.status!)
+ ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ fleetAgentStatusToEndpointHostStatus(fleetAgent.status!)
: DEFAULT_ENDPOINT_HOST_STATUS,
policy_info: {
agent: {
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts
index f9693c87631b7..8914e8eec87d0 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts
@@ -94,7 +94,7 @@ export const createMigration = async ({
return {
destinationIndex: migrationIndex,
sourceIndex: index,
- taskId: String(response.body.task!),
+ taskId: String(response.body.task),
version,
};
};
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts
index 61635fdcef9f0..6ec23c32e4976 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts
@@ -58,7 +58,7 @@ export const createIndexRoute = (
if (!siemClient) {
return siemResponse.error({ statusCode: 404 });
}
- await createDetectionIndex(context, siemClient!, ruleDataService, ruleRegistryEnabled);
+ await createDetectionIndex(context, siemClient, ruleDataService, ruleRegistryEnabled);
return response.ok({ body: { acknowledged: true } });
} catch (err) {
const error = transformError(err);
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts
index 48efcc4495aff..26e09d69d3a45 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts
@@ -124,7 +124,7 @@ describe.each([
});
test('returns 404 if rulesClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const request = addPrepackagedRulesRequest();
const response = await server.inject(request, context);
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts
index 2c8696dbd4554..6f721bb2bb9c5 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts
@@ -55,7 +55,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getReadBulkRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts
index d1be96a44930a..59fe5c0ff68a1 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts
@@ -56,7 +56,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getCreateRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts
index 7db5651de2c34..49580fc09ca63 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts
@@ -84,7 +84,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getDeleteBulkRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts
index 7c447660acb45..466012a045eb3 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts
@@ -65,7 +65,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getDeleteRequest(), context);
expect(response.status).toEqual(404);
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts
index 7ae3f56b6fea9..0b0650d48872f 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts
@@ -48,7 +48,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getFindRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_status_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_status_route.test.ts
index 053e0b7178de5..5d6b9810a2cda 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_status_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_status_route.test.ts
@@ -41,7 +41,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(ruleStatusRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts
index 78572863f7472..e97744a5fe5a8 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts
@@ -100,7 +100,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getPrepackagedRulesStatusRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts
index bf29dbe870153..aa301bcc0335e 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts
@@ -77,7 +77,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(request, context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts
index 2c3db023dccc4..d0d5937eab2d7 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts
@@ -89,7 +89,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getPatchBulkRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts
index 97773c45ce0d9..00d7180dfc9be 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts
@@ -69,7 +69,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getPatchRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts
index ebc86acc964e6..41b909bd718c0 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts
@@ -65,7 +65,7 @@ describe.each([
});
it('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getBulkActionRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts
index 37b8228ac1e9b..bc9fa43b56ae7 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts
@@ -86,7 +86,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getReadRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts
index 746a40dfa8dc2..f7bef76944a97 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts
@@ -65,7 +65,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getUpdateBulkRequest(), context);
expect(response.status).toEqual(404);
expect(response.body).toEqual({ message: 'Not Found', status_code: 404 });
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts
index 5b3e2737418c2..7d611f3cccbf2 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts
@@ -66,7 +66,7 @@ describe.each([
});
test('returns 404 if alertClient is not available on the route', async () => {
- context.alerting!.getRulesClient = jest.fn();
+ context.alerting.getRulesClient = jest.fn();
const response = await server.inject(getUpdateRequest(), context);
expect(response.status).toEqual(404);
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts
index 279a824426cec..e2be04fc6e7df 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts
@@ -51,7 +51,7 @@ export const querySignalsRoute = (router: SecuritySolutionPluginRouter, config:
});
}
const esClient = context.core.elasticsearch.client.asCurrentUser;
- const siemClient = context.securitySolution!.getAppClient();
+ const siemClient = context.securitySolution.getAppClient();
// TODO: Once we are past experimental phase this code should be removed
const { ruleRegistryEnabled } = parseExperimentalConfigValue(config.enableExperimental);
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_event_type_signal.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_event_type_signal.ts
index d22ca0d1f5090..0dd2acfb88ffe 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_event_type_signal.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_event_type_signal.ts
@@ -8,8 +8,8 @@ import { BaseSignalHit, SimpleHit } from './types';
import { getField } from './utils';
export const buildEventTypeSignal = (doc: BaseSignalHit): object => {
- if (doc._source?.event != null && doc._source?.event instanceof Object) {
- return { ...doc._source!.event, kind: 'signal' };
+ if (doc._source != null && doc._source.event instanceof Object) {
+ return { ...doc._source.event, kind: 'signal' };
} else {
return { kind: 'signal' };
}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts
index bd5444a325128..012977da2a00f 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts
@@ -108,7 +108,7 @@ describe('buildRuleWithOverrides', () => {
test('it applies rule name override in buildRule', () => {
const ruleSO = sampleRuleSO(getQueryRuleParams());
ruleSO.attributes.params.ruleNameOverride = 'someKey';
- const rule = buildRuleWithOverrides(ruleSO, sampleDocNoSortId()._source!);
+ const rule = buildRuleWithOverrides(ruleSO, sampleDocNoSortId()._source);
const expected = {
...expectedRule(),
name: 'someValue',
@@ -135,7 +135,7 @@ describe('buildRuleWithOverrides', () => {
];
const doc = sampleDocNoSortId();
doc._source.new_risk_score = newRiskScore;
- const rule = buildRuleWithOverrides(ruleSO, doc._source!);
+ const rule = buildRuleWithOverrides(ruleSO, doc._source);
const expected = {
...expectedRule(),
risk_score: newRiskScore,
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts
index 9da5934489023..272c3f64fb105 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/enrich_signal_threat_matches.ts
@@ -107,7 +107,7 @@ export const enrichSignalThreatMatches = async (
return {
...signalHit,
_source: {
- ...signalHit._source!,
+ ...signalHit._source,
threat: {
...threat,
enrichments: [...existingEnrichments, ...enrichments[i]],
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.ts
index 31bf7674b4f92..c202065176ff1 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.ts
@@ -116,6 +116,7 @@ const getTransformedHits = (
? [
{
field: threshold.cardinality[0].field,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
value: bucket.cardinality_count!.value,
},
]
@@ -131,6 +132,7 @@ const getTransformedHits = (
};
return getCombinations(
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
(results.aggregations![aggParts.name] as { buckets: TermAggregationBucket[] }).buckets,
0,
aggParts.field
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/get_threshold_bucket_filters.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/get_threshold_bucket_filters.ts
index 5cafff24c544b..610be59deaa5f 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/get_threshold_bucket_filters.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/get_threshold_bucket_filters.ts
@@ -40,6 +40,7 @@ export const getThresholdBucketFilters = async ({
// Terms to filter events older than `lastSignalTimestamp`.
bucket.terms.forEach((term) => {
if (term.field != null) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
(filter.bool!.filter as ESFilter[]).push({
term: {
[term.field]: `${term.value}`,
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts
index 7d2eafa46d382..0e50db97d1256 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts
@@ -1277,7 +1277,7 @@ describe('utils', () => {
test('It returns timestampOverride date time if set', () => {
const override = '2020-10-07T19:20:28.049Z';
const searchResult = sampleDocSearchResultsNoSortId();
- searchResult.hits.hits[0]._source!.different_timestamp = new Date(override).toISOString();
+ searchResult.hits.hits[0]._source.different_timestamp = new Date(override).toISOString();
const date = lastValidDate({ searchResult, timestampOverride: 'different_timestamp' });
expect(date?.toISOString()).toEqual(override);
});
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts
index 2aefc7ea0bd64..79b36cf62573a 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts
@@ -874,6 +874,7 @@ export const mergeSearchResults = (searchResults: SignalSearchResponse[]) => {
aggregations: newAggregations,
hits: {
total: calculateTotal(prev.hits.total, next.hits.total),
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
max_score: Math.max(newHits.max_score!, existingHits.max_score!),
hits: [...existingHits.hits, ...newHits.hits],
},
diff --git a/x-pack/plugins/security_solution/server/lib/timeline/utils/check_timelines_status.ts b/x-pack/plugins/security_solution/server/lib/timeline/utils/check_timelines_status.ts
index 560df1112ac58..f524d0c7ca3a6 100644
--- a/x-pack/plugins/security_solution/server/lib/timeline/utils/check_timelines_status.ts
+++ b/x-pack/plugins/security_solution/server/lib/timeline/utils/check_timelines_status.ts
@@ -40,6 +40,7 @@ export const getTimelinesToUpdate = (
installedTimelines.some((installedTimeline) => {
return (
timeline.templateTimelineId === installedTimeline.templateTimelineId &&
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
timeline.templateTimelineVersion! > installedTimeline.templateTimelineVersion!
);
})
diff --git a/x-pack/plugins/security_solution/server/lib/timeline/utils/failure_cases.ts b/x-pack/plugins/security_solution/server/lib/timeline/utils/failure_cases.ts
index 99365a55a1d61..44f16c57ad2b4 100644
--- a/x-pack/plugins/security_solution/server/lib/timeline/utils/failure_cases.ts
+++ b/x-pack/plugins/security_solution/server/lib/timeline/utils/failure_cases.ts
@@ -227,7 +227,7 @@ export const checkIsUpdateViaImportFailureCases = (
return { body: UPDAT_TIMELINE_VIA_IMPORT_NOT_ALLOWED_ERROR_MESSAGE, statusCode: 405 };
} else {
return {
- body: getImportExistingTimelineError(existTimeline!.savedObjectId),
+ body: getImportExistingTimelineError(existTimeline.savedObjectId),
statusCode: 405,
};
}
diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts
index 7ae4eea4c4700..a6ccc0f5569fb 100644
--- a/x-pack/plugins/security_solution/server/plugin.ts
+++ b/x-pack/plugins/security_solution/server/plugin.ts
@@ -361,6 +361,7 @@ export class Plugin implements IPlugin {
ignoreUnavailable: true,
index: ['filebeat-*'],
});
- const parsedInspect = JSON.parse(parsedResponse.inspect!.dsl[0]);
+ const parsedInspect = JSON.parse(parsedResponse.inspect.dsl[0]);
expect(parsedInspect).toEqual(expectedInspect);
});
diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/helpers.ts
index c96e0040fd23d..ae68d81d6b922 100644
--- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/helpers.ts
+++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/details/helpers.ts
@@ -223,6 +223,7 @@ export const getHostEndpoint = async (
endpointPolicy: endpointData.Endpoint.policy.applied.name,
policyStatus: endpointData.Endpoint.policy.applied.status,
sensorVersion: endpointData.agent.version,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
elasticAgentStatus: fleetAgentStatusToEndpointHostStatus(fleetAgentStatus!),
isolation: endpointData.Endpoint.state?.isolation ?? false,
pendingActions,
diff --git a/x-pack/plugins/spaces/server/config.ts b/x-pack/plugins/spaces/server/config.ts
index 4abaf4f0ca569..a8c3a1c6223da 100644
--- a/x-pack/plugins/spaces/server/config.ts
+++ b/x-pack/plugins/spaces/server/config.ts
@@ -28,6 +28,7 @@ export function createConfig$(context: PluginInitializerContext) {
const disabledDeprecation: ConfigDeprecation = (config, fromPath, addDeprecation) => {
if ('enabled' in (config?.xpack?.spaces || {})) {
addDeprecation({
+ configPath: 'xpack.spaces.enabled',
title: i18n.translate('xpack.spaces.deprecations.enabledTitle', {
defaultMessage: 'Setting "xpack.spaces.enabled" is deprecated',
}),
diff --git a/x-pack/plugins/stack_alerts/server/index.ts b/x-pack/plugins/stack_alerts/server/index.ts
index 9491f3e646c70..1ac774a2d6c3f 100644
--- a/x-pack/plugins/stack_alerts/server/index.ts
+++ b/x-pack/plugins/stack_alerts/server/index.ts
@@ -18,6 +18,7 @@ export const config: PluginConfigDescriptor = {
const stackAlerts = get(settings, fromPath);
if (stackAlerts?.enabled === false || stackAlerts?.enabled === true) {
addDeprecation({
+ configPath: 'xpack.stack_alerts.enabled',
message: `"xpack.stack_alerts.enabled" is deprecated. The ability to disable this plugin will be removed in 8.0.0.`,
correctiveActions: {
manualSteps: [`Remove "xpack.stack_alerts.enabled" from your kibana configs.`],
diff --git a/x-pack/plugins/task_manager/server/index.ts b/x-pack/plugins/task_manager/server/index.ts
index 84bee044c4de9..2a360fc1a1d90 100644
--- a/x-pack/plugins/task_manager/server/index.ts
+++ b/x-pack/plugins/task_manager/server/index.ts
@@ -49,6 +49,7 @@ export const config: PluginConfigDescriptor = {
const taskManager = get(settings, fromPath);
if (taskManager?.index) {
addDeprecation({
+ configPath: `${fromPath}.index`,
documentationUrl: 'https://ela.st/kbn-remove-legacy-multitenancy',
message: `"${fromPath}.index" is deprecated. Multitenancy by changing "kibana.index" will not be supported starting in 8.0. See https://ela.st/kbn-remove-legacy-multitenancy for more details`,
correctiveActions: {
@@ -61,6 +62,7 @@ export const config: PluginConfigDescriptor = {
}
if (taskManager?.max_workers > MAX_WORKERS_LIMIT) {
addDeprecation({
+ configPath: `${fromPath}.max_workers`,
message: `setting "${fromPath}.max_workers" (${taskManager?.max_workers}) greater than ${MAX_WORKERS_LIMIT} is deprecated. Values greater than ${MAX_WORKERS_LIMIT} will not be supported starting in 8.0.`,
correctiveActions: {
manualSteps: [
@@ -75,6 +77,7 @@ export const config: PluginConfigDescriptor = {
const taskManager = get(settings, fromPath);
if (taskManager?.enabled === false || taskManager?.enabled === true) {
addDeprecation({
+ configPath: 'xpack.task_manager.enabled',
message: `"xpack.task_manager.enabled" is deprecated. The ability to disable this plugin will be removed in 8.0.0.`,
correctiveActions: {
manualSteps: [`Remove "xpack.task_manager.enabled" from your kibana configs.`],
diff --git a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx
index af19a6b7cdb74..30181a96aa70b 100644
--- a/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx
+++ b/x-pack/plugins/timelines/public/components/actions/timeline/cases/add_to_existing_case_button.tsx
@@ -32,7 +32,7 @@ const AddToCaseActionComponent: React.FC = ({
{userCanCrud && (
= ({
{userCanCrud && (
{
};
export const getHoverActions = (store?: Store): HoverActionsConfig => ({
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
getAddToTimelineButton: getAddToTimelineButtonLazy.bind(null, store!),
getColumnToggleButton: getColumnToggleButtonLazy,
getCopyButton: getCopyButtonLazy,
diff --git a/x-pack/plugins/timelines/public/components/index.tsx b/x-pack/plugins/timelines/public/components/index.tsx
index 9959574464836..0ff8c9bf97e8b 100644
--- a/x-pack/plugins/timelines/public/components/index.tsx
+++ b/x-pack/plugins/timelines/public/components/index.tsx
@@ -41,6 +41,7 @@ export const TGrid = (props: TGridComponent) => {
browserFields = (tGridProps as TGridIntegratedProps).browserFields;
}
return (
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/index.tsx
index b973d99584d61..91dd64d8fed3a 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/index.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/body/column_headers/header_tooltip_content/index.tsx
@@ -61,7 +61,7 @@ export const HeaderToolTipContent = React.memo<{ header: ColumnHeaderOptions }>(
{':'}
-
+
{header.type}
diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/events/stateful_event.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/events/stateful_event.tsx
index f448ba3831b14..d746368e389c8 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/body/events/stateful_event.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/body/events/stateful_event.tsx
@@ -122,6 +122,7 @@ const StatefulEventComponent: React.FC = ({
const handleOnEventDetailPanelOpened = useCallback(() => {
const eventId = event._id;
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const indexName = event._index!;
const updatedExpandedDetail: TimelineExpandedDetailType = {
diff --git a/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx b/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx
index 02c3d10a76058..e2eb1d4d04547 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx
@@ -192,6 +192,7 @@ export const buildCombinedQuery = (combineQueriesParams: CombineQueries) => {
const combinedQuery = combineQueries(combineQueriesParams);
return combinedQuery
? {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
filterQuery: replaceStatusField(combinedQuery!.filterQuery),
}
: null;
diff --git a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx
index b649dc36abe0a..e363297d04be5 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx
@@ -237,7 +237,7 @@ const TGridIntegratedComponent: React.FC = ({
endDate: end,
entityType,
fields,
- filterQuery: combinedQueries!.filterQuery,
+ filterQuery: combinedQueries?.filterQuery,
id,
indexNames,
limit: itemsPerPage,
diff --git a/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx
index 1a374d0c6b87a..ae092d8634bb7 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx
@@ -217,7 +217,7 @@ const TGridStandaloneComponent: React.FC = ({
entityType,
excludeEcsData: true,
fields,
- filterQuery: combinedQueries!.filterQuery,
+ filterQuery: combinedQueries?.filterQuery,
id: STANDALONE_ID,
indexNames,
limit: itemsPerPageStore,
diff --git a/x-pack/plugins/timelines/public/components/t_grid/styles.tsx b/x-pack/plugins/timelines/public/components/t_grid/styles.tsx
index 28e425f53824b..9f957e2c61910 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/styles.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/styles.tsx
@@ -270,13 +270,13 @@ export const EventsTrData = styled.div.attrs(({ className = '' }) => ({
const TIMELINE_EVENT_DETAILS_OFFSET = 40;
interface WidthProp {
- width?: number;
+ width: number;
}
export const EventsTrSupplementContainer = styled.div.attrs(({ width }) => ({
role: 'dialog',
style: {
- width: `${width! - TIMELINE_EVENT_DETAILS_OFFSET}px`,
+ width: `${width - TIMELINE_EVENT_DETAILS_OFFSET}px`,
},
}))``;
diff --git a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.test.tsx
index e44ee1d45d19b..e19499628e8c1 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.test.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/field_browser.test.tsx
@@ -235,7 +235,7 @@ describe('FieldsBrowser', () => {
expect(
wrapper.find('[data-test-subj="field-search"]').first().getDOMNode().id ===
- document.activeElement!.id
+ document.activeElement?.id
).toBe(true);
});
@@ -266,7 +266,7 @@ describe('FieldsBrowser', () => {
const changeEvent: any = { target: { value: inputText } };
const onChange = searchField.props().onChange;
- onChange!(changeEvent);
+ onChange?.(changeEvent);
searchField.simulate('change').update();
expect(onSearchInputChange).toBeCalledWith(inputText);
diff --git a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/helpers.tsx b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/helpers.tsx
index f4b608b456fed..552c228363e49 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/helpers.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/helpers.tsx
@@ -97,6 +97,7 @@ export const filterBrowserFieldsByFieldName = ({
fields: filter(
(f) => f.name != null && f.name.includes(trimmedSubstring),
browserFields[categoryId].fields
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
).reduce((filtered, field) => ({ ...filtered, [field.name!]: field }), {}),
},
}),
diff --git a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/index.tsx
index bdec76418dc8c..0b67f53cca76e 100644
--- a/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/index.tsx
+++ b/x-pack/plugins/timelines/public/components/t_grid/toolbar/fields_browser/index.tsx
@@ -100,7 +100,9 @@ export const StatefulFieldsBrowserComponent: React.FC = ({
(selected, category) =>
newFilteredBrowserFields[category].fields != null &&
newFilteredBrowserFields[selected].fields != null &&
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Object.keys(newFilteredBrowserFields[category].fields!).length >
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Object.keys(newFilteredBrowserFields[selected].fields!).length
? category
: selected,
diff --git a/x-pack/plugins/timelines/public/components/utils/helpers.ts b/x-pack/plugins/timelines/public/components/utils/helpers.ts
index f02c86aecc108..23f92c119d574 100644
--- a/x-pack/plugins/timelines/public/components/utils/helpers.ts
+++ b/x-pack/plugins/timelines/public/components/utils/helpers.ts
@@ -53,7 +53,7 @@ export const getColumnsWithTimestamp = ({
: [];
};
-export const getIconFromType = (type: string | null) => {
+export const getIconFromType = (type: string | null | undefined) => {
switch (type) {
case 'string': // fall through
case 'keyword':
diff --git a/x-pack/plugins/timelines/public/container/use_update_alerts.ts b/x-pack/plugins/timelines/public/container/use_update_alerts.ts
index b38c3b9a71fef..1b9e6218eecca 100644
--- a/x-pack/plugins/timelines/public/container/use_update_alerts.ts
+++ b/x-pack/plugins/timelines/public/container/use_update_alerts.ts
@@ -17,7 +17,7 @@ import {
/**
* Update alert status by query
- *
+ *
* @param useDetectionEngine logic flag for using the regular Detection Engine URL or the RAC URL
*
* @param status to update to('open' / 'closed' / 'acknowledged')
@@ -40,7 +40,7 @@ export const useUpdateAlertsStatus = (
return {
updateAlertStatus: async ({ status, index, query }) => {
if (useDetectionEngine) {
- return http!.fetch(DETECTION_ENGINE_SIGNALS_STATUS_URL, {
+ return http.fetch(DETECTION_ENGINE_SIGNALS_STATUS_URL, {
method: 'POST',
body: JSON.stringify({ status, query }),
});
diff --git a/x-pack/plugins/timelines/public/plugin.ts b/x-pack/plugins/timelines/public/plugin.ts
index 4b383ce392147..acb7b26d0cf84 100644
--- a/x-pack/plugins/timelines/public/plugin.ts
+++ b/x-pack/plugins/timelines/public/plugin.ts
@@ -45,7 +45,7 @@ export class TimelinesPlugin implements Plugin {
}
return {
getHoverActions: () => {
- return getHoverActions(this._store!);
+ return getHoverActions(this._store);
},
getTGrid: (props: TGridProps) => {
if (props.type === 'standalone' && this._store) {
@@ -73,6 +73,7 @@ export class TimelinesPlugin implements Plugin {
},
getFieldBrowser: (props: FieldBrowserProps) => {
return getFieldsBrowserLazy(props, {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
store: this._store!,
});
},
@@ -90,6 +91,7 @@ export class TimelinesPlugin implements Plugin {
},
getAddToCaseAction: (props) => {
return getAddToCaseLazy(props, {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
store: this._store!,
storage: this._storage,
setStore: this.setStore.bind(this),
@@ -97,6 +99,7 @@ export class TimelinesPlugin implements Plugin {
},
getAddToCasePopover: (props) => {
return getAddToCasePopoverLazy(props, {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
store: this._store!,
storage: this._storage,
setStore: this.setStore.bind(this),
@@ -104,6 +107,7 @@ export class TimelinesPlugin implements Plugin {
},
getAddToExistingCaseButton: (props) => {
return getAddToExistingCaseButtonLazy(props, {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
store: this._store!,
storage: this._storage,
setStore: this.setStore.bind(this),
@@ -111,6 +115,7 @@ export class TimelinesPlugin implements Plugin {
},
getAddToNewCaseButton: (props) => {
return getAddToNewCaseButtonLazy(props, {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
store: this._store!,
storage: this._storage,
setStore: this.setStore.bind(this),
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 118b99b7cb8ef..a563079a101c3 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -10843,7 +10843,6 @@
"xpack.fleet.epm.detailsTitle": "詳細",
"xpack.fleet.epm.errorLoadingNotice": "NOTICE.txtの読み込みエラー",
"xpack.fleet.epm.featuresLabel": "機能",
- "xpack.fleet.epm.illustrationAltText": "統合の例",
"xpack.fleet.epm.install.packageInstallError": "{pkgName} {pkgVersion}のインストールエラー",
"xpack.fleet.epm.install.packageUpdateError": "{pkgName} {pkgVersion}の更新エラー",
"xpack.fleet.epm.licenseLabel": "ライセンス",
@@ -10878,7 +10877,6 @@
"xpack.fleet.epm.usedByLabel": "エージェントポリシー",
"xpack.fleet.epm.versionLabel": "バージョン",
"xpack.fleet.epmList.allPackagesFilterLinkText": "すべて",
- "xpack.fleet.epmList.allTitle": "カテゴリで参照",
"xpack.fleet.epmList.installedTitle": "インストールされている統合",
"xpack.fleet.epmList.missingIntegrationPlaceholder": "検索用語と一致する統合が見つかりませんでした。別のキーワードを試すか、左側のカテゴリを使用して参照してください。",
"xpack.fleet.epmList.noPackagesFoundPlaceholder": "パッケージが見つかりません",
@@ -10952,12 +10950,10 @@
"xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "注:",
"xpack.fleet.hostsInput.addRow": "行の追加",
"xpack.fleet.initializationErrorMessageTitle": "Fleet を初期化できません",
- "xpack.fleet.integrations.beatsModulesLink": "Beatsモジュール",
"xpack.fleet.integrations.customInputsLink": "カスタム入力",
"xpack.fleet.integrations.discussForumLink": "ディスカッションフォーラム",
"xpack.fleet.integrations.installPackage.installingPackageButtonLabel": "{title} アセットをインストールしています",
"xpack.fleet.integrations.installPackage.installPackageButtonLabel": "{title}アセットをインストール",
- "xpack.fleet.integrations.missing": "統合が表示されない場合{customInputsLink}を使用してログまたはメトリックを収集するか、{beatsTutorialLink}を使用してデータを追加してください。{discussForumLink}を使用して新しい統合を要求してください。",
"xpack.fleet.integrations.packageInstallErrorDescription": "このパッケージのインストール中に問題が発生しました。しばらくたってから再試行してください。",
"xpack.fleet.integrations.packageInstallErrorTitle": "{title}パッケージをインストールできませんでした",
"xpack.fleet.integrations.packageInstallSuccessDescription": "正常に{title}をインストールしました",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index c9924169a2eaa..4781e206cac20 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -10958,7 +10958,6 @@
"xpack.fleet.epm.detailsTitle": "详情",
"xpack.fleet.epm.errorLoadingNotice": "加载 NOTICE.txt 时出错",
"xpack.fleet.epm.featuresLabel": "功能",
- "xpack.fleet.epm.illustrationAltText": "集成的图示",
"xpack.fleet.epm.install.packageInstallError": "安装 {pkgName} {pkgVersion} 时出错",
"xpack.fleet.epm.install.packageUpdateError": "将 {pkgName} 更新到 {pkgVersion} 时出错",
"xpack.fleet.epm.licenseLabel": "许可证",
@@ -10993,7 +10992,6 @@
"xpack.fleet.epm.usedByLabel": "代理策略",
"xpack.fleet.epm.versionLabel": "版本",
"xpack.fleet.epmList.allPackagesFilterLinkText": "全部",
- "xpack.fleet.epmList.allTitle": "按类别浏览",
"xpack.fleet.epmList.installedTitle": "已安装集成",
"xpack.fleet.epmList.missingIntegrationPlaceholder": "我们未找到任何匹配搜索词的集成。请重试其他关键字,或使用左侧的类别浏览。",
"xpack.fleet.epmList.noPackagesFoundPlaceholder": "未找到任何软件包",
@@ -11067,12 +11065,10 @@
"xpack.fleet.homeIntegration.tutorialModule.noticeText.notePrefix": "注意:",
"xpack.fleet.hostsInput.addRow": "添加行",
"xpack.fleet.initializationErrorMessageTitle": "无法初始化 Fleet",
- "xpack.fleet.integrations.beatsModulesLink": "Beats 模板",
"xpack.fleet.integrations.customInputsLink": "定制输入",
"xpack.fleet.integrations.discussForumLink": "讨论论坛",
"xpack.fleet.integrations.installPackage.installingPackageButtonLabel": "正在安装 {title} 资产",
"xpack.fleet.integrations.installPackage.installPackageButtonLabel": "安装 {title} 资产",
- "xpack.fleet.integrations.missing": "未看到集成?使用我们的{customInputsLink}收集任何日志或指标或使用 {beatsTutorialLink} 添加数据。使用{discussForumLink}请求新的集成。",
"xpack.fleet.integrations.packageInstallErrorDescription": "尝试安装此软件包时出现问题。请稍后重试。",
"xpack.fleet.integrations.packageInstallErrorTitle": "无法安装 {title} 软件包",
"xpack.fleet.integrations.packageInstallSuccessDescription": "已成功安装 {title}",
diff --git a/x-pack/plugins/triggers_actions_ui/server/index.ts b/x-pack/plugins/triggers_actions_ui/server/index.ts
index c7d363af45247..72ca584250d03 100644
--- a/x-pack/plugins/triggers_actions_ui/server/index.ts
+++ b/x-pack/plugins/triggers_actions_ui/server/index.ts
@@ -31,6 +31,7 @@ export const config: PluginConfigDescriptor = {
const triggersActionsUi = get(settings, fromPath);
if (triggersActionsUi?.enabled === false || triggersActionsUi?.enabled === true) {
addDeprecation({
+ configPath: 'xpack.trigger_actions_ui.enabled',
message: `"xpack.trigger_actions_ui.enabled" is deprecated. The ability to disable this plugin will be removed in 8.0.0.`,
correctiveActions: {
manualSteps: [`Remove "xpack.trigger_actions_ui.enabled" from your kibana configs.`],
diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/service.mock.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/service.mock.ts
index 1767143fdf527..6a3d376acecab 100644
--- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/service.mock.ts
+++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/kibana_deprecations/service.mock.ts
@@ -22,6 +22,7 @@ const kibanaDeprecations: DomainDeprecationDetails[] = [
title: 'Test deprecation title 1',
message: 'Test deprecation message 1',
deprecationType: 'config',
+ configPath: 'test',
},
{
correctiveActions: {
diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx
index 23697b00923c8..013f59a7dcf56 100644
--- a/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx
+++ b/x-pack/plugins/upgrade_assistant/public/application/components/kibana_deprecations/kibana_deprecations.tsx
@@ -75,10 +75,10 @@ export interface DeprecationResolutionState {
resolveDeprecationError?: string;
}
-export interface KibanaDeprecationDetails extends DomainDeprecationDetails {
+export type KibanaDeprecationDetails = DomainDeprecationDetails & {
id: string;
filterType: DomainDeprecationDetails['deprecationType'] | 'uncategorized';
-}
+};
const getDeprecationCountByLevel = (deprecations: KibanaDeprecationDetails[]) => {
const criticalDeprecations: KibanaDeprecationDetails[] = [];
diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/fix_issues_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/fix_issues_step.tsx
index b061ab5ea2d4d..590bfac96770d 100644
--- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/fix_issues_step.tsx
+++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_issues_step/fix_issues_step.tsx
@@ -70,7 +70,7 @@ export const getFixIssuesStep = ({
diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_count.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_count.tsx
index 3312508a87073..32d214f0d80f2 100644
--- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_count.tsx
+++ b/x-pack/plugins/upgrade_assistant/public/application/components/shared/deprecation_count.tsx
@@ -6,10 +6,11 @@
*/
import React, { FunctionComponent } from 'react';
-
import { EuiFlexGroup, EuiFlexItem, EuiHealth } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
+import { LevelInfoTip } from './level_info_tip';
+
const i18nTexts = {
getCriticalStatusLabel: (count: number) =>
i18n.translate('xpack.upgradeAssistant.deprecationCount.criticalStatusLabel', {
@@ -39,14 +40,31 @@ export const DeprecationCount: FunctionComponent = ({
return (
-
- {i18nTexts.getCriticalStatusLabel(totalCriticalDeprecations)}
-
+
+
+
+ {i18nTexts.getCriticalStatusLabel(totalCriticalDeprecations)}
+
+
+
+
+
+
+
+
-
- {i18nTexts.getWarningStatusLabel(totalWarningDeprecations)}
-
+
+
+
+ {i18nTexts.getWarningStatusLabel(totalWarningDeprecations)}
+
+
+
+
+
+
+
);
diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts
index 57793cbfb2dd6..34496e1e8eb55 100644
--- a/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts
+++ b/x-pack/plugins/upgrade_assistant/public/application/components/shared/index.ts
@@ -10,3 +10,4 @@ export { DeprecationCount } from './deprecation_count';
export { DeprecationBadge } from './deprecation_badge';
export { DeprecationsPageLoadingError } from './deprecations_page_loading_error';
export { DeprecationFlyoutLearnMoreLink } from './deprecation_flyout_learn_more_link';
+export { LevelInfoTip } from './level_info_tip';
diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/shared/level_info_tip.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/shared/level_info_tip.tsx
new file mode 100644
index 0000000000000..d3600a7290b4e
--- /dev/null
+++ b/x-pack/plugins/upgrade_assistant/public/application/components/shared/level_info_tip.tsx
@@ -0,0 +1,27 @@
+/*
+ * 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, { FunctionComponent } from 'react';
+import { i18n } from '@kbn/i18n';
+import { EuiIconTip } from '@elastic/eui';
+
+const i18nTexts = {
+ critical: i18n.translate('xpack.upgradeAssistant.levelInfoTip.criticalLabel', {
+ defaultMessage: 'Critical issues must be resolved before you upgrade',
+ }),
+ warning: i18n.translate('xpack.upgradeAssistant.levelInfoTip.warningLabel', {
+ defaultMessage: 'Warning issues can be ignored at your discretion',
+ }),
+};
+
+interface Props {
+ level: 'critical' | 'warning';
+}
+
+export const LevelInfoTip: FunctionComponent = ({ level }) => {
+ return ;
+};
diff --git a/x-pack/plugins/upgrade_assistant/server/lib/kibana_status.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/kibana_status.test.ts
index 63532543a418b..296a313abef38 100644
--- a/x-pack/plugins/upgrade_assistant/server/lib/kibana_status.test.ts
+++ b/x-pack/plugins/upgrade_assistant/server/lib/kibana_status.test.ts
@@ -20,7 +20,7 @@ const mockKibanaDeprecations: DomainDeprecationDetails[] = [
'Using Kibana role-mapping management, change all role-mappings which assing the kibana_user role to the kibana_admin role.',
],
},
- deprecationType: 'config',
+ deprecationType: 'feature',
documentationUrl: 'testDocUrl',
level: 'critical',
message: 'testMessage',
diff --git a/x-pack/test/api_integration/apis/ml/modules/recognize_module.ts b/x-pack/test/api_integration/apis/ml/modules/recognize_module.ts
index 00b820a025c8b..2742fbff294c0 100644
--- a/x-pack/test/api_integration/apis/ml/modules/recognize_module.ts
+++ b/x-pack/test/api_integration/apis/ml/modules/recognize_module.ts
@@ -44,7 +44,7 @@ export default ({ getService }: FtrProviderContext) => {
user: USER.ML_POWERUSER,
expected: {
responseCode: 200,
- moduleIds: ['apm_jsbase', 'apm_nodejs'],
+ moduleIds: ['apm_jsbase', 'apm_transaction', 'apm_nodejs'],
},
},
{
diff --git a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts
index 6ff6b8113cb1a..c4dd529ac14f5 100644
--- a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts
+++ b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts
@@ -187,11 +187,9 @@ export default ({ getService }: FtrProviderContext) => {
dashboards: [] as string[],
},
},
- // Set startDatafeed and estimateModelMemory to false for the APM transaction test
- // until there is a new data set available with metric data.
{
testTitleSuffix:
- 'for apm_transaction with prefix, startDatafeed false and estimateModelMemory false',
+ 'for apm_transaction with prefix, startDatafeed true and estimateModelMemory true',
sourceDataArchive: 'x-pack/test/functional/es_archives/ml/module_apm',
indexPattern: { name: 'ft_module_apm', timeField: '@timestamp' },
module: 'apm_transaction',
@@ -199,14 +197,14 @@ export default ({ getService }: FtrProviderContext) => {
requestBody: {
prefix: 'pf5_',
indexPatternName: 'ft_module_apm',
- startDatafeed: false,
- estimateModelMemory: false,
+ startDatafeed: true,
+ end: Date.now(),
},
expected: {
responseCode: 200,
jobs: [
{
- jobId: 'pf5_apm_metrics',
+ jobId: 'pf5_high_mean_transaction_duration',
jobState: JOB_STATE.CLOSED,
datafeedState: DATAFEED_STATE.STOPPED,
},
diff --git a/x-pack/test/fleet_api_integration/apis/epm/index.js b/x-pack/test/fleet_api_integration/apis/epm/index.js
index b6a1fd5d7346d..3428b4c1ded08 100644
--- a/x-pack/test/fleet_api_integration/apis/epm/index.js
+++ b/x-pack/test/fleet_api_integration/apis/epm/index.js
@@ -15,6 +15,7 @@ export default function loadTests({ loadTestFile }) {
loadTestFile(require.resolve('./template'));
loadTestFile(require.resolve('./ilm'));
loadTestFile(require.resolve('./install_by_upload'));
+ loadTestFile(require.resolve('./install_endpoint'));
loadTestFile(require.resolve('./install_overrides'));
loadTestFile(require.resolve('./install_prerelease'));
loadTestFile(require.resolve('./install_remove_assets'));
diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_endpoint.ts b/x-pack/test/fleet_api_integration/apis/epm/install_endpoint.ts
new file mode 100644
index 0000000000000..ba9264e1d1999
--- /dev/null
+++ b/x-pack/test/fleet_api_integration/apis/epm/install_endpoint.ts
@@ -0,0 +1,108 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../api_integration/ftr_provider_context';
+import { skipIfNoDockerRegistry } from '../../helpers';
+import { setupFleetAndAgents } from '../agents/services';
+
+export default function (providerContext: FtrProviderContext) {
+ /**
+ * There are a few features that are only currently supported for the Endpoint
+ * package due to security concerns.
+ */
+ describe('Install endpoint package', () => {
+ const { getService } = providerContext;
+ skipIfNoDockerRegistry(providerContext);
+ setupFleetAndAgents(providerContext);
+
+ const supertest = getService('supertest');
+ const dockerServers = getService('dockerServers');
+ const server = dockerServers.get('registry');
+ const es = getService('es');
+ const pkgName = 'endpoint';
+ let pkgVersion: string;
+
+ const transforms = [
+ {
+ id: 'endpoint.metadata_current-default',
+ dest: 'metrics-endpoint.metadata_current_default',
+ },
+ {
+ id: 'endpoint.metadata_united-default',
+ dest: '.metrics-endpoint.metadata_united_default',
+ },
+ ];
+
+ before(async () => {
+ if (!server.enabled) return;
+ // The latest endpoint package is already installed by default in our FTR config,
+ // just get the most recent version number.
+ const getResp = await supertest.get(`/api/fleet/epm/packages/${pkgName}`).expect(200);
+ pkgVersion = getResp.body.response.version;
+ });
+
+ describe('install', () => {
+ transforms.forEach((transform) => {
+ it(`should have installed the [${transform.id}] transform`, async function () {
+ const res = await es.transport.request({
+ method: 'GET',
+ path: `/_transform/${transform.id}-${pkgVersion}`,
+ });
+ expect(res.statusCode).equal(200);
+ });
+ it(`should have created the destination index for the [${transform.id}] transform`, async function () {
+ // the index is defined in the transform file
+ const res = await es.transport.request({
+ method: 'GET',
+ path: `/${transform.dest}`,
+ });
+ expect(res.statusCode).equal(200);
+ });
+ });
+ });
+
+ const uninstallPackage = async (pkg: string) =>
+ supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx');
+
+ // Endpoint doesn't currently support uninstalls
+ describe.skip('uninstall', () => {
+ before(async () => {
+ await uninstallPackage(`${pkgName}-${pkgVersion}`);
+ });
+
+ transforms.forEach((transform) => {
+ it(`should have uninstalled the [${transform.id}] transforms`, async function () {
+ const res = await es.transport.request(
+ {
+ method: 'GET',
+ path: `/_transform/${transform.id}`,
+ },
+ {
+ ignore: [404],
+ }
+ );
+ expect(res.statusCode).equal(404);
+ });
+
+ it(`should have deleted the index for the [${transform.id}] transform`, async function () {
+ // the index is defined in the transform file
+ const res = await es.transport.request(
+ {
+ method: 'GET',
+ path: `/${transform.dest}`,
+ },
+ {
+ ignore: [404],
+ }
+ );
+ expect(res.statusCode).equal(404);
+ });
+ });
+ });
+ });
+}
diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts b/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts
index e57899531e939..7e48ed9d297c7 100644
--- a/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts
+++ b/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts
@@ -155,31 +155,6 @@ export default function (providerContext: FtrProviderContext) {
);
expect(resPipeline2.statusCode).equal(404);
});
- it('should have uninstalled the transforms', async function () {
- const res = await es.transport.request(
- {
- method: 'GET',
- path: `/_transform/${pkgName}-test-default-${pkgVersion}`,
- },
- {
- ignore: [404],
- }
- );
- expect(res.statusCode).equal(404);
- });
- it('should have deleted the index for the transform', async function () {
- // the index is defined in the transform file
- const res = await es.transport.request(
- {
- method: 'GET',
- path: `/logs-all_assets.test_log_current_default`,
- },
- {
- ignore: [404],
- }
- );
- expect(res.statusCode).equal(404);
- });
it('should have uninstalled the kibana assets', async function () {
let resDashboard;
try {
@@ -380,21 +355,6 @@ const expectAssetsInstalled = ({
});
expect(resUserSettings.statusCode).equal(200);
});
- it('should have installed the transform components', async function () {
- const res = await es.transport.request({
- method: 'GET',
- path: `/_transform/${pkgName}.test-default-${pkgVersion}`,
- });
- expect(res.statusCode).equal(200);
- });
- it('should have created the index for the transform', async function () {
- // the index is defined in the transform file
- const res = await es.transport.request({
- method: 'GET',
- path: `/logs-all_assets.test_log_current_default`,
- });
- expect(res.statusCode).equal(200);
- });
it('should have installed the kibana assets', async function () {
// These are installed from Fleet along with every package
const resIndexPatternLogs = await kibanaServer.savedObjects.get({
@@ -575,10 +535,6 @@ const expectAssetsInstalled = ({
id: 'logs-all_assets.test_logs-0.1.0-pipeline2',
type: 'ingest_pipeline',
},
- {
- id: 'all_assets.test-default-0.1.0',
- type: 'transform',
- },
],
es_index_patterns: {
test_logs: 'logs-all_assets.test_logs-*',
@@ -597,7 +553,6 @@ const expectAssetsInstalled = ({
{ id: 'f839c76e-d194-555a-90a1-3265a45789e4', type: 'epm-packages-assets' },
{ id: '9af7bbb3-7d8a-50fa-acc9-9dde6f5efca2', type: 'epm-packages-assets' },
{ id: '1e97a20f-9d1c-529b-8ff2-da4e8ba8bb71', type: 'epm-packages-assets' },
- { id: '8cfe0a2b-7016-5522-87e4-6d352360d1fc', type: 'epm-packages-assets' },
{ id: 'bd5ff3c5-655e-5385-9918-b60ff3040aad', type: 'epm-packages-assets' },
{ id: '0954ce3b-3165-5c1f-a4c0-56eb5f2fa487', type: 'epm-packages-assets' },
{ id: '60d6d054-57e4-590f-a580-52bf3f5e7cca', type: 'epm-packages-assets' },
diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/elasticsearch/transform/test/default.json b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/elasticsearch/transform/test/default.json
deleted file mode 100644
index eddc6bc0c304a..0000000000000
--- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/elasticsearch/transform/test/default.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "source": {
- "index": "logs-all_assets.test_log-default*"
- },
- "dest": {
- "index": "logs-all_assets.test_log_current_default"
- },
- "pivot": {
- "group_by": {
- "agent.id": {
- "terms": {
- "field": "agent.id"
- }
- }
- },
- "aggregations": {
- "HostDetails": {
- "scripted_metric": {
- "init_script": "state.timestamp_latest = 0L; state.last_doc=''",
- "map_script": "def current_date = doc['@timestamp'].getValue().toInstant().toEpochMilli(); if (current_date \u003e state.timestamp_latest) {state.timestamp_latest = current_date;state.last_doc = new HashMap(params['_source']);}",
- "combine_script": "return state",
- "reduce_script": "def last_doc = '';def timestamp_latest = 0L; for (s in states) {if (s.timestamp_latest \u003e (timestamp_latest)) {timestamp_latest = s.timestamp_latest; last_doc = s.last_doc;}} return last_doc"
- }
- }
- }
- },
- "description": "collapse and update the latest document for each host",
- "frequency": "1m",
- "sync": {
- "time": {
- "field": "event.ingested",
- "delay": "60s"
- }
- }
-}
diff --git a/x-pack/test/functional/apps/monitoring/enable_monitoring/index.js b/x-pack/test/functional/apps/monitoring/enable_monitoring/index.js
index 79bd479c45a17..cce6401453d21 100644
--- a/x-pack/test/functional/apps/monitoring/enable_monitoring/index.js
+++ b/x-pack/test/functional/apps/monitoring/enable_monitoring/index.js
@@ -11,7 +11,6 @@ export default function ({ getService, getPageObjects }) {
const PageObjects = getPageObjects(['monitoring', 'common', 'header']);
const esSupertest = getService('esSupertest');
const noData = getService('monitoringNoData');
- const testSubjects = getService('testSubjects');
const clusterOverview = getService('monitoringClusterOverview');
const retry = getService('retry');
const esDeleteAllIndices = getService('esDeleteAllIndices');
@@ -53,8 +52,6 @@ export default function ({ getService, getPageObjects }) {
// Here we are checking that once Monitoring is enabled,
// it moves on to the cluster overview page.
await retry.tryForTime(20000, async () => {
- // Click the refresh button
- await testSubjects.click('querySubmitButton');
await clusterOverview.closeAlertsModal();
expect(await clusterOverview.isOnClusterOverview()).to.be(true);
});
diff --git a/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_security.ts b/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_security.ts
index 988bbdc621f5f..bf83892ce1934 100644
--- a/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_security.ts
+++ b/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_security.ts
@@ -13,6 +13,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
const security = getService('security');
const appsMenu = getService('appsMenu');
const PageObjects = getPageObjects(['common', 'security']);
+ const noData = getService('monitoringNoData');
describe('security', () => {
before(async () => {
@@ -103,5 +104,32 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
expect(navLinks).to.contain('Stack Monitoring');
});
});
+
+ describe('monitoring_user and kibana_admin roles', function () {
+ this.tags(['skipCloud']);
+ before(async () => {
+ await security.user.create('monitoring_kibana_admin_user', {
+ password: 'monitoring_user-password',
+ roles: ['monitoring_user', 'kibana_admin'],
+ full_name: 'monitoring user',
+ });
+
+ await PageObjects.security.login(
+ 'monitoring_kibana_admin_user',
+ 'monitoring_user-password'
+ );
+ });
+
+ after(async () => {
+ await security.user.delete('monitoring_kibana_admin_user');
+ });
+
+ it('denies enabling monitoring without enough permissions', async () => {
+ await PageObjects.common.navigateToApp('monitoring');
+ await noData.isOnNoDataPage();
+ await noData.clickSetupWithSelfMonitoring();
+ expect(await noData.isOnNoDataPageMonitoringEnablementDenied()).to.be(true);
+ });
+ });
});
}
diff --git a/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_spaces.ts b/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_spaces.ts
index f2b872bccbaa7..71f100b49068f 100644
--- a/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_spaces.ts
+++ b/x-pack/test/functional/apps/monitoring/feature_controls/monitoring_spaces.ts
@@ -52,7 +52,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
basePath: '/s/custom_space',
});
- const exists = await find.existsByCssSelector('monitoring-main');
+ const exists = await find.existsByCssSelector('[data-test-subj="monitoringAppContainer"]');
expect(exists).to.be(true);
});
});
diff --git a/x-pack/test/functional/services/monitoring/no_data.js b/x-pack/test/functional/services/monitoring/no_data.js
index 7b4410425dcfe..bd34c45c2d293 100644
--- a/x-pack/test/functional/services/monitoring/no_data.js
+++ b/x-pack/test/functional/services/monitoring/no_data.js
@@ -30,5 +30,13 @@ export function MonitoringNoDataProvider({ getService }) {
const pageId = await retry.try(() => testSubjects.find('noDataContainer'));
return pageId !== null;
}
+
+ async isOnNoDataPageMonitoringEnablementDenied() {
+ return testSubjects.exists('weTriedContainer');
+ }
+
+ async clickSetupWithSelfMonitoring() {
+ await testSubjects.click('useInternalCollection');
+ }
})();
}
diff --git a/x-pack/test/functional/services/observability/alerts/add_to_case.ts b/x-pack/test/functional/services/observability/alerts/add_to_case.ts
new file mode 100644
index 0000000000000..1669fc69a683c
--- /dev/null
+++ b/x-pack/test/functional/services/observability/alerts/add_to_case.ts
@@ -0,0 +1,75 @@
+/*
+ * 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 { FtrProviderContext } from '../../../ftr_provider_context';
+
+const ADD_TO_EXISTING_CASE_SELECTOR = 'add-existing-case-menu-item';
+const ADD_TO_NEW_CASE_SELECTOR = 'add-new-case-item';
+const CREATE_CASE_FLYOUT = 'create-case-flyout';
+const SELECT_CASE_MODAL = 'all-cases-modal';
+
+export function ObservabilityAlertsAddToCaseProvider({ getService }: FtrProviderContext) {
+ const testSubjects = getService('testSubjects');
+
+ const getAddToExistingCaseSelector = async () => {
+ return await testSubjects.find(ADD_TO_EXISTING_CASE_SELECTOR);
+ };
+
+ const getAddToExistingCaseSelectorOrFail = async () => {
+ return await testSubjects.existOrFail(ADD_TO_EXISTING_CASE_SELECTOR);
+ };
+
+ const missingAddToExistingCaseSelectorOrFail = async () => {
+ return await testSubjects.missingOrFail(ADD_TO_EXISTING_CASE_SELECTOR);
+ };
+
+ const getAddToNewCaseSelector = async () => {
+ return await testSubjects.find(ADD_TO_NEW_CASE_SELECTOR);
+ };
+
+ const getAddToNewCaseSelectorOrFail = async () => {
+ return await testSubjects.existOrFail(ADD_TO_NEW_CASE_SELECTOR);
+ };
+
+ const missingAddToNewCaseSelectorOrFail = async () => {
+ return await testSubjects.missingOrFail(ADD_TO_NEW_CASE_SELECTOR);
+ };
+
+ const addToNewCaseButtonClick = async () => {
+ return await (await getAddToNewCaseSelector()).click();
+ };
+
+ const addToExistingCaseButtonClick = async () => {
+ return await (await getAddToExistingCaseSelector()).click();
+ };
+
+ const getCreateCaseFlyoutOrFail = async () => {
+ return await testSubjects.existOrFail(CREATE_CASE_FLYOUT);
+ };
+
+ const closeFlyout = async () => {
+ return await (await testSubjects.find('euiFlyoutCloseButton')).click();
+ };
+
+ const getAddtoExistingCaseModalOrFail = async () => {
+ return await testSubjects.existOrFail(SELECT_CASE_MODAL);
+ };
+
+ return {
+ getAddToExistingCaseSelector,
+ getAddToExistingCaseSelectorOrFail,
+ missingAddToExistingCaseSelectorOrFail,
+ getAddToNewCaseSelector,
+ getAddToNewCaseSelectorOrFail,
+ missingAddToNewCaseSelectorOrFail,
+ getCreateCaseFlyoutOrFail,
+ closeFlyout,
+ addToNewCaseButtonClick,
+ addToExistingCaseButtonClick,
+ getAddtoExistingCaseModalOrFail,
+ };
+}
diff --git a/x-pack/test/functional/services/observability/alerts/common.ts b/x-pack/test/functional/services/observability/alerts/common.ts
index 7098fdec2a9d4..d5a2ce2a18c41 100644
--- a/x-pack/test/functional/services/observability/alerts/common.ts
+++ b/x-pack/test/functional/services/observability/alerts/common.ts
@@ -204,5 +204,6 @@ export function ObservabilityAlertsCommonProvider({
setWorkflowStatusFilter,
submitQuery,
typeInQueryBar,
+ openActionsMenuForRow,
};
}
diff --git a/x-pack/test/functional/services/observability/alerts/index.ts b/x-pack/test/functional/services/observability/alerts/index.ts
index f373b0d75c543..f2b5173dfe5b0 100644
--- a/x-pack/test/functional/services/observability/alerts/index.ts
+++ b/x-pack/test/functional/services/observability/alerts/index.ts
@@ -7,15 +7,17 @@
import { ObservabilityAlertsPaginationProvider } from './pagination';
import { ObservabilityAlertsCommonProvider } from './common';
+import { ObservabilityAlertsAddToCaseProvider } from './add_to_case';
import { FtrProviderContext } from '../../../ftr_provider_context';
export function ObservabilityAlertsProvider(context: FtrProviderContext) {
const common = ObservabilityAlertsCommonProvider(context);
const pagination = ObservabilityAlertsPaginationProvider(context);
-
+ const addToCase = ObservabilityAlertsAddToCaseProvider(context);
return {
common,
pagination,
+ addToCase,
};
}
diff --git a/x-pack/test/observability_functional/apps/observability/alerts/add_to_case.ts b/x-pack/test/observability_functional/apps/observability/alerts/add_to_case.ts
new file mode 100644
index 0000000000000..f29111f2cb66b
--- /dev/null
+++ b/x-pack/test/observability_functional/apps/observability/alerts/add_to_case.ts
@@ -0,0 +1,92 @@
+/*
+ * 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 { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default ({ getService, getPageObjects }: FtrProviderContext) => {
+ const esArchiver = getService('esArchiver');
+ const observability = getService('observability');
+ const retry = getService('retry');
+
+ describe('Observability alerts / Add to case', function () {
+ this.tags('includeFirefox');
+
+ before(async () => {
+ await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts');
+ });
+
+ after(async () => {
+ await esArchiver.unload('x-pack/test/functional/es_archives/observability/alerts');
+ });
+
+ describe('When user has all priviledges for cases', () => {
+ before(async () => {
+ await observability.users.setTestUserRole(
+ observability.users.defineBasicObservabilityRole({
+ observabilityCases: ['all'],
+ logs: ['all'],
+ })
+ );
+ await observability.alerts.common.navigateToTimeWithData();
+ });
+
+ after(async () => {
+ await observability.users.restoreDefaultTestUserRole();
+ });
+
+ it('renders case options in the overflow menu', async () => {
+ await observability.alerts.common.openActionsMenuForRow(0);
+ await retry.try(async () => {
+ await observability.alerts.addToCase.getAddToExistingCaseSelectorOrFail();
+ await observability.alerts.addToCase.getAddToNewCaseSelectorOrFail();
+ });
+ });
+
+ it('opens a flyout when Add to new case is clicked', async () => {
+ await observability.alerts.addToCase.addToNewCaseButtonClick();
+
+ await retry.try(async () => {
+ await observability.alerts.addToCase.getCreateCaseFlyoutOrFail();
+ await observability.alerts.addToCase.closeFlyout();
+ });
+ });
+
+ it('opens a modal when Add to existing case is clicked', async () => {
+ await observability.alerts.common.openActionsMenuForRow(0);
+
+ await retry.try(async () => {
+ await observability.alerts.addToCase.addToExistingCaseButtonClick();
+ await observability.alerts.addToCase.getAddtoExistingCaseModalOrFail();
+ });
+ });
+ });
+
+ describe('When user has read permissions for cases', () => {
+ before(async () => {
+ await observability.users.setTestUserRole(
+ observability.users.defineBasicObservabilityRole({
+ observabilityCases: ['read'],
+ logs: ['all'],
+ })
+ );
+ await observability.alerts.common.navigateToTimeWithData();
+ });
+
+ after(async () => {
+ await observability.users.restoreDefaultTestUserRole();
+ });
+
+ it('does not render case options in the overflow menu', async () => {
+ await observability.alerts.common.openActionsMenuForRow(0);
+ await retry.try(async () => {
+ await observability.alerts.addToCase.missingAddToExistingCaseSelectorOrFail();
+ await observability.alerts.addToCase.missingAddToNewCaseSelectorOrFail();
+ });
+ });
+ });
+ });
+};
diff --git a/x-pack/test/observability_functional/apps/observability/index.ts b/x-pack/test/observability_functional/apps/observability/index.ts
index b163d4d6bb8d5..43e056bae65c0 100644
--- a/x-pack/test/observability_functional/apps/observability/index.ts
+++ b/x-pack/test/observability_functional/apps/observability/index.ts
@@ -15,5 +15,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./alerts'));
loadTestFile(require.resolve('./alerts/workflow_status'));
loadTestFile(require.resolve('./alerts/pagination'));
+ loadTestFile(require.resolve('./alerts/add_to_case'));
});
}