Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
455 changes: 405 additions & 50 deletions oas_docs/output/kibana.serverless.yaml

Large diffs are not rendered by default.

455 changes: 405 additions & 50 deletions oas_docs/output/kibana.yaml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"./oas_docs/output/kibana.yaml": 1242,
"./oas_docs/output/kibana.serverless.yaml": 1128
"./oas_docs/output/kibana.yaml": 1224,
"./oas_docs/output/kibana.serverless.yaml": 1110
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ import type { FtrProviderContext } from '@kbn/ftr-common-functional-services';
import { getRouteUrlForSpace } from '@kbn/spaces-plugin/common';

const securitySolutionApiServiceFactory = (supertest: SuperTest.Agent) => ({
/**
* Synchronize data view index patterns to all running entity engines so that newly added indices are picked up by the transforms.
*/
applyEntityEngineDataviewIndices(kibanaSpace: string = 'default') {
return supertest
.post(getRouteUrlForSpace('/api/entity_store/engines/apply_dataview_indices', kibanaSpace))
Expand Down Expand Up @@ -313,6 +316,9 @@ The entity will be immediately deleted from the latest index. It will remain av
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
/**
* Check whether the current user has the required Elasticsearch and Kibana privileges to use the Entity Store.
*/
entityStoreGetPrivileges(kibanaSpace: string = 'default') {
return supertest
.get(getRouteUrlForSpace('/internal/entity_store/privileges', kibanaSpace))
Expand Down Expand Up @@ -355,6 +361,9 @@ The entity will be immediately deleted from the latest index. It will remain av
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
},
/**
* Get the engine descriptor for a specific entity type, including its configuration and current status.
*/
getEntityEngine(props: GetEntityEngineProps, kibanaSpace: string = 'default') {
return supertest
.get(
Expand All @@ -379,6 +388,9 @@ The entity will be immediately deleted from the latest index. It will remain av
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
},
/**
* Get the overall Entity Store status and per-engine statuses, optionally including component-level health details.
*/
getEntityStoreStatus(props: GetEntityStoreStatusProps, kibanaSpace: string = 'default') {
return supertest
.get(getRouteUrlForSpace('/api/entity_store/status', kibanaSpace))
Expand Down Expand Up @@ -409,6 +421,9 @@ The entity will be immediately deleted from the latest index. It will remain av
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
},
/**
* Initialize a single entity engine for the specified entity type.
*/
initEntityEngine(props: InitEntityEngineProps, kibanaSpace: string = 'default') {
return supertest
.post(
Expand All @@ -422,6 +437,9 @@ The entity will be immediately deleted from the latest index. It will remain av
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
/**
* Initialize the entire Entity Store, creating engines for all or specified entity types.
*/
initEntityStore(props: InitEntityStoreProps, kibanaSpace: string = 'default') {
return supertest
.post(getRouteUrlForSpace('/api/entity_store/enable', kibanaSpace))
Expand Down Expand Up @@ -477,6 +495,9 @@ The entity will be immediately deleted from the latest index. It will remain av
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
/**
* Get a list of all installed entity engines and their current status.
*/
listEntityEngines(kibanaSpace: string = 'default') {
return supertest
.get(getRouteUrlForSpace('/api/entity_store/engines', kibanaSpace))
Expand Down Expand Up @@ -585,6 +606,9 @@ The entity will be immediately deleted from the latest index. It will remain av
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
/**
* Start a previously stopped entity engine, resuming transform processing for the given entity type.
*/
startEntityEngine(props: StartEntityEngineProps, kibanaSpace: string = 'default') {
return supertest
.post(
Expand All @@ -597,6 +621,9 @@ The entity will be immediately deleted from the latest index. It will remain av
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
},
/**
* Stop a running entity engine, pausing transform processing for the given entity type.
*/
stopEntityEngine(props: StopEntityEngineProps, kibanaSpace: string = 'default') {
return supertest
.post(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,85 +16,190 @@

import { z } from '@kbn/zod';

/**
* The type of entity.
*/
export type EntityType = z.infer<typeof EntityType>;
export const EntityType = z.enum(['user', 'host', 'service', 'generic']);
export type EntityTypeEnum = typeof EntityType.enum;
export const EntityTypeEnum = EntityType.enum;

/**
* The top-level Elastic Common Schema (ECS) field group that the entity maps to.
*/
export type BaseECSEntityField = z.infer<typeof BaseECSEntityField>;
export const BaseECSEntityField = z.enum(['user', 'host', 'service', 'entity']);
export type BaseECSEntityFieldEnum = typeof BaseECSEntityField.enum;
export const BaseECSEntityFieldEnum = BaseECSEntityField.enum;

/**
* An additional Elasticsearch index pattern to include as a source for entity data. Merged with the default data view indices when the engine runs.
*/
export type IndexPattern = z.infer<typeof IndexPattern>;
export const IndexPattern = z.string();

/**
* The current operational status of an entity engine.
*/
export type EngineStatus = z.infer<typeof EngineStatus>;
export const EngineStatus = z.enum(['installing', 'started', 'stopped', 'updating', 'error']);
export type EngineStatusEnum = typeof EngineStatus.enum;
export const EngineStatusEnum = EngineStatus.enum;

/**
* Describes a single entity engine, including its configuration and current status.
*/
export type EngineDescriptor = z.infer<typeof EngineDescriptor>;
export const EngineDescriptor = z.object({
type: EntityType,
indexPattern: IndexPattern,
status: EngineStatus,
/**
* An optional Kibana Query Language (KQL) filter applied to source documents before aggregation.
*/
filter: z.string().optional(),
/**
* The number of historical values retained per field.
*/
fieldHistoryLength: z.number().int(),
/**
* How far back the transform looks when calculating aggregations.
*/
lookbackPeriod: z
.string()
.regex(/[smdh]$/)
.optional()
.default('24h'),
/**
* The field used as the timestamp for source documents.
*/
timestampField: z.string().optional(),
/**
* The timeout for initializing the aggregating transform.
*/
timeout: z
.string()
.regex(/[smdh]$/)
.optional()
.default('180s'),
/**
* How often the transform runs.
*/
frequency: z
.string()
.regex(/[smdh]$/)
.optional()
.default('1m'),
/**
* The delay before the transform processes new data, allowing late-arriving documents to be included.
*/
delay: z
.string()
.regex(/[smdh]$/)
.optional()
.default('1m'),
/**
* Throttle value for the number of documents processed per second. Use -1 for no throttle.
*/
docsPerSecond: z.number().int().optional(),
/**
* Present when the engine status is `error`. Describes the failure.
*/
error: z
.object({
/**
* A human-readable error message.
*/
message: z.string(),
/**
* The lifecycle action that caused the error.
*/
action: z.literal('init'),
})
.optional(),
});

/**
* Statistics from the underlying Elasticsearch transform.
*/
export type TransformStatsMetadata = z.infer<typeof TransformStatsMetadata>;
export const TransformStatsMetadata = z.object({
/**
* Number of composite aggregation pages processed.
*/
pages_processed: z.number().int(),
/**
* Total number of source documents processed.
*/
documents_processed: z.number().int(),
/**
* Total number of documents written to the destination index.
*/
documents_indexed: z.number().int(),
/**
* Total number of documents deleted from the destination index.
*/
documents_deleted: z.number().int().optional(),
/**
* Number of times the transform has been triggered.
*/
trigger_count: z.number().int(),
/**
* Total time spent indexing documents, in milliseconds.
*/
index_time_in_ms: z.number().int(),
/**
* Total number of index operations.
*/
index_total: z.number().int(),
/**
* Total number of failed index operations.
*/
index_failures: z.number().int(),
/**
* Total time spent on search queries, in milliseconds.
*/
search_time_in_ms: z.number().int(),
/**
* Total number of search operations.
*/
search_total: z.number().int(),
/**
* Total number of failed search operations.
*/
search_failures: z.number().int(),
/**
* Total time spent processing results, in milliseconds.
*/
processing_time_in_ms: z.number().int(),
/**
* Total number of processing operations.
*/
processing_total: z.number().int(),
/**
* Total time spent deleting documents, in milliseconds.
*/
delete_time_in_ms: z.number().int().optional(),
/**
* Exponential moving average of checkpoint duration, in milliseconds.
*/
exponential_avg_checkpoint_duration_ms: z.number().int(),
/**
* Exponential moving average of documents indexed per checkpoint.
*/
exponential_avg_documents_indexed: z.number().int(),
/**
* Exponential moving average of documents processed per checkpoint.
*/
exponential_avg_documents_processed: z.number().int(),
});

export type Metadata = z.infer<typeof Metadata>;
export const Metadata = TransformStatsMetadata;

/**
* The type of Elasticsearch or Kibana resource backing an engine component.
*/
export type EngineComponentResource = z.infer<typeof EngineComponentResource>;
export const EngineComponentResource = z.enum([
'entity_engine',
Expand All @@ -112,31 +217,64 @@ export const EngineComponentResource = z.enum([
export type EngineComponentResourceEnum = typeof EngineComponentResource.enum;
export const EngineComponentResourceEnum = EngineComponentResource.enum;

/**
* Status of an individual Elasticsearch or Kibana resource backing an engine.
*/
export type EngineComponentStatus = z.infer<typeof EngineComponentStatus>;
export const EngineComponentStatus = z.object({
/**
* Unique identifier for the component.
*/
id: z.string(),
/**
* Whether the component is currently installed.
*/
installed: z.boolean(),
metadata: Metadata.optional(),
resource: EngineComponentResource,
/**
* The health status of the component.
*/
health: z.enum(['green', 'yellow', 'red', 'unavailable', 'unknown']).optional(),
/**
* Errors reported by this component, if any.
*/
errors: z
.array(
z.object({
/**
* Short error title.
*/
title: z.string().optional(),
/**
* Detailed error message.
*/
message: z.string().optional(),
})
)
.optional(),
});

/**
* The overall operational status of the Entity Store.
*/
export type StoreStatus = z.infer<typeof StoreStatus>;
export const StoreStatus = z.enum(['not_installed', 'installing', 'running', 'stopped', 'error']);
export type StoreStatusEnum = typeof StoreStatus.enum;
export const StoreStatusEnum = StoreStatus.enum;

/**
* Debug information about the Elasticsearch query executed.
*/
export type InspectQuery = z.infer<typeof InspectQuery>;
export const InspectQuery = z.object({
/**
* Raw Elasticsearch responses.
*/
response: z.array(z.string()),
/**
* Elasticsearch query DSL that was executed.
*/
dsl: z.array(z.string()),
});

Expand Down
Loading
Loading