Skip to content

Commit

Permalink
Update existing endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
banderror committed Nov 1, 2021
1 parent fb92607 commit e6e84bf
Show file tree
Hide file tree
Showing 25 changed files with 155 additions and 246 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { ALERT_WORKFLOW_STATUS } from '@kbn/rule-data-utils';
import { ruleTypeMappings } from '@kbn/securitysolution-rules';

import { SavedObjectsFindResponse, SavedObjectsFindResult } from 'kibana/server';
import { SavedObjectsFindResponse } from 'src/core/server';

import { ActionResult } from '../../../../../../actions/server';
import {
Expand Down Expand Up @@ -42,7 +42,8 @@ import { SanitizedAlert, ResolvedSanitizedRule } from '../../../../../../alertin
import { getQueryRuleParams } from '../../schemas/rule_schemas.mock';
import { getPerformBulkActionSchemaMock } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema.mock';
import { RuleExecutionStatus } from '../../../../../common/detection_engine/schemas/common/schemas';
import { FindBulkExecutionLogResponse } from '../../rule_execution_log/types';
import { GetCurrentStatusBulkResult } from '../../rule_execution_log/types';
import { ruleTypeMappings } from '../../signals/utils';
// eslint-disable-next-line no-restricted-imports
import type { LegacyRuleNotificationAlertType } from '../../notifications/legacy_types';

Expand Down Expand Up @@ -475,94 +476,64 @@ export const getEmptySavedObjectsResponse =
saved_objects: [],
});

export const getRuleExecutionStatuses = (): Array<
SavedObjectsFindResult<IRuleStatusSOAttributes>
> => [
{
type: 'my-type',
id: 'e0b86950-4e9f-11ea-bdbd-07b56aa159b3',
attributes: {
statusDate: '2020-02-18T15:26:49.783Z',
status: RuleExecutionStatus.succeeded,
lastFailureAt: undefined,
lastSuccessAt: '2020-02-18T15:26:49.783Z',
lastFailureMessage: undefined,
lastSuccessMessage: 'succeeded',
lastLookBackDate: new Date('2020-02-18T15:14:58.806Z').toISOString(),
gap: '500.32',
searchAfterTimeDurations: ['200.00'],
bulkCreateTimeDurations: ['800.43'],
},
score: 1,
references: [
{
id: '04128c15-0d1b-4716-a4c5-46997ac7f3bc',
type: 'alert',
name: 'alert_0',
},
],
updated_at: '2020-02-18T15:26:51.333Z',
version: 'WzQ2LDFd',
},
{
type: 'my-type',
id: '91246bd0-5261-11ea-9650-33b954270f67',
attributes: {
statusDate: '2020-02-18T15:15:58.806Z',
status: RuleExecutionStatus.failed,
lastFailureAt: '2020-02-18T15:15:58.806Z',
lastSuccessAt: '2020-02-13T20:31:59.855Z',
lastFailureMessage:
'Signal rule name: "Query with a rule id Number 1", id: "1ea5a820-4da1-4e82-92a1-2b43a7bece08", rule_id: "query-rule-id-1" has a time gap of 5 days (412682928ms), and could be missing signals within that time. Consider increasing your look behind time or adding more Kibana instances.',
lastSuccessMessage: 'succeeded',
lastLookBackDate: new Date('2020-02-18T15:14:58.806Z').toISOString(),
gap: '500.32',
searchAfterTimeDurations: ['200.00'],
bulkCreateTimeDurations: ['800.43'],
},
score: 1,
references: [
{
id: '1ea5a820-4da1-4e82-92a1-2b43a7bece08',
type: 'alert',
name: 'alert_0',
},
],
updated_at: '2020-02-18T15:15:58.860Z',
version: 'WzMyLDFd',
},
export const getRuleExecutionStatusSucceeded = (): IRuleStatusSOAttributes => ({
statusDate: '2020-02-18T15:26:49.783Z',
status: RuleExecutionStatus.succeeded,
lastFailureAt: undefined,
lastSuccessAt: '2020-02-18T15:26:49.783Z',
lastFailureMessage: undefined,
lastSuccessMessage: 'succeeded',
lastLookBackDate: new Date('2020-02-18T15:14:58.806Z').toISOString(),
gap: '500.32',
searchAfterTimeDurations: ['200.00'],
bulkCreateTimeDurations: ['800.43'],
});

export const getRuleExecutionStatusFailed = (): IRuleStatusSOAttributes => ({
statusDate: '2020-02-18T15:15:58.806Z',
status: RuleExecutionStatus.failed,
lastFailureAt: '2020-02-18T15:15:58.806Z',
lastSuccessAt: '2020-02-13T20:31:59.855Z',
lastFailureMessage:
'Signal rule name: "Query with a rule id Number 1", id: "1ea5a820-4da1-4e82-92a1-2b43a7bece08", rule_id: "query-rule-id-1" has a time gap of 5 days (412682928ms), and could be missing signals within that time. Consider increasing your look behind time or adding more Kibana instances.',
lastSuccessMessage: 'succeeded',
lastLookBackDate: new Date('2020-02-18T15:14:58.806Z').toISOString(),
gap: '500.32',
searchAfterTimeDurations: ['200.00'],
bulkCreateTimeDurations: ['800.43'],
});

export const getRuleExecutionStatuses = (): IRuleStatusSOAttributes[] => [
getRuleExecutionStatusSucceeded(),
getRuleExecutionStatusFailed(),
];

export const getFindBulkResultStatus = (): FindBulkExecutionLogResponse => ({
'04128c15-0d1b-4716-a4c5-46997ac7f3bd': [
{
statusDate: '2020-02-18T15:26:49.783Z',
status: RuleExecutionStatus.succeeded,
lastFailureAt: undefined,
lastSuccessAt: '2020-02-18T15:26:49.783Z',
lastFailureMessage: undefined,
lastSuccessMessage: 'succeeded',
lastLookBackDate: new Date('2020-02-18T15:14:58.806Z').toISOString(),
gap: '500.32',
searchAfterTimeDurations: ['200.00'],
bulkCreateTimeDurations: ['800.43'],
},
],
'1ea5a820-4da1-4e82-92a1-2b43a7bece08': [
{
statusDate: '2020-02-18T15:15:58.806Z',
status: RuleExecutionStatus.failed,
lastFailureAt: '2020-02-18T15:15:58.806Z',
lastSuccessAt: '2020-02-13T20:31:59.855Z',
lastFailureMessage:
'Signal rule name: "Query with a rule id Number 1", id: "1ea5a820-4da1-4e82-92a1-2b43a7bece08", rule_id: "query-rule-id-1" has a time gap of 5 days (412682928ms), and could be missing signals within that time. Consider increasing your look behind time or adding more Kibana instances.',
lastSuccessMessage: 'succeeded',
lastLookBackDate: new Date('2020-02-18T15:14:58.806Z').toISOString(),
gap: '500.32',
searchAfterTimeDurations: ['200.00'],
bulkCreateTimeDurations: ['800.43'],
},
],
export const getFindBulkResultStatus = (): GetCurrentStatusBulkResult => ({
'04128c15-0d1b-4716-a4c5-46997ac7f3bd': {
statusDate: '2020-02-18T15:26:49.783Z',
status: RuleExecutionStatus.succeeded,
lastFailureAt: undefined,
lastSuccessAt: '2020-02-18T15:26:49.783Z',
lastFailureMessage: undefined,
lastSuccessMessage: 'succeeded',
lastLookBackDate: new Date('2020-02-18T15:14:58.806Z').toISOString(),
gap: '500.32',
searchAfterTimeDurations: ['200.00'],
bulkCreateTimeDurations: ['800.43'],
},
'1ea5a820-4da1-4e82-92a1-2b43a7bece08': {
statusDate: '2020-02-18T15:15:58.806Z',
status: RuleExecutionStatus.failed,
lastFailureAt: '2020-02-18T15:15:58.806Z',
lastSuccessAt: '2020-02-13T20:31:59.855Z',
lastFailureMessage:
'Signal rule name: "Query with a rule id Number 1", id: "1ea5a820-4da1-4e82-92a1-2b43a7bece08", rule_id: "query-rule-id-1" has a time gap of 5 days (412682928ms), and could be missing signals within that time. Consider increasing your look behind time or adding more Kibana instances.',
lastSuccessMessage: 'succeeded',
lastLookBackDate: new Date('2020-02-18T15:14:58.806Z').toISOString(),
gap: '500.32',
searchAfterTimeDurations: ['200.00'],
bulkCreateTimeDurations: ['800.43'],
},
});

export const getBasicEmptySearchResponse = (): estypes.SearchResponse<unknown> => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
getEmptyFindResult,
getAlertMock,
getCreateRequest,
getRuleExecutionStatuses,
getRuleExecutionStatusSucceeded,
getFindResultWithSingleHit,
createMlRuleRequest,
getBasicEmptySearchResponse,
Expand Down Expand Up @@ -43,7 +43,9 @@ describe.each([
clients.rulesClient.create.mockResolvedValue(
getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())
); // creation succeeds
clients.ruleExecutionLogClient.find.mockResolvedValue(getRuleExecutionStatuses()); // needed to transform: ;
clients.ruleExecutionLogClient.getCurrentStatus.mockResolvedValue(
getRuleExecutionStatusSucceeded()
);

context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValue(
elasticsearchClientMock.createSuccessTransportRequestPromise(getBasicEmptySearchResponse())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,13 @@ export const createRulesRoute = (
await rulesClient.muteAll({ id: createdRule.id });
}

const ruleStatuses = await context.securitySolution.getExecutionLogClient().find({
logsCount: 1,
const ruleStatus = await context.securitySolution.getExecutionLogClient().getCurrentStatus({
ruleId: createdRule.id,
spaceId: context.securitySolution.getSpaceId(),
});
const [validated, errors] = newTransformValidate(
createdRule,
ruleStatuses[0],
ruleStatus,
isRuleRegistryEnabled
);
if (errors != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,21 +80,19 @@ export const deleteRulesBulkRoute = (
return getIdBulkError({ id, ruleId });
}

const ruleStatuses = await ruleStatusClient.find({
logsCount: 6,
const ruleStatus = await ruleStatusClient.getCurrentStatus({
ruleId: rule.id,
spaceId: context.securitySolution.getSpaceId(),
});
await deleteRules({
ruleId: rule.id,
rulesClient,
ruleStatusClient,
ruleStatuses,
id: rule.id,
});
return transformValidateBulkError(
idOrRuleIdOrUnknown,
rule,
ruleStatuses,
[ruleStatus],
isRuleRegistryEnabled
);
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
getDeleteRequest,
getFindResultWithSingleHit,
getDeleteRequestById,
getRuleExecutionStatuses,
getRuleExecutionStatusSucceeded,
getEmptySavedObjectsResponse,
} from '../__mocks__/request_responses';
import { requestContextMock, serverMock, requestMock } from '../__mocks__';
Expand All @@ -32,7 +32,9 @@ describe.each([

clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled));
clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse());
clients.ruleExecutionLogClient.find.mockResolvedValue(getRuleExecutionStatuses());
clients.ruleExecutionLogClient.getCurrentStatus.mockResolvedValue(
getRuleExecutionStatusSucceeded()
);

deleteRulesRoute(server.router, isRuleRegistryEnabled);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,16 @@ export const deleteRulesRoute = (
});
}

const ruleStatuses = await ruleStatusClient.find({
logsCount: 6,
const currentStatus = await ruleStatusClient.getCurrentStatus({
ruleId: rule.id,
spaceId: context.securitySolution.getSpaceId(),
});
await deleteRules({
ruleId: rule.id,
rulesClient,
ruleStatusClient,
ruleStatuses,
id: rule.id,
});
const transformed = transform(rule, ruleStatuses[0], isRuleRegistryEnabled);
const transformed = transform(rule, currentStatus, isRuleRegistryEnabled);
if (transformed == null) {
return siemResponse.error({ statusCode: 500, body: 'failed to transform alert' });
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ describe.each([
getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())
);
clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse());
clients.ruleExecutionLogClient.findBulk.mockResolvedValue(getFindBulkResultStatus());
clients.ruleExecutionLogClient.getCurrentStatusBulk.mockResolvedValue(
getFindBulkResultStatus()
);

findRulesRoute(server.router, logger, isRuleRegistryEnabled);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,14 @@ export const findRulesRoute = (
});
const alertIds = rules.data.map((rule) => rule.id);

const [ruleStatuses, ruleActions] = await Promise.all([
execLogClient.findBulk({
const [currentStatusesByRuleId, ruleActions] = await Promise.all([
execLogClient.getCurrentStatusBulk({
ruleIds: alertIds,
logsCount: 1,
spaceId: context.securitySolution.getSpaceId(),
}),
legacyGetBulkRuleActionsSavedObject({ alertIds, savedObjectsClient, logger }),
]);
const transformed = transformFindAlerts(rules, ruleStatuses, ruleActions);
const transformed = transformFindAlerts(rules, currentStatusesByRuleId, ruleActions);
if (transformed == null) {
return siemResponse.error({ statusCode: 500, body: 'Internal error transforming' });
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ describe.each([
beforeEach(async () => {
server = serverMock.create();
({ clients, context } = requestContextMock.createTools());
clients.ruleExecutionLogClient.findBulk.mockResolvedValue(getFindBulkResultStatus()); // successful status search
clients.ruleExecutionLogClient.getCurrentStatusBulk.mockResolvedValue(
getFindBulkResultStatus()
); // successful status search
clients.rulesClient.get.mockResolvedValue(
getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())
);
Expand All @@ -48,7 +50,7 @@ describe.each([
});

test('catch error when status search throws error', async () => {
clients.ruleExecutionLogClient.findBulk.mockImplementation(async () => {
clients.ruleExecutionLogClient.getCurrentStatusBulk.mockImplementation(async () => {
throw new Error('Test error');
});
const response = await server.inject(ruleStatusRequest(), context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,31 +48,30 @@ export const findRulesStatusesRoute = (router: SecuritySolutionPluginRouter) =>
const ids = body.ids;
try {
const ruleStatusClient = context.securitySolution.getExecutionLogClient();
const [statusesById, failingRules] = await Promise.all([
ruleStatusClient.findBulk({
const [currentStatusesByRuleId, failingRules] = await Promise.all([
ruleStatusClient.getCurrentStatusBulk({
ruleIds: ids,
logsCount: 6,
spaceId: context.securitySolution.getSpaceId(),
}),
getFailingRules(ids, rulesClient),
]);

const statuses = ids.reduce((acc, id) => {
const lastFiveErrorsForId = statusesById[id];
const currentStatus = currentStatusesByRuleId[id];
const failingRule = failingRules[id];

if (lastFiveErrorsForId == null || lastFiveErrorsForId.length === 0) {
if (currentStatus == null) {
return acc;
}

const failingRule = failingRules[id];
const finalCurrentStatus =
failingRule != null
? mergeAlertWithSidecarStatus(failingRule, currentStatus)
: currentStatus;

if (failingRule != null) {
const currentStatus = mergeAlertWithSidecarStatus(failingRule, lastFiveErrorsForId[0]);
const updatedLastFiveErrorsSO = [currentStatus, ...lastFiveErrorsForId.slice(1)];
return mergeStatuses(id, updatedLastFiveErrorsSO, acc);
}
return mergeStatuses(id, [...lastFiveErrorsForId], acc);
return mergeStatuses(id, [finalCurrentStatus], acc);
}, {});

return response.ok({ body: statuses });
} catch (err) {
const error = transformError(err);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,11 @@ export const patchRulesBulkRoute = (
exceptionsList,
});
if (rule != null && rule.enabled != null && rule.name != null) {
const ruleStatuses = await ruleStatusClient.find({
logsCount: 1,
const ruleStatus = await ruleStatusClient.getCurrentStatus({
ruleId: rule.id,
spaceId: context.securitySolution.getSpaceId(),
});
return transformValidateBulkError(rule.id, rule, ruleStatuses, isRuleRegistryEnabled);
return transformValidateBulkError(rule.id, rule, [ruleStatus], isRuleRegistryEnabled);
} else {
return getIdBulkError({ id, ruleId });
}
Expand Down
Loading

0 comments on commit e6e84bf

Please sign in to comment.