diff --git a/x-pack/plugins/enterprise_search/common/ui_settings_keys.ts b/x-pack/plugins/enterprise_search/common/ui_settings_keys.ts index bccb83e63e01b..1007c3f4421af 100644 --- a/x-pack/plugins/enterprise_search/common/ui_settings_keys.ts +++ b/x-pack/plugins/enterprise_search/common/ui_settings_keys.ts @@ -6,4 +6,4 @@ */ export const enterpriseSearchFeatureId = 'enterpriseSearch'; -export const enableIndexTransformsTab = 'enterpriseSearch:enableIndexTransformsTab'; +export const enableIndexPipelinesTab = 'enterpriseSearch:enableIndexTransformsTab'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines.tsx new file mode 100644 index 0000000000000..c80f4cd669273 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { DataPanel } from '../../../../shared/data_panel/data_panel'; + +export const SearchIndexPipelines: React.FC = () => { + return ( + <> + + + + + {i18n.translate( + 'xpack.enterpriseSearch.content.indices.pipelines.ingestionPipeline.title', + { + defaultMessage: 'Ingest Pipelines', + } + )} + + } + iconType="logstashInput" + > +
+ + + + {i18n.translate( + 'xpack.enterpriseSearch.content.indices.pipelines.mlInferencePipelines.title', + { + defaultMessage: 'ML Inference pipelines', + } + )} + + } + iconType="compute" + > +
+ + + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx index a376b4dd5bd48..b998fa5d10db2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/search_index.tsx @@ -17,7 +17,7 @@ import { i18n } from '@kbn/i18n'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { Status } from '../../../../../common/types/api'; -import { enableIndexTransformsTab } from '../../../../../common/ui_settings_keys'; +import { enableIndexPipelinesTab } from '../../../../../common/ui_settings_keys'; import { generateEncodedPath } from '../../../shared/encode_path_params'; import { KibanaLogic } from '../../../shared/kibana'; import { FetchIndexApiLogic } from '../../api/index/fetch_index_api_logic'; @@ -38,16 +38,17 @@ import { SearchIndexDocuments } from './documents'; import { SearchIndexIndexMappings } from './index_mappings'; import { IndexNameLogic } from './index_name_logic'; import { SearchIndexOverview } from './overview'; +import { SearchIndexPipelines } from './pipelines/pipelines'; export enum SearchIndexTabId { // all indices OVERVIEW = 'overview', DOCUMENTS = 'documents', INDEX_MAPPINGS = 'index_mappings', + PIPELINES = 'pipelines', // connector indices CONFIGURATION = 'configuration', SCHEDULING = 'scheduling', - TRANSFORMS = 'transforms', // crawler indices DOMAIN_MANAGEMENT = 'domain_management', } @@ -64,7 +65,7 @@ export const SearchIndex: React.FC = () => { const { indexName } = useValues(IndexNameLogic); - const transformsEnabled = uiSettings?.get(enableIndexTransformsTab) ?? false; + const pipelinesEnabled = uiSettings?.get(enableIndexPipelinesTab) ?? false; const ALL_INDICES_TABS: EuiTabbedContentTab[] = [ { @@ -124,12 +125,12 @@ export const SearchIndex: React.FC = () => { }, ]; - const TRANSFORMS_TAB: EuiTabbedContentTab[] = [ + const PIPELINES_TAB: EuiTabbedContentTab[] = [ { - content:
, - id: SearchIndexTabId.TRANSFORMS, - name: i18n.translate('xpack.enterpriseSearch.content.searchIndex.transformsTabLabel', { - defaultMessage: 'Transforms', + content: , + id: SearchIndexTabId.PIPELINES, + name: i18n.translate('xpack.enterpriseSearch.content.searchIndex.pipelinesTabLabel', { + defaultMessage: 'Pipelines', }), }, ]; @@ -138,7 +139,7 @@ export const SearchIndex: React.FC = () => { ...ALL_INDICES_TABS, ...(isConnectorIndex(indexData) ? CONNECTOR_TABS : []), ...(isCrawlerIndex(indexData) ? CRAWLER_TABS : []), - ...(transformsEnabled && isConnectorIndex(indexData) ? TRANSFORMS_TAB : []), + ...(pipelinesEnabled ? PIPELINES_TAB : []), ]; const selectedTab = tabs.find((tab) => tab.id === tabId); diff --git a/x-pack/plugins/enterprise_search/server/ui_settings.ts b/x-pack/plugins/enterprise_search/server/ui_settings.ts index 15241cc5fe890..0497aa54d2eec 100644 --- a/x-pack/plugins/enterprise_search/server/ui_settings.ts +++ b/x-pack/plugins/enterprise_search/server/ui_settings.ts @@ -9,19 +9,19 @@ import { schema } from '@kbn/config-schema'; import { UiSettingsParams } from '@kbn/core/types'; import { i18n } from '@kbn/i18n'; -import { enterpriseSearchFeatureId, enableIndexTransformsTab } from '../common/ui_settings_keys'; +import { enterpriseSearchFeatureId, enableIndexPipelinesTab } from '../common/ui_settings_keys'; /** * uiSettings definitions for Enterprise Search */ export const uiSettings: Record> = { - [enableIndexTransformsTab]: { + [enableIndexPipelinesTab]: { category: [enterpriseSearchFeatureId], - description: i18n.translate('xpack.enterpriseSearch.uiSettings.indexTransforms.description', { - defaultMessage: 'Enable the new index transforms tab in Enterprise Search.', + description: i18n.translate('xpack.enterpriseSearch.uiSettings.indexPipelines.description', { + defaultMessage: 'Enable the new index pipelines tab in Enterprise Search.', }), - name: i18n.translate('xpack.enterpriseSearch.uiSettings.indexTransforms.name', { - defaultMessage: 'Enable index transforms', + name: i18n.translate('xpack.enterpriseSearch.uiSettings.indexPipelines.name', { + defaultMessage: 'Enable index pipelines', }), requiresPageReload: false, schema: schema.boolean(), diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 6f3958cbb54e1..a59f57e45cdd0 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -458,3 +458,6 @@ export enum BulkActionsDryRunErrCode { MACHINE_LEARNING_AUTH = 'MACHINE_LEARNING_AUTH', MACHINE_LEARNING_INDEX_PATTERN = 'MACHINE_LEARNING_INDEX_PATTERN', } + +export const RISKY_HOSTS_DOC_LINK = + 'https://www.github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/host-risk-score.md'; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_generators/base_data_generator.ts b/x-pack/plugins/security_solution/common/endpoint/data_generators/base_data_generator.ts index 8c917b4ef6898..868129f3a6737 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_generators/base_data_generator.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_generators/base_data_generator.ts @@ -167,7 +167,9 @@ export class BaseDataGenerator { } protected randomVersion(): string { - return [7, ...this.randomNGenerator(20, 2)].map((x) => x.toString()).join('.'); + // the `major` is sometimes (30%) 7 and most of the time (70%) 8 + const major = this.randomBoolean(0.4) ? 7 : 8; + return [major, ...this.randomNGenerator(20, 2)].map((x) => x.toString()).join('.'); } protected randomChoice(choices: T[] | readonly T[]): T { diff --git a/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_metadata_generator.ts b/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_metadata_generator.ts new file mode 100644 index 0000000000000..67ff2d3605093 --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_metadata_generator.ts @@ -0,0 +1,149 @@ +/* + * 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 { DeepPartial } from 'utility-types'; +import { merge } from 'lodash'; +import { gte } from 'semver'; +import { BaseDataGenerator } from './base_data_generator'; +import type { HostMetadataInterface, OSFields } from '../types'; +import { EndpointStatus, HostPolicyResponseActionStatus } from '../types'; + +/** + * Metadata generator for docs that are sent by the Endpoint running on hosts + */ +export class EndpointMetadataGenerator extends BaseDataGenerator { + /** Generate an Endpoint host metadata document */ + generate(overrides: DeepPartial = {}): HostMetadataInterface { + const ts = overrides['@timestamp'] ?? new Date().getTime(); + const hostName = this.randomHostname(); + const agentVersion = overrides?.agent?.version ?? this.randomVersion(); + const agentId = this.seededUUIDv4(); + const isIsolated = this.randomBoolean(0.3); + const capabilities = ['isolation']; + + // v8.4 introduced additional endpoint capabilities + if (gte(agentVersion, '8.4.0')) { + capabilities.push('kill_process', 'suspend_process', 'running_processes'); + } + + const hostMetadataDoc: HostMetadataInterface = { + '@timestamp': ts, + event: { + created: ts, + id: this.seededUUIDv4(), + kind: 'metric', + category: ['host'], + type: ['info'], + module: 'endpoint', + action: 'endpoint_metadata', + dataset: 'endpoint.metadata', + }, + data_stream: { + type: 'metrics', + dataset: 'endpoint.metadata', + namespace: 'default', + }, + agent: { + version: agentVersion, + id: agentId, + type: 'endpoint', + }, + elastic: { + agent: { + id: agentId, + }, + }, + host: { + id: this.seededUUIDv4(), + hostname: hostName, + name: hostName, + architecture: this.randomString(10), + ip: this.randomArray(3, () => this.randomIP()), + mac: this.randomArray(3, () => this.randomMac()), + os: this.randomOsFields(), + }, + Endpoint: { + status: EndpointStatus.enrolled, + policy: { + applied: { + name: 'With Eventing', + id: 'C2A9093E-E289-4C0A-AA44-8C32A414FA7A', + status: HostPolicyResponseActionStatus.success, + endpoint_policy_version: 3, + version: 5, + }, + }, + configuration: { + isolation: isIsolated, + }, + state: { + isolation: isIsolated, + }, + capabilities, + }, + }; + + return merge(hostMetadataDoc, overrides); + } + + protected randomOsFields(): OSFields { + return this.randomChoice([ + { + name: 'Windows', + full: 'Windows 10', + version: '10.0', + platform: 'Windows', + family: 'windows', + Ext: { + variant: 'Windows Pro', + }, + }, + { + name: 'Windows', + full: 'Windows Server 2016', + version: '10.0', + platform: 'Windows', + family: 'windows', + Ext: { + variant: 'Windows Server', + }, + }, + { + name: 'Windows', + full: 'Windows Server 2012', + version: '6.2', + platform: 'Windows', + family: 'windows', + Ext: { + variant: 'Windows Server', + }, + }, + { + name: 'Windows', + full: 'Windows Server 2012R2', + version: '6.3', + platform: 'Windows', + family: 'windows', + Ext: { + variant: 'Windows Server Release 2', + }, + }, + { + Ext: { + variant: 'Debian', + }, + kernel: '4.19.0-21-cloud-amd64 #1 SMP Debian 4.19.249-2 (2022-06-30)', + name: 'Linux', + family: 'debian', + type: 'linux', + version: '10.12', + platform: 'debian', + full: 'Debian 10.12', + }, + ]); + } +} diff --git a/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts b/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts index 1586e47aa1f4c..a005004a90682 100644 --- a/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts +++ b/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts @@ -504,7 +504,7 @@ describe('data generator', () => { events[previousProcessEventIndex].process?.parent?.entity_id ); expect(events[events.length - 1].event?.kind).toEqual('alert'); - expect(events[events.length - 1].event?.category).toEqual('malware'); + expect(events[events.length - 1].event?.category).toEqual('behavior'); }); }); diff --git a/x-pack/plugins/security_solution/common/endpoint/generate_data.ts b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts index c9b554fc89031..59808b1df430c 100644 --- a/x-pack/plugins/security_solution/common/endpoint/generate_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts @@ -14,17 +14,17 @@ import type { KibanaAssetReference, } from '@kbn/fleet-plugin/common'; import { agentPolicyStatuses } from '@kbn/fleet-plugin/common'; +import { EndpointMetadataGenerator } from './data_generators/endpoint_metadata_generator'; import type { AlertEvent, DataStream, - Host, HostMetadata, + HostMetadataInterface, HostPolicyResponse, - OSFields, PolicyData, SafeEndpointEvent, } from './types'; -import { EndpointStatus, HostPolicyResponseActionStatus } from './types'; +import { HostPolicyResponseActionStatus } from './types'; import { policyFactory } from './models/policy_config'; import { ancestryArray, @@ -49,55 +49,6 @@ export type Event = AlertEvent | SafeEndpointEvent; */ export const ANCESTRY_LIMIT: number = 2; -const Windows: OSFields[] = [ - { - name: 'Windows', - full: 'Windows 10', - version: '10.0', - platform: 'Windows', - family: 'windows', - Ext: { - variant: 'Windows Pro', - }, - }, - { - name: 'Windows', - full: 'Windows Server 2016', - version: '10.0', - platform: 'Windows', - family: 'windows', - Ext: { - variant: 'Windows Server', - }, - }, - { - name: 'Windows', - full: 'Windows Server 2012', - version: '6.2', - platform: 'Windows', - family: 'windows', - Ext: { - variant: 'Windows Server', - }, - }, - { - name: 'Windows', - full: 'Windows Server 2012R2', - version: '6.3', - platform: 'Windows', - family: 'windows', - Ext: { - variant: 'Windows Server Release 2', - }, - }, -]; - -const Linux: OSFields[] = []; - -const Mac: OSFields[] = []; - -const OS: OSFields[] = [...Windows, ...Mac, ...Linux]; - const POLICY_RESPONSE_STATUSES: HostPolicyResponseActionStatus[] = [ HostPolicyResponseActionStatus.success, HostPolicyResponseActionStatus.failure, @@ -105,13 +56,7 @@ const POLICY_RESPONSE_STATUSES: HostPolicyResponseActionStatus[] = [ HostPolicyResponseActionStatus.unsupported, ]; -const APPLIED_POLICIES: Array<{ - name: string; - id: string; - status: HostPolicyResponseActionStatus; - endpoint_policy_version: number; - version: number; -}> = [ +const APPLIED_POLICIES: Array = [ { name: 'Default', id: '00000000-0000-0000-0000-000000000000', @@ -231,38 +176,7 @@ const OTHER_EVENT_CATEGORIES: Record< }, }; -interface HostInfo { - elastic: { - agent: { - id: string; - }; - }; - agent: { - version: string; - id: string; - type: string; - }; - host: Host; - Endpoint: { - status: EndpointStatus; - policy: { - applied: { - id: string; - status: HostPolicyResponseActionStatus; - name: string; - endpoint_policy_version: number; - version: number; - }; - }; - configuration?: { - isolation: boolean; - }; - state?: { - isolation: boolean; - }; - capabilities?: string[]; - }; -} +type CommonHostInfo = Pick; interface NodeState { event: Event; @@ -403,17 +317,32 @@ const alertsDefaultDataStream = { namespace: 'default', }; +/** + * Generator to create various ElasticSearch documents that are normally streamed by the Endpoint. + * + * NOTE: this generator currently reuses certain data (ex. `this.commonInfo`) across several + * documents, thus use caution if manipulating/mutating value in the generated data + * (ex. in tests). Individual standalone generators exist, whose generated data does not + * contain shared data structures. + */ export class EndpointDocGenerator extends BaseDataGenerator { - commonInfo: HostInfo; + commonInfo: CommonHostInfo; sequence: number = 0; + private readonly metadataGenerator: EndpointMetadataGenerator; + /** * The EndpointDocGenerator parameters * * @param seed either a string to seed the random number generator or a random number generator function + * @param MetadataGenerator */ - constructor(seed: string | seedrandom.prng = Math.random().toString()) { + constructor( + seed: string | seedrandom.prng = Math.random().toString(), + MetadataGenerator: typeof EndpointMetadataGenerator = EndpointMetadataGenerator + ) { super(seed); + this.metadataGenerator = new MetadataGenerator(seed); this.commonInfo = this.createHostData(); } @@ -456,47 +385,12 @@ export class EndpointDocGenerator extends BaseDataGenerator { }; } - private createHostData(): HostInfo { - const hostName = this.randomHostname(); - const isIsolated = this.randomBoolean(0.3); - const agentVersion = this.randomVersion(); - const capabilities = ['isolation', 'kill_process', 'suspend_process', 'running_processes']; - const agentId = this.seededUUIDv4(); + private createHostData(): CommonHostInfo { + const { agent, elastic, host, Endpoint } = this.metadataGenerator.generate({ + Endpoint: { policy: { applied: this.randomChoice(APPLIED_POLICIES) } }, + }); - return { - agent: { - version: agentVersion, - id: agentId, - type: 'endpoint', - }, - elastic: { - agent: { - id: agentId, - }, - }, - host: { - id: this.seededUUIDv4(), - hostname: hostName, - name: hostName, - architecture: this.randomString(10), - ip: this.randomArray(3, () => this.randomIP()), - mac: this.randomArray(3, () => this.randomMac()), - os: this.randomChoice(OS), - }, - Endpoint: { - status: EndpointStatus.enrolled, - policy: { - applied: this.randomChoice(APPLIED_POLICIES), - }, - configuration: { - isolation: isIsolated, - }, - state: { - isolation: isIsolated, - }, - capabilities, - }, - }; + return { agent, elastic, host, Endpoint }; } /** @@ -508,21 +402,11 @@ export class EndpointDocGenerator extends BaseDataGenerator { ts = new Date().getTime(), metadataDataStream = metadataDefaultDataStream ): HostMetadata { - return { + return this.metadataGenerator.generate({ '@timestamp': ts, - event: { - created: ts, - id: this.seededUUIDv4(), - kind: 'metric', - category: ['host'], - type: ['info'], - module: 'endpoint', - action: 'endpoint_metadata', - dataset: 'endpoint.metadata', - }, - ...this.commonInfo, data_stream: metadataDataStream, - }; + ...this.commonInfo, + }); } /** @@ -1628,7 +1512,7 @@ export class EndpointDocGenerator extends BaseDataGenerator { } /** - * Generates an Ingest `package policy` that includes the Endpoint Policy data + * Generates a Fleet `package policy` that includes the Endpoint Policy data */ public generatePolicyPackagePolicy(): PolicyData { const created = new Date(Date.now() - 8.64e7).toISOString(); // 24h ago @@ -1673,7 +1557,7 @@ export class EndpointDocGenerator extends BaseDataGenerator { } /** - * Generate an Agent Policy (ingest) + * Generate an Agent Policy (Fleet) */ public generateAgentPolicy(): GetAgentPoliciesResponseItem { // FIXME: remove and use new FleetPackagePolicyGenerator (#2262) @@ -1693,7 +1577,7 @@ export class EndpointDocGenerator extends BaseDataGenerator { } /** - * Generate an EPM Package for Endpoint + * Generate a Fleet EPM Package for Endpoint */ public generateEpmPackage(): GetPackagesResponse['items'][0] { return { diff --git a/x-pack/plugins/security_solution/common/endpoint/index_data.ts b/x-pack/plugins/security_solution/common/endpoint/index_data.ts index ea01e62fbc807..4971dc83c29aa 100644 --- a/x-pack/plugins/security_solution/common/endpoint/index_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/index_data.ts @@ -43,6 +43,7 @@ export type IndexedHostsAndAlertsResponse = IndexedHostsResponse; * @param alertsPerHost * @param fleet * @param options + * @param DocGenerator */ export async function indexHostsAndAlerts( client: Client, @@ -56,7 +57,8 @@ export async function indexHostsAndAlerts( alertIndex: string, alertsPerHost: number, fleet: boolean, - options: TreeOptions = {} + options: TreeOptions = {}, + DocGenerator: typeof EndpointDocGenerator = EndpointDocGenerator ): Promise { const random = seedrandom(seed); const epmEndpointPackage = await getEndpointPackageInfo(kbnClient); @@ -91,7 +93,7 @@ export async function indexHostsAndAlerts( const realPolicies: Record = {}; for (let i = 0; i < numHosts; i++) { - const generator = new EndpointDocGenerator(random); + const generator = new DocGenerator(random); const indexedHosts = await indexEndpointHostDocs({ numDocs, client, diff --git a/x-pack/plugins/security_solution/common/endpoint/types/index.ts b/x-pack/plugins/security_solution/common/endpoint/types/index.ts index 0f791a1f409d1..cdadf9619f008 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/index.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/index.ts @@ -492,9 +492,11 @@ export type HostInfo = Immutable<{ }; }>; -// HostMetadataDetails is now just HostMetadata -// HostDetails is also just HostMetadata -export type HostMetadata = Immutable<{ +// Host metadata document streamed up to ES by the Endpoint running on host machines. +// NOTE: `HostMetadata` type is the original and defined as Immutable. If needing to +// work with metadata that is not mutable, use `HostMetadataInterface` +export type HostMetadata = Immutable; +export interface HostMetadataInterface { '@timestamp': number; event: { created: number; @@ -542,10 +544,11 @@ export type HostMetadata = Immutable<{ agent: { id: string; version: string; + type: string; }; host: Host; data_stream: DataStream; -}>; +} export type UnitedAgentMetadata = Immutable<{ agent: { diff --git a/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_flyout.spec.ts b/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_flyout.spec.ts index dfb018b4bfb5a..20f55a4fffd4f 100644 --- a/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_flyout.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_flyout.spec.ts @@ -303,7 +303,7 @@ describe('Exceptions flyout', () => { goToExceptionsTab(); }); - context('When updating an item with version conflict', () => { + context.skip('When updating an item with version conflict', () => { it('Displays version conflict error', () => { editException(); @@ -334,7 +334,7 @@ describe('Exceptions flyout', () => { }); }); - context('When updating an item for a list that has since been deleted', () => { + context.skip('When updating an item for a list that has since been deleted', () => { it('Displays missing exception list error', () => { editException(); diff --git a/x-pack/plugins/security_solution/cypress/integration/overview/risky_hosts_panel.spec.ts b/x-pack/plugins/security_solution/cypress/integration/overview/risky_hosts_panel.spec.ts deleted file mode 100644 index 686acd5fd048c..0000000000000 --- a/x-pack/plugins/security_solution/cypress/integration/overview/risky_hosts_panel.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - OVERVIEW_RISKY_HOSTS_ENABLE_MODULE_BUTTON, - OVERVIEW_RISKY_HOSTS_LINKS, - OVERVIEW_RISKY_HOSTS_LINKS_ERROR_INNER_PANEL, - OVERVIEW_RISKY_HOSTS_LINKS_WARNING_INNER_PANEL, - OVERVIEW_RISKY_HOSTS_TOTAL_EVENT_COUNT, - OVERVIEW_RISKY_HOSTS_DOC_LINK, - OVERVIEW_RISKY_HOSTS_IMPORT_DASHBOARD_BUTTON, -} from '../../screens/overview'; - -import { login, visit } from '../../tasks/login'; -import { OVERVIEW_URL } from '../../urls/navigation'; -import { cleanKibana } from '../../tasks/common'; -import { changeSpace } from '../../tasks/kibana_navigation'; -import { createSpace, removeSpace } from '../../tasks/api_calls/spaces'; -import { esArchiverLoad, esArchiverUnload } from '../../tasks/es_archiver'; - -const testSpaceName = 'test'; - -describe('Risky Hosts Link Panel', () => { - before(() => { - cleanKibana(); - login(); - }); - - it('renders disabled panel view as expected', () => { - visit(OVERVIEW_URL); - cy.get(`${OVERVIEW_RISKY_HOSTS_LINKS} ${OVERVIEW_RISKY_HOSTS_LINKS_ERROR_INNER_PANEL}`).should( - 'exist' - ); - cy.get(`${OVERVIEW_RISKY_HOSTS_TOTAL_EVENT_COUNT}`).should('have.text', 'Showing: 0 hosts'); - cy.get(`${OVERVIEW_RISKY_HOSTS_ENABLE_MODULE_BUTTON}`).should('exist'); - cy.get(`${OVERVIEW_RISKY_HOSTS_DOC_LINK}`) - .should('have.attr', 'href') - .and('match', /host-risk-score.md/); - }); - - describe('enabled module', () => { - before(() => { - esArchiverLoad('risky_hosts'); - createSpace(testSpaceName); - }); - - after(() => { - esArchiverUnload('risky_hosts'); - removeSpace(testSpaceName); - }); - - it('renders disabled dashboard module as expected when there are no hosts in the selected time period', () => { - visit( - `${OVERVIEW_URL}?sourcerer=(timerange:(from:%272021-07-08T04:00:00.000Z%27,kind:absolute,to:%272021-07-09T03:59:59.999Z%27))` - ); - cy.get( - `${OVERVIEW_RISKY_HOSTS_LINKS} ${OVERVIEW_RISKY_HOSTS_LINKS_WARNING_INNER_PANEL}` - ).should('exist'); - cy.get(`${OVERVIEW_RISKY_HOSTS_TOTAL_EVENT_COUNT}`).should('have.text', 'Showing: 0 hosts'); - }); - - it('renders space aware dashboard module as expected when there are hosts in the selected time period', () => { - visit(OVERVIEW_URL); - cy.get( - `${OVERVIEW_RISKY_HOSTS_LINKS} ${OVERVIEW_RISKY_HOSTS_LINKS_WARNING_INNER_PANEL}` - ).should('not.exist'); - cy.get(`${OVERVIEW_RISKY_HOSTS_IMPORT_DASHBOARD_BUTTON}`).should('exist'); - cy.get(`${OVERVIEW_RISKY_HOSTS_TOTAL_EVENT_COUNT}`).should('have.text', 'Showing: 6 hosts'); - - changeSpace(testSpaceName); - cy.visit(`/s/${testSpaceName}${OVERVIEW_URL}`); - cy.get(`${OVERVIEW_RISKY_HOSTS_TOTAL_EVENT_COUNT}`).should('have.text', 'Showing: 0 hosts'); - cy.get(`${OVERVIEW_RISKY_HOSTS_ENABLE_MODULE_BUTTON}`).should('exist'); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/cypress/screens/overview.ts b/x-pack/plugins/security_solution/cypress/screens/overview.ts index 1e91e4fe462b9..14bfce599dfaf 100644 --- a/x-pack/plugins/security_solution/cypress/screens/overview.ts +++ b/x-pack/plugins/security_solution/cypress/screens/overview.ts @@ -151,19 +151,4 @@ export const OVERVIEW_CTI_LINKS_ERROR_INNER_PANEL = '[data-test-subj="cti-inner- export const OVERVIEW_CTI_TOTAL_EVENT_COUNT = `${OVERVIEW_CTI_LINKS} [data-test-subj="header-panel-subtitle"]`; export const OVERVIEW_CTI_ENABLE_MODULE_BUTTON = '[data-test-subj="cti-enable-module-button"]'; -export const OVERVIEW_RISKY_HOSTS_LINKS = '[data-test-subj="risky-hosts-dashboard-links"]'; -export const OVERVIEW_RISKY_HOSTS_LINKS_ERROR_INNER_PANEL = - '[data-test-subj="risky-hosts-inner-panel-danger"]'; -export const OVERVIEW_RISKY_HOSTS_LINKS_WARNING_INNER_PANEL = - '[data-test-subj="risky-hosts-inner-panel-warning"]'; -export const OVERVIEW_RISKY_HOSTS_VIEW_DASHBOARD_BUTTON = - '[data-test-subj="risky-hosts-view-dashboard-button"]'; -export const OVERVIEW_RISKY_HOSTS_IMPORT_DASHBOARD_BUTTON = - '[data-test-subj="create-saved-object-button"]'; -export const OVERVIEW_RISKY_HOSTS_DOC_LINK = - '[data-test-subj="risky-hosts-inner-panel-danger-learn-more"]'; -export const OVERVIEW_RISKY_HOSTS_TOTAL_EVENT_COUNT = `${OVERVIEW_RISKY_HOSTS_LINKS} [data-test-subj="header-panel-subtitle"]`; -export const OVERVIEW_RISKY_HOSTS_ENABLE_MODULE_BUTTON = - '[data-test-subj="disabled-open-in-console-button-with-tooltip"]'; - export const OVERVIEW_ALERTS_HISTOGRAM = '[data-test-subj="alerts-histogram-panel"]'; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/host_risk_summary.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/host_risk_summary.tsx index 9f425da6475d7..970656933b938 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/host_risk_summary.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/cti_details/host_risk_summary.tsx @@ -9,10 +9,10 @@ import React from 'react'; import { EuiLoadingSpinner, EuiPanel, EuiSpacer, EuiLink, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import * as i18n from './translations'; -import { RISKY_HOSTS_DOC_LINK } from '../../../../overview/components/overview_risky_host_links/risky_hosts_disabled_module'; import { EnrichedDataRow, ThreatSummaryPanelHeader } from './threat_summary_view'; import { RiskScore } from '../../severity/common'; import type { HostRisk } from '../../../../risk_score/containers'; +import { RISKY_HOSTS_DOC_LINK } from '../../../../../common/constants'; const HostRiskSummaryComponent: React.FC<{ hostRisk: HostRisk; diff --git a/x-pack/plugins/security_solution/public/hosts/components/host_risk_information/index.tsx b/x-pack/plugins/security_solution/public/hosts/components/host_risk_information/index.tsx index 11d3575a27567..ea1ecf8c9d652 100644 --- a/x-pack/plugins/security_solution/public/hosts/components/host_risk_information/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/components/host_risk_information/index.tsx @@ -27,12 +27,11 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import React from 'react'; -import { RISKY_HOSTS_DOC_LINK } from '../../../overview/components/overview_risky_host_links/risky_hosts_disabled_module'; - import * as i18n from './translations'; import { useOnOpenCloseHandler } from '../../../helper_hooks'; import { RiskScore } from '../../../common/components/severity/common'; import { RiskSeverity } from '../../../../common/search_strategy'; +import { RISKY_HOSTS_DOC_LINK } from '../../../../common/constants'; const tableColumns: Array> = [ { diff --git a/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx b/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx index 7c73cb4f24508..f7c9352f3a951 100644 --- a/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx @@ -12,9 +12,9 @@ import { HostsKpiHosts } from './hosts'; import { HostsKpiUniqueIps } from './unique_ips'; import type { HostsKpiProps } from './types'; import { CallOutSwitcher } from '../../../common/components/callouts'; -import { RISKY_HOSTS_DOC_LINK } from '../../../overview/components/overview_risky_host_links/risky_hosts_disabled_module'; import * as i18n from './translations'; import { useHostRiskScore } from '../../../risk_score/containers'; +import { RISKY_HOSTS_DOC_LINK } from '../../../../common/constants'; export const HostsKpiComponent = React.memo( ({ filterQuery, from, indexNames, to, setQuery, skip, updateDateRange }) => { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts index 7d1fd0a3d77fe..c2cecdba29b3d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts @@ -255,15 +255,15 @@ describe('endpoint list middleware', () => { query: { agent_ids: [ '0dc3661d-6e67-46b0-af39-6f12b025fcb0', - 'a8e32a61-2685-47f0-83eb-edf157b8e616', - '37e219a8-fe16-4da9-bf34-634c5824b484', - '2484eb13-967e-4491-bf83-dffefdfe607c', - '0bc08ef6-6d6a-4113-92f2-b97811187c63', - 'f4127d87-b567-4a6e-afa6-9a1c7dc95f01', - 'f9ab5b8c-a43e-4e80-99d6-11570845a697', - '406c4b6a-ca57-4bd1-bc66-d9d999df3e70', - '2da1dd51-f7af-4f0e-b64c-e7751c74b0e7', - '89a94ea4-073c-4cb6-90a2-500805837027', + '34634c58-24b4-4448-80f4-107fb9918494', + '5a1298e3-e607-4bc0-8ef6-6d6a811312f2', + '78c54b13-596d-4891-95f4-80092d04454b', + '445f1fd2-5f81-4ddd-bdb6-f0d1bf2efe90', + 'd77a3fc6-3096-4852-a6ee-f6b09278fbc6', + '892fcccf-1bd8-45a2-a9cc-9a7860a3cb81', + '693a3110-5ba0-4284-a264-5d78301db08c', + '554db084-64fa-4e4a-ba47-2ba713f9932b', + 'c217deb6-674d-4f97-bb1d-a3a04238e6d7', ], }, }); diff --git a/x-pack/plugins/security_solution/public/overview/components/link_panel/inner_link_panel.tsx b/x-pack/plugins/security_solution/public/overview/components/link_panel/inner_link_panel.tsx index c4f234b43efd0..f76b446ac72e8 100644 --- a/x-pack/plugins/security_solution/public/overview/components/link_panel/inner_link_panel.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/link_panel/inner_link_panel.tsx @@ -8,7 +8,7 @@ import React from 'react'; import styled from 'styled-components'; import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiSplitPanel, EuiText } from '@elastic/eui'; -import { LEARN_MORE } from '../overview_risky_host_links/translations'; +import * as i18n from './translations'; const ButtonContainer = styled(EuiFlexGroup)` padding: ${({ theme }) => theme.eui.euiSizeS}; @@ -66,7 +66,7 @@ export const InnerLinkPanel = ({ data-test-subj={`${dataTestSubj}-learn-more`} external > - {LEARN_MORE} + {i18n.LEARN_MORE} )}

diff --git a/x-pack/plugins/security_solution/public/overview/components/link_panel/translations.ts b/x-pack/plugins/security_solution/public/overview/components/link_panel/translations.ts new file mode 100644 index 0000000000000..edbfa06477ba5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/link_panel/translations.ts @@ -0,0 +1,15 @@ +/* + * 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'; + +export const LEARN_MORE = i18n.translate( + 'xpack.securitySolution.overview.linkPanelLearnMoreButton', + { + defaultMessage: 'Learn More', + } +); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/threat_intel_panel_view.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/threat_intel_panel_view.tsx index 371f9a1e79f20..c6a623f19681f 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/threat_intel_panel_view.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/threat_intel_panel_view.tsx @@ -16,7 +16,6 @@ import type { LinkPanelViewProps } from '../link_panel/types'; import { shortenCountIntoString } from '../../../common/utils/shorten_count_into_string'; import { Link } from '../link_panel/link'; import { ID as CTIEventCountQueryId } from '../../containers/overview_cti_links/use_ti_data_sources'; -import { LINK_COPY } from '../overview_risky_host_links/translations'; const columns: Array> = [ { name: 'Name', field: 'title', sortable: true, truncateText: true, width: '100%' }, @@ -34,7 +33,7 @@ const columns: Array> = [ field: 'path', truncateText: true, width: '80px', - render: (path: string) => , + render: (path: string) => , }, ]; diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/translations.ts b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/translations.ts index 775dab6721da1..ef7f1f6540ee5 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/translations.ts +++ b/x-pack/plugins/security_solution/public/overview/components/overview_cti_links/translations.ts @@ -42,3 +42,7 @@ export const OTHER_DATA_SOURCE_TITLE = i18n.translate( defaultMessage: 'Others', } ); + +export const LINK_COPY = i18n.translate('xpack.securitySolution.overview.ctiLinkSource', { + defaultMessage: 'Source', +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/index.test.tsx deleted file mode 100644 index b0c5f8bc7cff9..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/index.test.tsx +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { Provider } from 'react-redux'; -import { cloneDeep } from 'lodash/fp'; -import { render, screen } from '@testing-library/react'; -import { I18nProvider } from '@kbn/i18n-react'; -import { ThemeProvider } from 'styled-components'; -import { mockTheme } from '../overview_cti_links/mock'; -import { RiskyHostLinks } from '.'; -import type { State } from '../../../common/store'; -import { createStore } from '../../../common/store'; -import { - createSecuritySolutionStorageMock, - kibanaObservable, - mockGlobalState, - SUB_PLUGINS_REDUCER, -} from '../../../common/mock'; - -import { useRiskyHostsDashboardLinks } from '../../containers/overview_risky_host_links/use_risky_hosts_dashboard_links'; -import { useHostRiskScore } from '../../../risk_score/containers'; -import { useDashboardButtonHref } from '../../../common/hooks/use_dashboard_button_href'; - -jest.mock('../../../common/lib/kibana'); - -jest.mock('../../../risk_score/containers'); -const useHostRiskScoreMock = useHostRiskScore as jest.Mock; - -jest.mock('../../../common/hooks/use_dashboard_button_href'); -const useRiskyHostsDashboardButtonHrefMock = useDashboardButtonHref as jest.Mock; -useRiskyHostsDashboardButtonHrefMock.mockReturnValue({ buttonHref: '/test' }); - -jest.mock('../../containers/overview_risky_host_links/use_risky_hosts_dashboard_links'); -const useRiskyHostsDashboardLinksMock = useRiskyHostsDashboardLinks as jest.Mock; -useRiskyHostsDashboardLinksMock.mockReturnValue({ - listItemsWithLinks: [{ title: 'a', count: 1, path: '/test' }], -}); - -describe('RiskyHostLinks', () => { - const state: State = mockGlobalState; - - const { storage } = createSecuritySolutionStorageMock(); - let store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage); - - beforeEach(() => { - const myState = cloneDeep(state); - store = createStore(myState, SUB_PLUGINS_REDUCER, kibanaObservable, storage); - }); - - it('renders enabled module view if module is enabled', () => { - useHostRiskScoreMock.mockReturnValueOnce([ - false, - { - data: [], - isModuleEnabled: true, - }, - ]); - - render( - - - - - - - - ); - - expect(screen.queryByTestId('risky-hosts-enable-module-button')).not.toBeInTheDocument(); - }); - - it('renders disabled module view if module is disabled', () => { - useHostRiskScoreMock.mockReturnValueOnce([ - false, - { - data: [], - isModuleEnabled: false, - }, - ]); - - render( - - - - - - - - ); - - expect(screen.getByTestId('disabled-open-in-console-button-with-tooltip')).toBeInTheDocument(); - }); -}); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/index.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/index.tsx deleted file mode 100644 index df6286647e82e..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/index.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { RiskyHostsEnabledModule } from './risky_hosts_enabled_module'; -import { RiskyHostsDisabledModule } from './risky_hosts_disabled_module'; -import { useQueryInspector } from '../../../common/components/page/manage_query'; -import type { GlobalTimeArgs } from '../../../common/containers/use_global_time'; -import { useHostRiskScore, HostRiskScoreQueryId } from '../../../risk_score/containers'; -export interface RiskyHostLinksProps extends Pick { - timerange: { to: string; from: string }; -} - -const QUERY_ID = HostRiskScoreQueryId.OVERVIEW_RISKY_HOSTS; - -const RiskyHostLinksComponent: React.FC = ({ - timerange, - deleteQuery, - setQuery, -}) => { - const [loading, { data, isModuleEnabled, inspect, refetch }] = useHostRiskScore({ - timerange, - }); - - useQueryInspector({ - queryId: QUERY_ID, - loading, - refetch, - setQuery, - deleteQuery, - inspect, - }); - - switch (isModuleEnabled) { - case true: - return ( - - ); - case false: - return ; - case undefined: - default: - return null; - } -}; - -export const RiskyHostLinks = React.memo(RiskyHostLinksComponent); -RiskyHostLinks.displayName = 'RiskyHostLinks'; diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/navigate_to_host.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/navigate_to_host.tsx deleted file mode 100644 index afa0cfe7e9ae8..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/navigate_to_host.tsx +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback } from 'react'; -import { EuiButtonEmpty, EuiText, EuiToolTip } from '@elastic/eui'; -import { APP_UI_ID, SecurityPageName } from '../../../../common/constants'; -import { useKibana } from '../../../common/lib/kibana'; - -export const NavigateToHost: React.FC<{ name: string }> = ({ name }): JSX.Element => { - const { navigateToApp } = useKibana().services.application; - const { filterManager } = useKibana().services.data.query; - - const goToHostPage = useCallback( - (e) => { - e.preventDefault(); - filterManager.addFilters([ - { - meta: { - alias: null, - disabled: false, - negate: false, - }, - query: { match_phrase: { 'host.name': name } }, - }, - ]); - navigateToApp(APP_UI_ID, { - deepLinkId: SecurityPageName.hosts, - }); - }, - [filterManager, name, navigateToApp] - ); - return ( - - - {name} - - - ); -}; diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_disabled_module.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_disabled_module.test.tsx deleted file mode 100644 index e8a50c83a3a27..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_disabled_module.test.tsx +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { Provider } from 'react-redux'; -import { cloneDeep } from 'lodash/fp'; -import { render, screen } from '@testing-library/react'; -import { I18nProvider } from '@kbn/i18n-react'; -import { ThemeProvider } from 'styled-components'; -import type { State } from '../../../common/store'; -import { createStore } from '../../../common/store'; -import { - createSecuritySolutionStorageMock, - kibanaObservable, - mockGlobalState, - SUB_PLUGINS_REDUCER, -} from '../../../common/mock'; -import { RiskyHostsDisabledModule } from './risky_hosts_disabled_module'; -import { mockTheme } from '../overview_cti_links/mock'; - -jest.mock('../../../common/lib/kibana'); - -describe('RiskyHostsModule', () => { - const state: State = mockGlobalState; - - const { storage } = createSecuritySolutionStorageMock(); - let store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage); - - beforeEach(() => { - const myState = cloneDeep(state); - store = createStore(myState, SUB_PLUGINS_REDUCER, kibanaObservable, storage); - }); - - it('renders expected children', () => { - render( - - - - - - - - ); - - expect(screen.getByTestId('risky-hosts-dashboard-links')).toBeInTheDocument(); - expect(screen.getByTestId('risky-hosts-inner-panel-danger-learn-more')).toBeInTheDocument(); - - expect(screen.getByTestId('disabled-open-in-console-button-with-tooltip')).toBeInTheDocument(); - }); -}); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_disabled_module.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_disabled_module.tsx deleted file mode 100644 index e13089dc6404e..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_disabled_module.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import * as i18n from './translations'; -import { DisabledLinkPanel } from '../link_panel/disabled_link_panel'; -import { RiskyHostsPanelView } from './risky_hosts_panel_view'; - -import { ENABLE_VIA_DEV_TOOLS } from './translations'; - -import { OpenInDevConsoleButton } from '../../../common/components/open_in_dev_console'; -import { useCheckSignalIndex } from '../../../detections/containers/detection_engine/alerts/use_check_signal_index'; -import type { LinkPanelListItem } from '../link_panel'; -import { useEnableHostRiskFromUrl } from '../../../common/hooks/use_enable_host_risk_from_url'; - -export const RISKY_HOSTS_DOC_LINK = - 'https://www.github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/host-risk-score.md'; - -const emptyList: LinkPanelListItem[] = []; - -export const RiskyHostsDisabledModuleComponent = () => { - const loadFromUrl = useEnableHostRiskFromUrl(); - const { signalIndexExists } = useCheckSignalIndex(); - - return ( - - } - /> - ); -}; - -export const RiskyHostsDisabledModule = React.memo(RiskyHostsDisabledModuleComponent); -RiskyHostsDisabledModule.displayName = 'RiskyHostsDisabledModule'; diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_enabled_module.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_enabled_module.test.tsx deleted file mode 100644 index 46956823d1961..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_enabled_module.test.tsx +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { Provider } from 'react-redux'; -import { cloneDeep } from 'lodash/fp'; -import { render, screen } from '@testing-library/react'; -import { I18nProvider } from '@kbn/i18n-react'; -import { ThemeProvider } from 'styled-components'; -import type { State } from '../../../common/store'; -import { createStore } from '../../../common/store'; -import { - createSecuritySolutionStorageMock, - kibanaObservable, - mockGlobalState, - SUB_PLUGINS_REDUCER, -} from '../../../common/mock'; - -import { useRiskyHostsDashboardLinks } from '../../containers/overview_risky_host_links/use_risky_hosts_dashboard_links'; -import { mockTheme } from '../overview_cti_links/mock'; -import { RiskyHostsEnabledModule } from './risky_hosts_enabled_module'; -import { useDashboardButtonHref } from '../../../common/hooks/use_dashboard_button_href'; -import { RiskSeverity } from '../../../../common/search_strategy'; - -jest.mock('../../../common/lib/kibana'); - -jest.mock('../../../common/hooks/use_dashboard_button_href'); -const useRiskyHostsDashboardButtonHrefMock = useDashboardButtonHref as jest.Mock; -useRiskyHostsDashboardButtonHrefMock.mockReturnValue({ buttonHref: '/test' }); - -jest.mock('../../containers/overview_risky_host_links/use_risky_hosts_dashboard_links'); -const useRiskyHostsDashboardLinksMock = useRiskyHostsDashboardLinks as jest.Mock; -useRiskyHostsDashboardLinksMock.mockReturnValue({ - listItemsWithLinks: [{ title: 'a', count: 1, path: '/test' }], -}); - -describe('RiskyHostsEnabledModule', () => { - const state: State = mockGlobalState; - - const { storage } = createSecuritySolutionStorageMock(); - let store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage); - - beforeEach(() => { - const myState = cloneDeep(state); - store = createStore(myState, SUB_PLUGINS_REDUCER, kibanaObservable, storage); - }); - - it('renders expected children', () => { - render( - - - - - - - - ); - expect(screen.getByTestId('risky-hosts-dashboard-links')).toBeInTheDocument(); - expect(screen.getByTestId('create-saved-object-success-button')).toBeInTheDocument(); - }); -}); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_enabled_module.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_enabled_module.tsx deleted file mode 100644 index 49a185d6e1513..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_enabled_module.tsx +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useMemo } from 'react'; -import { RiskyHostsPanelView } from './risky_hosts_panel_view'; -import type { LinkPanelListItem } from '../link_panel'; -import { useRiskyHostsDashboardLinks } from '../../containers/overview_risky_host_links/use_risky_hosts_dashboard_links'; -import type { HostRiskScore } from '../../../../common/search_strategy'; - -const getListItemsFromHits = (items: HostRiskScore[]): LinkPanelListItem[] => { - return items.map(({ host }) => ({ - title: host.name, - count: host.risk.calculated_score_norm, - copy: host.risk.calculated_level, - path: '', - })); -}; - -const RiskyHostsEnabledModuleComponent: React.FC<{ - from: string; - hostRiskScore?: HostRiskScore[]; - to: string; -}> = ({ hostRiskScore, to, from }) => { - const listItems = useMemo(() => getListItemsFromHits(hostRiskScore || []), [hostRiskScore]); - const { listItemsWithLinks } = useRiskyHostsDashboardLinks(to, from, listItems); - - return ( - - ); -}; - -export const RiskyHostsEnabledModule = React.memo(RiskyHostsEnabledModuleComponent); -RiskyHostsEnabledModule.displayName = 'RiskyHostsEnabledModule'; diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_panel_view.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_panel_view.test.tsx deleted file mode 100644 index 863bd4fcbd35d..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_panel_view.test.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import type { State } from '../../../common/store'; -import { createStore } from '../../../common/store'; -import { - createSecuritySolutionStorageMock, - kibanaObservable, - mockGlobalState, - SUB_PLUGINS_REDUCER, - TestProviders, -} from '../../../common/mock'; - -import { RiskyHostsPanelView } from './risky_hosts_panel_view'; -import { useDashboardButtonHref } from '../../../common/hooks/use_dashboard_button_href'; - -jest.mock('../../../common/lib/kibana'); - -jest.mock('../../../common/hooks/use_dashboard_button_href'); -const useRiskyHostsDashboardButtonHrefMock = useDashboardButtonHref as jest.Mock; -useRiskyHostsDashboardButtonHrefMock.mockReturnValue({ buttonHref: '/test' }); - -describe('RiskyHostsPanelView', () => { - const state: State = mockGlobalState; - - beforeEach(() => { - const { storage } = createSecuritySolutionStorageMock(); - const store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage); - render( - - - - ); - }); - - it('renders title', () => { - expect(screen.getByTestId('header-section-title')).toHaveTextContent( - 'Current host risk scores' - ); - }); - - it('renders host number', () => { - expect(screen.getByTestId('header-panel-subtitle')).toHaveTextContent('Showing: 1 host'); - }); - - it('renders view dashboard button', () => { - expect(screen.getByTestId('create-saved-object-success-button')).toHaveAttribute( - 'href', - '/test' - ); - expect(screen.getByTestId('create-saved-object-success-button')).toHaveTextContent( - 'View dashboard' - ); - }); -}); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_panel_view.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_panel_view.tsx deleted file mode 100644 index 7aadf6bcfa991..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/risky_hosts_panel_view.tsx +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback, useMemo, useState } from 'react'; - -import type { EuiTableFieldDataColumnType } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import type { SavedObject, SavedObjectAttributes } from '@kbn/core/types'; -import type { LinkPanelListItem } from '../link_panel'; -import { InnerLinkPanel, LinkPanel } from '../link_panel'; -import type { LinkPanelViewProps } from '../link_panel/types'; -import { Link } from '../link_panel/link'; -import * as i18n from './translations'; -import { NavigateToHost } from './navigate_to_host'; -import { HostRiskScoreQueryId } from '../../../risk_score/containers'; -import { useKibana } from '../../../common/lib/kibana'; -import { RISKY_HOSTS_DASHBOARD_TITLE } from '../../../hosts/pages/navigation/constants'; -import { useDashboardButtonHref } from '../../../common/hooks/use_dashboard_button_href'; -import { ImportSavedObjectsButton } from '../../../common/components/create_prebuilt_saved_objects/components/bulk_create_button'; -import { VIEW_DASHBOARD } from '../overview_cti_links/translations'; - -const columns: Array> = [ - { - name: 'Host Name', - field: 'title', - sortable: true, - truncateText: true, - width: '55%', - render: (name) => () as JSX.Element, - }, - { - align: 'right', - field: 'count', - name: 'Risk Score', - render: (riskScore) => - Number.isNaN(riskScore) ? riskScore : Number.parseFloat(riskScore).toFixed(2), - sortable: true, - truncateText: true, - width: '15%', - }, - { - field: 'copy', - name: 'Current Risk', - sortable: true, - truncateText: true, - width: '15%', - }, - { - field: 'path', - name: '', - render: (path: string) => () as JSX.Element, - truncateText: true, - width: '80px', - }, -]; - -const warningPanel = ( - -); - -const RiskyHostsPanelViewComponent: React.FC = ({ - isInspectEnabled, - listItems, - splitPanel, - totalCount = 0, - to, - from, -}) => { - const splitPanelElement = - typeof splitPanel === 'undefined' - ? listItems.length === 0 - ? warningPanel - : undefined - : splitPanel; - - const [dashboardUrl, setDashboardUrl] = useState(); - const { buttonHref } = useDashboardButtonHref({ - to, - from, - title: RISKY_HOSTS_DASHBOARD_TITLE, - }); - const { - services: { dashboard }, - } = useKibana(); - - const onImportDashboardSuccessCallback = useCallback( - (response: Array>) => { - const targetDashboard = response.find( - (obj) => obj.type === 'dashboard' && obj?.attributes?.title === RISKY_HOSTS_DASHBOARD_TITLE - ); - - const fetchDashboardUrl = (targetDashboardId: string | null | undefined) => { - if (to && from && targetDashboardId) { - const targetUrl = dashboard?.locator?.getRedirectUrl({ - dashboardId: targetDashboardId, - timeRange: { - to, - from, - }, - }); - - setDashboardUrl(targetUrl); - } - }; - - fetchDashboardUrl(targetDashboard?.id); - }, - [dashboard?.locator, from, to] - ); - - return ( - - ), - columns, - dataTestSubj: 'risky-hosts-dashboard-links', - defaultSortField: 'count', - defaultSortOrder: 'desc', - inspectQueryId: isInspectEnabled ? HostRiskScoreQueryId.OVERVIEW_RISKY_HOSTS : undefined, - listItems, - panelTitle: i18n.PANEL_TITLE, - splitPanel: splitPanelElement, - subtitle: useMemo( - () => ( - - ), - [totalCount] - ), - }} - /> - ); -}; - -export const RiskyHostsPanelView = React.memo(RiskyHostsPanelViewComponent); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/translations.ts b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/translations.ts deleted file mode 100644 index 5ba4bb2323b24..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/translations.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const WARNING_TITLE = i18n.translate( - 'xpack.securitySolution.overview.riskyHostsDashboardWarningPanelTitle', - { - defaultMessage: 'No host risk score data available to display', - } -); - -export const WARNING_BODY = i18n.translate( - 'xpack.securitySolution.overview.riskyHostsDashboardWarningPanelBody', - { - defaultMessage: `We haven't detected any host risk score data from the hosts in your environment for the selected time range.`, - } -); - -export const DANGER_TITLE = i18n.translate( - 'xpack.securitySolution.overview.riskyHostsDashboardDangerPanelTitle', - { - defaultMessage: 'No host risk score data', - } -); - -export const DANGER_BODY = i18n.translate( - 'xpack.securitySolution.overview.riskyHostsDashboardEnableThreatIntel', - { - defaultMessage: 'You must enable the host risk module to view risky hosts.', - } -); - -export const ENABLE_VIA_DEV_TOOLS = i18n.translate( - 'xpack.securitySolution.overview.riskyHostsDashboardDangerPanelButton', - { - defaultMessage: 'Enable via Dev Tools', - } -); - -export const LEARN_MORE = i18n.translate( - 'xpack.securitySolution.overview.riskyHostsDashboardLearnMoreButton', - { - defaultMessage: 'Learn More', - } -); - -export const LINK_COPY = i18n.translate('xpack.securitySolution.overview.riskyHostsSource', { - defaultMessage: 'Source', -}); - -export const PANEL_TITLE = i18n.translate( - 'xpack.securitySolution.overview.riskyHostsDashboardTitle', - { - defaultMessage: 'Current host risk scores', - } -); - -export const IMPORT_DASHBOARD = i18n.translate('xpack.securitySolution.overview.importDasboard', { - defaultMessage: 'Import dashboard', -}); - -export const ENABLE_RISK_SCORE_POPOVER = i18n.translate( - 'xpack.securitySolution.overview.enableRiskScorePopoverTitle', - { - defaultMessage: 'Alerts need to be available before enabling module', - } -); diff --git a/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_risky_hosts_dashboard_id.ts b/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_risky_hosts_dashboard_id.ts deleted file mode 100644 index 1e0758343ba47..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_risky_hosts_dashboard_id.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useState, useEffect } from 'react'; -import type { SavedObjectAttributes } from '@kbn/securitysolution-io-ts-alerting-types'; -import { useKibana } from '../../../common/lib/kibana'; - -const DASHBOARD_REQUEST_BODY_SEARCH = '"Drilldown of Host Risk Score"'; -export const DASHBOARD_REQUEST_BODY = { - type: 'dashboard', - search: DASHBOARD_REQUEST_BODY_SEARCH, - fields: ['title'], -}; - -export const useRiskyHostsDashboardId = () => { - const savedObjectsClient = useKibana().services.savedObjects.client; - const [dashboardId, setDashboardId] = useState(); - - useEffect(() => { - if (savedObjectsClient) { - savedObjectsClient.find(DASHBOARD_REQUEST_BODY).then( - async (DashboardsSO?: { - savedObjects?: Array<{ - attributes?: SavedObjectAttributes; - id?: string; - }>; - }) => { - if (DashboardsSO?.savedObjects?.length) { - setDashboardId(DashboardsSO.savedObjects[0].id); - } - } - ); - } - }, [savedObjectsClient]); - - return dashboardId; -}; diff --git a/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_risky_hosts_dashboard_links.tsx b/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_risky_hosts_dashboard_links.tsx deleted file mode 100644 index bf09bb56bb6f4..0000000000000 --- a/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_risky_hosts_dashboard_links.tsx +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { useState, useEffect } from 'react'; -import { useKibana } from '../../../common/lib/kibana'; -import type { LinkPanelListItem } from '../../components/link_panel'; -import { useRiskyHostsDashboardId } from './use_risky_hosts_dashboard_id'; - -export const useRiskyHostsDashboardLinks = ( - to: string, - from: string, - listItems: LinkPanelListItem[] -) => { - const { dashboard } = useKibana().services; - - const dashboardId = useRiskyHostsDashboardId(); - const [listItemsWithLinks, setListItemsWithLinks] = useState([]); - - useEffect(() => { - let cancelled = false; - const createLinks = async () => { - if (dashboard?.locator && dashboardId) { - const dashboardUrls = await Promise.all( - listItems.reduce( - (acc: Array>, listItem) => - dashboard && dashboard.locator - ? [ - ...acc, - dashboard.locator.getUrl({ - dashboardId, - timeRange: { - to, - from, - }, - filters: [ - { - meta: { - alias: null, - disabled: false, - negate: false, - }, - query: { match_phrase: { 'host.name': listItem.title } }, - }, - ], - }), - ] - : acc, - [] - ) - ); - if (!cancelled && dashboardUrls.length) { - setListItemsWithLinks( - listItems.map((item, i) => ({ - ...item, - path: dashboardUrls[i], - })) - ); - } - } else { - setListItemsWithLinks(listItems); - } - }; - createLinks(); - return () => { - cancelled = true; - }; - }, [dashboard, dashboardId, from, listItems, to]); - - return { listItemsWithLinks }; -}; diff --git a/x-pack/plugins/security_solution/public/overview/pages/overview.tsx b/x-pack/plugins/security_solution/public/overview/pages/overview.tsx index 2e3aa7c4d8d28..6cccf353e4b1c 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/overview.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/overview.tsx @@ -30,9 +30,7 @@ import { useDeepEqualSelector } from '../../common/hooks/use_selector'; import { ThreatIntelLinkPanel } from '../components/overview_cti_links'; import { useAllTiDataSources } from '../containers/overview_cti_links/use_all_ti_data_sources'; import { useUserPrivileges } from '../../common/components/user_privileges'; -import { RiskyHostLinks } from '../components/overview_risky_host_links'; import { useAlertsPrivileges } from '../../detections/containers/detection_engine/alerts/use_alerts_privileges'; -import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; import { LandingPageComponent } from '../../common/components/landing_page'; const OverviewComponent = () => { @@ -68,15 +66,6 @@ const OverviewComponent = () => { const { hasIndexRead, hasKibanaREAD } = useAlertsPrivileges(); const { tiDataSources: allTiDataSources, isInitiallyLoaded: isTiLoaded } = useAllTiDataSources(); - const riskyHostsEnabled = useIsExperimentalFeatureEnabled('riskyHostsEnabled'); - - const timerange = useMemo( - () => ({ - from, - to, - }), - [from, to] - ); return ( <> {indicesExist ? ( @@ -146,15 +135,6 @@ const OverviewComponent = () => { /> )} - - {riskyHostsEnabled && ( - - )} - diff --git a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/__snapshots__/isometric_taxi_layout.test.ts.snap b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/__snapshots__/isometric_taxi_layout.test.ts.snap index b033febcd1ac8..f6afb2bbe033c 100644 --- a/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/__snapshots__/isometric_taxi_layout.test.ts.snap +++ b/x-pack/plugins/security_solution/public/resolver/models/indexed_process_tree/__snapshots__/isometric_taxi_layout.test.ts.snap @@ -15,11 +15,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "A", - "process.name": "lsass.exe", + "process.name": "mimikatz.exe", "process.parent.entity_id": "", }, "id": "A", - "name": "lsass.exe", + "name": "mimikatz.exe", "parent": undefined, "stats": Object { "byCategory": Object {}, @@ -33,11 +33,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "A", - "process.name": "lsass.exe", + "process.name": "mimikatz.exe", "process.parent.entity_id": "", }, "id": "A", - "name": "lsass.exe", + "name": "mimikatz.exe", "parent": undefined, "stats": Object { "byCategory": Object {}, @@ -58,11 +58,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "A", - "process.name": "mimikatz.exe", + "process.name": "explorer.exe", "process.parent.entity_id": "", }, "id": "A", - "name": "mimikatz.exe", + "name": "explorer.exe", "parent": undefined, "stats": Object { "byCategory": Object {}, @@ -88,11 +88,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "C", - "process.name": "lsass.exe", + "process.name": "iexlorer.exe", "process.parent.entity_id": "A", }, "id": "C", - "name": "lsass.exe", + "name": "iexlorer.exe", "parent": "A", "stats": Object { "byCategory": Object {}, @@ -103,11 +103,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "I", - "process.name": "notepad.exe", + "process.name": "explorer.exe", "process.parent.entity_id": "A", }, "id": "I", - "name": "notepad.exe", + "name": "explorer.exe", "parent": "A", "stats": Object { "byCategory": Object {}, @@ -118,11 +118,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "D", - "process.name": "lsass.exe", + "process.name": "powershell.exe", "process.parent.entity_id": "B", }, "id": "D", - "name": "lsass.exe", + "name": "powershell.exe", "parent": "B", "stats": Object { "byCategory": Object {}, @@ -148,11 +148,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "F", - "process.name": "powershell.exe", + "process.name": "notepad.exe", "process.parent.entity_id": "C", }, "id": "F", - "name": "powershell.exe", + "name": "notepad.exe", "parent": "C", "stats": Object { "byCategory": Object {}, @@ -178,11 +178,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "H", - "process.name": "notepad.exe", + "process.name": "explorer.exe", "process.parent.entity_id": "G", }, "id": "H", - "name": "notepad.exe", + "name": "explorer.exe", "parent": "G", "stats": Object { "byCategory": Object {}, @@ -439,11 +439,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "A", - "process.name": "mimikatz.exe", + "process.name": "explorer.exe", "process.parent.entity_id": "", }, "id": "A", - "name": "mimikatz.exe", + "name": "explorer.exe", "parent": undefined, "stats": Object { "byCategory": Object {}, @@ -475,11 +475,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "C", - "process.name": "lsass.exe", + "process.name": "iexlorer.exe", "process.parent.entity_id": "A", }, "id": "C", - "name": "lsass.exe", + "name": "iexlorer.exe", "parent": "A", "stats": Object { "byCategory": Object {}, @@ -493,11 +493,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "I", - "process.name": "notepad.exe", + "process.name": "explorer.exe", "process.parent.entity_id": "A", }, "id": "I", - "name": "notepad.exe", + "name": "explorer.exe", "parent": "A", "stats": Object { "byCategory": Object {}, @@ -511,11 +511,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "D", - "process.name": "lsass.exe", + "process.name": "powershell.exe", "process.parent.entity_id": "B", }, "id": "D", - "name": "lsass.exe", + "name": "powershell.exe", "parent": "B", "stats": Object { "byCategory": Object {}, @@ -547,11 +547,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "F", - "process.name": "powershell.exe", + "process.name": "notepad.exe", "process.parent.entity_id": "C", }, "id": "F", - "name": "powershell.exe", + "name": "notepad.exe", "parent": "C", "stats": Object { "byCategory": Object {}, @@ -583,11 +583,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "H", - "process.name": "notepad.exe", + "process.name": "explorer.exe", "process.parent.entity_id": "G", }, "id": "H", - "name": "notepad.exe", + "name": "explorer.exe", "parent": "G", "stats": Object { "byCategory": Object {}, @@ -608,11 +608,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "A", - "process.name": "mimikatz.exe", + "process.name": "explorer.exe", "process.parent.entity_id": "", }, "id": "A", - "name": "mimikatz.exe", + "name": "explorer.exe", "parent": undefined, "stats": Object { "byCategory": Object {}, @@ -623,11 +623,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "B", - "process.name": "mimikatz.exe", + "process.name": "notepad.exe", "process.parent.entity_id": "A", }, "id": "B", - "name": "mimikatz.exe", + "name": "notepad.exe", "parent": "A", "stats": Object { "byCategory": Object {}, @@ -661,11 +661,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "A", - "process.name": "mimikatz.exe", + "process.name": "explorer.exe", "process.parent.entity_id": "", }, "id": "A", - "name": "mimikatz.exe", + "name": "explorer.exe", "parent": undefined, "stats": Object { "byCategory": Object {}, @@ -679,11 +679,11 @@ Object { "data": Object { "@timestamp": 1606234833273, "process.entity_id": "B", - "process.name": "mimikatz.exe", + "process.name": "notepad.exe", "process.parent.entity_id": "A", }, "id": "B", - "name": "mimikatz.exe", + "name": "notepad.exe", "parent": "A", "stats": Object { "byCategory": Object {}, diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts index 72dbf3ade5e4a..213f839421a71 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/stack_services.ts @@ -8,6 +8,7 @@ import { Client } from '@elastic/elasticsearch'; import { ToolingLog } from '@kbn/tooling-log'; import { KbnClient } from '@kbn/test'; +import type { StatusResponse } from '@kbn/core-status-common-internal'; import { createSecuritySuperuser } from './security_user_services'; export interface RuntimeServices { @@ -116,3 +117,24 @@ export const createKbnClient = ({ return new KbnClient({ log, url: kbnUrl }); }; + +/** + * Retrieves the Stack (kibana/ES) version from the `/api/status` kibana api + * @param kbnClient + */ +export const fetchStackVersion = async (kbnClient: KbnClient): Promise => { + const status = ( + await kbnClient.request({ + method: 'GET', + path: '/api/status', + }) + ).data; + + if (!status?.version?.number) { + throw new Error( + `unable to get stack version from '/api/status' \n${JSON.stringify(status, null, 2)}` + ); + } + + return status.version.number; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts b/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts index 9eb03dd80e326..a871151ed0b0d 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts @@ -5,7 +5,7 @@ * 2.0. */ -/* eslint-disable no-console */ +/* eslint-disable no-console,max-classes-per-file */ import yargs from 'yargs'; import fs from 'fs'; import { Client, errors } from '@elastic/elasticsearch'; @@ -14,8 +14,10 @@ import { CA_CERT_PATH } from '@kbn/dev-utils'; import { ToolingLog } from '@kbn/tooling-log'; import type { KbnClientOptions } from '@kbn/test'; import { KbnClient } from '@kbn/test'; +import { EndpointMetadataGenerator } from '../../common/endpoint/data_generators/endpoint_metadata_generator'; import { indexHostsAndAlerts } from '../../common/endpoint/index_data'; import { ANCESTRY_LIMIT, EndpointDocGenerator } from '../../common/endpoint/generate_data'; +import { fetchStackVersion } from './common/stack_services'; main(); @@ -249,6 +251,13 @@ async function main() { type: 'string', default: '', }, + randomVersions: { + describe: + 'By default, the data generated (that contains a stack version - ex: `agent.version`) will have a ' + + 'version number set to be the same as the version of the running stack. Using this flag (`--randomVersions=true`) ' + + 'will result in random version being generated', + default: false, + }, }).argv; let ca: Buffer; @@ -323,11 +332,14 @@ async function main() { } let seed = argv.seed; + if (!seed) { seed = Math.random().toString(); console.log(`No seed supplied, using random seed: ${seed}`); } + const startTime = new Date().getTime(); + if (argv.fleet && !argv.withNewUser) { // warn and exit when using fleet flag console.log( @@ -336,6 +348,29 @@ async function main() { // eslint-disable-next-line no-process-exit process.exit(0); } + + let DocGenerator: typeof EndpointDocGenerator = EndpointDocGenerator; + + // If `--randomVersions` is NOT set, then use custom generator that ensures all data generated + // has a stack version number that matches that of the running stack + if (!argv.randomVersions) { + const stackVersion = await fetchStackVersion(kbnClient); + + // Document Generator override that uses a custom Endpoint Metadata generator and sets the + // `agent.version` to the current version + DocGenerator = class extends EndpointDocGenerator { + constructor(...args: ConstructorParameters) { + const MetadataGenerator = class extends EndpointMetadataGenerator { + protected randomVersion(): string { + return stackVersion; + } + }; + + super(args[0], MetadataGenerator); + } + }; + } + await indexHostsAndAlerts( client, kbnClient, @@ -360,10 +395,11 @@ async function main() { ancestryArraySize: argv.ancestryArraySize, eventsDataStream: EndpointDocGenerator.createDataStreamFromIndex(argv.eventIndex), alertsDataStream: EndpointDocGenerator.createDataStreamFromIndex(argv.alertIndex), - } + }, + DocGenerator ); - // delete endpoint_user after + // delete endpoint_user after if (user) { const deleted = await deleteUser(client, user.username); if (deleted.found) { diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 43bb33e7fceec..266779c7ad92d 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -25517,7 +25517,6 @@ "xpack.securitySolution.overview.ctiDashboardSubtitle": "Affichage : {totalCount} {totalCount, plural, one {indicateur} other {indicateurs}}", "xpack.securitySolution.overview.overviewHost.hostsSubtitle": "Affichage de : {formattedHostEventsCount} {hostEventsCount, plural, one {événement} other {événements}}", "xpack.securitySolution.overview.overviewNetwork.networkSubtitle": "Affichage de : {formattedNetworkEventsCount} {networkEventsCount, plural, one {événement} other {événements}}", - "xpack.securitySolution.overview.riskyHostsDashboardSubtitle": "Affichage : {totalCount} {totalCount, plural, one {hôte} other {hôtes}}", "xpack.securitySolution.overview.topNLabel": "Premiers {fieldName}", "xpack.securitySolution.pages.common.updateAlertStatusFailed": "Impossible de mettre à jour { conflicts } {conflicts, plural, =1 {alerte} other {alertes}}.", "xpack.securitySolution.pages.common.updateAlertStatusFailedDetailed": "{ updated } {updated, plural, =1 {alerte a été mise à jour} other {alertes ont été mises à jour}} correctement, mais { conflicts } n'ont pas pu être mis à jour\n car { conflicts, plural, =1 {elle était} other {elles étaient}} déjà en cours de modification.", @@ -28578,7 +28577,6 @@ "xpack.securitySolution.overview.ctiDashboardOtherDatasourceTitle": "Autres", "xpack.securitySolution.overview.ctiDashboardTitle": "Threat Intelligence", "xpack.securitySolution.overview.ctiViewDasboard": "Afficher le tableau de bord", - "xpack.securitySolution.overview.enableRiskScorePopoverTitle": "Les alertes doivent être disponibles avant d'activer le module", "xpack.securitySolution.overview.endgameDnsTitle": "DNS", "xpack.securitySolution.overview.endgameFileTitle": "Fichier", "xpack.securitySolution.overview.endgameImageLoadTitle": "Chargement de la page", @@ -28604,7 +28602,6 @@ "xpack.securitySolution.overview.hostStatGroupFilebeat": "Filebeat", "xpack.securitySolution.overview.hostStatGroupWinlogbeat": "Winlogbeat", "xpack.securitySolution.overview.hostsTitle": "Événements d'hôte", - "xpack.securitySolution.overview.importDasboard": "Importer un tableau de bord", "xpack.securitySolution.overview.landingCards.box.cloudCard.desc": "Évaluez votre niveau de cloud et protégez vos charges de travail contre les attaques.", "xpack.securitySolution.overview.landingCards.box.cloudCard.title": "Protection cloud de bout en bout", "xpack.securitySolution.overview.landingCards.box.endpoint.desc": "Prévention, collecte, détection et réponse, le tout avec Elastic Agent.", @@ -28627,14 +28624,6 @@ "xpack.securitySolution.overview.packetBeatFlowTitle": "Flux", "xpack.securitySolution.overview.packetbeatTLSTitle": "TLS", "xpack.securitySolution.overview.recentTimelinesSidebarTitle": "Chronologies récentes", - "xpack.securitySolution.overview.riskyHostsDashboardDangerPanelButton": "Activer via Dev Tools", - "xpack.securitySolution.overview.riskyHostsDashboardDangerPanelTitle": "Pas de données de score de risque de l'hôte", - "xpack.securitySolution.overview.riskyHostsDashboardEnableThreatIntel": "Vous devez activer le module de risque des hôtes pour visualiser les hôtes à risque.", - "xpack.securitySolution.overview.riskyHostsDashboardLearnMoreButton": "En savoir plus", - "xpack.securitySolution.overview.riskyHostsDashboardTitle": "Scores de risque de l'hôte actuel", - "xpack.securitySolution.overview.riskyHostsDashboardWarningPanelBody": "Nous n'avons détecté aucune donnée de score de risque de l'hôte provenant des hôtes de votre environnement pour la plage temporelle sélectionnée.", - "xpack.securitySolution.overview.riskyHostsDashboardWarningPanelTitle": "Aucune donnée de score de risque de l'hôte disponible pour l'affichage", - "xpack.securitySolution.overview.riskyHostsSource": "Source", "xpack.securitySolution.overview.signalCountTitle": "Tendance des alertes", "xpack.securitySolution.overview.viewAlertsButtonLabel": "Afficher les alertes", "xpack.securitySolution.overview.viewEventsButtonLabel": "Afficher les événements", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 93ff4cfa81fb2..64f598d1b7d08 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -25494,7 +25494,6 @@ "xpack.securitySolution.overview.ctiDashboardSubtitle": "{totalCount} {totalCount, plural, other {個の指標}}を表示しています", "xpack.securitySolution.overview.overviewHost.hostsSubtitle": "表示中:{formattedHostEventsCount} {hostEventsCount, plural, other {イベント}}", "xpack.securitySolution.overview.overviewNetwork.networkSubtitle": "表示中:{formattedNetworkEventsCount} {networkEventsCount, plural, other {イベント}}", - "xpack.securitySolution.overview.riskyHostsDashboardSubtitle": "{totalCount} {totalCount, plural, other {個のホスト}}を表示しています", "xpack.securitySolution.overview.topNLabel": "トップ{fieldName}", "xpack.securitySolution.pages.common.updateAlertStatusFailed": "{ conflicts } {conflicts, plural, other {アラート}}を更新できませんでした。", "xpack.securitySolution.pages.common.updateAlertStatusFailedDetailed": "{ updated } {updated, plural, other {アラート}}が正常に更新されましたが、{ conflicts }は更新できませんでした。\n { conflicts, plural, other {}}すでに修正されています。", @@ -28555,7 +28554,6 @@ "xpack.securitySolution.overview.ctiDashboardOtherDatasourceTitle": "その他", "xpack.securitySolution.overview.ctiDashboardTitle": "脅威インテリジェンス", "xpack.securitySolution.overview.ctiViewDasboard": "ダッシュボードを表示", - "xpack.securitySolution.overview.enableRiskScorePopoverTitle": "モジュールを有効にする前に、アラートが使用可能でなければなりません", "xpack.securitySolution.overview.endgameDnsTitle": "DNS", "xpack.securitySolution.overview.endgameFileTitle": "ファイル", "xpack.securitySolution.overview.endgameImageLoadTitle": "画像読み込み", @@ -28581,7 +28579,6 @@ "xpack.securitySolution.overview.hostStatGroupFilebeat": "Filebeat", "xpack.securitySolution.overview.hostStatGroupWinlogbeat": "Winlogbeat", "xpack.securitySolution.overview.hostsTitle": "ホストイベント", - "xpack.securitySolution.overview.importDasboard": "ダッシュボードをインポート", "xpack.securitySolution.overview.landingCards.box.cloudCard.desc": "クラウド態勢を評価し、ワークロードを攻撃から保護します。", "xpack.securitySolution.overview.landingCards.box.cloudCard.title": "エンドツーエンドのクラウド保護", "xpack.securitySolution.overview.landingCards.box.endpoint.desc": "防御から収集、検知、対応まで実行する、Elastic Agent。", @@ -28604,14 +28601,6 @@ "xpack.securitySolution.overview.packetBeatFlowTitle": "フロー", "xpack.securitySolution.overview.packetbeatTLSTitle": "TLS", "xpack.securitySolution.overview.recentTimelinesSidebarTitle": "最近のタイムライン", - "xpack.securitySolution.overview.riskyHostsDashboardDangerPanelButton": "開発ツールで有効化", - "xpack.securitySolution.overview.riskyHostsDashboardDangerPanelTitle": "ホストリスクスコアデータがありません", - "xpack.securitySolution.overview.riskyHostsDashboardEnableThreatIntel": "リスクがあるホストを表示するには、ホストリスクモジュールを有効化する必要があります。", - "xpack.securitySolution.overview.riskyHostsDashboardLearnMoreButton": "詳細情報", - "xpack.securitySolution.overview.riskyHostsDashboardTitle": "現在のホストリスクスコア", - "xpack.securitySolution.overview.riskyHostsDashboardWarningPanelBody": "選択した期間では、ご使用の環境のホストからホストリスクスコアデータが検出されませんでした。", - "xpack.securitySolution.overview.riskyHostsDashboardWarningPanelTitle": "表示するホストリスクスコアデータがありません", - "xpack.securitySolution.overview.riskyHostsSource": "送信元", "xpack.securitySolution.overview.signalCountTitle": "アラート傾向", "xpack.securitySolution.overview.viewAlertsButtonLabel": "アラートを表示", "xpack.securitySolution.overview.viewEventsButtonLabel": "イベントを表示", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 9ef7459001f1f..e39add5811ff4 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -25525,7 +25525,6 @@ "xpack.securitySolution.overview.ctiDashboardSubtitle": "正在显示:{totalCount} 个{totalCount, plural, other {指标}}", "xpack.securitySolution.overview.overviewHost.hostsSubtitle": "正在显示:{formattedHostEventsCount} 个{hostEventsCount, plural, other {事件}}", "xpack.securitySolution.overview.overviewNetwork.networkSubtitle": "正在显示:{formattedNetworkEventsCount} 个{networkEventsCount, plural, other {事件}}", - "xpack.securitySolution.overview.riskyHostsDashboardSubtitle": "正在显示:{totalCount} 台{totalCount, plural, other {主机}}", "xpack.securitySolution.overview.topNLabel": "排名靠前的{fieldName}", "xpack.securitySolution.pages.common.updateAlertStatusFailed": "无法更新{ conflicts } 个{conflicts, plural, other {告警}}。", "xpack.securitySolution.pages.common.updateAlertStatusFailedDetailed": "{ updated } 个{updated, plural, other {告警}}已成功更新,但是 { conflicts } 个无法更新,\n 因为{ conflicts, plural, other {其}}已被修改。", @@ -28586,7 +28585,6 @@ "xpack.securitySolution.overview.ctiDashboardOtherDatasourceTitle": "其他", "xpack.securitySolution.overview.ctiDashboardTitle": "威胁情报", "xpack.securitySolution.overview.ctiViewDasboard": "查看仪表板", - "xpack.securitySolution.overview.enableRiskScorePopoverTitle": "启用模块之前,告警需要处于可用状态", "xpack.securitySolution.overview.endgameDnsTitle": "DNS", "xpack.securitySolution.overview.endgameFileTitle": "文件", "xpack.securitySolution.overview.endgameImageLoadTitle": "映像加载", @@ -28612,7 +28610,6 @@ "xpack.securitySolution.overview.hostStatGroupFilebeat": "Filebeat", "xpack.securitySolution.overview.hostStatGroupWinlogbeat": "Winlogbeat", "xpack.securitySolution.overview.hostsTitle": "主机事件", - "xpack.securitySolution.overview.importDasboard": "导入仪表板", "xpack.securitySolution.overview.landingCards.box.cloudCard.desc": "评估您的云态势并防止工作负载受到攻击。", "xpack.securitySolution.overview.landingCards.box.cloudCard.title": "端到端云防护", "xpack.securitySolution.overview.landingCards.box.endpoint.desc": "防御、收集、检测和响应 — 所有这些活动均可通过 Elastic 代理来实现。", @@ -28635,14 +28632,6 @@ "xpack.securitySolution.overview.packetBeatFlowTitle": "流", "xpack.securitySolution.overview.packetbeatTLSTitle": "TLS", "xpack.securitySolution.overview.recentTimelinesSidebarTitle": "最近的时间线", - "xpack.securitySolution.overview.riskyHostsDashboardDangerPanelButton": "通过开发工具启用", - "xpack.securitySolution.overview.riskyHostsDashboardDangerPanelTitle": "无主机风险分数数据", - "xpack.securitySolution.overview.riskyHostsDashboardEnableThreatIntel": "必须启用主机风险模块才能查看有风险主机。", - "xpack.securitySolution.overview.riskyHostsDashboardLearnMoreButton": "了解详情", - "xpack.securitySolution.overview.riskyHostsDashboardTitle": "当前主机风险分数", - "xpack.securitySolution.overview.riskyHostsDashboardWarningPanelBody": "对于选定时间范围,我们尚未从您环境中的主机中检测到任何主机风险分数数据。", - "xpack.securitySolution.overview.riskyHostsDashboardWarningPanelTitle": "没有可显示的主机风险分数数据", - "xpack.securitySolution.overview.riskyHostsSource": "源", "xpack.securitySolution.overview.signalCountTitle": "告警趋势", "xpack.securitySolution.overview.viewAlertsButtonLabel": "查看告警", "xpack.securitySolution.overview.viewEventsButtonLabel": "查看事件", diff --git a/x-pack/test/observability_functional/apps/observability/pages/alerts/index.ts b/x-pack/test/observability_functional/apps/observability/pages/alerts/index.ts index cdb0ea37a6417..f2a59d6b22b2e 100644 --- a/x-pack/test/observability_functional/apps/observability/pages/alerts/index.ts +++ b/x-pack/test/observability_functional/apps/observability/pages/alerts/index.ts @@ -20,7 +20,8 @@ export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const find = getService('find'); - describe('Observability alerts', function () { + // Failing: See https://github.com/elastic/kibana/issues/140248 + describe.skip('Observability alerts', function () { this.tags('includeFirefox'); const testSubjects = getService('testSubjects'); diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts index 81a1dc109b562..8c8629002c93f 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts @@ -34,28 +34,38 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { 'Actions', ], [ - 'Host-ku5jy6j0pw', + 'Host-nyierkw2gu', 'x', 'x', - 'Unsupported', + 'Failure', 'Windows', - '10.12.215.130, 10.130.188.228,10.19.102.141', - '7.0.13', + '10.180.151.227, 10.44.18.210', + '7.1.9', 'x', '', ], [ - 'Host-ntr4rkj24m', + 'Host-rs9wp4o6l9', 'x', 'x', - 'Success', + 'Warning', 'Windows', - '10.36.46.252, 10.222.152.110', - '7.4.13', + '10.218.38.118, 10.80.35.162', + '8.0.8', + 'x', + '', + ], + [ + 'Host-u5jy6j0pwb', + 'x', + 'x', + 'Warning', + 'Linux', + '10.87.11.145, 10.117.106.109,10.242.136.97', + '7.13.1', 'x', '', ], - ['Host-q9qenwrl9k', 'x', 'x', 'Warning', 'Windows', '10.206.226.90', '7.11.10', 'x', ''], ]; const formattedTableData = async () => { @@ -183,38 +193,16 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { expect(tableData).to.eql(expectedDataFromQuery); }); - it('for the kql filtering for united.endpoint.host.hostname : "Host-ku5jy6j0pw", table shows 1 item', async () => { + it('for the kql filtering for united.endpoint.host.hostname, table shows 1 item', async () => { + const expectedDataFromQuery = [...expectedData.slice(0, 2).map((row) => [...row])]; + const hostName = expectedDataFromQuery[1][0]; const adminSearchBar = await testSubjects.find('adminSearchBar'); await adminSearchBar.clearValueWithKeyboard(); await adminSearchBar.type( - 'united.endpoint.host.hostname : "Host-ku5jy6j0pw" or host.hostname : "Host-ku5jy6j0pw" ' + `united.endpoint.host.hostname : "${hostName}" or host.hostname : "${hostName}" ` ); const querySubmitButton = await testSubjects.find('querySubmitButton'); await querySubmitButton.click(); - const expectedDataFromQuery = [ - [ - 'Endpoint', - 'Agent status', - 'Policy', - 'Policy status', - 'OS', - 'IP address', - 'Version', - 'Last active', - 'Actions', - ], - [ - 'Host-ku5jy6j0pw', - 'x', - 'x', - 'Unsupported', - 'Windows', - '10.12.215.130, 10.130.188.228,10.19.102.141', - '7.0.13', - 'x', - '', - ], - ]; await pageObjects.endpoint.waitForTableToHaveNumberOfEntries( 'endpointListTable', 1,