Deprecate outdated detection rules Bulk APIs (#129448)

This commit is contained in:
Dmitrii Shevchenko 2022-04-12 13:06:27 +02:00 committed by GitHub
parent 623070bbde
commit a8977474a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 367 additions and 171 deletions

View file

@ -328,6 +328,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
detectionsReq: `${SECURITY_SOLUTION_DOCS}detections-permissions-section.html`,
networkMap: `${SECURITY_SOLUTION_DOCS}conf-map-ui.html`,
troubleshootGaps: `${SECURITY_SOLUTION_DOCS}alerts-ui-monitor.html#troubleshoot-gaps`,
ruleApiOverview: `${SECURITY_SOLUTION_DOCS}rule-api-overview.html`,
},
securitySolution: {
trustedApps: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/trusted-apps-ov.html`,

View file

@ -233,6 +233,7 @@ export interface DocLinks {
readonly detectionsReq: string;
readonly networkMap: string;
readonly troubleshootGaps: string;
readonly ruleApiOverview: string;
};
readonly securitySolution: {
readonly trustedApps: string;

View file

@ -235,6 +235,12 @@ export const DETECTION_ENGINE_PREPACKAGED_RULES_STATUS_URL =
export const DETECTION_ENGINE_RULES_BULK_ACTION =
`${DETECTION_ENGINE_RULES_URL}/_bulk_action` as const;
export const DETECTION_ENGINE_RULES_PREVIEW = `${DETECTION_ENGINE_RULES_URL}/preview` as const;
export const DETECTION_ENGINE_RULES_BULK_DELETE =
`${DETECTION_ENGINE_RULES_URL}/_bulk_delete` as const;
export const DETECTION_ENGINE_RULES_BULK_CREATE =
`${DETECTION_ENGINE_RULES_URL}/_bulk_create` as const;
export const DETECTION_ENGINE_RULES_BULK_UPDATE =
`${DETECTION_ENGINE_RULES_URL}/_bulk_update` as const;
/**
* Internal detection engine routes

View file

@ -24,6 +24,9 @@ import {
DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL,
DETECTION_ENGINE_RULES_BULK_ACTION,
DETECTION_ENGINE_RULE_EXECUTION_EVENTS_URL,
DETECTION_ENGINE_RULES_BULK_UPDATE,
DETECTION_ENGINE_RULES_BULK_DELETE,
DETECTION_ENGINE_RULES_BULK_CREATE,
} from '../../../../../common/constants';
import { GetAggregateRuleExecutionEventsResponse } from '../../../../../common/detection_engine/schemas/response';
import { RuleAlertType, HapiReadableStream } from '../../rules/types';
@ -110,21 +113,21 @@ export const getFindRequest = () =>
export const getReadBulkRequest = () =>
requestMock.create({
method: 'post',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_create`,
path: DETECTION_ENGINE_RULES_BULK_CREATE,
body: [getCreateRulesSchemaMock()],
});
export const getUpdateBulkRequest = () =>
requestMock.create({
method: 'put',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [getCreateRulesSchemaMock()],
});
export const getPatchBulkRequest = () =>
requestMock.create({
method: 'patch',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [getCreateRulesSchemaMock()],
});
@ -145,28 +148,28 @@ export const getBulkActionEditRequest = () =>
export const getDeleteBulkRequest = () =>
requestMock.create({
method: 'delete',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_delete`,
path: DETECTION_ENGINE_RULES_BULK_DELETE,
body: [{ rule_id: 'rule-1' }],
});
export const getDeleteBulkRequestById = () =>
requestMock.create({
method: 'delete',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_delete`,
path: DETECTION_ENGINE_RULES_BULK_DELETE,
body: [{ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd' }],
});
export const getDeleteAsPostBulkRequestById = () =>
requestMock.create({
method: 'post',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_delete`,
path: DETECTION_ENGINE_RULES_BULK_DELETE,
body: [{ id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd' }],
});
export const getDeleteAsPostBulkRequest = () =>
requestMock.create({
method: 'post',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_delete`,
path: DETECTION_ENGINE_RULES_BULK_DELETE,
body: [{ rule_id: 'rule-1' }],
});

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { DETECTION_ENGINE_RULES_BULK_CREATE } from '../../../../../common/constants';
import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks';
import { buildMlAuthz } from '../../../machine_learning/authz';
import {
@ -23,6 +23,7 @@ import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks';
import { getQueryRuleParams } from '../../schemas/rule_schemas.mock';
import { loggingSystemMock } from '../../../../../../../../src/core/server/mocks';
jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create());
@ -38,6 +39,7 @@ describe.each([
server = serverMock.create();
({ clients, context } = requestContextMock.createTools());
ml = mlServicesMock.createSetupContract();
const logger = loggingSystemMock.createLogger();
clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); // no existing rules
clients.rulesClient.create.mockResolvedValue(
@ -47,7 +49,7 @@ describe.each([
context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValue(
elasticsearchClientMock.createSuccessTransportRequestPromise(getBasicEmptySearchResponse())
);
createRulesBulkRoute(server.router, ml, isRuleRegistryEnabled);
createRulesBulkRoute(server.router, ml, isRuleRegistryEnabled, logger);
});
describe('status codes', () => {
@ -137,7 +139,7 @@ describe.each([
test('returns an error object if duplicate rule_ids found in request payload', async () => {
const request = requestMock.create({
method: 'post',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_create`,
path: DETECTION_ENGINE_RULES_BULK_CREATE,
body: [getCreateRulesSchemaMock(), getCreateRulesSchemaMock()],
});
const response = await server.inject(request, context);
@ -158,7 +160,7 @@ describe.each([
test('allows rule type of query', async () => {
const request = requestMock.create({
method: 'post',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_create`,
path: DETECTION_ENGINE_RULES_BULK_CREATE,
body: [{ ...getCreateRulesSchemaMock(), type: 'query' }],
});
const result = server.validate(request);
@ -169,7 +171,7 @@ describe.each([
test('allows rule type of query and custom from and interval', async () => {
const request = requestMock.create({
method: 'post',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_create`,
path: DETECTION_ENGINE_RULES_BULK_CREATE,
body: [{ from: 'now-7m', interval: '5m', ...getCreateRulesSchemaMock() }],
});
const result = server.validate(request);
@ -180,7 +182,7 @@ describe.each([
test('disallows unknown rule type', async () => {
const request = requestMock.create({
method: 'post',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_create`,
path: DETECTION_ENGINE_RULES_BULK_CREATE,
body: [{ ...getCreateRulesSchemaMock(), type: 'unexpected_type' }],
});
const result = server.validate(request);
@ -191,7 +193,7 @@ describe.each([
test('disallows invalid "from" param on rule', async () => {
const request = requestMock.create({
method: 'post',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_create`,
path: DETECTION_ENGINE_RULES_BULK_CREATE,
body: [
{
from: 'now-3755555555555555.67s',

View file

@ -12,7 +12,7 @@ import { createRulesBulkSchema } from '../../../../../common/detection_engine/sc
import { rulesBulkSchema } from '../../../../../common/detection_engine/schemas/response/rules_bulk_schema';
import type { SecuritySolutionPluginRouter } from '../../../../types';
import {
DETECTION_ENGINE_RULES_URL,
DETECTION_ENGINE_RULES_BULK_CREATE,
NOTIFICATION_THROTTLE_NO_ACTIONS,
} from '../../../../../common/constants';
import { SetupPlugins } from '../../../../plugin';
@ -25,15 +25,21 @@ import { buildRouteValidation } from '../../../../utils/build_validation/route_v
import { transformBulkError, createBulkErrorObject, buildSiemResponse } from '../utils';
import { convertCreateAPIToInternalSchema } from '../../schemas/rule_converters';
import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './utils/deprecation';
import { Logger } from '../../../../../../../../src/core/server';
/**
* @deprecated since version 8.2.0. Use the detection_engine/rules/_bulk_action API instead
*/
export const createRulesBulkRoute = (
router: SecuritySolutionPluginRouter,
ml: SetupPlugins['ml'],
isRuleRegistryEnabled: boolean
isRuleRegistryEnabled: boolean,
logger: Logger
) => {
router.post(
{
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_create`,
path: DETECTION_ENGINE_RULES_BULK_CREATE,
validate: {
body: buildRouteValidation(createRulesBulkSchema),
},
@ -42,6 +48,8 @@ export const createRulesBulkRoute = (
},
},
async (context, request, response) => {
logDeprecatedBulkEndpoint(logger, DETECTION_ENGINE_RULES_BULK_CREATE);
const siemResponse = buildSiemResponse(response);
const rulesClient = context.alerting.getRulesClient();
const esClient = context.core.elasticsearch.client;
@ -138,9 +146,16 @@ export const createRulesBulkRoute = (
];
const [validated, errors] = validate(rulesBulk, rulesBulkSchema);
if (errors != null) {
return siemResponse.error({ statusCode: 500, body: errors });
return siemResponse.error({
statusCode: 500,
body: errors,
headers: getDeprecatedBulkEndpointHeader(DETECTION_ENGINE_RULES_BULK_CREATE),
});
} else {
return response.ok({ body: validated ?? {} });
return response.ok({
body: validated ?? {},
headers: getDeprecatedBulkEndpointHeader(DETECTION_ENGINE_RULES_BULK_CREATE),
});
}
}
);

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { DETECTION_ENGINE_RULES_BULK_DELETE } from '../../../../../common/constants';
import {
getEmptyFindResult,
getFindResultWithSingleHit,
@ -17,6 +17,7 @@ import {
} from '../__mocks__/request_responses';
import { requestContextMock, serverMock, requestMock } from '../__mocks__';
import { deleteRulesBulkRoute } from './delete_rules_bulk_route';
import { loggingSystemMock } from '../../../../../../../../src/core/server/mocks';
describe.each([
['Legacy', false],
@ -28,12 +29,13 @@ describe.each([
beforeEach(() => {
server = serverMock.create();
({ clients, context } = requestContextMock.createTools());
const logger = loggingSystemMock.createLogger();
clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); // rule exists
clients.rulesClient.delete.mockResolvedValue({}); // successful deletion
clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse()); // rule status request
deleteRulesBulkRoute(server.router, isRuleRegistryEnabled);
deleteRulesBulkRoute(server.router, isRuleRegistryEnabled, logger);
});
describe('status codes with actionClient and alertClient', () => {
@ -42,7 +44,7 @@ describe.each([
expect(response.status).toEqual(200);
});
test('resturns 200 when deleting a single rule and related rule status', async () => {
test('returns 200 when deleting a single rule and related rule status', async () => {
const response = await server.inject(getDeleteBulkRequest(), context);
expect(response.status).toEqual(200);
});
@ -88,7 +90,7 @@ describe.each([
test('rejects requests without IDs', async () => {
const request = requestMock.create({
method: 'post',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_delete`,
path: DETECTION_ENGINE_RULES_BULK_DELETE,
body: [{}],
});
const response = await server.inject(request, context);
@ -104,7 +106,7 @@ describe.each([
test('rejects requests with both id and rule_id', async () => {
const request = requestMock.create({
method: 'post',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_delete`,
path: DETECTION_ENGINE_RULES_BULK_DELETE,
body: [{ id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f', rule_id: 'rule_1' }],
});
const response = await server.inject(request, context);

View file

@ -14,18 +14,19 @@ import {
QueryRulesBulkSchemaDecoded,
} from '../../../../../common/detection_engine/schemas/request/query_rules_bulk_schema';
import { rulesBulkSchema } from '../../../../../common/detection_engine/schemas/response/rules_bulk_schema';
import type { RouteConfig, RequestHandler } from '../../../../../../../../src/core/server';
import type { RouteConfig, RequestHandler, Logger } from '../../../../../../../../src/core/server';
import type {
SecuritySolutionPluginRouter,
SecuritySolutionRequestHandlerContext,
} from '../../../../types';
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { DETECTION_ENGINE_RULES_BULK_DELETE } from '../../../../../common/constants';
import { getIdBulkError } from './utils';
import { transformValidateBulkError } from './validate';
import { transformBulkError, buildSiemResponse, createBulkErrorObject } from '../utils';
import { deleteRules } from '../../rules/delete_rules';
import { readRules } from '../../rules/read_rules';
import { legacyMigrate } from '../../rules/utils';
import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './utils/deprecation';
type Config = RouteConfig<unknown, unknown, QueryRulesBulkSchemaDecoded, 'delete' | 'post'>;
type Handler = RequestHandler<
@ -36,9 +37,13 @@ type Handler = RequestHandler<
'delete' | 'post'
>;
/**
* @deprecated since version 8.2.0. Use the detection_engine/rules/_bulk_action API instead
*/
export const deleteRulesBulkRoute = (
router: SecuritySolutionPluginRouter,
isRuleRegistryEnabled: boolean
isRuleRegistryEnabled: boolean,
logger: Logger
) => {
const config: Config = {
validate: {
@ -46,12 +51,14 @@ export const deleteRulesBulkRoute = (
queryRulesBulkSchema
),
},
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_delete`,
path: DETECTION_ENGINE_RULES_BULK_DELETE,
options: {
tags: ['access:securitySolution'],
},
};
const handler: Handler = async (context, request, response) => {
logDeprecatedBulkEndpoint(logger, DETECTION_ENGINE_RULES_BULK_DELETE);
const siemResponse = buildSiemResponse(response);
const rulesClient = context.alerting.getRulesClient();
const ruleExecutionLog = context.securitySolution.getRuleExecutionLog();
@ -102,9 +109,16 @@ export const deleteRulesBulkRoute = (
);
const [validated, errors] = validate(rules, rulesBulkSchema);
if (errors != null) {
return siemResponse.error({ statusCode: 500, body: errors });
return siemResponse.error({
statusCode: 500,
body: errors,
headers: getDeprecatedBulkEndpointHeader(DETECTION_ENGINE_RULES_BULK_DELETE),
});
} else {
return response.ok({ body: validated ?? {} });
return response.ok({
body: validated ?? {},
headers: getDeprecatedBulkEndpointHeader(DETECTION_ENGINE_RULES_BULK_DELETE),
});
}
};

View file

@ -5,7 +5,10 @@
* 2.0.
*/
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import {
DETECTION_ENGINE_RULES_BULK_UPDATE,
DETECTION_ENGINE_RULES_URL,
} from '../../../../../common/constants';
import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks';
import { buildMlAuthz } from '../../../machine_learning/authz';
import {
@ -19,6 +22,7 @@ import { serverMock, requestContextMock, requestMock } from '../__mocks__';
import { patchRulesBulkRoute } from './patch_rules_bulk_route';
import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock';
import { getQueryRuleParams } from '../../schemas/rule_schemas.mock';
import { loggingSystemMock } from '../../../../../../../../src/core/server/mocks';
jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create());
@ -34,13 +38,14 @@ describe.each([
server = serverMock.create();
({ clients, context } = requestContextMock.createTools());
ml = mlServicesMock.createSetupContract();
const logger = loggingSystemMock.createLogger();
clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); // rule exists
clients.rulesClient.update.mockResolvedValue(
getAlertMock(isRuleRegistryEnabled, getQueryRuleParams())
); // update succeeds
patchRulesBulkRoute(server.router, ml, isRuleRegistryEnabled);
patchRulesBulkRoute(server.router, ml, isRuleRegistryEnabled, logger);
});
describe('status codes', () => {
@ -96,7 +101,7 @@ describe.each([
});
const request = requestMock.create({
method: 'patch',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [typicalMlRulePayload()],
});
const response = await server.inject(request, context);
@ -122,7 +127,7 @@ describe.each([
const { type, ...payloadWithoutType } = typicalMlRulePayload();
const request = requestMock.create({
method: 'patch',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [payloadWithoutType],
});
const response = await server.inject(request, context);
@ -144,7 +149,7 @@ describe.each([
test('rejects payloads with no ID', async () => {
const request = requestMock.create({
method: 'patch',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [{ ...getCreateRulesSchemaMock(), rule_id: undefined }],
});
const response = await server.inject(request, context);
@ -164,7 +169,7 @@ describe.each([
test('allows query rule type', async () => {
const request = requestMock.create({
method: 'patch',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [{ ...getCreateRulesSchemaMock(), type: 'query' }],
});
const result = server.validate(request);
@ -175,7 +180,7 @@ describe.each([
test('rejects unknown rule type', async () => {
const request = requestMock.create({
method: 'patch',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [{ ...getCreateRulesSchemaMock(), type: 'unknown_type' }],
});
const result = server.validate(request);
@ -188,7 +193,7 @@ describe.each([
test('allows rule type of query and custom from and interval', async () => {
const request = requestMock.create({
method: 'patch',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [{ from: 'now-7m', interval: '5m', ...getCreateRulesSchemaMock() }],
});
const result = server.validate(request);
@ -199,7 +204,7 @@ describe.each([
test('disallows invalid "from" param on rule', async () => {
const request = requestMock.create({
method: 'patch',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [
{
from: 'now-3755555555555555.67s',

View file

@ -14,7 +14,7 @@ import {
import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';
import { rulesBulkSchema } from '../../../../../common/detection_engine/schemas/response/rules_bulk_schema';
import type { SecuritySolutionPluginRouter } from '../../../../types';
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../../common/constants';
import { SetupPlugins } from '../../../../plugin';
import { buildMlAuthz } from '../../../machine_learning/authz';
import { throwAuthzError } from '../../../machine_learning/validation';
@ -25,15 +25,21 @@ import { patchRules } from '../../rules/patch_rules';
import { readRules } from '../../rules/read_rules';
import { PartialFilter } from '../../types';
import { legacyMigrate } from '../../rules/utils';
import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './utils/deprecation';
import { Logger } from '../../../../../../../../src/core/server';
/**
* @deprecated since version 8.2.0. Use the detection_engine/rules/_bulk_action API instead
*/
export const patchRulesBulkRoute = (
router: SecuritySolutionPluginRouter,
ml: SetupPlugins['ml'],
isRuleRegistryEnabled: boolean
isRuleRegistryEnabled: boolean,
logger: Logger
) => {
router.patch(
{
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
validate: {
body: buildRouteValidation<typeof patchRulesBulkSchema, PatchRulesBulkSchemaDecoded>(
patchRulesBulkSchema
@ -44,6 +50,8 @@ export const patchRulesBulkRoute = (
},
},
async (context, request, response) => {
logDeprecatedBulkEndpoint(logger, DETECTION_ENGINE_RULES_BULK_UPDATE);
const siemResponse = buildSiemResponse(response);
const rulesClient = context.alerting.getRulesClient();
@ -207,9 +215,16 @@ export const patchRulesBulkRoute = (
const [validated, errors] = validate(rules, rulesBulkSchema);
if (errors != null) {
return siemResponse.error({ statusCode: 500, body: errors });
return siemResponse.error({
statusCode: 500,
body: errors,
headers: getDeprecatedBulkEndpointHeader(DETECTION_ENGINE_RULES_BULK_UPDATE),
});
} else {
return response.ok({ body: validated ?? {} });
return response.ok({
body: validated ?? {},
headers: getDeprecatedBulkEndpointHeader(DETECTION_ENGINE_RULES_BULK_UPDATE),
});
}
}
);

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../../common/constants';
import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks';
import { buildMlAuthz } from '../../../machine_learning/authz';
import {
@ -20,6 +20,7 @@ import { updateRulesBulkRoute } from './update_rules_bulk_route';
import { BulkError } from '../utils';
import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock';
import { getQueryRuleParams } from '../../schemas/rule_schemas.mock';
import { loggingSystemMock } from '../../../../../../../../src/core/server/mocks';
jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create());
@ -35,6 +36,7 @@ describe.each([
server = serverMock.create();
({ clients, context } = requestContextMock.createTools());
ml = mlServicesMock.createSetupContract();
const logger = loggingSystemMock.createLogger();
clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled));
clients.rulesClient.update.mockResolvedValue(
@ -43,7 +45,7 @@ describe.each([
clients.appClient.getSignalsIndex.mockReturnValue('.siem-signals-test-index');
updateRulesBulkRoute(server.router, ml, isRuleRegistryEnabled);
updateRulesBulkRoute(server.router, ml, isRuleRegistryEnabled, logger);
});
describe('status codes', () => {
@ -90,7 +92,7 @@ describe.each([
});
const request = requestMock.create({
method: 'put',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [typicalMlRulePayload()],
});
@ -112,7 +114,7 @@ describe.each([
test('rejects payloads with no ID', async () => {
const noIdRequest = requestMock.create({
method: 'put',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [{ ...getCreateRulesSchemaMock(), rule_id: undefined }],
});
const response = await server.inject(noIdRequest, context);
@ -127,7 +129,7 @@ describe.each([
test('allows query rule type', async () => {
const request = requestMock.create({
method: 'put',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [{ ...getCreateRulesSchemaMock(), type: 'query' }],
});
const result = server.validate(request);
@ -138,7 +140,7 @@ describe.each([
test('rejects unknown rule type', async () => {
const request = requestMock.create({
method: 'put',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [{ ...getCreateRulesSchemaMock(), type: 'unknown_type' }],
});
const result = server.validate(request);
@ -149,7 +151,7 @@ describe.each([
test('allows rule type of query and custom from and interval', async () => {
const request = requestMock.create({
method: 'put',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [{ from: 'now-7m', interval: '5m', ...getCreateRulesSchemaMock(), type: 'query' }],
});
const result = server.validate(request);
@ -160,7 +162,7 @@ describe.each([
test('disallows invalid "from" param on rule', async () => {
const request = requestMock.create({
method: 'put',
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
body: [
{
from: 'now-3755555555555555.67s',

View file

@ -11,7 +11,7 @@ import { buildRouteValidation } from '../../../../utils/build_validation/route_v
import { updateRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request/update_rules_bulk_schema';
import { rulesBulkSchema } from '../../../../../common/detection_engine/schemas/response/rules_bulk_schema';
import type { SecuritySolutionPluginRouter } from '../../../../types';
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../../common/constants';
import { SetupPlugins } from '../../../../plugin';
import { buildMlAuthz } from '../../../machine_learning/authz';
import { throwAuthzError } from '../../../machine_learning/validation';
@ -21,15 +21,21 @@ import { transformBulkError, buildSiemResponse, createBulkErrorObject } from '..
import { updateRules } from '../../rules/update_rules';
import { legacyMigrate } from '../../rules/utils';
import { readRules } from '../../rules/read_rules';
import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './utils/deprecation';
import { Logger } from '../../../../../../../../src/core/server';
/**
* @deprecated since version 8.2.0. Use the detection_engine/rules/_bulk_action API instead
*/
export const updateRulesBulkRoute = (
router: SecuritySolutionPluginRouter,
ml: SetupPlugins['ml'],
isRuleRegistryEnabled: boolean
isRuleRegistryEnabled: boolean,
logger: Logger
) => {
router.put(
{
path: `${DETECTION_ENGINE_RULES_URL}/_bulk_update`,
path: DETECTION_ENGINE_RULES_BULK_UPDATE,
validate: {
body: buildRouteValidation(updateRulesBulkSchema),
},
@ -38,6 +44,8 @@ export const updateRulesBulkRoute = (
},
},
async (context, request, response) => {
logDeprecatedBulkEndpoint(logger, DETECTION_ENGINE_RULES_BULK_UPDATE);
const siemResponse = buildSiemResponse(response);
const rulesClient = context.alerting.getRulesClient();
@ -105,9 +113,16 @@ export const updateRulesBulkRoute = (
const [validated, errors] = validate(rules, rulesBulkSchema);
if (errors != null) {
return siemResponse.error({ statusCode: 500, body: errors });
return siemResponse.error({
statusCode: 500,
body: errors,
headers: getDeprecatedBulkEndpointHeader(DETECTION_ENGINE_RULES_BULK_UPDATE),
});
} else {
return response.ok({ body: validated ?? {} });
return response.ok({
body: validated ?? {},
headers: getDeprecatedBulkEndpointHeader(DETECTION_ENGINE_RULES_BULK_UPDATE),
});
}
}
);

View file

@ -0,0 +1,42 @@
/*
* 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 { getDocLinks } from '@kbn/doc-links';
import { Logger } from 'src/core/server';
import { DETECTION_ENGINE_RULES_BULK_ACTION } from '../../../../../../common/constants';
/**
* Helper method for building deprecation messages
*
* @param path Deprecated endpoint path
* @returns string
*/
export const buildDeprecatedBulkEndpointMessage = (path: string) => {
const docsLink = getDocLinks({ kibanaBranch: 'main' }).siem.ruleApiOverview;
return `Deprecated endpoint: ${path} API is deprecated since v8.2. Please use the ${DETECTION_ENGINE_RULES_BULK_ACTION} API instead. See ${docsLink} for more detail.`;
};
/**
* Logs usages of a deprecated bulk endpoint
*
* @param logger System logger
* @param path Deprecated endpoint path
*/
export const logDeprecatedBulkEndpoint = (logger: Logger, path: string) => {
logger.warn(buildDeprecatedBulkEndpointMessage(path), { tags: ['deprecation'] });
};
/**
* Creates a warning header with a message formatted according to RFC7234.
* We follow the same formatting as Elasticsearch
* https://github.com/elastic/elasticsearch/blob/5baabff6670a8ed49297488ca8cac8ec12a2078d/server/src/main/java/org/elasticsearch/common/logging/HeaderWarning.java#L55
*
* @param path Deprecated endpoint path
*/
export const getDeprecatedBulkEndpointHeader = (path: string) => ({
warning: `299 Kibana "${buildDeprecatedBulkEndpointMessage(path)}"`,
});

View file

@ -112,10 +112,10 @@ export const initRoutes = (
addPrepackedRulesRoute(router);
getPrepackagedRulesStatusRoute(router, config, security, isRuleRegistryEnabled);
createRulesBulkRoute(router, ml, isRuleRegistryEnabled);
updateRulesBulkRoute(router, ml, isRuleRegistryEnabled);
patchRulesBulkRoute(router, ml, isRuleRegistryEnabled);
deleteRulesBulkRoute(router, isRuleRegistryEnabled);
createRulesBulkRoute(router, ml, isRuleRegistryEnabled, logger);
updateRulesBulkRoute(router, ml, isRuleRegistryEnabled, logger);
patchRulesBulkRoute(router, ml, isRuleRegistryEnabled, logger);
deleteRulesBulkRoute(router, isRuleRegistryEnabled, logger);
performBulkActionRoute(router, ml, logger, isRuleRegistryEnabled);
getRuleExecutionEventsRoute(router);

View file

@ -7,7 +7,7 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '../../../../plugins/security_solution/common/constants';
import { DETECTION_ENGINE_RULES_BULK_CREATE } from '../../../../plugins/security_solution/common/constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createSignalsIndex,
@ -48,7 +48,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should create a single rule with a rule_id', async () => {
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.send([getSimpleRule()])
.expect(200);
@ -59,7 +59,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should create a single rule without a rule_id', async () => {
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.send([getSimpleRuleWithoutRuleId()])
.expect(200);
@ -70,7 +70,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return a 200 ok but have a 409 conflict if we attempt to create the same rule_id twice', async () => {
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.send([getSimpleRule(), getSimpleRule()])
.expect(200);
@ -88,13 +88,13 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return a 200 ok but have a 409 conflict if we attempt to create the same rule_id that already exists', async () => {
await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.send([getSimpleRule()])
.expect(200);
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'foo')
.send([getSimpleRule()])
.expect(200);

View file

@ -7,7 +7,7 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '../../../../plugins/security_solution/common/constants';
import { DETECTION_ENGINE_RULES_BULK_DELETE } from '../../../../plugins/security_solution/common/constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createRule,
@ -43,7 +43,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete the rule in bulk
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1' }])
.expect(200);
@ -57,7 +57,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete that rule by its rule_id
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ rule_id: bodyWithCreatedRule.rule_id }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -71,7 +71,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete that rule by its id
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: bodyWithCreatedRule.id }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -82,7 +82,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return an error if the ruled_id does not exist when trying to delete a rule_id', async () => {
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ rule_id: 'fake_id' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -100,7 +100,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return an error if the id does not exist when trying to delete an id', async () => {
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -120,7 +120,7 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: bodyWithCreatedRule.id }, { id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -155,7 +155,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete the rule in bulk
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1' }])
.expect(200);
@ -169,7 +169,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete that rule by its rule_id
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ rule_id: bodyWithCreatedRule.rule_id }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -183,7 +183,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete that rule by its id
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: bodyWithCreatedRule.id }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -194,7 +194,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return an error if the ruled_id does not exist when trying to delete a rule_id', async () => {
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ rule_id: 'fake_id' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -212,7 +212,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return an error if the id does not exist when trying to delete an id', async () => {
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -232,7 +232,7 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: bodyWithCreatedRule.id }, { id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
.set('kbn-xsrf', 'true')
.expect(200);

View file

@ -7,7 +7,7 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '../../../../plugins/security_solution/common/constants';
import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../plugins/security_solution/common/constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createSignalsIndex,
@ -42,7 +42,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's name
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', name: 'some other name' }])
.expect(200);
@ -60,7 +60,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch both rule names
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([
{ rule_id: 'rule-1', name: 'some other name' },
@ -87,7 +87,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's name
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ id: createRuleBody.id, name: 'some other name' }])
.expect(200);
@ -105,7 +105,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch both rule names
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([
{ id: createRule1.id, name: 'some other name' },
@ -132,7 +132,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's name
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ id: createdBody.id, name: 'some other name' }])
.expect(200);
@ -149,7 +149,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's enabled to false
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', enabled: false }])
.expect(200);
@ -166,7 +166,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's enabled to false and another property
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', severity: 'low', enabled: false }])
.expect(200);
@ -185,14 +185,14 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's timeline_title
await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', timeline_title: 'some title', timeline_id: 'some id' }])
.expect(200);
// patch a simple rule's name
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', name: 'some other name' }])
.expect(200);
@ -209,7 +209,7 @@ export default ({ getService }: FtrProviderContext) => {
it('should return a 200 but give a 404 in the message if it is given a fake id', async () => {
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' }])
.expect(200);
@ -227,7 +227,7 @@ export default ({ getService }: FtrProviderContext) => {
it('should return a 200 but give a 404 in the message if it is given a fake rule_id', async () => {
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'fake_id', name: 'some other name' }])
.expect(200);
@ -245,7 +245,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch one rule name and give a fake id for the second
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([
{ rule_id: 'rule-1', name: 'some other name' },
@ -275,7 +275,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch one rule name and give a fake id for the second
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([
{ id: createdBody.id, name: 'some other name' },

View file

@ -7,7 +7,10 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '../../../../plugins/security_solution/common/constants';
import {
DETECTION_ENGINE_RULES_BULK_UPDATE,
DETECTION_ENGINE_RULES_URL,
} from '../../../../plugins/security_solution/common/constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createSignalsIndex,
@ -46,7 +49,7 @@ export default ({ getService }: FtrProviderContext) => {
// update a simple rule's name
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule])
.expect(200);
@ -76,7 +79,7 @@ export default ({ getService }: FtrProviderContext) => {
// update both rule names
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1, updatedRule2])
.expect(200);
@ -105,7 +108,7 @@ export default ({ getService }: FtrProviderContext) => {
delete updatedRule1.rule_id;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1])
.expect(200);
@ -133,7 +136,7 @@ export default ({ getService }: FtrProviderContext) => {
delete updatedRule2.rule_id;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1, updatedRule2])
.expect(200);
@ -162,7 +165,7 @@ export default ({ getService }: FtrProviderContext) => {
delete updatedRule1.rule_id;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1])
.expect(200);
@ -183,7 +186,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule1.enabled = false;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1])
.expect(200);
@ -206,7 +209,7 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate.timeline_id = 'some id';
await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([ruleUpdate])
.expect(200);
@ -216,7 +219,7 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate2.name = 'some other name';
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([ruleUpdate2])
.expect(200);
@ -235,7 +238,7 @@ export default ({ getService }: FtrProviderContext) => {
delete ruleUpdate.rule_id;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([ruleUpdate])
.expect(200);
@ -257,7 +260,7 @@ export default ({ getService }: FtrProviderContext) => {
delete ruleUpdate.id;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([ruleUpdate])
.expect(200);
@ -283,7 +286,7 @@ export default ({ getService }: FtrProviderContext) => {
// update one rule name and give a fake id for the second
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([ruleUpdate, ruleUpdate2])
.expect(200);
@ -320,7 +323,7 @@ export default ({ getService }: FtrProviderContext) => {
rule2.name = 'some other name';
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([rule1, rule2])
.expect(200);

View file

@ -7,7 +7,7 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '../../../../plugins/security_solution/common/constants';
import { DETECTION_ENGINE_RULES_BULK_CREATE } from '../../../../plugins/security_solution/common/constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createSignalsIndex,
@ -30,6 +30,24 @@ export default ({ getService }: FtrProviderContext): void => {
const log = getService('log');
describe('create_rules_bulk', () => {
describe('deprecations', () => {
afterEach(async () => {
await deleteAllAlerts(supertest, log);
});
it('should return a warning header', async () => {
const { header } = await supertest
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.send([getSimpleRule()])
.expect(200);
expect(header.warning).to.be(
'299 Kibana "Deprecated endpoint: /api/detection_engine/rules/_bulk_create API is deprecated since v8.2. Please use the /api/detection_engine/rules/_bulk_action API instead. See https://www.elastic.co/guide/en/security/master/rule-api-overview.html for more detail."'
);
});
});
describe('creating rules in bulk', () => {
before(async () => {
await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts');
@ -50,7 +68,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should create a single rule with a rule_id', async () => {
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.send([getSimpleRule()])
.expect(200);
@ -81,7 +99,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should create a single rule with a rule_id and validate it ran successfully', async () => {
const simpleRule = getRuleForSignalTesting(['auditbeat-*']);
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.send([simpleRule])
.expect(200);
@ -91,7 +109,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should create a single rule without a rule_id', async () => {
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.send([getSimpleRuleWithoutRuleId()])
.expect(200);
@ -102,7 +120,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return a 200 ok but have a 409 conflict if we attempt to create the same rule_id twice', async () => {
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.send([getSimpleRule(), getSimpleRule()])
.expect(200);
@ -120,13 +138,13 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return a 200 ok but have a 409 conflict if we attempt to create the same rule_id that already exists', async () => {
await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.send([getSimpleRule()])
.expect(200);
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_create`)
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'foo')
.send([getSimpleRule()])
.expect(200);

View file

@ -8,7 +8,7 @@
import expect from '@kbn/expect';
import { BASE_ALERTING_API_PATH } from '../../../../plugins/alerting/common';
import { DETECTION_ENGINE_RULES_URL } from '../../../../plugins/security_solution/common/constants';
import { DETECTION_ENGINE_RULES_BULK_DELETE } from '../../../../plugins/security_solution/common/constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createLegacyRuleAction,
@ -31,6 +31,22 @@ export default ({ getService }: FtrProviderContext): void => {
const log = getService('log');
describe('delete_rules_bulk', () => {
describe('deprecations', () => {
it('should return a warning header', async () => {
await createRule(supertest, log, getSimpleRule());
const { header } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1' }])
.expect(200);
expect(header.warning).to.be(
'299 Kibana "Deprecated endpoint: /api/detection_engine/rules/_bulk_delete API is deprecated since v8.2. Please use the /api/detection_engine/rules/_bulk_action API instead. See https://www.elastic.co/guide/en/security/master/rule-api-overview.html for more detail."'
);
});
});
describe('deleting rules bulk using DELETE', () => {
beforeEach(async () => {
await createSignalsIndex(supertest, log);
@ -46,7 +62,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete the rule in bulk
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1' }])
.expect(200);
@ -60,7 +76,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete that rule by its rule_id
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ rule_id: bodyWithCreatedRule.rule_id }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -74,7 +90,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete that rule by its id
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: bodyWithCreatedRule.id }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -85,7 +101,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return an error if the ruled_id does not exist when trying to delete a rule_id', async () => {
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ rule_id: 'fake_id' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -103,7 +119,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return an error if the id does not exist when trying to delete an id', async () => {
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -123,7 +139,7 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: bodyWithCreatedRule.id }, { id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -158,7 +174,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete the rule in bulk
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1' }])
.expect(200);
@ -172,7 +188,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete that rule by its rule_id
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ rule_id: bodyWithCreatedRule.rule_id }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -186,7 +202,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete that rule by its id
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: bodyWithCreatedRule.id }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -197,7 +213,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return an error if the ruled_id does not exist when trying to delete a rule_id', async () => {
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ rule_id: 'fake_id' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -215,7 +231,7 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return an error if the id does not exist when trying to delete an id', async () => {
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -235,7 +251,7 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
const { body } = await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.post(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: bodyWithCreatedRule.id }, { id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -272,7 +288,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete the rule with the legacy action
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: createRuleBody.id }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -320,7 +336,7 @@ export default ({ getService }: FtrProviderContext): void => {
// delete 2 rules where both have legacy actions
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: createRuleBody1.id }, { id: createRuleBody2.id }])
.set('kbn-xsrf', 'true')
.expect(200);
@ -372,7 +388,7 @@ export default ({ getService }: FtrProviderContext): void => {
// bulk delete the rule
await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.send([{ id: createRuleBody.id }])
.set('kbn-xsrf', 'true')
.expect(200);

View file

@ -7,7 +7,7 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '../../../../plugins/security_solution/common/constants';
import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../plugins/security_solution/common/constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createSignalsIndex,
@ -28,6 +28,26 @@ export default ({ getService }: FtrProviderContext) => {
const log = getService('log');
describe('patch_rules_bulk', () => {
describe('deprecations', () => {
afterEach(async () => {
await deleteAllAlerts(supertest, log);
});
it('should return a warning header', async () => {
await createRule(supertest, log, getSimpleRule('rule-1'));
const { header } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', name: 'some other name' }])
.expect(200);
expect(header.warning).to.be(
'299 Kibana "Deprecated endpoint: /api/detection_engine/rules/_bulk_update API is deprecated since v8.2. Please use the /api/detection_engine/rules/_bulk_action API instead. See https://www.elastic.co/guide/en/security/master/rule-api-overview.html for more detail."'
);
});
});
describe('patch rules bulk', () => {
beforeEach(async () => {
await createSignalsIndex(supertest, log);
@ -43,7 +63,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's name
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', name: 'some other name' }])
.expect(200);
@ -61,7 +81,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch both rule names
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([
{ rule_id: 'rule-1', name: 'some other name' },
@ -88,7 +108,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's name
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ id: createRuleBody.id, name: 'some other name' }])
.expect(200);
@ -106,7 +126,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch both rule names
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([
{ id: createRule1.id, name: 'some other name' },
@ -149,7 +169,7 @@ export default ({ getService }: FtrProviderContext) => {
]);
// patch a simple rule's name
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([
{ id: rule1.id, enabled: false },
@ -182,7 +202,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's name
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ id: createdBody.id, name: 'some other name' }])
.expect(200);
@ -199,7 +219,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's enabled to false
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', enabled: false }])
.expect(200);
@ -216,7 +236,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's enabled to false and another property
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', severity: 'low', enabled: false }])
.expect(200);
@ -235,14 +255,14 @@ export default ({ getService }: FtrProviderContext) => {
// patch a simple rule's timeline_title
await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', timeline_title: 'some title', timeline_id: 'some id' }])
.expect(200);
// patch a simple rule's name
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'rule-1', name: 'some other name' }])
.expect(200);
@ -259,7 +279,7 @@ export default ({ getService }: FtrProviderContext) => {
it('should return a 200 but give a 404 in the message if it is given a fake id', async () => {
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' }])
.expect(200);
@ -277,7 +297,7 @@ export default ({ getService }: FtrProviderContext) => {
it('should return a 200 but give a 404 in the message if it is given a fake rule_id', async () => {
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([{ rule_id: 'fake_id', name: 'some other name' }])
.expect(200);
@ -295,7 +315,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch one rule name and give a fake id for the second
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([
{ rule_id: 'rule-1', name: 'some other name' },
@ -325,7 +345,7 @@ export default ({ getService }: FtrProviderContext) => {
// patch one rule name and give a fake id for the second
const { body } = await supertest
.patch(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([
{ id: createdBody.id, name: 'some other name' },

View file

@ -8,7 +8,10 @@
import expect from '@kbn/expect';
import { FullResponseSchema } from '../../../../plugins/security_solution/common/detection_engine/schemas/request';
import { DETECTION_ENGINE_RULES_URL } from '../../../../plugins/security_solution/common/constants';
import {
DETECTION_ENGINE_RULES_URL,
DETECTION_ENGINE_RULES_BULK_UPDATE,
} from '../../../../plugins/security_solution/common/constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createSignalsIndex,
@ -30,6 +33,27 @@ export default ({ getService }: FtrProviderContext) => {
const log = getService('log');
describe('update_rules_bulk', () => {
describe('deprecations', () => {
afterEach(async () => {
await deleteAllAlerts(supertest, log);
});
it('should return a warning header', async () => {
await createRule(supertest, log, getSimpleRule('rule-1'));
const updatedRule = getSimpleRuleUpdate('rule-1');
const { header } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule])
.expect(200);
expect(header.warning).to.be(
'299 Kibana "Deprecated endpoint: /api/detection_engine/rules/_bulk_update API is deprecated since v8.2. Please use the /api/detection_engine/rules/_bulk_action API instead. See https://www.elastic.co/guide/en/security/master/rule-api-overview.html for more detail."'
);
});
});
describe('update rules bulk', () => {
beforeEach(async () => {
await createSignalsIndex(supertest, log);
@ -48,7 +72,7 @@ export default ({ getService }: FtrProviderContext) => {
// update a simple rule's name
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule])
.expect(200);
@ -78,7 +102,7 @@ export default ({ getService }: FtrProviderContext) => {
// update both rule names
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1, updatedRule2])
.expect(200);
@ -137,7 +161,7 @@ export default ({ getService }: FtrProviderContext) => {
// update both rule names
const { body }: { body: FullResponseSchema[] } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1, updatedRule2])
.expect(200);
@ -199,7 +223,7 @@ export default ({ getService }: FtrProviderContext) => {
// update both rule names
const { body }: { body: FullResponseSchema[] } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1, updatedRule2])
.expect(200);
@ -225,7 +249,7 @@ export default ({ getService }: FtrProviderContext) => {
delete updatedRule1.rule_id;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1])
.expect(200);
@ -253,7 +277,7 @@ export default ({ getService }: FtrProviderContext) => {
delete updatedRule2.rule_id;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1, updatedRule2])
.expect(200);
@ -282,7 +306,7 @@ export default ({ getService }: FtrProviderContext) => {
delete updatedRule1.rule_id;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1])
.expect(200);
@ -303,7 +327,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule1.enabled = false;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([updatedRule1])
.expect(200);
@ -326,7 +350,7 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate.timeline_id = 'some id';
await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([ruleUpdate])
.expect(200);
@ -336,7 +360,7 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate2.name = 'some other name';
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([ruleUpdate2])
.expect(200);
@ -355,7 +379,7 @@ export default ({ getService }: FtrProviderContext) => {
delete ruleUpdate.rule_id;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([ruleUpdate])
.expect(200);
@ -377,7 +401,7 @@ export default ({ getService }: FtrProviderContext) => {
delete ruleUpdate.id;
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([ruleUpdate])
.expect(200);
@ -403,7 +427,7 @@ export default ({ getService }: FtrProviderContext) => {
// update one rule name and give a fake id for the second
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([ruleUpdate, ruleUpdate2])
.expect(200);
@ -440,7 +464,7 @@ export default ({ getService }: FtrProviderContext) => {
rule2.name = 'some other name';
const { body } = await supertest
.put(`${DETECTION_ENGINE_RULES_URL}/_bulk_update`)
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.send([rule1, rule2])
.expect(200);

View file

@ -52,6 +52,7 @@ import {
DETECTION_ENGINE_INDEX_URL,
DETECTION_ENGINE_PREPACKAGED_URL,
DETECTION_ENGINE_QUERY_SIGNALS_URL,
DETECTION_ENGINE_RULES_BULK_ACTION,
DETECTION_ENGINE_RULES_URL,
DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL,
DETECTION_ENGINE_SIGNALS_MIGRATION_URL,
@ -513,18 +514,9 @@ export const deleteAllAlerts = async (
): Promise<void> => {
await countDownTest(
async () => {
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}/_find?per_page=9999`)
.set('kbn-xsrf', 'true')
.send();
const ids = body.data.map((rule: FullResponseSchema) => ({
id: rule.id,
}));
await supertest
.post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`)
.send(ids)
.post(DETECTION_ENGINE_RULES_BULK_ACTION)
.send({ action: 'delete', query: '' })
.set('kbn-xsrf', 'true');
const { body: finalCheck } = await supertest