mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Security Solution][Entity Analytics] APIs for Entity Store engine (#191986)
This PR introduces the following API routes for setting up Entity Store "engines": <meta charset="utf-8"><b style="font-weight:normal;" id="docs-internal-guid-9410c5d7-7fff-e873-6830-887939a306fb"><div dir="ltr" style="margin-left:-0.75pt;" align="left"> Initialise Engine | POST /api/entity_store/engines/<entity_type>/init -- | -- Start Engine | POST /api/entity_store/engines/<entity_type>/start Stop Engine | POST /api/entity_store/engines/<entity_type>/stop Delete Engine | DELETE /api/entity_store/engines/<entity_type> Get engine | GET /api/entity_store/engines/<entity_type> List Engines | GET /api/entity_store/engines </div></b> The PR includes the following: - Adding the `EntityManager` plugin (see elastic/obs-entities) as a dependency of the Security Solution - The OpenAPI schemas for the new routes - The actual Kibana side endpoints - A `Saved Object` to track the installed engines - A new `EntityStoreDataClient` - A new feature flag `entityStoreEngineRoutesEnabled` ### How to test 1. Add some host/user data * Easiest is to use [elastic/security-data-generator](https://github.com/elastic/security-documents-generator) 2. Make sure to add `entityStoreEngineRoutesEnabled` under `xpack.securitySolution.enableExperimental` in your `kibana.dev.yml` 3. In kibana dev tools or your terminal, call the `INIT` route for either `user` or `host`. 4. You should now see 2 transforms in kibana. Make sure to re-trigger them if needed so they process the documents. 5. Check that new entities have been observed by querying the new entities index via: * `GET .entities.v1.latest.ea*/_search` 6. Check the other endpoints are working (`START`, `STOP`, `LIST`, etc) 7. Calling `DELETE` should remove the transforms Implements https://github.com/elastic/security-team/issues/10230 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
f029f8086a
commit
cd964f1229
50 changed files with 2097 additions and 2 deletions
|
@ -312,6 +312,12 @@
|
|||
"entity-discovery-api-key": [
|
||||
"apiKey"
|
||||
],
|
||||
"entity-engine-status": [
|
||||
"filter",
|
||||
"indexPattern",
|
||||
"status",
|
||||
"type"
|
||||
],
|
||||
"epm-packages": [
|
||||
"additional_spaces_installed_kibana",
|
||||
"es_index_patterns",
|
||||
|
|
|
@ -1057,6 +1057,23 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"entity-engine-status": {
|
||||
"dynamic": false,
|
||||
"properties": {
|
||||
"filter": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"indexPattern": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"status": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"type": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"epm-packages": {
|
||||
"properties": {
|
||||
"additional_spaces_installed_kibana": {
|
||||
|
|
|
@ -93,6 +93,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
|
|||
"enterprise_search_telemetry": "9ac912e1417fc8681e0cd383775382117c9e3d3d",
|
||||
"entity-definition": "61be3e95966045122b55e181bb39658b1dc9bbe9",
|
||||
"entity-discovery-api-key": "c267a65c69171d1804362155c1378365f5acef88",
|
||||
"entity-engine-status": "0738aa1a06d3361911740f8f166071ea43a00927",
|
||||
"epm-packages": "8042d4a1522f6c4e6f5486e791b3ffe3a22f88fd",
|
||||
"epm-packages-assets": "7a3e58efd9a14191d0d1a00b8aaed30a145fd0b1",
|
||||
"event-annotation-group": "715ba867d8c68f3c9438052210ea1c30a9362582",
|
||||
|
|
|
@ -124,6 +124,7 @@ const previouslyRegisteredTypes = [
|
|||
'security-rule',
|
||||
'security-solution-signals-migration',
|
||||
'risk-engine-configuration',
|
||||
'entity-engine-status',
|
||||
'server',
|
||||
'siem-detection-engine-rule-actions',
|
||||
'siem-detection-engine-rule-execution-info',
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Entity Store Common Schema
|
||||
* version: 1
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
export type EntityType = z.infer<typeof EntityType>;
|
||||
export const EntityType = z.enum(['user', 'host']);
|
||||
export type EntityTypeEnum = typeof EntityType.enum;
|
||||
export const EntityTypeEnum = EntityType.enum;
|
||||
|
||||
export type IndexPattern = z.infer<typeof IndexPattern>;
|
||||
export const IndexPattern = z.string();
|
||||
|
||||
export type EngineStatus = z.infer<typeof EngineStatus>;
|
||||
export const EngineStatus = z.enum(['installing', 'started', 'stopped']);
|
||||
export type EngineStatusEnum = typeof EngineStatus.enum;
|
||||
export const EngineStatusEnum = EngineStatus.enum;
|
||||
|
||||
export type EngineDescriptor = z.infer<typeof EngineDescriptor>;
|
||||
export const EngineDescriptor = z.object({
|
||||
type: EntityType.optional(),
|
||||
indexPattern: IndexPattern.optional(),
|
||||
status: EngineStatus.optional(),
|
||||
filter: z.string().optional(),
|
||||
});
|
|
@ -0,0 +1,37 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Entity Store Common Schema
|
||||
description: Common schema for Entity Store
|
||||
version: '1'
|
||||
paths: {}
|
||||
components:
|
||||
schemas:
|
||||
|
||||
EntityType:
|
||||
type: string
|
||||
enum:
|
||||
- user
|
||||
- host
|
||||
|
||||
EngineDescriptor:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
indexPattern:
|
||||
$ref: '#/components/schemas/IndexPattern'
|
||||
status:
|
||||
$ref: '#/components/schemas/EngineStatus'
|
||||
filter:
|
||||
type: string
|
||||
|
||||
EngineStatus:
|
||||
type: string
|
||||
enum:
|
||||
- installing
|
||||
- started
|
||||
- stopped
|
||||
|
||||
IndexPattern:
|
||||
type: string
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Delete the entity store engine
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
import { BooleanFromString } from '@kbn/zod-helpers';
|
||||
|
||||
import { EntityType } from '../common.gen';
|
||||
|
||||
export type DeleteEntityStoreRequestQuery = z.infer<typeof DeleteEntityStoreRequestQuery>;
|
||||
export const DeleteEntityStoreRequestQuery = z.object({
|
||||
/**
|
||||
* Control flag to also delete the entity data.
|
||||
*/
|
||||
data: BooleanFromString.optional(),
|
||||
});
|
||||
export type DeleteEntityStoreRequestQueryInput = z.input<typeof DeleteEntityStoreRequestQuery>;
|
||||
|
||||
export type DeleteEntityStoreRequestParams = z.infer<typeof DeleteEntityStoreRequestParams>;
|
||||
export const DeleteEntityStoreRequestParams = z.object({
|
||||
/**
|
||||
* The entity type of the store (either 'user' or 'host').
|
||||
*/
|
||||
entityType: EntityType,
|
||||
});
|
||||
export type DeleteEntityStoreRequestParamsInput = z.input<typeof DeleteEntityStoreRequestParams>;
|
||||
|
||||
export type DeleteEntityStoreResponse = z.infer<typeof DeleteEntityStoreResponse>;
|
||||
export const DeleteEntityStoreResponse = z.object({
|
||||
deleted: z.boolean().optional(),
|
||||
});
|
|
@ -0,0 +1,37 @@
|
|||
openapi: 3.0.0
|
||||
|
||||
info:
|
||||
title: Delete the entity store engine
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/entity_store/engines/{entityType}:
|
||||
delete:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: DeleteEntityStore
|
||||
summary: Delete the Entity Store engine
|
||||
parameters:
|
||||
- name: entityType
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
$ref: '../common.schema.yaml#/components/schemas/EntityType'
|
||||
description: The entity type of the store (either 'user' or 'host').
|
||||
|
||||
- name: data
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
description: Control flag to also delete the entity data.
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
deleted:
|
||||
type: boolean
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Get Entity Store engine
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { EntityType, EngineDescriptor } from '../common.gen';
|
||||
|
||||
export type GetEntityStoreEngineRequestParams = z.infer<typeof GetEntityStoreEngineRequestParams>;
|
||||
export const GetEntityStoreEngineRequestParams = z.object({
|
||||
/**
|
||||
* The entity type of the store (either 'user' or 'host').
|
||||
*/
|
||||
entityType: EntityType,
|
||||
});
|
||||
export type GetEntityStoreEngineRequestParamsInput = z.input<
|
||||
typeof GetEntityStoreEngineRequestParams
|
||||
>;
|
||||
|
||||
export type GetEntityStoreEngineResponse = z.infer<typeof GetEntityStoreEngineResponse>;
|
||||
export const GetEntityStoreEngineResponse = EngineDescriptor;
|
|
@ -0,0 +1,25 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Get Entity Store engine
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/entity_store/engines/{entityType}:
|
||||
get:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: GetEntityStoreEngine
|
||||
summary: Get the Entity Store engine
|
||||
parameters:
|
||||
- name: entityType
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
$ref: '../common.schema.yaml#/components/schemas/EntityType'
|
||||
description: The entity type of the store (either 'user' or 'host').
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '../common.schema.yaml#/components/schemas/EngineDescriptor'
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Init Entity Store types
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { EntityType, IndexPattern, EngineDescriptor } from '../common.gen';
|
||||
|
||||
export type InitEntityStoreRequestParams = z.infer<typeof InitEntityStoreRequestParams>;
|
||||
export const InitEntityStoreRequestParams = z.object({
|
||||
/**
|
||||
* The entity type of the store (either 'user' or 'host').
|
||||
*/
|
||||
entityType: EntityType,
|
||||
});
|
||||
export type InitEntityStoreRequestParamsInput = z.input<typeof InitEntityStoreRequestParams>;
|
||||
|
||||
export type InitEntityStoreRequestBody = z.infer<typeof InitEntityStoreRequestBody>;
|
||||
export const InitEntityStoreRequestBody = z.object({
|
||||
indexPattern: IndexPattern.optional(),
|
||||
filter: z.string().optional(),
|
||||
});
|
||||
export type InitEntityStoreRequestBodyInput = z.input<typeof InitEntityStoreRequestBody>;
|
||||
|
||||
export type InitEntityStoreResponse = z.infer<typeof InitEntityStoreResponse>;
|
||||
export const InitEntityStoreResponse = EngineDescriptor;
|
|
@ -0,0 +1,39 @@
|
|||
openapi: 3.0.0
|
||||
|
||||
info:
|
||||
title: Init Entity Store types
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/entity_store/engines/{entityType}/init:
|
||||
post:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: InitEntityStore
|
||||
summary: Initialize the Entity Store
|
||||
parameters:
|
||||
- name: entityType
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
$ref: '../common.schema.yaml#/components/schemas/EntityType'
|
||||
description: The entity type of the store (either 'user' or 'host').
|
||||
requestBody:
|
||||
description: Schema for the engine initialization
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
indexPattern:
|
||||
$ref: '../common.schema.yaml#/components/schemas/IndexPattern'
|
||||
filter:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '../common.schema.yaml#/components/schemas/EngineDescriptor'
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: List Entity Store engines
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { EngineDescriptor } from '../common.gen';
|
||||
|
||||
export type ListEntityStoreEnginesResponse = z.infer<typeof ListEntityStoreEnginesResponse>;
|
||||
export const ListEntityStoreEnginesResponse = z.object({
|
||||
count: z.number().int().optional(),
|
||||
engines: z.array(EngineDescriptor).optional(),
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: List Entity Store engines
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/entity_store/engines:
|
||||
get:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: ListEntityStoreEngines
|
||||
summary: List the Entity Store engines
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
count:
|
||||
type: integer
|
||||
engines:
|
||||
type: array
|
||||
items:
|
||||
$ref: '../common.schema.yaml#/components/schemas/EngineDescriptor'
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Start the entity store engine
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { EntityType } from '../common.gen';
|
||||
|
||||
export type StartEntityStoreRequestParams = z.infer<typeof StartEntityStoreRequestParams>;
|
||||
export const StartEntityStoreRequestParams = z.object({
|
||||
/**
|
||||
* The entity type of the store (either 'user' or 'host').
|
||||
*/
|
||||
entityType: EntityType,
|
||||
});
|
||||
export type StartEntityStoreRequestParamsInput = z.input<typeof StartEntityStoreRequestParams>;
|
||||
|
||||
export type StartEntityStoreResponse = z.infer<typeof StartEntityStoreResponse>;
|
||||
export const StartEntityStoreResponse = z.object({
|
||||
started: z.boolean().optional(),
|
||||
});
|
|
@ -0,0 +1,31 @@
|
|||
openapi: 3.0.0
|
||||
|
||||
info:
|
||||
title: Start the entity store engine
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/entity_store/engines/{entityType}/start:
|
||||
post:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: StartEntityStore
|
||||
summary: Start the Entity Store engine
|
||||
parameters:
|
||||
- name: entityType
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
$ref: '../common.schema.yaml#/components/schemas/EntityType'
|
||||
description: The entity type of the store (either 'user' or 'host').
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
started:
|
||||
type: boolean
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Get the entity store engine stats
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { EntityType, IndexPattern, EngineStatus } from '../common.gen';
|
||||
|
||||
export type GetEntityStoreStatsRequestParams = z.infer<typeof GetEntityStoreStatsRequestParams>;
|
||||
export const GetEntityStoreStatsRequestParams = z.object({
|
||||
/**
|
||||
* The entity type of the store (either 'user' or 'host').
|
||||
*/
|
||||
entityType: EntityType,
|
||||
});
|
||||
export type GetEntityStoreStatsRequestParamsInput = z.input<
|
||||
typeof GetEntityStoreStatsRequestParams
|
||||
>;
|
||||
|
||||
export type GetEntityStoreStatsResponse = z.infer<typeof GetEntityStoreStatsResponse>;
|
||||
export const GetEntityStoreStatsResponse = z.object({
|
||||
type: EntityType.optional(),
|
||||
indexPattern: IndexPattern.optional(),
|
||||
status: EngineStatus.optional(),
|
||||
transforms: z.array(z.object({})).optional(),
|
||||
indices: z.array(z.object({})).optional(),
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
openapi: 3.0.0
|
||||
|
||||
info:
|
||||
title: Get the entity store engine stats
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/entity_store/engines/{entityType}/stats:
|
||||
post:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: GetEntityStoreStats
|
||||
summary: Get the Entity Store engine stats
|
||||
parameters:
|
||||
- name: entityType
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
$ref: '../common.schema.yaml#/components/schemas/EntityType'
|
||||
description: The entity type of the store (either 'user' or 'host').
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
$ref : '../common.schema.yaml#/components/schemas/EntityType'
|
||||
indexPattern:
|
||||
$ref : '../common.schema.yaml#/components/schemas/IndexPattern'
|
||||
status:
|
||||
$ref : '../common.schema.yaml#/components/schemas/EngineStatus'
|
||||
transforms:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
indices:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Stop the entity store engine
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { EntityType } from '../common.gen';
|
||||
|
||||
export type StopEntityStoreRequestParams = z.infer<typeof StopEntityStoreRequestParams>;
|
||||
export const StopEntityStoreRequestParams = z.object({
|
||||
/**
|
||||
* The entity type of the store (either 'user' or 'host').
|
||||
*/
|
||||
entityType: EntityType,
|
||||
});
|
||||
export type StopEntityStoreRequestParamsInput = z.input<typeof StopEntityStoreRequestParams>;
|
||||
|
||||
export type StopEntityStoreResponse = z.infer<typeof StopEntityStoreResponse>;
|
||||
export const StopEntityStoreResponse = z.object({
|
||||
stopped: z.boolean().optional(),
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
openapi: 3.0.0
|
||||
|
||||
info:
|
||||
title: Stop the entity store engine
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/entity_store/engines/{entityType}/stop:
|
||||
post:
|
||||
x-labels: [ess, serverless]
|
||||
x-codegen-enabled: true
|
||||
operationId: StopEntityStore
|
||||
summary: Stop the Entity Store engine
|
||||
parameters:
|
||||
- name: entityType
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
$ref: '../common.schema.yaml#/components/schemas/EntityType'
|
||||
description: The entity type of the store (either 'user' or 'host').
|
||||
responses:
|
||||
'200':
|
||||
description: Successful response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
stopped:
|
||||
type: boolean
|
||||
|
|
@ -242,6 +242,33 @@ import type {
|
|||
InternalUploadAssetCriticalityRecordsResponse,
|
||||
UploadAssetCriticalityRecordsResponse,
|
||||
} from './entity_analytics/asset_criticality/upload_asset_criticality_csv.gen';
|
||||
import type {
|
||||
DeleteEntityStoreRequestQueryInput,
|
||||
DeleteEntityStoreRequestParamsInput,
|
||||
DeleteEntityStoreResponse,
|
||||
} from './entity_analytics/entity_store/engine/delete.gen';
|
||||
import type {
|
||||
GetEntityStoreEngineRequestParamsInput,
|
||||
GetEntityStoreEngineResponse,
|
||||
} from './entity_analytics/entity_store/engine/get.gen';
|
||||
import type {
|
||||
InitEntityStoreRequestParamsInput,
|
||||
InitEntityStoreRequestBodyInput,
|
||||
InitEntityStoreResponse,
|
||||
} from './entity_analytics/entity_store/engine/init.gen';
|
||||
import type { ListEntityStoreEnginesResponse } from './entity_analytics/entity_store/engine/list.gen';
|
||||
import type {
|
||||
StartEntityStoreRequestParamsInput,
|
||||
StartEntityStoreResponse,
|
||||
} from './entity_analytics/entity_store/engine/start.gen';
|
||||
import type {
|
||||
GetEntityStoreStatsRequestParamsInput,
|
||||
GetEntityStoreStatsResponse,
|
||||
} from './entity_analytics/entity_store/engine/stats.gen';
|
||||
import type {
|
||||
StopEntityStoreRequestParamsInput,
|
||||
StopEntityStoreResponse,
|
||||
} from './entity_analytics/entity_store/engine/stop.gen';
|
||||
import type { DisableRiskEngineResponse } from './entity_analytics/risk_engine/engine_disable_route.gen';
|
||||
import type { EnableRiskEngineResponse } from './entity_analytics/risk_engine/engine_enable_route.gen';
|
||||
import type { InitRiskEngineResponse } from './entity_analytics/risk_engine/engine_init_route.gen';
|
||||
|
@ -620,6 +647,20 @@ Migrations are initiated per index. While the process is neither destructive nor
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async deleteEntityStore(props: DeleteEntityStoreProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API DeleteEntityStore`);
|
||||
return this.kbnClient
|
||||
.request<DeleteEntityStoreResponse>({
|
||||
path: replaceParams('/api/entity_store/engines/{entityType}', props.params),
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'DELETE',
|
||||
|
||||
query: props.query,
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async deleteNote(props: DeleteNoteProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API DeleteNote`);
|
||||
return this.kbnClient
|
||||
|
@ -1155,6 +1196,30 @@ finalize it.
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async getEntityStoreEngine(props: GetEntityStoreEngineProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API GetEntityStoreEngine`);
|
||||
return this.kbnClient
|
||||
.request<GetEntityStoreEngineResponse>({
|
||||
path: replaceParams('/api/entity_store/engines/{entityType}', props.params),
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'GET',
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async getEntityStoreStats(props: GetEntityStoreStatsProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API GetEntityStoreStats`);
|
||||
return this.kbnClient
|
||||
.request<GetEntityStoreStatsResponse>({
|
||||
path: replaceParams('/api/entity_store/engines/{entityType}/stats', props.params),
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'POST',
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Gets notes
|
||||
*/
|
||||
|
@ -1311,6 +1376,19 @@ finalize it.
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async initEntityStore(props: InitEntityStoreProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API InitEntityStore`);
|
||||
return this.kbnClient
|
||||
.request<InitEntityStoreResponse>({
|
||||
path: replaceParams('/api/entity_store/engines/{entityType}/init', props.params),
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'POST',
|
||||
body: props.body,
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Initializes the Risk Engine by creating the necessary indices and mappings, removing old transforms, and starting the new risk engine
|
||||
*/
|
||||
|
@ -1367,6 +1445,18 @@ finalize it.
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async listEntityStoreEngines() {
|
||||
this.log.info(`${new Date().toISOString()} Calling API ListEntityStoreEngines`);
|
||||
return this.kbnClient
|
||||
.request<ListEntityStoreEnginesResponse>({
|
||||
path: '/api/entity_store/engines',
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'GET',
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Update specific fields of an existing detection rule using the `rule_id` or `id` field.
|
||||
*/
|
||||
|
@ -1699,6 +1789,30 @@ detection engine rules.
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async startEntityStore(props: StartEntityStoreProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API StartEntityStore`);
|
||||
return this.kbnClient
|
||||
.request<StartEntityStoreResponse>({
|
||||
path: replaceParams('/api/entity_store/engines/{entityType}/start', props.params),
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'POST',
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async stopEntityStore(props: StopEntityStoreProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API StopEntityStore`);
|
||||
return this.kbnClient
|
||||
.request<StopEntityStoreResponse>({
|
||||
path: replaceParams('/api/entity_store/engines/{entityType}/stop', props.params),
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'POST',
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Suggests user profiles.
|
||||
*/
|
||||
|
@ -1809,6 +1923,10 @@ export interface CreateUpdateProtectionUpdatesNoteProps {
|
|||
export interface DeleteAssetCriticalityRecordProps {
|
||||
query: DeleteAssetCriticalityRecordRequestQueryInput;
|
||||
}
|
||||
export interface DeleteEntityStoreProps {
|
||||
query: DeleteEntityStoreRequestQueryInput;
|
||||
params: DeleteEntityStoreRequestParamsInput;
|
||||
}
|
||||
export interface DeleteNoteProps {
|
||||
body: DeleteNoteRequestBodyInput;
|
||||
}
|
||||
|
@ -1902,6 +2020,12 @@ export interface GetEndpointSuggestionsProps {
|
|||
params: GetEndpointSuggestionsRequestParamsInput;
|
||||
body: GetEndpointSuggestionsRequestBodyInput;
|
||||
}
|
||||
export interface GetEntityStoreEngineProps {
|
||||
params: GetEntityStoreEngineRequestParamsInput;
|
||||
}
|
||||
export interface GetEntityStoreStatsProps {
|
||||
params: GetEntityStoreStatsRequestParamsInput;
|
||||
}
|
||||
export interface GetNotesProps {
|
||||
query: GetNotesRequestQueryInput;
|
||||
}
|
||||
|
@ -1932,6 +2056,10 @@ export interface ImportRulesProps {
|
|||
export interface ImportTimelinesProps {
|
||||
body: ImportTimelinesRequestBodyInput;
|
||||
}
|
||||
export interface InitEntityStoreProps {
|
||||
params: InitEntityStoreRequestParamsInput;
|
||||
body: InitEntityStoreRequestBodyInput;
|
||||
}
|
||||
export interface InstallPrepackedTimelinesProps {
|
||||
body: InstallPrepackedTimelinesRequestBodyInput;
|
||||
}
|
||||
|
@ -1984,6 +2112,12 @@ export interface SetAlertsStatusProps {
|
|||
export interface SetAlertTagsProps {
|
||||
body: SetAlertTagsRequestBodyInput;
|
||||
}
|
||||
export interface StartEntityStoreProps {
|
||||
params: StartEntityStoreRequestParamsInput;
|
||||
}
|
||||
export interface StopEntityStoreProps {
|
||||
params: StopEntityStoreRequestParamsInput;
|
||||
}
|
||||
export interface SuggestUserProfilesProps {
|
||||
query: SuggestUserProfilesRequestQueryInput;
|
||||
}
|
||||
|
|
|
@ -223,6 +223,11 @@ export const allowedExperimentalValues = Object.freeze({
|
|||
* Enables the new data ingestion hub
|
||||
*/
|
||||
dataIngestionHubEnabled: false,
|
||||
|
||||
/**
|
||||
* Enables the new Entity Store engine routes
|
||||
*/
|
||||
entityStoreEnabled: false,
|
||||
});
|
||||
|
||||
type ExperimentalConfigKeys = Array<keyof ExperimentalFeatures>;
|
||||
|
|
|
@ -256,6 +256,187 @@ paths:
|
|||
summary: List Asset Criticality Records
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
/api/entity_store/engines:
|
||||
get:
|
||||
operationId: ListEntityStoreEngines
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
count:
|
||||
type: integer
|
||||
engines:
|
||||
items:
|
||||
$ref: '#/components/schemas/EngineDescriptor'
|
||||
type: array
|
||||
description: Successful response
|
||||
summary: List the Entity Store engines
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
'/api/entity_store/engines/{entityType}':
|
||||
delete:
|
||||
operationId: DeleteEntityStore
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
- description: Control flag to also delete the entity data.
|
||||
in: query
|
||||
name: data
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
deleted:
|
||||
type: boolean
|
||||
description: Successful response
|
||||
summary: Delete the Entity Store engine
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
get:
|
||||
operationId: GetEntityStoreEngine
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/EngineDescriptor'
|
||||
description: Successful response
|
||||
summary: Get the Entity Store engine
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
'/api/entity_store/engines/{entityType}/init':
|
||||
post:
|
||||
operationId: InitEntityStore
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
filter:
|
||||
type: string
|
||||
indexPattern:
|
||||
$ref: '#/components/schemas/IndexPattern'
|
||||
description: Schema for the engine initialization
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/EngineDescriptor'
|
||||
description: Successful response
|
||||
summary: Initialize the Entity Store
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
'/api/entity_store/engines/{entityType}/start':
|
||||
post:
|
||||
operationId: StartEntityStore
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
started:
|
||||
type: boolean
|
||||
description: Successful response
|
||||
summary: Start the Entity Store engine
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
'/api/entity_store/engines/{entityType}/stats':
|
||||
post:
|
||||
operationId: GetEntityStoreStats
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
indexPattern:
|
||||
$ref: '#/components/schemas/IndexPattern'
|
||||
indices:
|
||||
items:
|
||||
type: object
|
||||
type: array
|
||||
status:
|
||||
$ref: '#/components/schemas/EngineStatus'
|
||||
transforms:
|
||||
items:
|
||||
type: object
|
||||
type: array
|
||||
type:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
description: Successful response
|
||||
summary: Get the Entity Store engine stats
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
'/api/entity_store/engines/{entityType}/stop':
|
||||
post:
|
||||
operationId: StopEntityStore
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
stopped:
|
||||
type: boolean
|
||||
description: Successful response
|
||||
summary: Stop the Entity Store engine
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
/api/risk_score/engine/schedule_now:
|
||||
post:
|
||||
operationId: ScheduleRiskEngineNow
|
||||
|
@ -351,11 +532,35 @@ components:
|
|||
$ref: '#/components/schemas/AssetCriticalityLevel'
|
||||
required:
|
||||
- criticality_level
|
||||
EngineDescriptor:
|
||||
type: object
|
||||
properties:
|
||||
filter:
|
||||
type: string
|
||||
indexPattern:
|
||||
$ref: '#/components/schemas/IndexPattern'
|
||||
status:
|
||||
$ref: '#/components/schemas/EngineStatus'
|
||||
type:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
EngineStatus:
|
||||
enum:
|
||||
- installing
|
||||
- started
|
||||
- stopped
|
||||
type: string
|
||||
EntityType:
|
||||
enum:
|
||||
- user
|
||||
- host
|
||||
type: string
|
||||
IdField:
|
||||
enum:
|
||||
- host.name
|
||||
- user.name
|
||||
type: string
|
||||
IndexPattern:
|
||||
type: string
|
||||
RiskEngineScheduleNowErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
@ -256,6 +256,187 @@ paths:
|
|||
summary: List Asset Criticality Records
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
/api/entity_store/engines:
|
||||
get:
|
||||
operationId: ListEntityStoreEngines
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
count:
|
||||
type: integer
|
||||
engines:
|
||||
items:
|
||||
$ref: '#/components/schemas/EngineDescriptor'
|
||||
type: array
|
||||
description: Successful response
|
||||
summary: List the Entity Store engines
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
'/api/entity_store/engines/{entityType}':
|
||||
delete:
|
||||
operationId: DeleteEntityStore
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
- description: Control flag to also delete the entity data.
|
||||
in: query
|
||||
name: data
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
deleted:
|
||||
type: boolean
|
||||
description: Successful response
|
||||
summary: Delete the Entity Store engine
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
get:
|
||||
operationId: GetEntityStoreEngine
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/EngineDescriptor'
|
||||
description: Successful response
|
||||
summary: Get the Entity Store engine
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
'/api/entity_store/engines/{entityType}/init':
|
||||
post:
|
||||
operationId: InitEntityStore
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
filter:
|
||||
type: string
|
||||
indexPattern:
|
||||
$ref: '#/components/schemas/IndexPattern'
|
||||
description: Schema for the engine initialization
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/EngineDescriptor'
|
||||
description: Successful response
|
||||
summary: Initialize the Entity Store
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
'/api/entity_store/engines/{entityType}/start':
|
||||
post:
|
||||
operationId: StartEntityStore
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
started:
|
||||
type: boolean
|
||||
description: Successful response
|
||||
summary: Start the Entity Store engine
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
'/api/entity_store/engines/{entityType}/stats':
|
||||
post:
|
||||
operationId: GetEntityStoreStats
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
indexPattern:
|
||||
$ref: '#/components/schemas/IndexPattern'
|
||||
indices:
|
||||
items:
|
||||
type: object
|
||||
type: array
|
||||
status:
|
||||
$ref: '#/components/schemas/EngineStatus'
|
||||
transforms:
|
||||
items:
|
||||
type: object
|
||||
type: array
|
||||
type:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
description: Successful response
|
||||
summary: Get the Entity Store engine stats
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
'/api/entity_store/engines/{entityType}/stop':
|
||||
post:
|
||||
operationId: StopEntityStore
|
||||
parameters:
|
||||
- description: The entity type of the store (either 'user' or 'host').
|
||||
in: path
|
||||
name: entityType
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
stopped:
|
||||
type: boolean
|
||||
description: Successful response
|
||||
summary: Stop the Entity Store engine
|
||||
tags:
|
||||
- Security Solution Entity Analytics API
|
||||
/api/risk_score/engine/schedule_now:
|
||||
post:
|
||||
operationId: ScheduleRiskEngineNow
|
||||
|
@ -351,11 +532,35 @@ components:
|
|||
$ref: '#/components/schemas/AssetCriticalityLevel'
|
||||
required:
|
||||
- criticality_level
|
||||
EngineDescriptor:
|
||||
type: object
|
||||
properties:
|
||||
filter:
|
||||
type: string
|
||||
indexPattern:
|
||||
$ref: '#/components/schemas/IndexPattern'
|
||||
status:
|
||||
$ref: '#/components/schemas/EngineStatus'
|
||||
type:
|
||||
$ref: '#/components/schemas/EntityType'
|
||||
EngineStatus:
|
||||
enum:
|
||||
- installing
|
||||
- started
|
||||
- stopped
|
||||
type: string
|
||||
EntityType:
|
||||
enum:
|
||||
- user
|
||||
- host
|
||||
type: string
|
||||
IdField:
|
||||
enum:
|
||||
- host.name
|
||||
- user.name
|
||||
type: string
|
||||
IndexPattern:
|
||||
type: string
|
||||
RiskEngineScheduleNowErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
@ -53,7 +53,8 @@
|
|||
"notifications",
|
||||
"savedSearch",
|
||||
"unifiedDocViewer",
|
||||
"charts"
|
||||
"charts",
|
||||
"entityManager"
|
||||
],
|
||||
"optionalPlugins": [
|
||||
"cloudExperiments",
|
||||
|
@ -87,4 +88,4 @@
|
|||
"common"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,6 +36,7 @@ import { getEndpointAuthzInitialStateMock } from '../../../../../common/endpoint
|
|||
import type { EndpointAuthz } from '../../../../../common/endpoint/types/authz';
|
||||
import { riskEngineDataClientMock } from '../../../entity_analytics/risk_engine/risk_engine_data_client.mock';
|
||||
import { riskScoreDataClientMock } from '../../../entity_analytics/risk_score/risk_score_data_client.mock';
|
||||
import { entityStoreDataClientMock } from '../../../entity_analytics/entity_store/entity_store_data_client.mock';
|
||||
import { assetCriticalityDataClientMock } from '../../../entity_analytics/asset_criticality/asset_criticality_data_client.mock';
|
||||
import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks';
|
||||
import { detectionRulesClientMock } from '../../rule_management/logic/detection_rules_client/__mocks__/detection_rules_client';
|
||||
|
@ -72,6 +73,7 @@ export const createMockClients = () => {
|
|||
riskEngineDataClient: riskEngineDataClientMock.create(),
|
||||
riskScoreDataClient: riskScoreDataClientMock.create(),
|
||||
assetCriticalityDataClient: assetCriticalityDataClientMock.create(),
|
||||
entityStoreDataClient: entityStoreDataClientMock.create(),
|
||||
|
||||
internalFleetServices: {
|
||||
packages: packageServiceMock.createClient(),
|
||||
|
@ -159,6 +161,7 @@ const createSecuritySolutionRequestContextMock = (
|
|||
getRiskScoreDataClient: jest.fn(() => clients.riskScoreDataClient),
|
||||
getAssetCriticalityDataClient: jest.fn(() => clients.assetCriticalityDataClient),
|
||||
getAuditLogger: jest.fn(() => mockAuditLogger),
|
||||
getEntityStoreDataClient: jest.fn(() => clients.entityStoreDataClient),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { EngineStatus } from '../../../../common/api/entity_analytics/entity_store/common.gen';
|
||||
import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants';
|
||||
|
||||
/**
|
||||
* Default index pattern for entity store
|
||||
* This is the same as the default index pattern for the SIEM app but might diverge in the future
|
||||
*/
|
||||
export const ENTITY_STORE_DEFAULT_SOURCE_INDICES = DEFAULT_INDEX_PATTERN;
|
||||
|
||||
export const ENGINE_STATUS: Record<Uppercase<EngineStatus>, EngineStatus> = {
|
||||
INSTALLING: 'installing',
|
||||
STARTED: 'started',
|
||||
STOPPED: 'stopped',
|
||||
};
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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 { entityDefinitionSchema, type EntityDefinition } from '@kbn/entities-schema';
|
||||
import { ENTITY_STORE_DEFAULT_SOURCE_INDICES } from './constants';
|
||||
|
||||
export const HOST_ENTITY_DEFINITION: EntityDefinition = entityDefinitionSchema.parse({
|
||||
id: 'ea_host_entity_store',
|
||||
name: 'EA Host Store',
|
||||
type: 'host',
|
||||
indexPatterns: ENTITY_STORE_DEFAULT_SOURCE_INDICES,
|
||||
identityFields: ['host.name'],
|
||||
displayNameTemplate: '{{host.name}}',
|
||||
metadata: [
|
||||
'host.domain',
|
||||
'host.hostname',
|
||||
'host.id',
|
||||
'host.ip',
|
||||
'host.mac',
|
||||
'host.name',
|
||||
'host.type',
|
||||
'host.architecture',
|
||||
],
|
||||
history: {
|
||||
timestampField: '@timestamp',
|
||||
interval: '1m',
|
||||
},
|
||||
version: '1.0.0',
|
||||
});
|
||||
|
||||
export const USER_ENTITY_DEFINITION: EntityDefinition = entityDefinitionSchema.parse({
|
||||
id: 'ea_user_entity_store',
|
||||
name: 'EA User Store',
|
||||
type: 'user',
|
||||
indexPatterns: ENTITY_STORE_DEFAULT_SOURCE_INDICES,
|
||||
identityFields: ['user.name'],
|
||||
displayNameTemplate: '{{user.name}}',
|
||||
metadata: [
|
||||
'user.domain',
|
||||
'user.email',
|
||||
'user.full_name',
|
||||
'user.hash',
|
||||
'user.id',
|
||||
'user.name',
|
||||
'user.roles',
|
||||
],
|
||||
history: {
|
||||
timestampField: '@timestamp',
|
||||
interval: '1m',
|
||||
},
|
||||
version: '1.0.0',
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { EntityStoreDataClient } from './entity_store_data_client';
|
||||
|
||||
const createEntityStoreDataClientMock = () =>
|
||||
({
|
||||
init: jest.fn(),
|
||||
start: jest.fn(),
|
||||
stop: jest.fn(),
|
||||
get: jest.fn(),
|
||||
list: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
} as unknown as jest.Mocked<EntityStoreDataClient>);
|
||||
|
||||
export const entityStoreDataClientMock = { create: createEntityStoreDataClientMock };
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { Logger, ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import type { EntityClient } from '@kbn/entityManager-plugin/server/lib/entity_client';
|
||||
|
||||
import type {
|
||||
InitEntityStoreRequestBody,
|
||||
InitEntityStoreResponse,
|
||||
} from '../../../../common/api/entity_analytics/entity_store/engine/init.gen';
|
||||
import type {
|
||||
EngineDescriptor,
|
||||
EntityType,
|
||||
} from '../../../../common/api/entity_analytics/entity_store/common.gen';
|
||||
import { entityEngineDescriptorTypeName } from './saved_object';
|
||||
import { EngineDescriptorClient } from './saved_object/engine_descriptor';
|
||||
import { getEntityDefinition } from './utils/utils';
|
||||
import { ENGINE_STATUS } from './constants';
|
||||
|
||||
interface EntityStoreClientOpts {
|
||||
logger: Logger;
|
||||
esClient: ElasticsearchClient;
|
||||
entityClient: EntityClient;
|
||||
namespace: string;
|
||||
soClient: SavedObjectsClientContract;
|
||||
}
|
||||
|
||||
export class EntityStoreDataClient {
|
||||
private engineClient: EngineDescriptorClient;
|
||||
constructor(private readonly options: EntityStoreClientOpts) {
|
||||
this.engineClient = new EngineDescriptorClient(options.soClient);
|
||||
}
|
||||
|
||||
public async init(
|
||||
entityType: EntityType,
|
||||
{ indexPattern = '', filter = '' }: InitEntityStoreRequestBody
|
||||
): Promise<InitEntityStoreResponse> {
|
||||
const definition = getEntityDefinition(entityType);
|
||||
|
||||
this.options.logger.info(`Initializing entity store for ${entityType}`);
|
||||
|
||||
const descriptor = await this.engineClient.init(entityType, definition, filter);
|
||||
await this.options.entityClient.createEntityDefinition({
|
||||
definition: {
|
||||
...definition,
|
||||
filter,
|
||||
indexPatterns: indexPattern
|
||||
? [...definition.indexPatterns, ...indexPattern.split(',')]
|
||||
: definition.indexPatterns,
|
||||
},
|
||||
});
|
||||
const updated = await this.engineClient.update(definition.id, ENGINE_STATUS.STARTED);
|
||||
|
||||
return { ...descriptor, ...updated };
|
||||
}
|
||||
|
||||
public async start(entityType: EntityType) {
|
||||
const definition = getEntityDefinition(entityType);
|
||||
|
||||
const descriptor = await this.engineClient.get(entityType);
|
||||
|
||||
if (descriptor.status !== ENGINE_STATUS.STOPPED) {
|
||||
throw new Error(
|
||||
`Cannot start Entity engine for ${entityType} when current status is: ${descriptor.status}`
|
||||
);
|
||||
}
|
||||
|
||||
this.options.logger.info(`Starting entity store for ${entityType}`);
|
||||
await this.options.entityClient.startEntityDefinition(definition);
|
||||
|
||||
return this.engineClient.update(definition.id, ENGINE_STATUS.STARTED);
|
||||
}
|
||||
|
||||
public async stop(entityType: EntityType) {
|
||||
const definition = getEntityDefinition(entityType);
|
||||
|
||||
const descriptor = await this.engineClient.get(entityType);
|
||||
|
||||
if (descriptor.status !== ENGINE_STATUS.STARTED) {
|
||||
throw new Error(
|
||||
`Cannot stop Entity engine for ${entityType} when current status is: ${descriptor.status}`
|
||||
);
|
||||
}
|
||||
|
||||
this.options.logger.info(`Stopping entity store for ${entityType}`);
|
||||
await this.options.entityClient.stopEntityDefinition(definition);
|
||||
|
||||
return this.engineClient.update(definition.id, ENGINE_STATUS.STOPPED);
|
||||
}
|
||||
|
||||
public async get(entityType: EntityType) {
|
||||
return this.engineClient.get(entityType);
|
||||
}
|
||||
|
||||
public async list() {
|
||||
return this.options.soClient
|
||||
.find<EngineDescriptor>({
|
||||
type: entityEngineDescriptorTypeName,
|
||||
})
|
||||
.then(({ saved_objects: engines }) => ({
|
||||
engines: engines.map((engine) => engine.attributes),
|
||||
count: engines.length,
|
||||
}));
|
||||
}
|
||||
|
||||
public async delete(entityType: EntityType, deleteData: boolean) {
|
||||
const { id } = getEntityDefinition(entityType);
|
||||
|
||||
this.options.logger.info(`Deleting entity store for ${entityType}`);
|
||||
|
||||
await this.options.entityClient.deleteEntityDefinition({ id, deleteData });
|
||||
await this.engineClient.delete(id);
|
||||
|
||||
return { deleted: true };
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
|
||||
import type { DeleteEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/delete.gen';
|
||||
import {
|
||||
DeleteEntityStoreRequestQuery,
|
||||
DeleteEntityStoreRequestParams,
|
||||
} from '../../../../../common/api/entity_analytics/entity_store/engine/delete.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../types';
|
||||
|
||||
export const deleteEntityEngineRoute = (
|
||||
router: EntityAnalyticsRoutesDeps['router'],
|
||||
logger: Logger
|
||||
) => {
|
||||
router.versioned
|
||||
.delete({
|
||||
access: 'public',
|
||||
path: '/api/entity_store/engines/{entityType}',
|
||||
options: {
|
||||
tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
query: buildRouteValidationWithZod(DeleteEntityStoreRequestQuery),
|
||||
params: buildRouteValidationWithZod(DeleteEntityStoreRequestParams),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
async (context, request, response): Promise<IKibanaResponse<DeleteEntityStoreResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
const body = await secSol
|
||||
.getEntityStoreDataClient()
|
||||
.delete(request.params.entityType, !!request.query.data);
|
||||
|
||||
return response.ok({ body });
|
||||
} catch (e) {
|
||||
logger.error('Error in DeleteEntityStore:', e);
|
||||
const error = transformError(e);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
|
||||
import type { GetEntityStoreEngineResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/get.gen';
|
||||
import { GetEntityStoreEngineRequestParams } from '../../../../../common/api/entity_analytics/entity_store/engine/get.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../types';
|
||||
|
||||
export const getEntityEngineRoute = (
|
||||
router: EntityAnalyticsRoutesDeps['router'],
|
||||
logger: Logger
|
||||
) => {
|
||||
router.versioned
|
||||
.get({
|
||||
access: 'public',
|
||||
path: '/api/entity_store/engines/{entityType}',
|
||||
options: {
|
||||
tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
params: buildRouteValidationWithZod(GetEntityStoreEngineRequestParams),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
async (
|
||||
context,
|
||||
request,
|
||||
response
|
||||
): Promise<IKibanaResponse<GetEntityStoreEngineResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
const body = await secSol.getEntityStoreDataClient().get(request.params.entityType);
|
||||
|
||||
return response.ok({ body });
|
||||
} catch (e) {
|
||||
logger.error('Error in GetEntityStoreEngine:', e);
|
||||
const error = transformError(e);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { registerEntityStoreRoutes } from './register_entity_store_routes';
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
|
||||
import type { InitEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/init.gen';
|
||||
import {
|
||||
InitEntityStoreRequestBody,
|
||||
InitEntityStoreRequestParams,
|
||||
} from '../../../../../common/api/entity_analytics/entity_store/engine/init.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../types';
|
||||
|
||||
export const initEntityEngineRoute = (
|
||||
router: EntityAnalyticsRoutesDeps['router'],
|
||||
logger: Logger
|
||||
) => {
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: '/api/entity_store/engines/{entityType}/init',
|
||||
options: {
|
||||
tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
params: buildRouteValidationWithZod(InitEntityStoreRequestParams),
|
||||
body: buildRouteValidationWithZod(InitEntityStoreRequestBody),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
async (context, request, response): Promise<IKibanaResponse<InitEntityStoreResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
|
||||
const body: InitEntityStoreResponse = await secSol
|
||||
.getEntityStoreDataClient()
|
||||
.init(request.params.entityType, request.body);
|
||||
|
||||
return response.ok({ body });
|
||||
} catch (e) {
|
||||
logger.error('Error in InitEntityStore:', e);
|
||||
const error = transformError(e);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
|
||||
import type { ListEntityStoreEnginesResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/list.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../common/constants';
|
||||
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../types';
|
||||
|
||||
export const listEntityEnginesRoute = (
|
||||
router: EntityAnalyticsRoutesDeps['router'],
|
||||
logger: Logger
|
||||
) => {
|
||||
router.versioned
|
||||
.get({
|
||||
access: 'public',
|
||||
path: '/api/entity_store/engines',
|
||||
options: {
|
||||
tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {},
|
||||
},
|
||||
|
||||
async (
|
||||
context,
|
||||
request,
|
||||
response
|
||||
): Promise<IKibanaResponse<ListEntityStoreEnginesResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
const body = await secSol.getEntityStoreDataClient().list();
|
||||
|
||||
return response.ok({ body });
|
||||
} catch (e) {
|
||||
logger.error('Error in ListEntityStoreEngines:', e);
|
||||
const error = transformError(e);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../types';
|
||||
import { deleteEntityEngineRoute } from './delete';
|
||||
import { getEntityEngineRoute } from './get';
|
||||
import { initEntityEngineRoute } from './init';
|
||||
import { listEntityEnginesRoute } from './list';
|
||||
import { startEntityEngineRoute } from './start';
|
||||
import { stopEntityEngineRoute } from './stop';
|
||||
|
||||
export const registerEntityStoreRoutes = ({ router, logger }: EntityAnalyticsRoutesDeps) => {
|
||||
initEntityEngineRoute(router, logger);
|
||||
startEntityEngineRoute(router, logger);
|
||||
stopEntityEngineRoute(router, logger);
|
||||
deleteEntityEngineRoute(router, logger);
|
||||
getEntityEngineRoute(router, logger);
|
||||
listEntityEnginesRoute(router, logger);
|
||||
};
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
|
||||
import type { StartEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/start.gen';
|
||||
import { StartEntityStoreRequestParams } from '../../../../../common/api/entity_analytics/entity_store/engine/start.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../types';
|
||||
import { ENGINE_STATUS } from '../constants';
|
||||
|
||||
export const startEntityEngineRoute = (
|
||||
router: EntityAnalyticsRoutesDeps['router'],
|
||||
logger: Logger
|
||||
) => {
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: '/api/entity_store/engines/{entityType}/start',
|
||||
options: {
|
||||
tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
params: buildRouteValidationWithZod(StartEntityStoreRequestParams),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
async (context, request, response): Promise<IKibanaResponse<StartEntityStoreResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
const engine = await secSol.getEntityStoreDataClient().start(request.params.entityType);
|
||||
|
||||
return response.ok({ body: { started: engine.status === ENGINE_STATUS.STARTED } });
|
||||
} catch (e) {
|
||||
logger.error('Error in StartEntityStore:', e);
|
||||
const error = transformError(e);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
|
||||
import type { GetEntityStoreStatsResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/stats.gen';
|
||||
import { GetEntityStoreStatsRequestParams } from '../../../../../common/api/entity_analytics/entity_store/engine/stats.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../types';
|
||||
|
||||
export const getEntityEngineStatsRoute = (
|
||||
router: EntityAnalyticsRoutesDeps['router'],
|
||||
logger: Logger
|
||||
) => {
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: '/api/entity_store/engines/{entityType}/stats',
|
||||
options: {
|
||||
tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
params: buildRouteValidationWithZod(GetEntityStoreStatsRequestParams),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
async (context, request, response): Promise<IKibanaResponse<GetEntityStoreStatsResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
// TODO
|
||||
throw new Error('Not implemented');
|
||||
|
||||
// return response.ok({ body });
|
||||
} catch (e) {
|
||||
logger.error('Error in GetEntityStoreStats:', e);
|
||||
const error = transformError(e);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse, Logger } from '@kbn/core/server';
|
||||
import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
|
||||
import type { StopEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/stop.gen';
|
||||
import { StopEntityStoreRequestParams } from '../../../../../common/api/entity_analytics/entity_store/engine/stop.gen';
|
||||
import { API_VERSIONS, APP_ID } from '../../../../../common/constants';
|
||||
import type { EntityAnalyticsRoutesDeps } from '../../types';
|
||||
import { ENGINE_STATUS } from '../constants';
|
||||
|
||||
export const stopEntityEngineRoute = (
|
||||
router: EntityAnalyticsRoutesDeps['router'],
|
||||
logger: Logger
|
||||
) => {
|
||||
router.versioned
|
||||
.post({
|
||||
access: 'public',
|
||||
path: '/api/entity_store/engines/{entityType}/stop',
|
||||
options: {
|
||||
tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`],
|
||||
},
|
||||
})
|
||||
.addVersion(
|
||||
{
|
||||
version: API_VERSIONS.public.v1,
|
||||
validate: {
|
||||
request: {
|
||||
params: buildRouteValidationWithZod(StopEntityStoreRequestParams),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
async (context, request, response): Promise<IKibanaResponse<StopEntityStoreResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const secSol = await context.securitySolution;
|
||||
const engine = await secSol.getEntityStoreDataClient().stop(request.params.entityType);
|
||||
|
||||
return response.ok({ body: { stopped: engine.status === ENGINE_STATUS.STOPPED } });
|
||||
} catch (e) {
|
||||
logger.error('Error in StopEntityStore:', e);
|
||||
const error = transformError(e);
|
||||
return siemResponse.error({
|
||||
statusCode: error.statusCode,
|
||||
body: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type {
|
||||
SavedObjectsClientContract,
|
||||
SavedObjectsFindResponse,
|
||||
} from '@kbn/core-saved-objects-api-server';
|
||||
import type { EntityDefinition } from '@kbn/entities-schema';
|
||||
import type {
|
||||
EngineDescriptor,
|
||||
EngineStatus,
|
||||
EntityType,
|
||||
} from '../../../../../common/api/entity_analytics/entity_store/common.gen';
|
||||
|
||||
import { entityEngineDescriptorTypeName } from './engine_descriptor_type';
|
||||
import { getByEntityTypeQuery, getEntityDefinition } from '../utils/utils';
|
||||
import { ENGINE_STATUS } from '../constants';
|
||||
|
||||
export class EngineDescriptorClient {
|
||||
constructor(private readonly soClient: SavedObjectsClientContract) {}
|
||||
|
||||
async init(entityType: EntityType, definition: EntityDefinition, filter: string) {
|
||||
const engineDescriptor = await this.find(entityType);
|
||||
|
||||
if (engineDescriptor.total > 0)
|
||||
throw new Error(`Entity engine for ${entityType} already exists`);
|
||||
|
||||
const { attributes } = await this.soClient.create<EngineDescriptor>(
|
||||
entityEngineDescriptorTypeName,
|
||||
{
|
||||
status: ENGINE_STATUS.INSTALLING,
|
||||
type: entityType,
|
||||
indexPattern: definition.indexPatterns.join(','),
|
||||
filter,
|
||||
},
|
||||
{ id: definition.id }
|
||||
);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
async update(id: string, status: EngineStatus) {
|
||||
const { attributes } = await this.soClient.update<EngineDescriptor>(
|
||||
entityEngineDescriptorTypeName,
|
||||
id,
|
||||
{ status },
|
||||
{ refresh: 'wait_for' }
|
||||
);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
async find(entityType: EntityType): Promise<SavedObjectsFindResponse<EngineDescriptor>> {
|
||||
return this.soClient.find<EngineDescriptor>({
|
||||
type: entityEngineDescriptorTypeName,
|
||||
filter: getByEntityTypeQuery(entityType),
|
||||
});
|
||||
}
|
||||
|
||||
async get(entityType: EntityType): Promise<EngineDescriptor> {
|
||||
const { id } = getEntityDefinition(entityType);
|
||||
|
||||
const { attributes } = await this.soClient.get<EngineDescriptor>(
|
||||
entityEngineDescriptorTypeName,
|
||||
id
|
||||
);
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
async delete(id: string) {
|
||||
return this.soClient.delete(entityEngineDescriptorTypeName, id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 { SECURITY_SOLUTION_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server';
|
||||
import type { SavedObjectsType } from '@kbn/core/server';
|
||||
|
||||
export const entityEngineDescriptorTypeName = 'entity-engine-status';
|
||||
|
||||
export const entityEngineDescriptorTypeMappings: SavedObjectsType['mappings'] = {
|
||||
dynamic: false,
|
||||
properties: {
|
||||
indexPattern: {
|
||||
type: 'keyword',
|
||||
},
|
||||
filter: {
|
||||
type: 'keyword',
|
||||
},
|
||||
type: {
|
||||
type: 'keyword', // EntityType: user | host
|
||||
},
|
||||
status: {
|
||||
type: 'keyword', // EngineStatus: installing | started | stopped
|
||||
},
|
||||
},
|
||||
};
|
||||
export const entityEngineDescriptorType: SavedObjectsType = {
|
||||
name: entityEngineDescriptorTypeName,
|
||||
indexPattern: SECURITY_SOLUTION_SAVED_OBJECT_INDEX,
|
||||
hidden: false,
|
||||
namespaceType: 'multiple-isolated',
|
||||
mappings: entityEngineDescriptorTypeMappings,
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export * from './engine_descriptor_type';
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SavedObjectsFindResponse } from '@kbn/core-saved-objects-api-server';
|
||||
import type {
|
||||
EngineDescriptor,
|
||||
EntityType,
|
||||
} from '../../../../../common/api/entity_analytics/entity_store/common.gen';
|
||||
import { HOST_ENTITY_DEFINITION, USER_ENTITY_DEFINITION } from '../definition';
|
||||
import { entityEngineDescriptorTypeName } from '../saved_object';
|
||||
|
||||
export const getEntityDefinition = (entityType: EntityType) => {
|
||||
if (entityType === 'host') return HOST_ENTITY_DEFINITION;
|
||||
if (entityType === 'user') return USER_ENTITY_DEFINITION;
|
||||
|
||||
throw new Error(`Unsupported entity type: ${entityType}`);
|
||||
};
|
||||
|
||||
export const ensureEngineExists =
|
||||
(entityType: EntityType) => (results: SavedObjectsFindResponse<EngineDescriptor>) => {
|
||||
if (results.total === 0) {
|
||||
throw new Error(`Entity engine for ${entityType} does not exist`);
|
||||
}
|
||||
return results.saved_objects[0].attributes;
|
||||
};
|
||||
|
||||
export const getByEntityTypeQuery = (entityType: EntityType) => {
|
||||
return `${entityEngineDescriptorTypeName}.attributes.type: ${entityType}`;
|
||||
};
|
|
@ -9,9 +9,13 @@ import { registerAssetCriticalityRoutes } from './asset_criticality/routes';
|
|||
import { registerRiskScoreRoutes } from './risk_score/routes';
|
||||
import { registerRiskEngineRoutes } from './risk_engine/routes';
|
||||
import type { EntityAnalyticsRoutesDeps } from './types';
|
||||
import { registerEntityStoreRoutes } from './entity_store/routes';
|
||||
|
||||
export const registerEntityAnalyticsRoutes = (routeDeps: EntityAnalyticsRoutesDeps) => {
|
||||
registerAssetCriticalityRoutes(routeDeps);
|
||||
registerRiskScoreRoutes(routeDeps);
|
||||
registerRiskEngineRoutes(routeDeps);
|
||||
if (routeDeps.config.experimentalFeatures.entityStoreEnabled) {
|
||||
registerEntityStoreRoutes(routeDeps);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@ import { memoize } from 'lodash';
|
|||
import type { Logger, KibanaRequest, RequestHandlerContext } from '@kbn/core/server';
|
||||
|
||||
import type { BuildFlavor } from '@kbn/config';
|
||||
import { EntityClient } from '@kbn/entityManager-plugin/server/lib/entity_client';
|
||||
import { DEFAULT_SPACE_ID } from '../common/constants';
|
||||
import { AppClientFactory } from './client';
|
||||
import type { ConfigType } from './config';
|
||||
|
@ -31,6 +32,7 @@ import { RiskScoreDataClient } from './lib/entity_analytics/risk_score/risk_scor
|
|||
import { AssetCriticalityDataClient } from './lib/entity_analytics/asset_criticality';
|
||||
import { createDetectionRulesClient } from './lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client';
|
||||
import { buildMlAuthz } from './lib/machine_learning/authz';
|
||||
import { EntityStoreDataClient } from './lib/entity_analytics/entity_store/entity_store_data_client';
|
||||
|
||||
export interface IRequestContextFactory {
|
||||
create(
|
||||
|
@ -190,6 +192,22 @@ export class RequestContextFactory implements IRequestContextFactory {
|
|||
auditLogger: getAuditLogger(),
|
||||
})
|
||||
),
|
||||
getEntityStoreDataClient: memoize(() => {
|
||||
const esClient = coreContext.elasticsearch.client.asCurrentUser;
|
||||
const logger = options.logger;
|
||||
const soClient = coreContext.savedObjects.client;
|
||||
return new EntityStoreDataClient({
|
||||
namespace: getSpaceId(),
|
||||
esClient,
|
||||
logger,
|
||||
soClient,
|
||||
entityClient: new EntityClient({
|
||||
esClient,
|
||||
soClient,
|
||||
logger,
|
||||
}),
|
||||
});
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import { prebuiltRuleAssetType } from './lib/detection_engine/prebuilt_rules';
|
|||
import { type as signalsMigrationType } from './lib/detection_engine/migrations/saved_objects';
|
||||
import { manifestType, unifiedManifestType } from './endpoint/lib/artifacts/saved_object_mappings';
|
||||
import { riskEngineConfigurationType } from './lib/entity_analytics/risk_engine/saved_object';
|
||||
import { entityEngineDescriptorType } from './lib/entity_analytics/entity_store/saved_object';
|
||||
|
||||
const types = [
|
||||
noteType,
|
||||
|
@ -26,6 +27,7 @@ const types = [
|
|||
unifiedManifestType,
|
||||
signalsMigrationType,
|
||||
riskEngineConfigurationType,
|
||||
entityEngineDescriptorType,
|
||||
protectionUpdatesNoteType,
|
||||
];
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import type { RiskEngineDataClient } from './lib/entity_analytics/risk_engine/ri
|
|||
import type { RiskScoreDataClient } from './lib/entity_analytics/risk_score/risk_score_data_client';
|
||||
import type { AssetCriticalityDataClient } from './lib/entity_analytics/asset_criticality';
|
||||
import type { IDetectionRulesClient } from './lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client_interface';
|
||||
import type { EntityStoreDataClient } from './lib/entity_analytics/entity_store/entity_store_data_client';
|
||||
export { AppClient };
|
||||
|
||||
export interface SecuritySolutionApiRequestHandlerContext {
|
||||
|
@ -55,6 +56,7 @@ export interface SecuritySolutionApiRequestHandlerContext {
|
|||
getRiskEngineDataClient: () => RiskEngineDataClient;
|
||||
getRiskScoreDataClient: () => RiskScoreDataClient;
|
||||
getAssetCriticalityDataClient: () => AssetCriticalityDataClient;
|
||||
getEntityStoreDataClient: () => EntityStoreDataClient;
|
||||
}
|
||||
|
||||
export type SecuritySolutionRequestHandlerContext = CustomRequestHandlerContext<{
|
||||
|
|
|
@ -223,5 +223,7 @@
|
|||
"@kbn/cloud-security-posture",
|
||||
"@kbn/security-solution-distribution-bar",
|
||||
"@kbn/cloud-security-posture-common",
|
||||
"@kbn/entityManager-plugin",
|
||||
"@kbn/entities-schema",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -37,6 +37,10 @@ import {
|
|||
CreateUpdateProtectionUpdatesNoteRequestBodyInput,
|
||||
} from '@kbn/security-solution-plugin/common/api/endpoint/protection_updates_note/protection_updates_note.gen';
|
||||
import { DeleteAssetCriticalityRecordRequestQueryInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/asset_criticality/delete_asset_criticality.gen';
|
||||
import {
|
||||
DeleteEntityStoreRequestQueryInput,
|
||||
DeleteEntityStoreRequestParamsInput,
|
||||
} from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/delete.gen';
|
||||
import { DeleteNoteRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/delete_note/delete_note_route.gen';
|
||||
import { DeleteRuleRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/delete_rule/delete_rule_route.gen';
|
||||
import { DeleteTimelinesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/delete_timelines/delete_timelines_route.gen';
|
||||
|
@ -76,6 +80,8 @@ import {
|
|||
GetEndpointSuggestionsRequestParamsInput,
|
||||
GetEndpointSuggestionsRequestBodyInput,
|
||||
} from '@kbn/security-solution-plugin/common/api/endpoint/suggestions/get_suggestions.gen';
|
||||
import { GetEntityStoreEngineRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/get.gen';
|
||||
import { GetEntityStoreStatsRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/stats.gen';
|
||||
import { GetNotesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/timeline/get_notes/get_notes_route.gen';
|
||||
import { GetPolicyResponseRequestQueryInput } from '@kbn/security-solution-plugin/common/api/endpoint/policy/policy_response.gen';
|
||||
import { GetProtectionUpdatesNoteRequestParamsInput } from '@kbn/security-solution-plugin/common/api/endpoint/protection_updates_note/protection_updates_note.gen';
|
||||
|
@ -91,6 +97,10 @@ import { GetTimelineRequestQueryInput } from '@kbn/security-solution-plugin/comm
|
|||
import { GetTimelinesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/timeline/get_timelines/get_timelines_route.gen';
|
||||
import { ImportRulesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/import_rules/import_rules_route.gen';
|
||||
import { ImportTimelinesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/import_timelines/import_timelines_route.gen';
|
||||
import {
|
||||
InitEntityStoreRequestParamsInput,
|
||||
InitEntityStoreRequestBodyInput,
|
||||
} from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/init.gen';
|
||||
import { InstallPrepackedTimelinesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/install_prepackaged_timelines/install_prepackaged_timelines_route.gen';
|
||||
import { PatchRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.gen';
|
||||
import { PatchTimelineRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/patch_timelines/patch_timeline_route.gen';
|
||||
|
@ -110,6 +120,8 @@ import { SearchAlertsRequestBodyInput } from '@kbn/security-solution-plugin/comm
|
|||
import { SetAlertAssigneesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/alert_assignees/set_alert_assignees_route.gen';
|
||||
import { SetAlertsStatusRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/signals/set_signal_status/set_signals_status_route.gen';
|
||||
import { SetAlertTagsRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags.gen';
|
||||
import { StartEntityStoreRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/start.gen';
|
||||
import { StopEntityStoreRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/stop.gen';
|
||||
import { SuggestUserProfilesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/users/suggest_user_profiles_route.gen';
|
||||
import { TriggerRiskScoreCalculationRequestBodyInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/risk_engine/entity_calculation_route.gen';
|
||||
import { UpdateRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.gen';
|
||||
|
@ -313,6 +325,14 @@ Migrations are initiated per index. While the process is neither destructive nor
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.query(props.query);
|
||||
},
|
||||
deleteEntityStore(props: DeleteEntityStoreProps) {
|
||||
return supertest
|
||||
.delete(replaceParams('/api/entity_store/engines/{entityType}', props.params))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.query(props.query);
|
||||
},
|
||||
deleteNote(props: DeleteNoteProps) {
|
||||
return supertest
|
||||
.delete('/api/note')
|
||||
|
@ -668,6 +688,20 @@ finalize it.
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
getEntityStoreEngine(props: GetEntityStoreEngineProps) {
|
||||
return supertest
|
||||
.get(replaceParams('/api/entity_store/engines/{entityType}', props.params))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
getEntityStoreStats(props: GetEntityStoreStatsProps) {
|
||||
return supertest
|
||||
.post(replaceParams('/api/entity_store/engines/{entityType}/stats', props.params))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
/**
|
||||
* Gets notes
|
||||
*/
|
||||
|
@ -764,6 +798,14 @@ finalize it.
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
initEntityStore(props: InitEntityStoreProps) {
|
||||
return supertest
|
||||
.post(replaceParams('/api/entity_store/engines/{entityType}/init', props.params))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
/**
|
||||
* Initializes the Risk Engine by creating the necessary indices and mappings, removing old transforms, and starting the new risk engine
|
||||
*/
|
||||
|
@ -799,6 +841,13 @@ finalize it.
|
|||
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
listEntityStoreEngines() {
|
||||
return supertest
|
||||
.get('/api/entity_store/engines')
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
/**
|
||||
* Update specific fields of an existing detection rule using the `rule_id` or `id` field.
|
||||
*/
|
||||
|
@ -1018,6 +1067,20 @@ detection engine rules.
|
|||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send(props.body as object);
|
||||
},
|
||||
startEntityStore(props: StartEntityStoreProps) {
|
||||
return supertest
|
||||
.post(replaceParams('/api/entity_store/engines/{entityType}/start', props.params))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
stopEntityStore(props: StopEntityStoreProps) {
|
||||
return supertest
|
||||
.post(replaceParams('/api/entity_store/engines/{entityType}/stop', props.params))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
|
||||
},
|
||||
/**
|
||||
* Suggests user profiles.
|
||||
*/
|
||||
|
@ -1107,6 +1170,10 @@ export interface CreateUpdateProtectionUpdatesNoteProps {
|
|||
export interface DeleteAssetCriticalityRecordProps {
|
||||
query: DeleteAssetCriticalityRecordRequestQueryInput;
|
||||
}
|
||||
export interface DeleteEntityStoreProps {
|
||||
query: DeleteEntityStoreRequestQueryInput;
|
||||
params: DeleteEntityStoreRequestParamsInput;
|
||||
}
|
||||
export interface DeleteNoteProps {
|
||||
body: DeleteNoteRequestBodyInput;
|
||||
}
|
||||
|
@ -1200,6 +1267,12 @@ export interface GetEndpointSuggestionsProps {
|
|||
params: GetEndpointSuggestionsRequestParamsInput;
|
||||
body: GetEndpointSuggestionsRequestBodyInput;
|
||||
}
|
||||
export interface GetEntityStoreEngineProps {
|
||||
params: GetEntityStoreEngineRequestParamsInput;
|
||||
}
|
||||
export interface GetEntityStoreStatsProps {
|
||||
params: GetEntityStoreStatsRequestParamsInput;
|
||||
}
|
||||
export interface GetNotesProps {
|
||||
query: GetNotesRequestQueryInput;
|
||||
}
|
||||
|
@ -1229,6 +1302,10 @@ export interface ImportRulesProps {
|
|||
export interface ImportTimelinesProps {
|
||||
body: ImportTimelinesRequestBodyInput;
|
||||
}
|
||||
export interface InitEntityStoreProps {
|
||||
params: InitEntityStoreRequestParamsInput;
|
||||
body: InitEntityStoreRequestBodyInput;
|
||||
}
|
||||
export interface InstallPrepackedTimelinesProps {
|
||||
body: InstallPrepackedTimelinesRequestBodyInput;
|
||||
}
|
||||
|
@ -1278,6 +1355,12 @@ export interface SetAlertsStatusProps {
|
|||
export interface SetAlertTagsProps {
|
||||
body: SetAlertTagsRequestBodyInput;
|
||||
}
|
||||
export interface StartEntityStoreProps {
|
||||
params: StartEntityStoreRequestParamsInput;
|
||||
}
|
||||
export interface StopEntityStoreProps {
|
||||
params: StopEntityStoreRequestParamsInput;
|
||||
}
|
||||
export interface SuggestUserProfilesProps {
|
||||
query: SuggestUserProfilesRequestQueryInput;
|
||||
}
|
||||
|
|
|
@ -349,6 +349,18 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
"saved_object:risk-engine-configuration/delete",
|
||||
"saved_object:risk-engine-configuration/bulk_delete",
|
||||
"saved_object:risk-engine-configuration/share_to_space",
|
||||
"saved_object:entity-engine-status/bulk_get",
|
||||
"saved_object:entity-engine-status/get",
|
||||
"saved_object:entity-engine-status/find",
|
||||
"saved_object:entity-engine-status/open_point_in_time",
|
||||
"saved_object:entity-engine-status/close_point_in_time",
|
||||
"saved_object:entity-engine-status/create",
|
||||
"saved_object:entity-engine-status/bulk_create",
|
||||
"saved_object:entity-engine-status/update",
|
||||
"saved_object:entity-engine-status/bulk_update",
|
||||
"saved_object:entity-engine-status/delete",
|
||||
"saved_object:entity-engine-status/bulk_delete",
|
||||
"saved_object:entity-engine-status/share_to_space",
|
||||
"saved_object:policy-settings-protection-updates-note/bulk_get",
|
||||
"saved_object:policy-settings-protection-updates-note/get",
|
||||
"saved_object:policy-settings-protection-updates-note/find",
|
||||
|
@ -1182,6 +1194,18 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
"saved_object:risk-engine-configuration/delete",
|
||||
"saved_object:risk-engine-configuration/bulk_delete",
|
||||
"saved_object:risk-engine-configuration/share_to_space",
|
||||
"saved_object:entity-engine-status/bulk_get",
|
||||
"saved_object:entity-engine-status/get",
|
||||
"saved_object:entity-engine-status/find",
|
||||
"saved_object:entity-engine-status/open_point_in_time",
|
||||
"saved_object:entity-engine-status/close_point_in_time",
|
||||
"saved_object:entity-engine-status/create",
|
||||
"saved_object:entity-engine-status/bulk_create",
|
||||
"saved_object:entity-engine-status/update",
|
||||
"saved_object:entity-engine-status/bulk_update",
|
||||
"saved_object:entity-engine-status/delete",
|
||||
"saved_object:entity-engine-status/bulk_delete",
|
||||
"saved_object:entity-engine-status/share_to_space",
|
||||
"saved_object:policy-settings-protection-updates-note/bulk_get",
|
||||
"saved_object:policy-settings-protection-updates-note/get",
|
||||
"saved_object:policy-settings-protection-updates-note/find",
|
||||
|
@ -1779,6 +1803,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
"saved_object:risk-engine-configuration/find",
|
||||
"saved_object:risk-engine-configuration/open_point_in_time",
|
||||
"saved_object:risk-engine-configuration/close_point_in_time",
|
||||
"saved_object:entity-engine-status/bulk_get",
|
||||
"saved_object:entity-engine-status/get",
|
||||
"saved_object:entity-engine-status/find",
|
||||
"saved_object:entity-engine-status/open_point_in_time",
|
||||
"saved_object:entity-engine-status/close_point_in_time",
|
||||
"saved_object:policy-settings-protection-updates-note/bulk_get",
|
||||
"saved_object:policy-settings-protection-updates-note/get",
|
||||
"saved_object:policy-settings-protection-updates-note/find",
|
||||
|
@ -2135,6 +2164,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
"saved_object:risk-engine-configuration/find",
|
||||
"saved_object:risk-engine-configuration/open_point_in_time",
|
||||
"saved_object:risk-engine-configuration/close_point_in_time",
|
||||
"saved_object:entity-engine-status/bulk_get",
|
||||
"saved_object:entity-engine-status/get",
|
||||
"saved_object:entity-engine-status/find",
|
||||
"saved_object:entity-engine-status/open_point_in_time",
|
||||
"saved_object:entity-engine-status/close_point_in_time",
|
||||
"saved_object:policy-settings-protection-updates-note/bulk_get",
|
||||
"saved_object:policy-settings-protection-updates-note/get",
|
||||
"saved_object:policy-settings-protection-updates-note/find",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue