Skip to content

Commit

Permalink
please comments
Browse files Browse the repository at this point in the history
  • Loading branch information
MadameSheema committed Sep 27, 2022
1 parent 054632e commit c448dd4
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@

import { getIndexConnector } from '../../objects/connector';
import { getSimpleRule } from '../../objects/rule';
import { NUMBER_OF_ALERTS, ALERT_GRID_CELL } from '../../screens/alerts';

import { goToRuleDetails } from '../../tasks/alerts_detection_rules';
import { createEmptyDocument, createIndex, deleteIndex } from '../../tasks/api_calls';
import {
createDocument,
createIndex,
deleteIndex,
waitForNewDocumentToBeIndexed,
} from '../../tasks/api_calls/elasticsearch';
import {
cleanKibana,
deleteAlertsAndRules,
Expand All @@ -37,9 +41,11 @@ describe('Rule actions', () => {
before(() => {
cleanKibana();
login();

/* For later being able to create an index connector, we need to a dataview with at least one document ingested */
createIndex(INDEX_CONNECTOR.index);
createEmptyDocument(INDEX_CONNECTOR.index);
postDataView(INDEX_CONNECTOR.index);
createDocument(INDEX_CONNECTOR.index, '{}');
});

beforeEach(() => {
Expand All @@ -56,6 +62,9 @@ describe('Rule actions', () => {
...getSimpleRule(),
actions: { interval: 'rule', connectors: [INDEX_CONNECTOR] },
};
const index = rule.actions.connectors[0].index;
const initialNumberofDocuments = 1;
const expectedJson = JSON.parse(rule.actions.connectors[0].document);

it('Creates a custom query rule with an index action ', function () {
visit(RULE_CREATION);
Expand All @@ -66,17 +75,17 @@ describe('Rule actions', () => {
createAndEnableRule();
goToRuleDetails();
waitForTheRuleToBeExecuted();

/* We wait for the alerts to be populated first because is when the action is going to be triggered */
waitForAlertsToPopulate();

cy.get(NUMBER_OF_ALERTS)
.invoke('text')
.should('match', /^[1-9].+$/);
cy.get(ALERT_GRID_CELL).contains(rule.name);
/* Once the action is triggered we wait for the new document to be indexed */
waitForNewDocumentToBeIndexed(index, initialNumberofDocuments);

const expectedJson = JSON.parse(rule.actions.connectors[0].document);
/* We assert that the new indexed document is the one set on the index action */
cy.request({
method: 'GET',
url: `${Cypress.env('ELASTICSEARCH_URL')}/${rule.actions.connectors[0].index}/_search`,
url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_search`,
headers: { 'kbn-xsrf': 'cypress-creds' },
}).then((response) => {
expect(response.body.hits.hits[1]._source).to.have.property(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

interface Connector {
type: string;
name: string;
}

Expand All @@ -17,11 +16,13 @@ export interface EmailConnector extends Connector {
user: string;
password: string;
service: string;
type: 'email';
}

export interface IndexConnector extends Connector {
index: string;
document: string;
type: 'index';
}

export type Connectors = IndexConnector | EmailConnector;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ export const createIndex = (index: string) => {
});
};

export const createEmptyDocument = (index: string) => {
export const createDocument = (index: string, document: string) => {
cy.request({
method: 'POST',
url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_doc`,
headers: { 'kbn-xsrf': 'cypress-creds' },
body: {},
body: JSON.parse(document),
});
};

Expand All @@ -31,3 +31,20 @@ export const deleteIndex = (index: string) => {
failOnStatusCode: false,
});
};

export const waitForNewDocumentToBeIndexed = (index: string, initialNumberOfDocuments: number) => {
cy.waitUntil(
() => {
return cy
.request({
method: 'GET',
url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_search`,
headers: { 'kbn-xsrf': 'cypress-creds' },
})
.then((response) => {
return response.body.hits.hits.length > initialNumberOfDocuments;
});
},
{ interval: 500, timeout: 12000 }
);
};
79 changes: 41 additions & 38 deletions x-pack/plugins/security_solution/cypress/tasks/api_calls/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import type {
NewTermsRule,
SavedQueryRule,
} from '../../objects/rule';
import type { CompleteTimeline } from '../../objects/timeline';

export const createMachineLearningRule = (rule: MachineLearningRule, ruleId = 'ml_rule_testing') =>
cy.request({
Expand Down Expand Up @@ -42,20 +41,20 @@ export const createCustomRule = (
ruleId = 'rule_testing',
interval = '100m'
): Cypress.Chainable<Cypress.Response<unknown>> => {
const riskScore = rule.riskScore as string;
const severity = rule.severity as string;
const timeline = rule.timeline as CompleteTimeline;
const riskScore = rule.riskScore != null ? parseInt(rule.riskScore, 10) : undefined;
const severity = rule.severity != null ? rule.severity.toLocaleLowerCase() : undefined;
const timeline = rule.timeline != null ? rule.timeline : undefined;

return cy.request({
method: 'POST',
url: 'api/detection_engine/rules',
body: {
rule_id: ruleId,
risk_score: parseInt(riskScore, 10),
risk_score: riskScore,
description: rule.description,
interval,
name: rule.name,
severity: severity.toLocaleLowerCase(),
severity,
type: 'query',
from: 'now-50000h',
index: rule.dataSource.type === 'indexPatterns' ? rule.dataSource.index : '',
Expand All @@ -64,7 +63,7 @@ export const createCustomRule = (
enabled: false,
exceptions_list: rule.exceptionLists ?? [],
tags: rule.tags,
...(timeline.id ?? timeline.templateTimelineId
...(timeline?.id ?? timeline?.templateTimelineId
? {
timeline_id: timeline.id ?? timeline.templateTimelineId,
timeline_title: timeline.title,
Expand All @@ -78,20 +77,20 @@ export const createCustomRule = (

export const createEventCorrelationRule = (rule: CustomRule, ruleId = 'rule_testing') => {
if (rule.dataSource.type === 'indexPatterns') {
const riskScore = rule.riskScore as string;
const severity = rule.severity as string;
const riskScore = rule.riskScore != null ? parseInt(rule.riskScore, 10) : undefined;
const severity = rule.severity != null ? rule.severity.toLowerCase() : undefined;

cy.request({
method: 'POST',
url: 'api/detection_engine/rules',
body: {
rule_id: ruleId,
risk_score: parseInt(riskScore, 10),
risk_score: riskScore,
description: rule.description,
interval: `${rule.runsEvery?.interval}${rule.runsEvery?.type}`,
from: `now-${rule.lookBack?.interval}${rule.lookBack?.type}`,
name: rule.name,
severity: severity.toLocaleLowerCase(),
severity,
type: 'eql',
index: rule.dataSource.index,
query: rule.customQuery,
Expand All @@ -106,19 +105,20 @@ export const createEventCorrelationRule = (rule: CustomRule, ruleId = 'rule_test

export const createThresholdRule = (rule: ThresholdRule, ruleId = 'rule_testing') => {
if (rule.dataSource.type === 'indexPatterns') {
const riskScore = rule.riskScore as string;
const severity = rule.severity as string;
const riskScore = rule.riskScore != null ? parseInt(rule.riskScore, 10) : undefined;
const severity = rule.severity != null ? rule.severity.toLocaleLowerCase() : undefined;

cy.request({
method: 'POST',
url: 'api/detection_engine/rules',
body: {
rule_id: ruleId,
risk_score: parseInt(riskScore, 10),
risk_score: riskScore,
description: rule.description,
interval: `${rule.runsEvery?.interval}${rule.runsEvery?.type}`,
from: `now-${rule.lookBack?.interval}${rule.lookBack?.type}`,
name: rule.name,
severity: severity.toLocaleLowerCase(),
severity,
type: 'threshold',
index: rule.dataSource.index,
query: rule.customQuery,
Expand All @@ -137,19 +137,20 @@ export const createThresholdRule = (rule: ThresholdRule, ruleId = 'rule_testing'

export const createNewTermsRule = (rule: NewTermsRule, ruleId = 'rule_testing') => {
if (rule.dataSource.type === 'indexPatterns') {
const riskScore = rule.riskScore as string;
const severity = rule.severity as string;
const riskScore = rule.riskScore != null ? parseInt(rule.riskScore, 10) : undefined;
const severity = rule.severity != null ? rule.severity.toLocaleLowerCase() : undefined;

cy.request({
method: 'POST',
url: 'api/detection_engine/rules',
body: {
rule_id: ruleId,
risk_score: parseInt(riskScore, 10),
risk_score: riskScore,
description: rule.description,
interval: `${rule.runsEvery?.interval}${rule.runsEvery?.type}`,
from: `now-${rule.lookBack?.interval}${rule.lookBack?.type}`,
name: rule.name,
severity: severity.toLocaleLowerCase(),
severity,
type: 'new_terms',
index: rule.dataSource.index,
query: rule.customQuery,
Expand All @@ -167,19 +168,20 @@ export const createSavedQueryRule = (
rule: SavedQueryRule,
ruleId = 'saved_query_rule_testing'
): Cypress.Chainable<Cypress.Response<unknown>> => {
const riskScore = rule.riskScore as string;
const severity = rule.severity as string;
const timeline = rule.timeline as CompleteTimeline;
const riskScore = rule.riskScore != null ? parseInt(rule.riskScore, 10) : undefined;
const severity = rule.severity != null ? rule.severity.toLocaleLowerCase() : undefined;
const timeline = rule.timeline != null ? rule.timeline : undefined;

return cy.request({
method: 'POST',
url: 'api/detection_engine/rules',
body: {
rule_id: ruleId,
risk_score: parseInt(riskScore, 10),
risk_score: riskScore,
description: rule.description,
interval: rule.interval,
name: rule.name,
severity: severity.toLocaleLowerCase(),
severity,
type: 'saved_query',
from: 'now-50000h',
index: rule.dataSource.type === 'indexPatterns' ? rule.dataSource.index : '',
Expand All @@ -188,7 +190,7 @@ export const createSavedQueryRule = (
enabled: false,
exceptions_list: rule.exceptionLists ?? [],
tags: rule.tags,
...(timeline.id ?? timeline.templateTimelineId
...(timeline?.id ?? timeline?.templateTimelineId
? {
timeline_id: timeline.id ?? timeline.templateTimelineId,
timeline_title: timeline.title,
Expand All @@ -202,24 +204,25 @@ export const createSavedQueryRule = (

export const createCustomIndicatorRule = (rule: ThreatIndicatorRule, ruleId = 'rule_testing') => {
if (rule.dataSource.type === 'indexPatterns') {
const riskScore = rule.riskScore as string;
const severity = rule.severity as string;
const timeline = rule.timeline as CompleteTimeline;
const riskScore = rule.riskScore != null ? parseInt(rule.riskScore, 10) : undefined;
const severity = rule.severity != null ? rule.severity.toLocaleLowerCase() : undefined;
const timeline = rule.timeline != null ? rule.timeline : undefined;

cy.request({
method: 'POST',
url: 'api/detection_engine/rules',
body: {
rule_id: ruleId,
risk_score: parseInt(riskScore, 10),
risk_score: riskScore,
description: rule.description,
// Default interval is 1m, our tests config overwrite this to 1s
// See https://github.com/elastic/kibana/pull/125396 for details
interval: '10s',
name: rule.name,
severity: severity.toLocaleLowerCase(),
severity,
type: 'threat_match',
timeline_id: timeline.templateTimelineId,
timeline_title: timeline.title,
timeline_id: timeline?.templateTimelineId,
timeline_title: timeline?.title,
threat_mapping: [
{
entries: [
Expand Down Expand Up @@ -255,20 +258,20 @@ export const createCustomRuleEnabled = (
interval = '100m',
maxSignals = 500
) => {
const riskScore = rule.riskScore as string;
const severity = rule.severity as string;
const riskScore = rule.riskScore != null ? parseInt(rule.riskScore, 10) : undefined;
const severity = rule.severity != null ? rule.severity.toLocaleLowerCase() : undefined;

if (rule.dataSource.type === 'indexPatterns') {
cy.request({
method: 'POST',
url: 'api/detection_engine/rules',
body: {
rule_id: ruleId,
risk_score: parseInt(riskScore, 10),
risk_score: riskScore,
description: rule.description,
interval,
name: rule.name,
severity: severity.toLocaleLowerCase(),
severity,
type: 'query',
from: 'now-50000h',
index: rule.dataSource.index,
Expand All @@ -289,11 +292,11 @@ export const createCustomRuleEnabled = (
url: 'api/detection_engine/rules',
body: {
rule_id: ruleId,
risk_score: parseInt(riskScore, 10),
risk_score: riskScore,
description: rule.description,
interval,
name: rule.name,
severity: severity.toLocaleLowerCase(),
severity,
type: 'query',
from: 'now-50000h',
index: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,13 +296,13 @@ export const fillRuleAction = (rule: CustomRule) => {
rule.actions?.connectors.forEach((connector) => {
switch (connector.type) {
case 'index':
const indexConnector = connector as IndexConnector;
const indexConnector = connector;
cy.get(INDEX_SELECTOR).click();
cy.get(CREATE_CONNECTOR_BTN).click();
fillIndexConnectorForm(indexConnector);
break;
case 'email':
const emailConnector = connector as EmailConnector;
const emailConnector = connector;
cy.get(EMAIL_ACTION_BTN).click();
cy.get(CREATE_ACTION_CONNECTOR_BTN).click();
fillEmailConnectorForm(emailConnector);
Expand Down

0 comments on commit c448dd4

Please sign in to comment.