kibana/x-pack/plugins/endpoint/common/types.ts
Jonathan Buttner 0a9e17b57f
[Endpoint][EPM] Retrieve Index Pattern from Ingest Manager (#63016)
* Endpoint successfully depending on ingest manager to initialize

* Moving the endpoint functional tests to their own directory to avoid enabling ingest in the base tests

* Removing page objects and other endpoint fields from base functional

* Updating code owners with new functional location

* Adding index pattern functionality

* Missed a file

* Pointing resolver tests at endpoint functional tests

* Pointing space tests at the endpoint functional directory

* Adding ingest service to do setup and tests for 500s

* Correcting services path

* Adding jest test names

* Updating es archives with the correct mapping and index names

* Fixing import error

* Adding resolver tests to code owners

* enabling epm flag for functional tests

* adding correct tag to test

* Removing the version information and unneeded xsrf

* Addressing endpoint index pattern feedback

* Removing unused import

* Renaming index pattern to es index pattern

* Fixing missed index pattern calls

* Removing unused import

* Fixing type error

* Moving es_index_pattern outside of installed and fixing function name

* Keeping the event index the same for now

* Wrapping index pattern await in try catch

* Address PR feedback, adding comments
2020-04-16 16:20:16 -04:00

576 lines
13 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { SearchResponse } from 'elasticsearch';
import { TypeOf } from '@kbn/config-schema';
import { alertingIndexGetQuerySchema } from './schema/alert_index';
import { indexPatternGetParamsSchema } from './schema/index_pattern';
import { Datasource, NewDatasource } from '../../ingest_manager/common';
/**
* A deep readonly type that will make all children of a given object readonly recursively
*/
export type Immutable<T> = T extends undefined | null | boolean | string | number
? T
: unknown extends T
? unknown
: T extends Array<infer U>
? ImmutableArray<U>
: T extends Map<infer K, infer V>
? ImmutableMap<K, V>
: T extends Set<infer M>
? ImmutableSet<M>
: ImmutableObject<T>;
export type ImmutableArray<T> = ReadonlyArray<Immutable<T>>;
export type ImmutableMap<K, V> = ReadonlyMap<Immutable<K>, Immutable<V>>;
export type ImmutableSet<T> = ReadonlySet<Immutable<T>>;
export type ImmutableObject<T> = { readonly [K in keyof T]: Immutable<T[K]> };
export type Direction = 'asc' | 'desc';
export class EndpointAppConstants {
static BASE_API_URL = '/api/endpoint';
static INDEX_PATTERN_ROUTE = `${EndpointAppConstants.BASE_API_URL}/index_pattern`;
static ALERT_INDEX_NAME = 'events-endpoint-1';
static EVENT_DATASET = 'events';
static DEFAULT_TOTAL_HITS = 10000;
/**
* Legacy events are stored in indices with endgame-* prefix
*/
static LEGACY_EVENT_INDEX_NAME = 'endgame-*';
/**
* Alerts
**/
static ALERT_LIST_DEFAULT_PAGE_SIZE = 10;
static ALERT_LIST_DEFAULT_SORT = '@timestamp';
static MAX_LONG_INT = '9223372036854775807'; // 2^63-1
}
export interface AlertResultList {
/**
* The alerts restricted by page size.
*/
alerts: AlertData[];
/**
* The total number of alerts on the page.
*/
total: number;
/**
* The size of the requested page.
*/
request_page_size: number;
/**
* The index of the requested page, starting at 0.
*/
request_page_index?: number;
/**
* The offset of the requested page, starting at 0.
*/
result_from_index?: number;
/**
* A cursor-based URL for the next page.
*/
next: string | null;
/**
* A cursor-based URL for the previous page.
*/
prev: string | null;
}
export interface HostResultList {
/* the hosts restricted by the page size */
hosts: HostInfo[];
/* the total number of unique hosts in the index */
total: number;
/* the page size requested */
request_page_size: number;
/* the page index requested */
request_page_index: number;
}
export interface OSFields {
full: string;
name: string;
version: string;
variant: string;
}
export interface HostFields {
id: string;
hostname: string;
ip: string[];
mac: string[];
os: OSFields;
}
export interface HashFields {
md5: string;
sha1: string;
sha256: string;
}
export interface MalwareClassificationFields {
identifier: string;
score: number;
threshold: number;
version: string;
}
export interface PrivilegesFields {
description: string;
name: string;
enabled: boolean;
}
export interface ThreadFields {
id: number;
service_name: string;
start: number;
start_address: number;
start_address_module: string;
}
export interface DllFields {
pe: {
architecture: string;
imphash: string;
};
code_signature: {
subject_name: string;
trusted: boolean;
};
compile_time: number;
hash: HashFields;
malware_classification: MalwareClassificationFields;
mapped_address: number;
mapped_size: number;
path: string;
}
/**
* Describes an Alert Event.
* Should be in line with ECS schema.
*/
export type AlertEvent = Immutable<{
'@timestamp': number;
agent: {
id: string;
version: string;
};
event: {
id: string;
action: string;
category: string;
kind: string;
dataset: string;
module: string;
type: string;
};
endpoint: {
policy: {
id: string;
};
};
process: {
code_signature: {
subject_name: string;
trusted: boolean;
};
command_line?: string;
domain?: string;
pid: number;
ppid?: number;
entity_id: string;
parent?: {
pid: number;
entity_id: string;
};
name: string;
hash: HashFields;
pe?: {
imphash: string;
};
executable: string;
sid?: string;
start: number;
malware_classification?: MalwareClassificationFields;
token: {
domain: string;
type: string;
user: string;
sid: string;
integrity_level: number;
integrity_level_name: string;
privileges?: PrivilegesFields[];
};
thread?: ThreadFields[];
uptime: number;
user: string;
};
file: {
owner: string;
name: string;
path: string;
accessed: number;
mtime: number;
created: number;
size: number;
hash: HashFields;
pe?: {
imphash: string;
};
code_signature: {
trusted: boolean;
subject_name: string;
};
malware_classification: MalwareClassificationFields;
temp_file_path: string;
};
host: HostFields;
dll?: DllFields[];
}>;
interface AlertMetadata {
id: string;
// Alert Details Pagination
next: string | null;
prev: string | null;
}
interface AlertState {
state: {
host_metadata: HostMetadata;
};
}
/**
* Union of alert data and metadata.
*/
export type AlertData = AlertEvent & AlertMetadata;
export type AlertDetails = AlertData & AlertState;
/**
* The status of the host
*/
export enum HostStatus {
/**
* Default state of the host when no host information is present or host information cannot
* be retrieved. e.g. API error
*/
ERROR = 'error',
/**
* Host is online as indicated by its checkin status during the last checkin window
*/
ONLINE = 'online',
/**
* Host is offline as indicated by its checkin status during the last checkin window
*/
OFFLINE = 'offline',
}
export type HostInfo = Immutable<{
metadata: HostMetadata;
host_status: HostStatus;
}>;
export type HostMetadata = Immutable<{
'@timestamp': number;
event: {
created: number;
};
elastic: {
agent: {
id: string;
};
};
endpoint: {
policy: {
id: string;
};
};
agent: {
id: string;
version: string;
};
host: HostFields;
}>;
/**
* Represents `total` response from Elasticsearch after ES 7.0.
*/
export interface ESTotal {
value: number;
relation: string;
}
/**
* `Hits` array in responses from ES search API.
*/
export type AlertHits = SearchResponse<AlertEvent>['hits']['hits'];
export interface LegacyEndpointEvent {
'@timestamp': number;
endgame: {
pid?: number;
ppid?: number;
event_type_full?: string;
event_subtype_full?: string;
event_timestamp?: number;
event_type?: number;
unique_pid: number;
unique_ppid?: number;
machine_id?: string;
process_name?: string;
process_path?: string;
timestamp_utc?: string;
serial_event_id?: number;
};
agent: {
id: string;
type: string;
version: string;
};
process?: object;
rule?: object;
user?: object;
}
export interface EndpointEvent {
'@timestamp': number;
agent: {
id: string;
version: string;
type: string;
};
ecs: {
version: string;
};
event: {
category: string | string[];
type: string | string[];
id: string;
kind: string;
};
host: {
id: string;
hostname: string;
ip: string[];
mac: string[];
os: OSFields;
};
process: {
entity_id: string;
name: string;
parent?: {
entity_id: string;
name?: string;
};
};
}
export type ResolverEvent = EndpointEvent | LegacyEndpointEvent;
/**
* Takes a @kbn/config-schema 'schema' type and returns a type that represents valid inputs.
* Similar to `TypeOf`, but allows strings as input for `schema.number()` (which is inline
* with the behavior of the validator.) Also, for `schema.object`, when a value is a `schema.maybe`
* the key will be marked optional (via `?`) so that you can omit keys for optional values.
*
* Use this when creating a value that will be passed to the schema.
* e.g.
* ```ts
* const input: KbnConfigSchemaInputTypeOf<typeof schema> = value
* schema.validate(input) // should be valid
* ```
* Note that because the types coming from `@kbn/config-schema`'s schemas sometimes have deeply nested
* `Type` types, we process the result of `TypeOf` instead, as this will be consistent.
*/
type KbnConfigSchemaInputTypeOf<T> = T extends Record<string, unknown>
? KbnConfigSchemaInputObjectTypeOf<
T
> /** `schema.number()` accepts strings, so this type should accept them as well. */
: number extends T
? T | string
: T;
/**
* Works like ObjectResultType, except that 'maybe' schema will create an optional key.
* This allows us to avoid passing 'maybeKey: undefined' when constructing such an object.
*
* Instead of using this directly, use `InputTypeOf`.
*/
type KbnConfigSchemaInputObjectTypeOf<P extends Record<string, unknown>> = {
/** Use ? to make the field optional if the prop accepts undefined.
* This allows us to avoid writing `field: undefined` for optional fields.
*/
[K in Exclude<keyof P, keyof KbnConfigSchemaNonOptionalProps<P>>]?: KbnConfigSchemaInputTypeOf<
P[K]
>;
} &
{ [K in keyof KbnConfigSchemaNonOptionalProps<P>]: KbnConfigSchemaInputTypeOf<P[K]> };
/**
* Takes the props of a schema.object type, and returns a version that excludes
* optional values. Used by `InputObjectTypeOf`.
*
* Instead of using this directly, use `InputTypeOf`.
*/
type KbnConfigSchemaNonOptionalProps<Props extends Record<string, unknown>> = Pick<
Props,
{
[Key in keyof Props]: undefined extends Props[Key]
? never
: null extends Props[Key]
? never
: Key;
}[keyof Props]
>;
/**
* Query params to pass to the alert API when fetching new data.
*/
export type AlertingIndexGetQueryInput = KbnConfigSchemaInputTypeOf<
TypeOf<typeof alertingIndexGetQuerySchema>
>;
/**
* Result of the validated query params when handling alert index requests.
*/
export type AlertingIndexGetQueryResult = TypeOf<typeof alertingIndexGetQuerySchema>;
/**
* Result of the validated params when handling an index pattern request.
*/
export type IndexPatternGetParamsResult = TypeOf<typeof indexPatternGetParamsSchema>;
/**
* Endpoint Policy configuration
*/
export interface PolicyConfig {
windows: {
events: {
dll_and_driver_load: boolean;
dns: boolean;
file: boolean;
network: boolean;
process: boolean;
registry: boolean;
security: boolean;
};
malware: MalwareFields;
logging: {
stdout: string;
file: string;
};
advanced: PolicyConfigAdvancedOptions;
};
mac: {
events: {
file: boolean;
process: boolean;
network: boolean;
};
malware: MalwareFields;
logging: {
stdout: string;
file: string;
};
advanced: PolicyConfigAdvancedOptions;
};
linux: {
events: {
file: boolean;
process: boolean;
network: boolean;
};
logging: {
stdout: string;
file: string;
};
advanced: PolicyConfigAdvancedOptions;
};
}
/**
* Windows-specific policy configuration that is supported via the UI
*/
type WindowsPolicyConfig = Pick<PolicyConfig['windows'], 'events' | 'malware'>;
/**
* Mac-specific policy configuration that is supported via the UI
*/
type MacPolicyConfig = Pick<PolicyConfig['mac'], 'malware' | 'events'>;
/**
* Linux-specific policy configuration that is supported via the UI
*/
type LinuxPolicyConfig = Pick<PolicyConfig['linux'], 'events'>;
/**
* The set of Policy configuration settings that are show/edited via the UI
*/
export interface UIPolicyConfig {
windows: WindowsPolicyConfig;
mac: MacPolicyConfig;
linux: LinuxPolicyConfig;
}
interface PolicyConfigAdvancedOptions {
elasticsearch: {
indices: {
control: string;
event: string;
logging: string;
};
kernel: {
connect: boolean;
process: boolean;
};
};
}
/** Policy: Malware protection fields */
export interface MalwareFields {
mode: ProtectionModes;
}
/** Policy protection mode options */
export enum ProtectionModes {
detect = 'detect',
prevent = 'prevent',
preventNotify = 'preventNotify',
off = 'off',
}
/**
* Endpoint Policy data, which extends Ingest's `Datasource` type
*/
export type PolicyData = Datasource & NewPolicyData;
/**
* New policy data. Used when updating the policy record via ingest APIs
*/
export type NewPolicyData = NewDatasource & {
inputs: [
{
type: 'endpoint';
enabled: boolean;
streams: [];
config: {
policy: {
value: PolicyConfig;
};
};
}
];
};