Skip to content

Commit cde2885

Browse files
[SIEM] Changes ML conditional links to use tabs, fixes a small bug with null filterQuery (#45218)
## Summary Changes the ML drill-downs to use the tabs and re-direct to the Anomalies table when drilled down. #45080 Tests for this were both by playing with the Anomalies as well as hand testing that these clickable links below do what I would expect them to do based on the conditional rules of: * Split comma separated values into OR clauses within KQL. * Redirect from multiple hosts/ips on the details page to the host over view/detail overview page with a new KQL added as a filter since comma separated values on details would just be errors. * Remove/Replace any $value$ dollar values that did not have a value as before. Manual testing is from either the test cases below or by using the ML Anomalies explorerand clicking on the drill down links using the action menu items from Host or IP jobs which look like this: <img width="352" alt="Screen Shot 2019-09-06 at 4 17 05 PM" src="https://user-images.githubusercontent.com/1151048/64576200-c1852780-d334-11e9-8270-ef97569a2e78.png"> URL manual test cases I used: Testing conditional ml-network links: ----- Single IP with a null for the KQL: http://localhost:5601/app/siem#/ml-network/ip/127.0.0.1?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z'))) Single IP with kqlQuery: http://localhost:5601/app/siem#/ml-network/ip/127.0.0.1?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z'))) Multiple IP's with a null for the filterQuery: http://localhost:5601/app/siem#/ml-network/ip/127.0.0.1,127.0.0.2?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z'))) Multiple IP's with a value for the filterQuery: http://localhost:5601/app/siem#/ml-network/ip/127.0.0.1,127.0.0.2?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z'))) Undefined/null IP and a null filterQuery: http://localhost:5601/app/siem#/ml-network/ip/$ip$?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z'))) Undefined/null IP but a value for the filterQuery: http://localhost:5601/app/siem#/ml-network/ip/$ip$?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z'))) Testing conditional host links: Single host name with a null for the KQL: http://localhost:5601/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z'))) Single host name with a variable left in the KQL http://localhost:5601/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22$process.name$%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z'))) Single host name with a value for filterQuery: http://localhost:5601/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z'))) Multiple host names with null for filterQuery http://localhost:5601/app/siem#/ml-hosts/siem-windows,siem-suricata?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z'))) Multiple host names with a value for filterQuery http://localhost:5601/app/siem#/ml-hosts/siem-windows,siem-suricata?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z'))) Undefined/null host name with a null for the KQL: http://localhost:5601/app/siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z'))) Undefined/null host name but with a value for filterQuery http://localhost:5601/app/siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z'))) ---- Extra misc tests: 3 host names http://localhost:5601/app/siem#/ml-hosts/suricata-iowa,siem-windows,siem-fake?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22snapd%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-09-09T18:00:00.000Z',kind:absolute,to:'2019-09-09T20:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-09-09T18:00:00.000Z',kind:absolute,to:'2019-09-09T20:59:59.999Z'))) 3 ips http://localhost:5601/app/siem#/ml-network/ip/127.0.0.1,127.0.0.2,127.0.0.3?_g=()&kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T06:00:00.000Z',kind:absolute,to:'2019-08-29T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T06:00:00.000Z',kind:absolute,to:'2019-08-29T05:59:59.999Z'))) ### Checklist Use ~~strikethroughs~~ to remove checklist items you don't feel are applicable to this PR. - [x] This was checked for cross-browser compatibility, [including a check against IE11](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md) - [x] [Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios - [ ] This was checked for [keyboard-only and screenreader accessibility](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Accessibility_testing_checklist) ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process) - [x] This includes a feature addition or change that requires a release note and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)
1 parent 67e9eaf commit cde2885

File tree

8 files changed

+320
-26
lines changed

8 files changed

+320
-26
lines changed

x-pack/legacy/plugins/siem/cypress/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ CYPRESS_baseUrl=http://localhost:5601 CYPRESS_ELASTICSEARCH_USERNAME=elastic CYP
201201

202202
When Cypress tests are run on the command line via `yarn cypress:run`,
203203
reporting artifacts are generated under the `target` directory in the root
204-
of the Kibana, as detailed for each artifact type in the sections bleow.
204+
of the Kibana, as detailed for each artifact type in the sections below.
205205

206206
### HTML Reports
207207

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
/*
8+
* These links are for different test scenarios that try and capture different drill downs into
9+
* ml-network and ml-hosts and are of the flavor of testing:
10+
* A filter being null: (filterQuery:!n)
11+
* A filter being set with single values: filterQuery:(expression:%27process.name%20:%20%22conhost.exe%22%27,kind:kuery)
12+
* A filter being set with multiple values: filterQuery:(expression:%27process.name%20:%20%22conhost.exe,sc.exe%22%27,kind:kuery)
13+
* A filter containing variables not replaced: filterQuery:(expression:%27process.name%20:%20%$process.name$%22%27,kind:kuery)
14+
*
15+
* In different combination with:
16+
* network not being set: $ip$
17+
* host not being set: $host.name$
18+
* ...or...
19+
* network being set normally: 127.0.0.1
20+
* host being set normally: suricata-iowa
21+
* ...or...
22+
* network having multiple values: 127.0.0.1,127.0.0.2
23+
* host having multiple values: suricata-iowa,siem-windows
24+
*/
25+
26+
// Single IP with a null for the filterQuery:
27+
export const mlNetworkSingleIpNullFilterQuery =
28+
"/app/siem#/ml-network/ip/127.0.0.1?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";
29+
30+
// Single IP with a value for the filterQuery:
31+
export const mlNetworkSingleIpFilterQuery =
32+
"/app/siem#/ml-network/ip/127.0.0.1?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";
33+
34+
// Multiple IPs with a null for the filterQuery:
35+
export const mlNetworkMultipleIpNullFilterQuery =
36+
"/app/siem#/ml-network/ip/127.0.0.1,127.0.0.2?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";
37+
38+
// Multiple IPs with a value for the filterQuery:
39+
export const mlNetworkMultipleIpFilterQuery =
40+
"/app/siem#/ml-network/ip/127.0.0.1,127.0.0.2?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";
41+
42+
// $ip$ with a null filterQuery:
43+
export const mlNetworkNullFilterQuery =
44+
"/app/siem#/ml-network/ip/$ip$?kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";
45+
46+
// $ip$ with a value for the filterQuery:
47+
export const mlNetworkFilterQuery =
48+
"/app/siem#/ml-network/ip/$ip$?kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))";
49+
50+
// Single host name with a null for the filterQuery:
51+
export const mlHostSingleHostNullFilterQuery =
52+
"/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";
53+
54+
// Single host name with a variable in the filterQuery
55+
export const mlHostSingleHostFilterQueryVariable =
56+
"/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22$process.name$%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";
57+
58+
// Single host name with a value for filterQuery:
59+
export const mlHostSingleHostFilterQuery =
60+
"/app/siem#/ml-hosts/siem-windows?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";
61+
62+
// Multiple host names with null for filterQuery
63+
export const mlHostMultiHostNullFilterQuery =
64+
"/app/siem#/ml-hosts/siem-windows,siem-suricata?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";
65+
66+
// Multiple host names with a value for filterQuery
67+
export const mlHostMultiHostFilterQuery =
68+
"/app/siem#/ml-hosts/siem-windows,siem-suricata?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";
69+
70+
// Undefined/null host name with a null for the KQL:
71+
export const mlHostVariableHostNullFilterQuery =
72+
"/app/siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:!n,queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";
73+
74+
// Undefined/null host name but with a value for filterQuery
75+
export const mlHostVariableHostFilterQuery =
76+
"/app/siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:(expression:'process.name%20:%20%22conhost.exe,sc.exe%22',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))";
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { logout } from '../../lib/logout';
8+
import {
9+
mlNetworkSingleIpNullFilterQuery,
10+
mlNetworkSingleIpFilterQuery,
11+
mlNetworkMultipleIpNullFilterQuery,
12+
mlNetworkMultipleIpFilterQuery,
13+
mlNetworkNullFilterQuery,
14+
mlNetworkFilterQuery,
15+
mlHostSingleHostNullFilterQuery,
16+
mlHostSingleHostFilterQueryVariable,
17+
mlHostSingleHostFilterQuery,
18+
mlHostMultiHostNullFilterQuery,
19+
mlHostMultiHostFilterQuery,
20+
mlHostVariableHostNullFilterQuery,
21+
mlHostVariableHostFilterQuery,
22+
} from '../../lib/ml_conditional_links';
23+
import { loginAndWaitForPage } from '../../lib/util/helpers';
24+
import { KQL_INPUT } from '../../lib/url_state';
25+
26+
describe('ml conditional links', () => {
27+
afterEach(() => {
28+
return logout();
29+
});
30+
31+
it('sets the KQL from a single IP with a value for the filterQuery', () => {
32+
loginAndWaitForPage(mlNetworkSingleIpFilterQuery);
33+
cy.get(KQL_INPUT, { timeout: 5000 }).should(
34+
'have.attr',
35+
'value',
36+
'(process.name: "conhost.exe" or process.name: "sc.exe")'
37+
);
38+
});
39+
40+
it('sets the KQL from a multiple IPs with a null for the filterQuery', () => {
41+
loginAndWaitForPage(mlNetworkMultipleIpNullFilterQuery);
42+
cy.get(KQL_INPUT, { timeout: 5000 }).should(
43+
'have.attr',
44+
'value',
45+
'((source.ip: "127.0.0.1" or destination.ip: "127.0.0.1") or (source.ip: "127.0.0.2" or destination.ip: "127.0.0.2"))'
46+
);
47+
});
48+
49+
it('sets the KQL from a multiple IPs with a value for the filterQuery', () => {
50+
loginAndWaitForPage(mlNetworkMultipleIpFilterQuery);
51+
cy.get(KQL_INPUT, { timeout: 5000 }).should(
52+
'have.attr',
53+
'value',
54+
'((source.ip: "127.0.0.1" or destination.ip: "127.0.0.1") or (source.ip: "127.0.0.2" or destination.ip: "127.0.0.2")) and ((process.name: "conhost.exe" or process.name: "sc.exe"))'
55+
);
56+
});
57+
58+
it('sets the KQL from a $ip$ with a value for the filterQuery', () => {
59+
loginAndWaitForPage(mlNetworkFilterQuery);
60+
cy.get(KQL_INPUT, { timeout: 5000 }).should(
61+
'have.attr',
62+
'value',
63+
'(process.name: "conhost.exe" or process.name: "sc.exe")'
64+
);
65+
});
66+
67+
it('sets the KQL from a single host name with a value for filterQuery', () => {
68+
loginAndWaitForPage(mlHostSingleHostFilterQuery);
69+
cy.get(KQL_INPUT, { timeout: 5000 }).should(
70+
'have.attr',
71+
'value',
72+
'(process.name: "conhost.exe" or process.name: "sc.exe")'
73+
);
74+
});
75+
76+
it('sets the KQL from a multiple host names with null for filterQuery', () => {
77+
loginAndWaitForPage(mlHostMultiHostNullFilterQuery);
78+
cy.get(KQL_INPUT, { timeout: 5000 }).should(
79+
'have.attr',
80+
'value',
81+
'(host.name: "siem-windows" or host.name: "siem-suricata")'
82+
);
83+
});
84+
85+
it('sets the KQL from a multiple host names with a value for filterQuery', () => {
86+
loginAndWaitForPage(mlHostMultiHostFilterQuery);
87+
cy.get(KQL_INPUT, { timeout: 5000 }).should(
88+
'have.attr',
89+
'value',
90+
'(host.name: "siem-windows" or host.name: "siem-suricata") and ((process.name: "conhost.exe" or process.name: "sc.exe"))'
91+
);
92+
});
93+
94+
it('sets the KQL from a undefined/null host name but with a value for filterQuery', () => {
95+
loginAndWaitForPage(mlHostVariableHostFilterQuery);
96+
cy.get(KQL_INPUT, { timeout: 5000 }).should(
97+
'have.attr',
98+
'value',
99+
'(process.name: "conhost.exe" or process.name: "sc.exe")'
100+
);
101+
});
102+
103+
it('redirects from a single IP with a null for the filterQuery', () => {
104+
loginAndWaitForPage(mlNetworkSingleIpNullFilterQuery);
105+
cy.url().should(
106+
'equal',
107+
'http://localhost:5601/app/siem#/network/ip/127.0.0.1?timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))'
108+
);
109+
});
110+
111+
it('redirects from a single IP with a value for the filterQuery', () => {
112+
loginAndWaitForPage(mlNetworkSingleIpFilterQuery);
113+
cy.url().should(
114+
'equal',
115+
"http://localhost:5601/app/siem#/network/ip/127.0.0.1?kqlQuery=(filterQuery:(expression:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)',kind:kuery),queryLocation:network.details)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
116+
);
117+
});
118+
119+
it('redirects from a multiple IPs with a null for the filterQuery', () => {
120+
loginAndWaitForPage(mlNetworkMultipleIpNullFilterQuery);
121+
cy.url().should(
122+
'equal',
123+
"http://localhost:5601/app/siem#/network?kqlQuery=(filterQuery:(expression:'((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))'),queryLocation:network.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
124+
);
125+
});
126+
127+
it('redirects from a multiple IPs with a value for the filterQuery', () => {
128+
loginAndWaitForPage(mlNetworkMultipleIpFilterQuery);
129+
cy.url().should(
130+
'equal',
131+
"http://localhost:5601/app/siem#/network?kqlQuery=(filterQuery:(expression:'((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))',kind:kuery),queryLocation:network.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
132+
);
133+
});
134+
135+
it('redirects from a $ip$ with a null filterQuery', () => {
136+
loginAndWaitForPage(mlNetworkNullFilterQuery);
137+
cy.url().should(
138+
'equal',
139+
'http://localhost:5601/app/siem#/network?timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))'
140+
);
141+
});
142+
143+
it('redirects from a $ip$ with a value for the filterQuery', () => {
144+
loginAndWaitForPage(mlNetworkFilterQuery);
145+
cy.url().should(
146+
'equal',
147+
"http://localhost:5601/app/siem#/network?kqlQuery=(filterQuery:(expression:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)',kind:kuery),queryLocation:network.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
148+
);
149+
});
150+
151+
it('redirects from a single host name with a null for the filterQuery', () => {
152+
loginAndWaitForPage(mlHostSingleHostNullFilterQuery);
153+
cy.url().should(
154+
'equal',
155+
'http://localhost:5601/app/siem#/hosts/siem-windows/anomalies?_g=()&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))'
156+
);
157+
});
158+
159+
it('redirects from a host name with a variable in the filterQuery', () => {
160+
loginAndWaitForPage(mlHostSingleHostFilterQueryVariable);
161+
cy.url().should(
162+
'equal',
163+
'http://localhost:5601/app/siem#/hosts/siem-windows/anomalies?_g=()&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))'
164+
);
165+
});
166+
167+
it('redirects from a single host name with a value for filterQuery', () => {
168+
loginAndWaitForPage(mlHostSingleHostFilterQuery);
169+
cy.url().should(
170+
'equal',
171+
"http://localhost:5601/app/siem#/hosts/siem-windows/anomalies?_g=()&kqlQuery=(filterQuery:(expression:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)',kind:kuery),queryLocation:hosts.details)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
172+
);
173+
});
174+
175+
it('redirects from a multiple host names with null for filterQuery', () => {
176+
loginAndWaitForPage(mlHostMultiHostNullFilterQuery);
177+
cy.url().should(
178+
'equal',
179+
"http://localhost:5601/app/siem#/hosts/anomalies?_g=()&kqlQuery=(filterQuery:(expression:'(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)'),queryLocation:hosts.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
180+
);
181+
});
182+
183+
it('redirects from a multiple host names with a value for filterQuery', () => {
184+
loginAndWaitForPage(mlHostMultiHostFilterQuery);
185+
cy.url().should(
186+
'equal',
187+
"http://localhost:5601/app/siem#/hosts/anomalies?_g=()&kqlQuery=(filterQuery:(expression:'(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))',kind:kuery),queryLocation:hosts.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
188+
);
189+
});
190+
191+
it('redirects from a undefined/null host name with a null for the KQL', () => {
192+
loginAndWaitForPage(mlHostVariableHostNullFilterQuery);
193+
cy.url().should(
194+
'equal',
195+
'http://localhost:5601/app/siem#/hosts/anomalies?_g=()&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))'
196+
);
197+
});
198+
199+
it('redirects from a undefined/null host name but with a value for filterQuery', () => {
200+
loginAndWaitForPage(mlHostVariableHostFilterQuery);
201+
cy.url().should(
202+
'equal',
203+
"http://localhost:5601/app/siem#/hosts/anomalies?_g=()&kqlQuery=(filterQuery:(expression:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)',kind:kuery),queryLocation:hosts.page)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
204+
);
205+
});
206+
});

x-pack/legacy/plugins/siem/public/components/ml/conditional_links/add_entities_to_kql.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ describe('add_entities_to_kql', () => {
1717
afterAll(() => {
1818
console.log = originalError;
1919
});
20+
2021
describe('#entityToKql', () => {
2122
test('returns empty string with no entity names defined and an empty entity string', () => {
2223
const entity = entityToKql([], '');
@@ -165,5 +166,10 @@ describe('add_entities_to_kql', () => {
165166
'(filterQuery:(expression:\'(host.name: "host-name-1" or host.name: "host-name-2") and (process.name : "")\',kind:kuery))'
166167
);
167168
});
169+
170+
test('returns kql expression with a null filterQuery', () => {
171+
const entity = addEntitiesToKql(['host.name'], ['host-1'], '(filterQuery:!n)');
172+
expect(entity).toEqual('(filterQuery:(expression:\'(host.name: "host-1")\'))');
173+
});
168174
});
169175
});

x-pack/legacy/plugins/siem/public/components/ml/conditional_links/add_entities_to_kql.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ export const addEntitiesToKql = (
5252
}
5353
return encode(value);
5454
}
55+
} else if (value.filterQuery == null) {
56+
const entitiesKql = entitiesToKql(entityNames, entities);
57+
value.filterQuery = { expression: `(${entitiesKql})` };
58+
return encode(value);
5559
}
5660
}
5761
return kqlQuery;

0 commit comments

Comments
 (0)