diff --git a/docs/apm/troubleshooting.asciidoc b/docs/apm/troubleshooting.asciidoc index 65f7a378ec244..e00a67f6c78a4 100644 --- a/docs/apm/troubleshooting.asciidoc +++ b/docs/apm/troubleshooting.asciidoc @@ -49,7 +49,7 @@ GET /_template/apm-{version} *Using Logstash, Kafka, etc.* If you're not outputting data directly from APM Server to Elasticsearch (perhaps you're using Logstash or Kafka), then the index template will not be set up automatically. Instead, you'll need to -{apm-server-ref}/_manually_loading_template_configuration.html[load the template manually]. +{apm-server-ref}/configuration-template.html[load the template manually]. *Using a custom index names* This problem can also occur if you've customized the index name that you write APM data to. diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index 89330d2a86f76..dfffdffb08a08 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -123,7 +123,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [LoggerFactory](./kibana-plugin-core-server.loggerfactory.md) | The single purpose of LoggerFactory interface is to define a way to retrieve a context-based logger instance. | | [LoggingServiceSetup](./kibana-plugin-core-server.loggingservicesetup.md) | Provides APIs to plugins for customizing the plugin's logger. | | [LogMeta](./kibana-plugin-core-server.logmeta.md) | Contextual metadata | -| [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) | | +| [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) | APIs to retrieves metrics gathered and exposed by the core platform. | | [NodesVersionCompatibility](./kibana-plugin-core-server.nodesversioncompatibility.md) | | | [OnPostAuthToolkit](./kibana-plugin-core-server.onpostauthtoolkit.md) | A tool set defining an outcome of OnPostAuth interceptor for incoming request. | | [OnPreAuthToolkit](./kibana-plugin-core-server.onpreauthtoolkit.md) | A tool set defining an outcome of OnPreAuth interceptor for incoming request. | diff --git a/docs/development/core/server/kibana-plugin-core-server.metricsservicesetup.collectioninterval.md b/docs/development/core/server/kibana-plugin-core-server.metricsservicesetup.collectioninterval.md new file mode 100644 index 0000000000000..6f05526b66c83 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.metricsservicesetup.collectioninterval.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) > [collectionInterval](./kibana-plugin-core-server.metricsservicesetup.collectioninterval.md) + +## MetricsServiceSetup.collectionInterval property + +Interval metrics are collected in milliseconds + +Signature: + +```typescript +readonly collectionInterval: number; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.metricsservicesetup.getopsmetrics_.md b/docs/development/core/server/kibana-plugin-core-server.metricsservicesetup.getopsmetrics_.md new file mode 100644 index 0000000000000..61107fbf20ad9 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.metricsservicesetup.getopsmetrics_.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) > [getOpsMetrics$](./kibana-plugin-core-server.metricsservicesetup.getopsmetrics_.md) + +## MetricsServiceSetup.getOpsMetrics$ property + +Retrieve an observable emitting the [OpsMetrics](./kibana-plugin-core-server.opsmetrics.md) gathered. The observable will emit an initial value during core's `start` phase, and a new value every fixed interval of time, based on the `opts.interval` configuration property. + +Signature: + +```typescript +getOpsMetrics$: () => Observable; +``` + +## Example + + +```ts +core.metrics.getOpsMetrics$().subscribe(metrics => { + // do something with the metrics +}) + +``` + diff --git a/docs/development/core/server/kibana-plugin-core-server.metricsservicesetup.md b/docs/development/core/server/kibana-plugin-core-server.metricsservicesetup.md index 0bec919797b6f..5fcb1417dea0e 100644 --- a/docs/development/core/server/kibana-plugin-core-server.metricsservicesetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.metricsservicesetup.md @@ -4,8 +4,18 @@ ## MetricsServiceSetup interface +APIs to retrieves metrics gathered and exposed by the core platform. + Signature: ```typescript export interface MetricsServiceSetup ``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [collectionInterval](./kibana-plugin-core-server.metricsservicesetup.collectioninterval.md) | number | Interval metrics are collected in milliseconds | +| [getOpsMetrics$](./kibana-plugin-core-server.metricsservicesetup.getopsmetrics_.md) | () => Observable<OpsMetrics> | Retrieve an observable emitting the [OpsMetrics](./kibana-plugin-core-server.opsmetrics.md) gathered. The observable will emit an initial value during core's start phase, and a new value every fixed interval of time, based on the opts.interval configuration property. | + diff --git a/docs/development/core/server/kibana-plugin-core-server.opsmetrics.collected_at.md b/docs/development/core/server/kibana-plugin-core-server.opsmetrics.collected_at.md new file mode 100644 index 0000000000000..25125569b7b38 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.opsmetrics.collected_at.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [OpsMetrics](./kibana-plugin-core-server.opsmetrics.md) > [collected\_at](./kibana-plugin-core-server.opsmetrics.collected_at.md) + +## OpsMetrics.collected\_at property + +Time metrics were recorded at. + +Signature: + +```typescript +collected_at: Date; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.opsmetrics.md b/docs/development/core/server/kibana-plugin-core-server.opsmetrics.md index d2d4782385c06..9803c0fbd53cc 100644 --- a/docs/development/core/server/kibana-plugin-core-server.opsmetrics.md +++ b/docs/development/core/server/kibana-plugin-core-server.opsmetrics.md @@ -16,6 +16,7 @@ export interface OpsMetrics | Property | Type | Description | | --- | --- | --- | +| [collected\_at](./kibana-plugin-core-server.opsmetrics.collected_at.md) | Date | Time metrics were recorded at. | | [concurrent\_connections](./kibana-plugin-core-server.opsmetrics.concurrent_connections.md) | OpsServerMetrics['concurrent_connections'] | number of current concurrent connections to the server | | [os](./kibana-plugin-core-server.opsmetrics.os.md) | OpsOsMetrics | OS related metrics | | [process](./kibana-plugin-core-server.opsmetrics.process.md) | OpsProcessMetrics | Process related metrics | diff --git a/docs/development/core/server/kibana-plugin-core-server.opsosmetrics.cpu.md b/docs/development/core/server/kibana-plugin-core-server.opsosmetrics.cpu.md new file mode 100644 index 0000000000000..095c45266a251 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.opsosmetrics.cpu.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [OpsOsMetrics](./kibana-plugin-core-server.opsosmetrics.md) > [cpu](./kibana-plugin-core-server.opsosmetrics.cpu.md) + +## OpsOsMetrics.cpu property + +cpu cgroup metrics, undefined when not running in a cgroup + +Signature: + +```typescript +cpu?: { + control_group: string; + cfs_period_micros: number; + cfs_quota_micros: number; + stat: { + number_of_elapsed_periods: number; + number_of_times_throttled: number; + time_throttled_nanos: number; + }; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.opsosmetrics.cpuacct.md b/docs/development/core/server/kibana-plugin-core-server.opsosmetrics.cpuacct.md new file mode 100644 index 0000000000000..140646a0d1a35 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.opsosmetrics.cpuacct.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [OpsOsMetrics](./kibana-plugin-core-server.opsosmetrics.md) > [cpuacct](./kibana-plugin-core-server.opsosmetrics.cpuacct.md) + +## OpsOsMetrics.cpuacct property + +cpu accounting metrics, undefined when not running in a cgroup + +Signature: + +```typescript +cpuacct?: { + control_group: string; + usage_nanos: number; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.opsosmetrics.md b/docs/development/core/server/kibana-plugin-core-server.opsosmetrics.md index 5fedb76a9c8d7..8938608531139 100644 --- a/docs/development/core/server/kibana-plugin-core-server.opsosmetrics.md +++ b/docs/development/core/server/kibana-plugin-core-server.opsosmetrics.md @@ -16,6 +16,8 @@ export interface OpsOsMetrics | Property | Type | Description | | --- | --- | --- | +| [cpu](./kibana-plugin-core-server.opsosmetrics.cpu.md) | {
control_group: string;
cfs_period_micros: number;
cfs_quota_micros: number;
stat: {
number_of_elapsed_periods: number;
number_of_times_throttled: number;
time_throttled_nanos: number;
};
} | cpu cgroup metrics, undefined when not running in a cgroup | +| [cpuacct](./kibana-plugin-core-server.opsosmetrics.cpuacct.md) | {
control_group: string;
usage_nanos: number;
} | cpu accounting metrics, undefined when not running in a cgroup | | [distro](./kibana-plugin-core-server.opsosmetrics.distro.md) | string | The os distrib. Only present for linux platforms | | [distroRelease](./kibana-plugin-core-server.opsosmetrics.distrorelease.md) | string | The os distrib release, prefixed by the os distrib. Only present for linux platforms | | [load](./kibana-plugin-core-server.opsosmetrics.load.md) | {
'1m': number;
'5m': number;
'15m': number;
} | cpu load metrics | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md index 6ef7b991bb159..650459bfdb435 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md @@ -16,8 +16,6 @@ export interface SavedObjectsServiceSetup When plugins access the Saved Objects client, a new client is created using the factory provided to `setClientFactory` and wrapped by all wrappers registered through `addClientWrapper`. -All the setup APIs will throw if called after the service has started, and therefor cannot be used from legacy plugin code. Legacy plugins should use the legacy savedObject service until migrated. - ## Example 1 diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md index 57c9e04966c1b..54e01d3110a2d 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md @@ -14,10 +14,6 @@ See the [mappings format](./kibana-plugin-core-server.savedobjectstypemappingdef registerType: (type: SavedObjectsType) => void; ``` -## Remarks - -The type definition is an aggregation of the legacy savedObjects `schema`, `mappings` and `migration` concepts. This API is the single entry point to register saved object types in the new platform. - ## Example diff --git a/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.dependencies_.md b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.dependencies_.md new file mode 100644 index 0000000000000..7475f0e3a4c1c --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.dependencies_.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [StatusServiceSetup](./kibana-plugin-core-server.statusservicesetup.md) > [dependencies$](./kibana-plugin-core-server.statusservicesetup.dependencies_.md) + +## StatusServiceSetup.dependencies$ property + +Current status for all plugins this plugin depends on. Each key of the `Record` is a plugin id. + +Signature: + +```typescript +dependencies$: Observable>; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.derivedstatus_.md b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.derivedstatus_.md new file mode 100644 index 0000000000000..6c65e44270a06 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.derivedstatus_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [StatusServiceSetup](./kibana-plugin-core-server.statusservicesetup.md) > [derivedStatus$](./kibana-plugin-core-server.statusservicesetup.derivedstatus_.md) + +## StatusServiceSetup.derivedStatus$ property + +The status of this plugin as derived from its dependencies. + +Signature: + +```typescript +derivedStatus$: Observable; +``` + +## Remarks + +By default, plugins inherit this derived status from their dependencies. Calling overrides this default status. + +This may emit multliple times for a single status change event as propagates through the dependency tree + diff --git a/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.md b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.md index 3d3b73ccda25f..ba0645be4d26c 100644 --- a/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.md @@ -12,10 +12,73 @@ API for accessing status of Core and this plugin's dependencies as well as for c export interface StatusServiceSetup ``` +## Remarks + +By default, a plugin inherits it's current status from the most severe status level of any Core services and any plugins that it depends on. This default status is available on the API. + +Plugins may customize their status calculation by calling the API with an Observable. Within this Observable, a plugin may choose to only depend on the status of some of its dependencies, to ignore severe status levels of particular Core services they are not concerned with, or to make its status dependent on other external services. + +## Example 1 + +Customize a plugin's status to only depend on the status of SavedObjects: + +```ts +core.status.set( + core.status.core$.pipe( +. map((coreStatus) => { + return coreStatus.savedObjects; + }) ; + ); +); + +``` + +## Example 2 + +Customize a plugin's status to include an external service: + +```ts +const externalStatus$ = interval(1000).pipe( + switchMap(async () => { + const resp = await fetch(`https://myexternaldep.com/_healthz`); + const body = await resp.json(); + if (body.ok) { + return of({ level: ServiceStatusLevels.available, summary: 'External Service is up'}); + } else { + return of({ level: ServiceStatusLevels.available, summary: 'External Service is unavailable'}); + } + }), + catchError((error) => { + of({ level: ServiceStatusLevels.unavailable, summary: `External Service is down`, meta: { error }}) + }) +); + +core.status.set( + combineLatest([core.status.derivedStatus$, externalStatus$]).pipe( + map(([derivedStatus, externalStatus]) => { + if (externalStatus.level > derivedStatus) { + return externalStatus; + } else { + return derivedStatus; + } + }) + ) +); + +``` + ## Properties | Property | Type | Description | | --- | --- | --- | | [core$](./kibana-plugin-core-server.statusservicesetup.core_.md) | Observable<CoreStatus> | Current status for all Core services. | +| [dependencies$](./kibana-plugin-core-server.statusservicesetup.dependencies_.md) | Observable<Record<string, ServiceStatus>> | Current status for all plugins this plugin depends on. Each key of the Record is a plugin id. | +| [derivedStatus$](./kibana-plugin-core-server.statusservicesetup.derivedstatus_.md) | Observable<ServiceStatus> | The status of this plugin as derived from its dependencies. | | [overall$](./kibana-plugin-core-server.statusservicesetup.overall_.md) | Observable<ServiceStatus> | Overall system status for all of Kibana. | +## Methods + +| Method | Description | +| --- | --- | +| [set(status$)](./kibana-plugin-core-server.statusservicesetup.set.md) | Allows a plugin to specify a custom status dependent on its own criteria. Completely overrides the default inherited status. | + diff --git a/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.set.md b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.set.md new file mode 100644 index 0000000000000..143cd397c40ae --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.statusservicesetup.set.md @@ -0,0 +1,28 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [StatusServiceSetup](./kibana-plugin-core-server.statusservicesetup.md) > [set](./kibana-plugin-core-server.statusservicesetup.set.md) + +## StatusServiceSetup.set() method + +Allows a plugin to specify a custom status dependent on its own criteria. Completely overrides the default inherited status. + +Signature: + +```typescript +set(status$: Observable): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| status$ | Observable<ServiceStatus> | | + +Returns: + +`void` + +## Remarks + +See the [StatusServiceSetup.derivedStatus$](./kibana-plugin-core-server.statusservicesetup.derivedstatus_.md) API for leveraging the default status calculation that is provided by Core. + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearchparamsfromrequest.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearchparamsfromrequest.md index 337b4b3302cc3..d32e9a955f890 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearchparamsfromrequest.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getsearchparamsfromrequest.md @@ -9,7 +9,6 @@ ```typescript export declare function getSearchParamsFromRequest(searchRequest: SearchRequest, dependencies: { - esShardTimeout: number; getConfig: GetConfigFn; }): ISearchRequestParams; ``` @@ -19,7 +18,7 @@ export declare function getSearchParamsFromRequest(searchRequest: SearchRequest, | Parameter | Type | Description | | --- | --- | --- | | searchRequest | SearchRequest | | -| dependencies | {
esShardTimeout: number;
getConfig: GetConfigFn;
} | | +| dependencies | {
getConfig: GetConfigFn;
} | | Returns: diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index b651480a85899..0c493ca492953 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -69,6 +69,7 @@ | [OptionedValueProp](./kibana-plugin-plugins-data-public.optionedvalueprop.md) | | | [Query](./kibana-plugin-plugins-data-public.query.md) | | | [QueryState](./kibana-plugin-plugins-data-public.querystate.md) | All query state service state | +| [QueryStateChange](./kibana-plugin-plugins-data-public.querystatechange.md) | | | [QuerySuggestionBasic](./kibana-plugin-plugins-data-public.querysuggestionbasic.md) | \* | | [QuerySuggestionField](./kibana-plugin-plugins-data-public.querysuggestionfield.md) | \* | | [QuerySuggestionGetFnArgs](./kibana-plugin-plugins-data-public.querysuggestiongetfnargs.md) | \* | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.appfilters.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.appfilters.md new file mode 100644 index 0000000000000..b358e9477e515 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.appfilters.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [QueryStateChange](./kibana-plugin-plugins-data-public.querystatechange.md) > [appFilters](./kibana-plugin-plugins-data-public.querystatechange.appfilters.md) + +## QueryStateChange.appFilters property + +Signature: + +```typescript +appFilters?: boolean; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.globalfilters.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.globalfilters.md new file mode 100644 index 0000000000000..c395f169c35a5 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.globalfilters.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [QueryStateChange](./kibana-plugin-plugins-data-public.querystatechange.md) > [globalFilters](./kibana-plugin-plugins-data-public.querystatechange.globalfilters.md) + +## QueryStateChange.globalFilters property + +Signature: + +```typescript +globalFilters?: boolean; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.md new file mode 100644 index 0000000000000..71fb211da11d2 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystatechange.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [QueryStateChange](./kibana-plugin-plugins-data-public.querystatechange.md) + +## QueryStateChange interface + +Signature: + +```typescript +export interface QueryStateChange extends QueryStateChangePartial +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [appFilters](./kibana-plugin-plugins-data-public.querystatechange.appfilters.md) | boolean | | +| [globalFilters](./kibana-plugin-plugins-data-public.querystatechange.globalfilters.md) | boolean | | + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md index 498691c06285d..d1d20291a6799 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md @@ -7,7 +7,7 @@ Signature: ```typescript -SearchBar: React.ComponentClass, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "indexPatterns" | "dataTestSubj" | "customSubmitButton" | "screenTitle" | "showQueryBar" | "showQueryInput" | "showFilterBar" | "showDatePicker" | "showAutoRefreshOnly" | "isRefreshPaused" | "dateRangeFrom" | "dateRangeTo" | "showSaveQuery" | "savedQuery" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated" | "onClearSavedQuery" | "indicateNoData" | "timeHistory" | "onFiltersUpdated">, any> & { - WrappedComponent: React.ComponentType & ReactIntl.InjectedIntlProps>; +SearchBar: React.ComponentClass, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "indexPatterns" | "dataTestSubj" | "timeHistory" | "customSubmitButton" | "screenTitle" | "showQueryBar" | "showQueryInput" | "showFilterBar" | "showDatePicker" | "showAutoRefreshOnly" | "isRefreshPaused" | "dateRangeFrom" | "dateRangeTo" | "showSaveQuery" | "savedQuery" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated" | "onClearSavedQuery" | "indicateNoData" | "onFiltersUpdated">, any> & { + WrappedComponent: React.ComponentType & ReactIntl.InjectedIntlProps>; } ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md index 6f5dd1076fb40..4c67639300883 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md @@ -4,12 +4,12 @@ ## SearchInterceptor.(constructor) -This class should be instantiated with a `requestTimeout` corresponding with how many ms after requests are initiated that they should automatically cancel. +Constructs a new instance of the `SearchInterceptor` class Signature: ```typescript -constructor(deps: SearchInterceptorDeps, requestTimeout?: number | undefined); +constructor(deps: SearchInterceptorDeps); ``` ## Parameters @@ -17,5 +17,4 @@ constructor(deps: SearchInterceptorDeps, requestTimeout?: number | undefined); | Parameter | Type | Description | | --- | --- | --- | | deps | SearchInterceptorDeps | | -| requestTimeout | number | undefined | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md index 32954927504ae..fd9f23a7f0052 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md @@ -14,21 +14,18 @@ export declare class SearchInterceptor | Constructor | Modifiers | Description | | --- | --- | --- | -| [(constructor)(deps, requestTimeout)](./kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md) | | This class should be instantiated with a requestTimeout corresponding with how many ms after requests are initiated that they should automatically cancel. | +| [(constructor)(deps)](./kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md) | | Constructs a new instance of the SearchInterceptor class | ## Properties | Property | Modifiers | Type | Description | | --- | --- | --- | --- | | [deps](./kibana-plugin-plugins-data-public.searchinterceptor.deps.md) | | SearchInterceptorDeps | | -| [requestTimeout](./kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md) | | number | undefined | | ## Methods | Method | Modifiers | Description | | --- | --- | --- | | [getPendingCount$()](./kibana-plugin-plugins-data-public.searchinterceptor.getpendingcount_.md) | | Returns an Observable over the current number of pending searches. This could mean that one of the search requests is still in flight, or that it has only received partial responses. | -| [runSearch(request, signal, strategy)](./kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md) | | | | [search(request, options)](./kibana-plugin-plugins-data-public.searchinterceptor.search.md) | | Searches using the given search method. Overrides the AbortSignal with one that will abort either when cancelPending is called, when the request times out, or when the original AbortSignal is aborted. Updates pendingCount$ when the request is started/finalized. | -| [setupTimers(options)](./kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md) | | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md deleted file mode 100644 index 3123433762991..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [requestTimeout](./kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md) - -## SearchInterceptor.requestTimeout property - -Signature: - -```typescript -protected readonly requestTimeout?: number | undefined; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md deleted file mode 100644 index ad1d1dcb59d7b..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [runSearch](./kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md) - -## SearchInterceptor.runSearch() method - -Signature: - -```typescript -protected runSearch(request: IEsSearchRequest, signal: AbortSignal, strategy?: string): Observable; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| request | IEsSearchRequest | | -| signal | AbortSignal | | -| strategy | string | | - -Returns: - -`Observable` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md deleted file mode 100644 index fe35655258b4c..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md +++ /dev/null @@ -1,28 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [setupTimers](./kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md) - -## SearchInterceptor.setupTimers() method - -Signature: - -```typescript -protected setupTimers(options?: ISearchOptions): { - combinedSignal: AbortSignal; - cleanup: () => void; - }; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| options | ISearchOptions | | - -Returns: - -`{ - combinedSignal: AbortSignal; - cleanup: () => void; - }` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md index e515c3513df6c..6ed20beb396f1 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md @@ -20,6 +20,7 @@ UI_SETTINGS: { readonly COURIER_MAX_CONCURRENT_SHARD_REQUESTS: "courier:maxConcurrentShardRequests"; readonly COURIER_BATCH_SEARCHES: "courier:batchSearches"; readonly SEARCH_INCLUDE_FROZEN: "search:includeFrozen"; + readonly SEARCH_TIMEOUT: "search:timeout"; readonly HISTOGRAM_BAR_TARGET: "histogram:barTarget"; readonly HISTOGRAM_MAX_BARS: "histogram:maxBars"; readonly HISTORY_LIMIT: "history:limit"; diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md index 9de005c1fd0dd..e718ca42ca30f 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md @@ -7,24 +7,26 @@ Signature: ```typescript -export declare function getDefaultSearchParams(config: SharedGlobalConfig): { - timeout: string; +export declare function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient): Promise<{ + maxConcurrentShardRequests: number | undefined; + ignoreThrottled: boolean; ignoreUnavailable: boolean; - restTotalHitsAsInt: boolean; -}; + trackTotalHits: boolean; +}>; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| config | SharedGlobalConfig | | +| uiSettingsClient | IUiSettingsClient | | Returns: -`{ - timeout: string; +`Promise<{ + maxConcurrentShardRequests: number | undefined; + ignoreThrottled: boolean; ignoreUnavailable: boolean; - restTotalHitsAsInt: boolean; -}` + trackTotalHits: boolean; +}>` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getshardtimeout.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getshardtimeout.md new file mode 100644 index 0000000000000..d7e2a597ff33d --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getshardtimeout.md @@ -0,0 +1,30 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [getShardTimeout](./kibana-plugin-plugins-data-server.getshardtimeout.md) + +## getShardTimeout() function + +Signature: + +```typescript +export declare function getShardTimeout(config: SharedGlobalConfig): { + timeout: string; +} | { + timeout?: undefined; +}; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| config | SharedGlobalConfig | | + +Returns: + +`{ + timeout: string; +} | { + timeout?: undefined; +}` + diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md index 70c32adeab9fd..f5b587d86b349 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md @@ -26,11 +26,13 @@ | Function | Description | | --- | --- | -| [getDefaultSearchParams(config)](./kibana-plugin-plugins-data-server.getdefaultsearchparams.md) | | +| [getDefaultSearchParams(uiSettingsClient)](./kibana-plugin-plugins-data-server.getdefaultsearchparams.md) | | +| [getShardTimeout(config)](./kibana-plugin-plugins-data-server.getshardtimeout.md) | | | [getTime(indexPattern, timeRange, options)](./kibana-plugin-plugins-data-server.gettime.md) | | | [parseInterval(interval)](./kibana-plugin-plugins-data-server.parseinterval.md) | | | [plugin(initializerContext)](./kibana-plugin-plugins-data-server.plugin.md) | Static code to be shared externally | | [shouldReadFieldFromDocValues(aggregatable, esType)](./kibana-plugin-plugins-data-server.shouldreadfieldfromdocvalues.md) | | +| [toSnakeCase(obj)](./kibana-plugin-plugins-data-server.tosnakecase.md) | | | [usageProvider(core)](./kibana-plugin-plugins-data-server.usageprovider.md) | | ## Interfaces diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md index 2d9104ef894bc..455c5ecdd8195 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md @@ -8,7 +8,7 @@ ```typescript start(core: CoreStart): { - search: ISearchStart>; + search: ISearchStart>; fieldFormats: { fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise; }; @@ -27,7 +27,7 @@ start(core: CoreStart): { Returns: `{ - search: ISearchStart>; + search: ISearchStart>; fieldFormats: { fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise; }; diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.tosnakecase.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.tosnakecase.md new file mode 100644 index 0000000000000..eda9e9c312e59 --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.tosnakecase.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [toSnakeCase](./kibana-plugin-plugins-data-server.tosnakecase.md) + +## toSnakeCase() function + +Signature: + +```typescript +export declare function toSnakeCase(obj: Record): import("lodash").Dictionary; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| obj | Record<string, any> | | + +Returns: + +`import("lodash").Dictionary` + diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md index e419b64cd43aa..2d4ce75b956df 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md @@ -20,6 +20,7 @@ UI_SETTINGS: { readonly COURIER_MAX_CONCURRENT_SHARD_REQUESTS: "courier:maxConcurrentShardRequests"; readonly COURIER_BATCH_SEARCHES: "courier:batchSearches"; readonly SEARCH_INCLUDE_FROZEN: "search:includeFrozen"; + readonly SEARCH_TIMEOUT: "search:timeout"; readonly HISTOGRAM_BAR_TARGET: "histogram:barTarget"; readonly HISTOGRAM_MAX_BARS: "histogram:maxBars"; readonly HISTORY_LIMIT: "history:limit"; diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc index a64a0330ae43f..ed20166c87f29 100644 --- a/docs/management/advanced-options.asciidoc +++ b/docs/management/advanced-options.asciidoc @@ -225,6 +225,7 @@ be inconsistent because different shards might be in different refresh states. `search:includeFrozen`:: Includes {ref}/frozen-indices.html[frozen indices] in results. Searching through frozen indices might increase the search time. This setting is off by default. Users must opt-in to include frozen indices. +`search:timeout`:: Change the maximum timeout for a search session or set to 0 to disable the timeout and allow queries to run to completion. [float] [[kibana-siem-settings]] diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 4a931aabd3646..f03022e9e9f00 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -20,12 +20,12 @@ which may cause a delay before pages start being served. Set to `false` to disable Console. *Default: `true`* | `cpu.cgroup.path.override:` - | Override for cgroup cpu path when mounted in a -manner that is inconsistent with `/proc/self/cgroup`. + | *deprecated* This setting has been renamed to `ops.cGroupOverrides.cpuPath` +and the old name will no longer be supported as of 8.0. | `cpuacct.cgroup.path.override:` - | Override for cgroup cpuacct path when mounted -in a manner that is inconsistent with `/proc/self/cgroup`. + | *deprecated* This setting has been renamed to `ops.cGroupOverrides.cpuAcctPath` +and the old name will no longer be supported as of 8.0. | `csp.rules:` | A https://w3c.github.io/webappsec-csp/[content-security-policy] template @@ -438,6 +438,14 @@ not saved in {es}. *Default: `data`* | Set the interval in milliseconds to sample system and process performance metrics. The minimum value is 100. *Default: `5000`* +| `ops.cGroupOverrides.cpuPath:` + | Override for cgroup cpu path when mounted in a +manner that is inconsistent with `/proc/self/cgroup`. + +| `ops.cGroupOverrides.cpuAcctPath:` + | Override for cgroup cpuacct path when mounted +in a manner that is inconsistent with `/proc/self/cgroup`. + | `server.basePath:` | Enables you to specify a path to mount {kib} at if you are running behind a proxy. Use the `server.rewriteBasePath` setting to tell {kib} diff --git a/docs/user/dashboard/dashboard-drilldown.asciidoc b/docs/user/dashboard/dashboard-drilldown.asciidoc new file mode 100644 index 0000000000000..84701cae2ecc6 --- /dev/null +++ b/docs/user/dashboard/dashboard-drilldown.asciidoc @@ -0,0 +1,76 @@ +[[dashboard-drilldown]] +=== Dashboard drilldown + +The dashboard drilldown allows you to navigate from one dashboard to another dashboard. +For example, you might have a dashboard that shows the overall status of multiple data centers. +You can create a drilldown that navigates from this dashboard to a dashboard +that shows a single data center or server. + +This example shows a dashboard panel that contains a pie chart with a configured dashboard drilldown: + +[role="screenshot"] +image::images/drilldown_on_piechart.gif[Drilldown on pie chart that navigates to another dashboard] + +[float] +[[drilldowns-example]] +==== Try it: Create a dashboard drilldown + +Create the *Host Overview* drilldown shown above. + +*Set up the dashboards* + +. Add the <> data set. + +. Create a new dashboard, called `Host Overview`, and include these visualizations +from the sample data set: ++ +[%hardbreaks] +*[Logs] Heatmap* +*[Logs] Visitors by OS* +*[Logs] Host, Visits, and Bytes Table* +*[Logs] Total Requests and Bytes* ++ +TIP: If you don’t see data for a panel, try changing the time range. + +. Open the *[Logs] Web traffic* dashboard. + +. Set a search and filter. ++ +[%hardbreaks] +Search: `extension.keyword:( “gz” or “css” or “deb”)` +Filter: `geo.src : CN` + + +*Create the drilldown* + + +. In the dashboard menu bar, click *Edit*. + +. In *[Logs] Visitors by OS*, open the panel menu, and then select *Create drilldown*. + +. Pick *Go to dashboard* action. + +. Give the drilldown a name. + +. Select *Host Overview* as the destination dashboard. + +. Keep both filters enabled so that the drilldown carries over the global filters and date range. ++ +Your input should look similar to this: ++ +[role="screenshot"] +image::images/drilldown_create.png[Create drilldown with entries for drilldown name and destination] + +. Click *Create drilldown.* + +. Save the dashboard. ++ +If you don’t save the drilldown, and then navigate away, the drilldown is lost. + +. In *[Logs] Visitors by OS*, click the `win 8` slice of the pie, and then select the name of your drilldown. ++ +[role="screenshot"] +image::images/drilldown_on_panel.png[Drilldown on pie chart that navigates to another dashboard] ++ +You are navigated to your destination dashboard. Verify that the search query, filters, +and time range are carried over. diff --git a/docs/user/dashboard/dashboard.asciidoc b/docs/user/dashboard/dashboard.asciidoc index 0c0151cc3ace2..c8bff91be91a6 100644 --- a/docs/user/dashboard/dashboard.asciidoc +++ b/docs/user/dashboard/dashboard.asciidoc @@ -4,9 +4,9 @@ [partintro] -- -A _dashboard_ is a collection of panels that you use to analyze your data. On a dashboard, you can add a variety of panels that -you can rearrange and tell a story about your data. Panels contain everything you need, including visualizations, -interactive controls, markdown, and more. +A _dashboard_ is a collection of panels that you use to analyze your data. On a dashboard, you can add a variety of panels that +you can rearrange and tell a story about your data. Panels contain everything you need, including visualizations, +interactive controls, markdown, and more. With *Dashboard*s, you can: @@ -18,7 +18,7 @@ With *Dashboard*s, you can: * Create and apply filters to focus on the data you want to display. -* Control who can use your data, and share the dashboard with a small or large audience. +* Control who can use your data, and share the dashboard with a small or large audience. * Generate reports based on your findings. @@ -42,7 +42,7 @@ image::images/dashboard-read-only-badge.png[Example of Dashboard read only acces [[types-of-panels]] == Types of panels -Panels contain everything you need to tell a story about you data, including visualizations, +Panels contain everything you need to tell a story about you data, including visualizations, interactive controls, Markdown, and more. [cols="50, 50"] @@ -50,30 +50,30 @@ interactive controls, Markdown, and more. a| *Area* -Displays data points, connected by a line, where the area between the line and axes are shaded. +Displays data points, connected by a line, where the area between the line and axes are shaded. Use area charts to compare two or more categories over time, and display the magnitude of trends. | image:images/area.png[Area chart] a| *Stacked area* -Displays the evolution of the value of several data groups. The values of each group are displayed -on top of each other. Use stacked area charts to visualize part-to-whole relationships, and to show +Displays the evolution of the value of several data groups. The values of each group are displayed +on top of each other. Use stacked area charts to visualize part-to-whole relationships, and to show how each category contributes to the cumulative total. | image:images/stacked_area.png[Stacked area chart] a| *Bar* -Displays bars side-by-side where each bar represents a category. Use bar charts to compare data across a -large number of categories, display data that includes categories with negative values, and easily identify +Displays bars side-by-side where each bar represents a category. Use bar charts to compare data across a +large number of categories, display data that includes categories with negative values, and easily identify the categories that represent the highest and lowest values. Kibana also supports horizontal bar charts. | image:images/bar.png[Bar chart] a| *Stacked bar* -Displays numeric values across two or more categories. Use stacked bar charts to compare numeric values between +Displays numeric values across two or more categories. Use stacked bar charts to compare numeric values between levels of a categorical value. Kibana also supports stacked horizontal bar charts. | image:images/stacked_bar.png[Stacked area chart] @@ -81,15 +81,15 @@ levels of a categorical value. Kibana also supports stacked horizontal bar chart a| *Line* -Displays data points that are connected by a line. Use line charts to visualize a sequence of values, discover +Displays data points that are connected by a line. Use line charts to visualize a sequence of values, discover trends over time, and forecast future values. | image:images/line.png[Line chart] a| *Pie* -Displays slices that represent a data category, where the slice size is proportional to the quantity it represents. -Use pie charts to show comparisons between multiple categories, illustrate the dominance of one category over others, +Displays slices that represent a data category, where the slice size is proportional to the quantity it represents. +Use pie charts to show comparisons between multiple categories, illustrate the dominance of one category over others, and show percentage or proportional data. | image:images/pie.png[Pie chart] @@ -103,7 +103,7 @@ Similar to the pie chart, but the central circle is removed. Use donut charts wh a| *Tree map* -Relates different segments of your data to the whole. Each rectangle is subdivided into smaller rectangles, or sub branches, based on +Relates different segments of your data to the whole. Each rectangle is subdivided into smaller rectangles, or sub branches, based on its proportion to the whole. Use treemaps to make efficient use of space to show percent total for each category. | image:images/treemap.png[Tree map] @@ -111,7 +111,7 @@ its proportion to the whole. Use treemaps to make efficient use of space to show a| *Heat map* -Displays graphical representations of data where the individual values are represented by colors. Use heat maps when your data set includes +Displays graphical representations of data where the individual values are represented by colors. Use heat maps when your data set includes categorical data. For example, use a heat map to see the flights of origin countries compared to destination countries using the sample flight data. | image:images/heat_map.png[Heat map] @@ -125,7 +125,7 @@ Displays how your metric progresses toward a fixed goal. Use the goal to display a| *Gauge* -Displays your data along a scale that changes color according to where your data falls on the expected scale. Use the gauge to show how metric +Displays your data along a scale that changes color according to where your data falls on the expected scale. Use the gauge to show how metric values relate to reference threshold values, or determine how a specified field is performing versus how it is expected to perform. | image:images/gauge.png[Gauge] @@ -133,7 +133,7 @@ values relate to reference threshold values, or determine how a specified field a| *Metric* -Displays a single numeric value for an aggregation. Use the metric visualization when you have a numeric value that is powerful enough to tell +Displays a single numeric value for an aggregation. Use the metric visualization when you have a numeric value that is powerful enough to tell a story about your data. | image:images/metric.png[Metric] @@ -141,7 +141,7 @@ a story about your data. a| *Data table* -Displays your raw data or aggregation results in a tabular format. Use data tables to display server configuration details, track counts, min, +Displays your raw data or aggregation results in a tabular format. Use data tables to display server configuration details, track counts, min, or max values for a specific field, and monitor the status of key services. | image:images/data_table.png[Data table] @@ -149,7 +149,7 @@ or max values for a specific field, and monitor the status of key services. a| *Tag cloud* -Graphical representations of how frequently a word appears in the source text. Use tag clouds to easily produce a summary of large documents and +Graphical representations of how frequently a word appears in the source text. Use tag clouds to easily produce a summary of large documents and create visual art for a specific topic. | image:images/tag_cloud.png[Tag cloud] @@ -168,16 +168,16 @@ For all your mapping needs, use <>. [[create-panels]] == Create panels -To create a panel, make sure you have {ref}/getting-started-index.html[data indexed into {es}] and an <> -to retrieve the data from {es}. If you aren’t ready to use your own data, {kib} comes with several pre-built dashboards that you can test out. For more information, +To create a panel, make sure you have {ref}/getting-started-index.html[data indexed into {es}] and an <> +to retrieve the data from {es}. If you aren’t ready to use your own data, {kib} comes with several pre-built dashboards that you can test out. For more information, refer to <>. -To begin, click *Create new*, then choose one of the following options on the +To begin, click *Create new*, then choose one of the following options on the *New Visualization* window: -* Click on the type of panel you want to create, then configure the options. +* Click on the type of panel you want to create, then configure the options. -* Select an editor to help you create the panel. +* Select an editor to help you create the panel. [role="screenshot"] image:images/Dashboard_add_new_visualization.png[Example add new visualization to dashboard] @@ -188,19 +188,19 @@ image:images/Dashboard_add_new_visualization.png[Example add new visualization t [[lens]] === Create panels with Lens -*Lens* is the simplest and fastest way to create powerful visualizations of your data. To use *Lens*, you drag and drop as many data fields +*Lens* is the simplest and fastest way to create powerful visualizations of your data. To use *Lens*, you drag and drop as many data fields as you want onto the visualization builder pane, and *Lens* uses heuristics to decide how to apply each field to the visualization. With *Lens*, you can: * Use the automatically generated suggestions to change the visualization type. -* Create visualizations with multiple layers and indices. +* Create visualizations with multiple layers and indices. * Change the aggregation and labels to customize the data. [role="screenshot"] image::images/lens_drag_drop.gif[Drag and drop] -TIP: Drag-and-drop capabilities are available only when *Lens* knows how to use the data. If *Lens* is unable to automatically generate a +TIP: Drag-and-drop capabilities are available only when *Lens* knows how to use the data. If *Lens* is unable to automatically generate a visualization, configure the customization options for your visualization. [float] @@ -220,7 +220,7 @@ To filter the data fields: [[view-data-summaries]] ==== View data summaries -To help you decide exactly the data you want to display, get a quick summary of each field. The summary shows the distribution of +To help you decide exactly the data you want to display, get a quick summary of each field. The summary shows the distribution of values within the specified time range. To view the data field summary information, navigate to the field, then click *i*. @@ -250,10 +250,10 @@ When there is an exclamation point (!) next to a visualization type, *Lens* is u [[customize-the-data]] ==== Customize the data -For each visualization type, you can customize the aggregation and labels. The options available depend on the selected visualization type. +For each visualization type, you can customize the aggregation and labels. The options available depend on the selected visualization type. . Click a data field name in the editor, or click *Drop a field here*. -. Change the options that appear. +. Change the options that appear. + [role="screenshot"] image::images/lens_aggregation_labels.png[Quick function options] @@ -262,7 +262,7 @@ image::images/lens_aggregation_labels.png[Quick function options] [[add-layers-and-indices]] ==== Add layers and indices -To compare and analyze data from different sources, you can visualize multiple data layers and indices. Multiple layers and indices are +To compare and analyze data from different sources, you can visualize multiple data layers and indices. Multiple layers and indices are supported in area, line, and bar charts. To add a layer, click *+*, then drag and drop the data fields for the new layer. @@ -281,7 +281,7 @@ Ready to try out *Lens*? Refer to the <>. [[tsvb]] === Create panels with TSVB -*TSVB* is a time series data visualizer that allows you to use the full power of the Elasticsearch aggregation framework. To use *TSVB*, +*TSVB* is a time series data visualizer that allows you to use the full power of the Elasticsearch aggregation framework. To use *TSVB*, you can combine an infinite number of <> to display your data. With *TSVB*, you can: @@ -295,15 +295,15 @@ image::images/tsvb.png[TSVB UI] [float] [[configure-the-data]] -==== Configure the data +==== Configure the data -With *TSVB*, you can add and display multiple data sets to compare and analyze. {kib} uses many types of <> that you can use to build +With *TSVB*, you can add and display multiple data sets to compare and analyze. {kib} uses many types of <> that you can use to build complex summaries of that data. . Select *Data*. If you are using *Table*, select *Columns*. -. From the *Aggregation* drop down, select the aggregation you want to visualize. +. From the *Aggregation* drop down, select the aggregation you want to visualize. + -If you don’t see any data, change the <>. +If you don’t see any data, change the <>. + To add multiple aggregations, click *+*. . From the *Group by* drop down, select how you want to group or split the data. @@ -315,14 +315,14 @@ When you have more than one aggregation, the last value is displayed, which is i [[change-the-data-display]] ==== Change the data display -To find the best way to display your data, *TSVB* supports several types of panels and charts. +To find the best way to display your data, *TSVB* supports several types of panels and charts. To change the *Time Series* chart type: . Click *Data > Options*. . Select the *Chart type*. -To change the panel type, click on the panel options: +To change the panel type, click on the panel options: [role="screenshot"] image::images/tsvb_change_display.gif[TSVB change the panel type] @@ -331,7 +331,7 @@ image::images/tsvb_change_display.gif[TSVB change the panel type] [[custommize-the-data]] ==== Customize the data -View data in a different <>, and change the data label name and colors. The options available depend on the panel type. +View data in a different <>, and change the data label name and colors. The options available depend on the panel type. To change the index pattern, click *Panel options*, then enter the new *Index Pattern*. @@ -361,7 +361,7 @@ image::images/tsvb_annotations.png[TSVB annotations] [[filter-the-panel]] ==== Filter the panel -The data that displays on the panel is based on the <> and <>. +The data that displays on the panel is based on the <> and <>. You can filter the data on the panels using the <>. Click *Panel options*, then enter the syntax in the *Panel Filter* field. @@ -372,7 +372,7 @@ If you want to ignore filters from all of {kib}, select *Yes* for *Ignore global [[vega]] === Create custom panels with Vega -Build custom visualizations using *Vega* and *Vega-Lite*, backed by one or more data sources including {es}, Elastic Map Service, +Build custom visualizations using *Vega* and *Vega-Lite*, backed by one or more data sources including {es}, Elastic Map Service, URL, or static data. Use the {kib} extensions to embed *Vega* in your dashboard, and add interactive tools. Use *Vega* and *Vega-Lite* when you want to create a visualization for: @@ -405,7 +405,7 @@ For more information about *Vega* and *Vega-Lite*, refer to: [[timelion]] === Create panels with Timelion -*Timelion* is a time series data visualizer that enables you to combine independent data sources within a single visualization. +*Timelion* is a time series data visualizer that enables you to combine independent data sources within a single visualization. *Timelion* is driven by a simple expression language that you use to: @@ -422,9 +422,41 @@ Ready to try out Timelion? For step-by-step tutorials, refer to: * <> * <> +[float] +[[timelion-deprecation]] +==== Timelion app deprecation + +Deprecated since 7.0, the Timelion app will be removed in 8.0. If you have any Timelion worksheets, you must migrate them to a dashboard. + +NOTE: Only the Timelion app is deprecated. {kib} continues to support Timelion +visualizations on dashboards and in Visualize and Canvas. + +To migrate a Timelion worksheet to a dashboard: + +. Open the menu, click **Dashboard**, then click **Create dashboard**. + +. On the dashboard, click **Create New**, then select the Timelion visualization. + +. On a new tab, open the Timelion app, select the chart you want to copy, and copy its expression. ++ +[role="screenshot"] +image::images/timelion-copy-expression.png[] + +. Return to the other tab and paste the copied expression to the *Timelion Expression* field and click **Update**. ++ +[role="screenshot"] +image::images/timelion-vis-paste-expression.png[] + +. Save the new visualization, give it a name, and click **Save and Return**. ++ +Your Timelion visualization will appear on the dashboard. Repeat this for all your charts on each worksheet. ++ +[role="screenshot"] +image::images/timelion-dashboard.png[] + [float] [[save-panels]] -=== Save panels +== Save panels When you’ve finished making changes, save the panels. @@ -436,7 +468,7 @@ When you’ve finished making changes, save the panels. [[add-existing-panels]] == Add existing panels -Add panels that you’ve already created to your dashboard. +Add panels that you’ve already created to your dashboard. On the dashboard, click *Add an existing*, then select the panel you want to add. @@ -445,7 +477,7 @@ When a panel contains a stored query, both queries are applied. [role="screenshot"] image:images/Dashboard_add_visualization.png[Example add visualization to dashboard] -To make changes to the panel, put the dashboard in *Edit* mode, then select the edit option from the panel menu. +To make changes to the panel, put the dashboard in *Edit* mode, then select the edit option from the panel menu. The changes you make appear in every dashboard that uses the panel, except if you edit the panel title. Changes to the panel title appear only on the dashboard where you made the change. [float] @@ -463,6 +495,8 @@ include::edit-dashboards.asciidoc[] include::explore-dashboard-data.asciidoc[] +include::drilldowns.asciidoc[] + include::share-dashboards.asciidoc[] include::tutorials.asciidoc[] diff --git a/docs/user/dashboard/drilldowns.asciidoc b/docs/user/dashboard/drilldowns.asciidoc index 5fca974d58135..85230f1b6f70d 100644 --- a/docs/user/dashboard/drilldowns.asciidoc +++ b/docs/user/dashboard/drilldowns.asciidoc @@ -1,106 +1,51 @@ -[float] [[drilldowns]] -=== Use drilldowns for dashboard actions +== Use drilldowns for dashboard actions Drilldowns, also known as custom actions, allow you to configure a workflow for analyzing and troubleshooting your data. -Using a drilldown, you can navigate from one dashboard to another, +For example, using a drilldown, you can navigate from one dashboard to another, taking the current time range, filters, and other parameters with you, so the context remains the same. You can continue your analysis from a new perspective. -For example, you might have a dashboard that shows the overall status of multiple data centers. -You can create a drilldown that navigates from this dashboard to a dashboard -that shows a single data center or server. - -[float] -[[how-drilldowns-work]] -==== How drilldowns work - -Drilldowns are user-configurable {kib} actions that are stored with the -dashboard metadata. Drilldowns are specific to the dashboard panel -for which you create them—they are not shared across panels. -A panel can have multiple drilldowns. - -This example shows a dashboard panel that contains a pie chart. -Typically, clicking a pie slice applies the current filter. -When a panel has a drilldown, clicking a pie slice opens a menu with -the default action and your drilldowns. Refer to the <> -for instructions on how to create this drilldown. - [role="screenshot"] image::images/drilldown_on_piechart.gif[Drilldown on pie chart that navigates to another dashboard] -Third-party developers can create drilldowns. -Refer to https://github.com/elastic/kibana/tree/master/x-pack/examples/ui_actions_enhanced_examples[this example plugin] -to learn how to code drilldowns. - -[float] -[[create-manage-drilldowns]] -==== Create and manage drilldowns - -Your dashboard must be in *Edit* mode to create a drilldown. -Once a panel has at least one drilldown, the menu also includes a *Manage drilldowns* action -for editing and deleting drilldowns. - -[role="screenshot"] -image::images/drilldown_menu.png[Panel menu with Create drilldown and Manage drilldown actions] +Drilldowns are specific to the dashboard panel for which you create them—they are not shared across panels. A panel can have multiple drilldowns. [float] -[[drilldowns-example]] -==== Try it: Create a drilldown - -This example shows how to create the *Host Overview* drilldown shown earlier in this doc. +[[actions]] +=== Drilldown actions -*Set up the dashboards* +Drilldowns are user-configurable {kib} actions that are stored with the dashboard metadata. +Kibana provides the following types of actions: -. Add the <> data set. +[cols="2"] +|=== -. Create a new dashboard, called `Host Overview`, and include these visualizations -from the sample data set: -+ -[%hardbreaks] -*[Logs] Heatmap* -*[Logs] Visitors by OS* -*[Logs] Host, Visits, and Bytes Table* -*[Logs] Total Requests and Bytes* -+ -TIP: If you don’t see data for a panel, try changing the time range. +a| <> -. Open the *[Logs] Web traffic* dashboard. +| Navigate to a dashboard. -. Set a search and filter. -+ -[%hardbreaks] -Search: `extension.keyword:( “gz” or “css” or “deb”)` -Filter: `geo.src : CN` +a| <> -*Create the drilldown* +| Navigate to external or internal URL. -. In the dashboard menu bar, click *Edit*. +|=== -. In *[Logs] Visitors by OS*, open the panel menu, and then select *Create drilldown*. +[NOTE] +============================================== +Some action types are paid commercial features, while others are free. +For a comparison of the Elastic subscription levels, +see https://www.elastic.co/subscriptions[the subscription page]. +============================================== -. Give the drilldown a name. - -. Select *Host Overview* as the destination dashboard. - -. Keep both filters enabled so that the drilldown carries over the global filters and date range. -+ -Your input should look similar to this: -+ -[role="screenshot"] -image::images/drilldown_create.png[Create drilldown with entries for drilldown name and destination] - -. Click *Create drilldown.* +[float] +[[code-drilldowns]] +=== Code drilldowns +Third-party developers can create drilldowns. +Refer to {kib-repo}blob/{branch}/x-pack/examples/ui_actions_enhanced_examples[this example plugin] +to learn how to code drilldowns. -. Save the dashboard. -+ -If you don’t save the drilldown, and then navigate away, the drilldown is lost. +include::dashboard-drilldown.asciidoc[] +include::url-drilldown.asciidoc[] -. In *[Logs] Visitors by OS*, click the `win 8` slice of the pie, and then select the name of your drilldown. -+ -[role="screenshot"] -image::images/drilldown_on_panel.png[Drilldown on pie chart that navigates to another dashboard] -+ -You are navigated to your destination dashboard. Verify that the search query, filters, -and time range are carried over. diff --git a/docs/user/dashboard/explore-dashboard-data.asciidoc b/docs/user/dashboard/explore-dashboard-data.asciidoc index a0564f5bceb3d..238dfb79e900b 100644 --- a/docs/user/dashboard/explore-dashboard-data.asciidoc +++ b/docs/user/dashboard/explore-dashboard-data.asciidoc @@ -16,5 +16,3 @@ The data that displays depends on the element that you inspect. image:images/Dashboard_inspect.png[Inspect in dashboard] include::explore-underlying-data.asciidoc[] - -include::drilldowns.asciidoc[] diff --git a/docs/user/dashboard/images/drilldown_pick_an_action.png b/docs/user/dashboard/images/drilldown_pick_an_action.png new file mode 100644 index 0000000000000..c99e931e3fbe1 Binary files /dev/null and b/docs/user/dashboard/images/drilldown_pick_an_action.png differ diff --git a/docs/user/dashboard/images/url_drilldown_github.png b/docs/user/dashboard/images/url_drilldown_github.png new file mode 100644 index 0000000000000..d2eaec311948e Binary files /dev/null and b/docs/user/dashboard/images/url_drilldown_github.png differ diff --git a/docs/user/dashboard/images/url_drilldown_go_to_github.gif b/docs/user/dashboard/images/url_drilldown_go_to_github.gif new file mode 100644 index 0000000000000..7cca3f72d5a68 Binary files /dev/null and b/docs/user/dashboard/images/url_drilldown_go_to_github.gif differ diff --git a/docs/user/dashboard/images/url_drilldown_pick_an_action.png b/docs/user/dashboard/images/url_drilldown_pick_an_action.png new file mode 100644 index 0000000000000..c99e931e3fbe1 Binary files /dev/null and b/docs/user/dashboard/images/url_drilldown_pick_an_action.png differ diff --git a/docs/user/dashboard/images/url_drilldown_popup.png b/docs/user/dashboard/images/url_drilldown_popup.png new file mode 100644 index 0000000000000..392edd16ea328 Binary files /dev/null and b/docs/user/dashboard/images/url_drilldown_popup.png differ diff --git a/docs/user/dashboard/images/url_drilldown_trigger_picker.png b/docs/user/dashboard/images/url_drilldown_trigger_picker.png new file mode 100644 index 0000000000000..2fe930f35dce8 Binary files /dev/null and b/docs/user/dashboard/images/url_drilldown_trigger_picker.png differ diff --git a/docs/user/dashboard/images/url_drilldown_url_template.png b/docs/user/dashboard/images/url_drilldown_url_template.png new file mode 100644 index 0000000000000..d8515afe66a80 Binary files /dev/null and b/docs/user/dashboard/images/url_drilldown_url_template.png differ diff --git a/docs/user/dashboard/url-drilldown.asciidoc b/docs/user/dashboard/url-drilldown.asciidoc new file mode 100644 index 0000000000000..16f82477756b7 --- /dev/null +++ b/docs/user/dashboard/url-drilldown.asciidoc @@ -0,0 +1,221 @@ +[[url-drilldown]] +=== URL drilldown + +The URL drilldown allows you to navigate from a dashboard to an internal or external URL. +The destination URL can be dynamic, depending on the dashboard context or user’s interaction with a visualization. + +For example, you might have a dashboard that shows data from a Github repository. +You can create a drilldown that navigates from this dashboard to Github. + +[role="screenshot"] +image:images/url_drilldown_go_to_github.gif[Drilldown on pie chart that navigates to Github] + +NOTE: URL drilldown is available with the https://www.elastic.co/subscriptions[Gold subscription] and higher. + +[float] +[[try-it]] +==== Try it: Create a URL drilldown + +This example shows how to create the "Show on Github" drilldown shown above. + +. Add the <> data set. +. Open the *[Logs] Web traffic* dashboard. This isn’t data from Github, but it should work for demonstration purposes. +. In the dashboard menu bar, click *Edit*. +. In *[Logs] Visitors by OS*, open the panel menu, and then select *Create drilldown*. +. Give the drilldown a name: *Show on Github*. +. Select a drilldown action: *Go to URL*. ++ +[role="screenshot"] +image:images/url_drilldown_pick_an_action.png[Action picker] +. Enter a URL template: ++ +[source, bash] +---- +https://github.com/elastic/kibana/issues?q=is:issue+is:open+{{event.value}} +---- ++ +This example URL navigates to {kib} issues on Github. `{{event.value}}` will be substituted with a value associated with a clicked pie slice. In _preview_ `{{event.value}}` is substituted with a <> value. +[role="screenshot"] +image:images/url_drilldown_url_template.png[URL template input] +. Click *Create drilldown*. +. Save the dashboard. ++ +If you don’t save the drilldown, and then navigate away, the drilldown is lost. + +. In *[Logs] Visitors by OS*, click any slice of the pie, and then select the drilldown *Show on Github*. ++ +[role="screenshot"] +image:images/url_drilldown_popup.png[URL drilldown popup] ++ +You are navigated to the issue list in the {kib} repository. Verify that value from a pie slice you’ve clicked on is carried over to Github. ++ +[role="screenshot"] +image:images/url_drilldown_github.png[Github] + +[float] +[[trigger-picker]] +==== Picking a trigger for a URL drilldown + +Some panels support multiple user interactions (called triggers) for which you can configure a URL drilldown. The list of supported variables in the URL template depends on the trigger you selected. +In the preceding example, you configured a URL drilldown on a pie chart. The only trigger that pie chart supports is clicking on a pie slice, so you didn’t have to pick a trigger. + +However, the sample *[Logs] Unique Visitors vs. Average Bytes* chart supports both clicking on a data point and selecting a range. When you create a URL drilldown for this chart, you have the following choices: + +[role="screenshot"] +image:images/url_drilldown_trigger_picker.png[Trigger picker: Single click and Range selection] + +Variables in the URL template differ per trigger. +For example, *Single click* has `{{event.value}}` and *Range selection* has `{{event.from}}` and `{{event.to}}`. +You can create multiple URL drilldowns per panel and attach them to different triggers. + +[float] +[[templating]] +==== URL templating language + +The URL template input uses Handlebars — a simple templating language. Handlebars templates look like regular text with embedded Handlebars expressions. + +[source, bash] +---- +https://github.com/elastic/kibana/issues?q={{event.value}} +---- + +A Handlebars expression is a `{{`, some contents, followed by a `}}`. When the drilldown is executed, these expressions are replaced by values from the dashboard and interaction context. + +Refer to Handlebars https://handlebarsjs.com/guide/expressions.html#expressions[documentation] to learn about advanced use cases. + +[[helpers]] +In addition to https://handlebarsjs.com/guide/builtin-helpers.html[built-in] Handlebars helpers, you can use the following custom helpers: + + +|=== +|Helper |Use case + +|json +a|Serialize variables in JSON format. + +Example: + +`{{json event}}` + +`{{json event.key event.value}}` + +`{{json filters=context.panel.filters}}` + + +|rison +a|Serialize variables in https://github.com/w33ble/rison-node[rison] format. Rison is a common format for {kib} apps for storing state in the URL. + +Example: + +`{{rison event}}` + +`{{rison event.key event.value}}` + +`{{rison filters=context.panel.filters}}` + + +|date +a|Format dates. Supports relative dates expressions (for example, "now-15d"). Refer to the https://momentjs.com/docs/#/displaying/format/[moment] docs for different formatting options. + +Example: + +`{{ date event.from “YYYY MM DD”}}` + +`{{date “now-15”}}` +|=== + + +[float] +[[variables]] +==== URL template variables + +The URL drilldown template has three sources for variables: + +* *Global* static variables that don’t change depending on the place where the URL drilldown is used or which user interaction executed the drilldown. For example: `{{kibanaUrl}}`. +* *Context* variables that change depending on where the drilldown is created and used. These variables are extracted from a context of a panel on a dashboard. For example, `{{context.panel.filters}}` gives access to filters that applied to the current panel. +* *Event* variables that depend on the trigger context. These variables are dynamically extracted from the interaction context when the drilldown is executed. + +[[values-in-preview]] +A subtle but important difference between *context* and *event* variables is that *context* variables use real values in previews when creating a URL drilldown. +For example, `{{context.panel.filters}}` are previewed with the current filters that applied to a panel. +*Event* variables are extracted during drilldown execution from a user interaction with a panel (for example, from a pie slice that the user clicked on). + +Because there is no user interaction with a panel in preview, there is no interaction context to use in a preview. +To work around this, {kib} provides a sample interaction that relies on a picked <>. +So in a preview, you might notice that `{{event.value}}` is replaced with `{{event.value}}` instead of with a sample from your data. +Such previews can help you make sure that the structure of your URL template is valid. +However, to ensure that the configured URL drilldown works as expected with your data, you have to save the dashboard and test in the panel. + +You can access the full list of variables available for the current panel and selected trigger by clicking *Add variable* in the top-right corner of a URL template input. + +[float] +[[variables-reference]] +==== Variables reference + + +|=== +|Source |Variable |Description + +|*Global* +| kibanaUrl +| {kib} base URL. Useful for creating URL drilldowns that navigate within {kib}. + +| *Context* +| context.panel +| Context provided by current dashboard panel. + +| +| context.panel.id +| ID of a panel. + +| +| context.panel.title +| Title of a panel. + +| +| context.panel.filters +| List of {kib} filters applied to a panel. + +Tip: Use in combination with <> helper for +internal {kib} navigations with carrying over current filters. + +| +| context.panel.query.query +| Current query string. + +| +| context.panel.query.lang +| Current query language. + +| +| context.panel.timeRange.from + +context.panel.timeRange.to +| Current time picker values. + +Tip: Use in combination with <> helper to format date. + +| +| context.panel.timeRange.indexPatternId + +context.panel.timeRange.indexPatternIds +|Index pattern ids used by a panel. + +| +| context.panel.savedObjectId +| ID of saved object behind a panel. + +| *Single click* +| event.value +| Value behind clicked data point. + +| +| event.key +| Field name behind clicked data point + +| +| event.negate +| Boolean, indicating whether clicked data point resulted in negative filter. + +| *Range selection* +| event.from + +event.to +| `from` and `to` values of selected range. Depending on your data, could be either a date or number. + +Tip: Consider using <> helper for date formatting. + +| +| event.key +| Aggregation field behind the selected range, if available. + +|=== diff --git a/docs/user/reporting/reporting-troubleshooting.asciidoc b/docs/user/reporting/reporting-troubleshooting.asciidoc index dc4ffdfebdae9..82f0aa7ca0f19 100644 --- a/docs/user/reporting/reporting-troubleshooting.asciidoc +++ b/docs/user/reporting/reporting-troubleshooting.asciidoc @@ -7,6 +7,7 @@ Having trouble? Here are solutions to common problems you might encounter while using Reporting. +* <> * <> * <> * <> @@ -15,6 +16,11 @@ Having trouble? Here are solutions to common problems you might encounter while * <> * <> +[float] +[[reporting-diagnostics]] +=== Reporting Diagnostics +Reporting comes with a built-in utility to try to automatically find common issues. When Kibana is running, navigate to the Report Listing page, and click the "Run reporting diagnostics..." button. This will open up a diagnostic tool that checks various parts of the Kibana deployment to come up with any relevant recommendations. + [float] [[reporting-troubleshooting-system-dependencies]] === System dependencies diff --git a/kibana.d.ts b/kibana.d.ts index d64752abd8b60..517bda374af9d 100644 --- a/kibana.d.ts +++ b/kibana.d.ts @@ -39,8 +39,6 @@ export namespace Legacy { export type KibanaConfig = LegacyKibanaServer.KibanaConfig; export type Request = LegacyKibanaServer.Request; export type ResponseToolkit = LegacyKibanaServer.ResponseToolkit; - export type SavedObjectsClient = LegacyKibanaServer.SavedObjectsClient; - export type SavedObjectsService = LegacyKibanaServer.SavedObjectsLegacyService; export type Server = LegacyKibanaServer.Server; export type InitPluginFunction = LegacyKibanaPluginSpec.InitPluginFunction; diff --git a/package.json b/package.json index ff487510f7a32..95a6de337f62a 100644 --- a/package.json +++ b/package.json @@ -231,7 +231,7 @@ "@babel/parser": "^7.11.2", "@babel/types": "^7.11.0", "@elastic/apm-rum": "^5.5.0", - "@elastic/charts": "21.0.1", + "@elastic/charts": "21.1.2", "@elastic/ems-client": "7.9.3", "@elastic/eslint-config-kibana": "0.15.0", "@elastic/eslint-plugin-eui": "0.0.2", diff --git a/packages/kbn-ui-shared-deps/package.json b/packages/kbn-ui-shared-deps/package.json index 4b2e88d155245..bbe7b1bc2e8da 100644 --- a/packages/kbn-ui-shared-deps/package.json +++ b/packages/kbn-ui-shared-deps/package.json @@ -9,7 +9,7 @@ "kbn:watch": "node scripts/build --dev --watch" }, "dependencies": { - "@elastic/charts": "21.0.1", + "@elastic/charts": "21.1.2", "@elastic/eui": "28.2.0", "@elastic/numeral": "^2.5.0", "@kbn/i18n": "1.0.0", diff --git a/rfcs/text/0010_service_status.md b/rfcs/text/0010_service_status.md index ded594930a367..76195c4f1ab89 100644 --- a/rfcs/text/0010_service_status.md +++ b/rfcs/text/0010_service_status.md @@ -137,7 +137,7 @@ interface StatusSetup { * Current status for all dependencies of the current plugin. * Each key of the `Record` is a plugin id. */ - plugins$: Observable>; + dependencies$: Observable>; /** * The status of this plugin as derived from its dependencies. diff --git a/src/legacy/utils/binder.ts b/src/cli/cluster/binder.ts similarity index 100% rename from src/legacy/utils/binder.ts rename to src/cli/cluster/binder.ts diff --git a/src/legacy/utils/binder_for.ts b/src/cli/cluster/binder_for.ts similarity index 100% rename from src/legacy/utils/binder_for.ts rename to src/cli/cluster/binder_for.ts diff --git a/src/cli/cluster/worker.ts b/src/cli/cluster/worker.ts index 097a549187429..c8a8a067d30bf 100644 --- a/src/cli/cluster/worker.ts +++ b/src/cli/cluster/worker.ts @@ -21,7 +21,7 @@ import _ from 'lodash'; import cluster from 'cluster'; import { EventEmitter } from 'events'; -import { BinderFor } from '../../legacy/utils/binder_for'; +import { BinderFor } from './binder_for'; import { fromRoot } from '../../core/server/utils'; const cliPath = fromRoot('src/cli'); diff --git a/src/cli_keystore/add.js b/src/cli_keystore/add.js index 462259ec942dd..232392f34c63b 100644 --- a/src/cli_keystore/add.js +++ b/src/cli_keystore/add.js @@ -18,7 +18,7 @@ */ import { Logger } from '../cli_plugin/lib/logger'; -import { confirm, question } from '../legacy/server/utils'; +import { confirm, question } from './utils'; import { createPromiseFromStreams, createConcatStream } from '../core/server/utils'; /** diff --git a/src/cli_keystore/add.test.js b/src/cli_keystore/add.test.js index b5d5009667eb4..f1adee8879bc2 100644 --- a/src/cli_keystore/add.test.js +++ b/src/cli_keystore/add.test.js @@ -42,7 +42,7 @@ import { PassThrough } from 'stream'; import { Keystore } from '../legacy/server/keystore'; import { add } from './add'; import { Logger } from '../cli_plugin/lib/logger'; -import * as prompt from '../legacy/server/utils/prompt'; +import * as prompt from './utils/prompt'; describe('Kibana keystore', () => { describe('add', () => { diff --git a/src/cli_keystore/create.js b/src/cli_keystore/create.js index 8be1eb36882f1..55fe2c151dec0 100644 --- a/src/cli_keystore/create.js +++ b/src/cli_keystore/create.js @@ -18,7 +18,7 @@ */ import { Logger } from '../cli_plugin/lib/logger'; -import { confirm } from '../legacy/server/utils'; +import { confirm } from './utils'; export async function create(keystore, command, options) { const logger = new Logger(options); diff --git a/src/cli_keystore/create.test.js b/src/cli_keystore/create.test.js index f48b3775ddfff..cb85475eab1cb 100644 --- a/src/cli_keystore/create.test.js +++ b/src/cli_keystore/create.test.js @@ -41,7 +41,7 @@ import sinon from 'sinon'; import { Keystore } from '../legacy/server/keystore'; import { create } from './create'; import { Logger } from '../cli_plugin/lib/logger'; -import * as prompt from '../legacy/server/utils/prompt'; +import * as prompt from './utils/prompt'; describe('Kibana keystore', () => { describe('create', () => { diff --git a/src/legacy/server/utils/index.js b/src/cli_keystore/utils/index.js similarity index 100% rename from src/legacy/server/utils/index.js rename to src/cli_keystore/utils/index.js diff --git a/src/legacy/server/utils/prompt.js b/src/cli_keystore/utils/prompt.js similarity index 100% rename from src/legacy/server/utils/prompt.js rename to src/cli_keystore/utils/prompt.js diff --git a/src/legacy/server/utils/prompt.test.js b/src/cli_keystore/utils/prompt.test.js similarity index 100% rename from src/legacy/server/utils/prompt.test.js rename to src/cli_keystore/utils/prompt.test.js diff --git a/src/core/public/core_app/status/lib/load_status.test.ts b/src/core/public/core_app/status/lib/load_status.test.ts index 3a444a4448467..5a9f982e106a7 100644 --- a/src/core/public/core_app/status/lib/load_status.test.ts +++ b/src/core/public/core_app/status/lib/load_status.test.ts @@ -57,6 +57,7 @@ const mockedResponse: StatusResponse = { ], }, metrics: { + collected_at: new Date('2020-01-01 01:00:00'), collection_interval_in_millis: 1000, os: { platform: 'darwin' as const, diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index fc753517fd940..95ac8bba57049 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -129,7 +129,7 @@ export class DocLinksService { }, visualize: { guide: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/visualize.html`, - timelionDeprecation: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/timelion.html#timelion-deprecation`, + timelionDeprecation: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/dashboard.html#timelion-deprecation`, }, }, }); diff --git a/src/core/server/config/deprecation/core_deprecations.ts b/src/core/server/config/deprecation/core_deprecations.ts index e4e881ab24372..2b8b8e383da24 100644 --- a/src/core/server/config/deprecation/core_deprecations.ts +++ b/src/core/server/config/deprecation/core_deprecations.ts @@ -113,7 +113,7 @@ const mapManifestServiceUrlDeprecation: ConfigDeprecation = (settings, fromPath, return settings; }; -export const coreDeprecationProvider: ConfigDeprecationProvider = ({ unusedFromRoot }) => [ +export const coreDeprecationProvider: ConfigDeprecationProvider = ({ rename, unusedFromRoot }) => [ unusedFromRoot('savedObjects.indexCheckTimeout'), unusedFromRoot('server.xsrf.token'), unusedFromRoot('maps.manifestServiceUrl'), @@ -136,6 +136,8 @@ export const coreDeprecationProvider: ConfigDeprecationProvider = ({ unusedFromR unusedFromRoot('optimize.workers'), unusedFromRoot('optimize.profile'), unusedFromRoot('optimize.validateSyntaxOfNodeModules'), + rename('cpu.cgroup.path.override', 'ops.cGroupOverrides.cpuPath'), + rename('cpuacct.cgroup.path.override', 'ops.cGroupOverrides.cpuAcctPath'), configPathDeprecation, dataPathDeprecation, rewriteBasePathDeprecation, diff --git a/src/core/server/index.ts b/src/core/server/index.ts index c17d3d7546779..97aca74bfd48f 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -266,9 +266,7 @@ export { SavedObjectUnsanitizedDoc, SavedObjectsRepositoryFactory, SavedObjectsResolveImportErrorsOptions, - SavedObjectsSchema, SavedObjectsSerializer, - SavedObjectsLegacyService, SavedObjectsUpdateOptions, SavedObjectsUpdateResponse, SavedObjectsAddToNamespacesOptions, diff --git a/src/core/server/legacy/legacy_service.mock.ts b/src/core/server/legacy/legacy_service.mock.ts index 26ec52185a5d8..c27f5be04d965 100644 --- a/src/core/server/legacy/legacy_service.mock.ts +++ b/src/core/server/legacy/legacy_service.mock.ts @@ -24,13 +24,7 @@ type LegacyServiceMock = jest.Mocked & { legacyId const createDiscoverPluginsMock = (): LegacyServiceDiscoverPlugins => ({ pluginSpecs: [], - uiExports: { - savedObjectSchemas: {}, - savedObjectMappings: [], - savedObjectMigrations: {}, - savedObjectValidations: {}, - savedObjectsManagement: {}, - }, + uiExports: {}, navLinks: [], pluginExtendedConfig: { get: jest.fn(), diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index 880011d2e1923..6e6d5cfc24340 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -264,6 +264,7 @@ export class LegacyService implements CoreService { getTypeRegistry: startDeps.core.savedObjects.getTypeRegistry, }, metrics: { + collectionInterval: startDeps.core.metrics.collectionInterval, getOpsMetrics$: startDeps.core.metrics.getOpsMetrics$, }, uiSettings: { asScopedToClient: startDeps.core.uiSettings.asScopedToClient }, @@ -310,6 +311,17 @@ export class LegacyService implements CoreService { status: { core$: setupDeps.core.status.core$, overall$: setupDeps.core.status.overall$, + set: () => { + throw new Error(`core.status.set is unsupported in legacy`); + }, + // @ts-expect-error + get dependencies$() { + throw new Error(`core.status.dependencies$ is unsupported in legacy`); + }, + // @ts-expect-error + get derivedStatus$() { + throw new Error(`core.status.derivedStatus$ is unsupported in legacy`); + }, }, uiSettings: { register: setupDeps.core.uiSettings.register, @@ -341,11 +353,9 @@ export class LegacyService implements CoreService { registerStaticDir: setupDeps.core.http.registerStaticDir, }, hapiServer: setupDeps.core.http.server, - kibanaMigrator: startDeps.core.savedObjects.migrator, uiPlugins: setupDeps.uiPlugins, elasticsearch: setupDeps.core.elasticsearch, rendering: setupDeps.core.rendering, - savedObjectsClientProvider: startDeps.core.savedObjects.clientProvider, legacy: this.legacyInternals, }, logger: this.coreContext.logger, diff --git a/src/core/server/legacy/types.ts b/src/core/server/legacy/types.ts index cf08689a6d0d4..1105308fd44cf 100644 --- a/src/core/server/legacy/types.ts +++ b/src/core/server/legacy/types.ts @@ -24,7 +24,6 @@ import { KibanaRequest, LegacyRequest } from '../http'; import { InternalCoreSetup, InternalCoreStart } from '../internal_types'; import { PluginsServiceSetup, PluginsServiceStart, UiPlugins } from '../plugins'; import { InternalRenderingServiceSetup } from '../rendering'; -import { SavedObjectsLegacyUiExports } from '../types'; /** * @internal @@ -128,13 +127,13 @@ export type LegacyNavLink = Omit; unknown?: [{ pluginSpec: LegacyPluginSpec; type: unknown }]; -}; +} /** * @public diff --git a/src/core/server/metrics/collectors/cgroup.test.ts b/src/core/server/metrics/collectors/cgroup.test.ts new file mode 100644 index 0000000000000..39f917b9f0ba1 --- /dev/null +++ b/src/core/server/metrics/collectors/cgroup.test.ts @@ -0,0 +1,115 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import mockFs from 'mock-fs'; +import { OsCgroupMetricsCollector } from './cgroup'; + +describe('OsCgroupMetricsCollector', () => { + afterEach(() => mockFs.restore()); + + it('returns empty object when no cgroup file present', async () => { + mockFs({ + '/proc/self': { + /** empty directory */ + }, + }); + + const collector = new OsCgroupMetricsCollector({}); + expect(await collector.collect()).toEqual({}); + }); + + it('collects default cgroup data', async () => { + mockFs({ + '/proc/self/cgroup': ` +123:memory:/groupname +123:cpu:/groupname +123:cpuacct:/groupname + `, + '/sys/fs/cgroup/cpuacct/groupname/cpuacct.usage': '111', + '/sys/fs/cgroup/cpu/groupname/cpu.cfs_period_us': '222', + '/sys/fs/cgroup/cpu/groupname/cpu.cfs_quota_us': '333', + '/sys/fs/cgroup/cpu/groupname/cpu.stat': ` +nr_periods 444 +nr_throttled 555 +throttled_time 666 + `, + }); + + const collector = new OsCgroupMetricsCollector({}); + expect(await collector.collect()).toMatchInlineSnapshot(` + Object { + "cpu": Object { + "cfs_period_micros": 222, + "cfs_quota_micros": 333, + "control_group": "/groupname", + "stat": Object { + "number_of_elapsed_periods": 444, + "number_of_times_throttled": 555, + "time_throttled_nanos": 666, + }, + }, + "cpuacct": Object { + "control_group": "/groupname", + "usage_nanos": 111, + }, + } + `); + }); + + it('collects override cgroup data', async () => { + mockFs({ + '/proc/self/cgroup': ` +123:memory:/groupname +123:cpu:/groupname +123:cpuacct:/groupname + `, + '/sys/fs/cgroup/cpuacct/xxcustomcpuacctxx/cpuacct.usage': '111', + '/sys/fs/cgroup/cpu/xxcustomcpuxx/cpu.cfs_period_us': '222', + '/sys/fs/cgroup/cpu/xxcustomcpuxx/cpu.cfs_quota_us': '333', + '/sys/fs/cgroup/cpu/xxcustomcpuxx/cpu.stat': ` +nr_periods 444 +nr_throttled 555 +throttled_time 666 + `, + }); + + const collector = new OsCgroupMetricsCollector({ + cpuAcctPath: 'xxcustomcpuacctxx', + cpuPath: 'xxcustomcpuxx', + }); + expect(await collector.collect()).toMatchInlineSnapshot(` + Object { + "cpu": Object { + "cfs_period_micros": 222, + "cfs_quota_micros": 333, + "control_group": "xxcustomcpuxx", + "stat": Object { + "number_of_elapsed_periods": 444, + "number_of_times_throttled": 555, + "time_throttled_nanos": 666, + }, + }, + "cpuacct": Object { + "control_group": "xxcustomcpuacctxx", + "usage_nanos": 111, + }, + } + `); + }); +}); diff --git a/src/core/server/metrics/collectors/cgroup.ts b/src/core/server/metrics/collectors/cgroup.ts new file mode 100644 index 0000000000000..867ea44dff1ae --- /dev/null +++ b/src/core/server/metrics/collectors/cgroup.ts @@ -0,0 +1,194 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import fs from 'fs'; +import { join as joinPath } from 'path'; +import { MetricsCollector, OpsOsMetrics } from './types'; + +type OsCgroupMetrics = Pick; + +interface OsCgroupMetricsCollectorOptions { + cpuPath?: string; + cpuAcctPath?: string; +} + +export class OsCgroupMetricsCollector implements MetricsCollector { + /** Used to prevent unnecessary file reads on systems not using cgroups. */ + private noCgroupPresent = false; + private cpuPath?: string; + private cpuAcctPath?: string; + + constructor(private readonly options: OsCgroupMetricsCollectorOptions) {} + + public async collect(): Promise { + try { + await this.initializePaths(); + if (this.noCgroupPresent || !this.cpuAcctPath || !this.cpuPath) { + return {}; + } + + const [cpuAcctUsage, cpuFsPeriod, cpuFsQuota, cpuStat] = await Promise.all([ + readCPUAcctUsage(this.cpuAcctPath), + readCPUFsPeriod(this.cpuPath), + readCPUFsQuota(this.cpuPath), + readCPUStat(this.cpuPath), + ]); + + return { + cpuacct: { + control_group: this.cpuAcctPath, + usage_nanos: cpuAcctUsage, + }, + + cpu: { + control_group: this.cpuPath, + cfs_period_micros: cpuFsPeriod, + cfs_quota_micros: cpuFsQuota, + stat: cpuStat, + }, + }; + } catch (err) { + if (err.code === 'ENOENT') { + this.noCgroupPresent = true; + return {}; + } else { + throw err; + } + } + } + + public reset() {} + + private async initializePaths() { + // Perform this setup lazily on the first collect call and then memoize the results. + // Makes the assumption this data doesn't change while the process is running. + if (this.cpuPath && this.cpuAcctPath) { + return; + } + + // Only read the file if both options are undefined. + if (!this.options.cpuPath || !this.options.cpuAcctPath) { + const cgroups = await readControlGroups(); + this.cpuPath = this.options.cpuPath || cgroups[GROUP_CPU]; + this.cpuAcctPath = this.options.cpuAcctPath || cgroups[GROUP_CPUACCT]; + } else { + this.cpuPath = this.options.cpuPath; + this.cpuAcctPath = this.options.cpuAcctPath; + } + + // prevents undefined cgroup paths + if (!this.cpuPath || !this.cpuAcctPath) { + this.noCgroupPresent = true; + } + } +} + +const CONTROL_GROUP_RE = new RegExp('\\d+:([^:]+):(/.*)'); +const CONTROLLER_SEPARATOR_RE = ','; + +const PROC_SELF_CGROUP_FILE = '/proc/self/cgroup'; +const PROC_CGROUP_CPU_DIR = '/sys/fs/cgroup/cpu'; +const PROC_CGROUP_CPUACCT_DIR = '/sys/fs/cgroup/cpuacct'; + +const GROUP_CPUACCT = 'cpuacct'; +const CPUACCT_USAGE_FILE = 'cpuacct.usage'; + +const GROUP_CPU = 'cpu'; +const CPU_FS_PERIOD_US_FILE = 'cpu.cfs_period_us'; +const CPU_FS_QUOTA_US_FILE = 'cpu.cfs_quota_us'; +const CPU_STATS_FILE = 'cpu.stat'; + +async function readControlGroups() { + const data = await fs.promises.readFile(PROC_SELF_CGROUP_FILE); + + return data + .toString() + .split(/\n/) + .reduce((acc, line) => { + const matches = line.match(CONTROL_GROUP_RE); + + if (matches !== null) { + const controllers = matches[1].split(CONTROLLER_SEPARATOR_RE); + controllers.forEach((controller) => { + acc[controller] = matches[2]; + }); + } + + return acc; + }, {} as Record); +} + +async function fileContentsToInteger(path: string) { + const data = await fs.promises.readFile(path); + return parseInt(data.toString(), 10); +} + +function readCPUAcctUsage(controlGroup: string) { + return fileContentsToInteger(joinPath(PROC_CGROUP_CPUACCT_DIR, controlGroup, CPUACCT_USAGE_FILE)); +} + +function readCPUFsPeriod(controlGroup: string) { + return fileContentsToInteger(joinPath(PROC_CGROUP_CPU_DIR, controlGroup, CPU_FS_PERIOD_US_FILE)); +} + +function readCPUFsQuota(controlGroup: string) { + return fileContentsToInteger(joinPath(PROC_CGROUP_CPU_DIR, controlGroup, CPU_FS_QUOTA_US_FILE)); +} + +async function readCPUStat(controlGroup: string) { + const stat = { + number_of_elapsed_periods: -1, + number_of_times_throttled: -1, + time_throttled_nanos: -1, + }; + + try { + const data = await fs.promises.readFile( + joinPath(PROC_CGROUP_CPU_DIR, controlGroup, CPU_STATS_FILE) + ); + return data + .toString() + .split(/\n/) + .reduce((acc, line) => { + const fields = line.split(/\s+/); + + switch (fields[0]) { + case 'nr_periods': + acc.number_of_elapsed_periods = parseInt(fields[1], 10); + break; + + case 'nr_throttled': + acc.number_of_times_throttled = parseInt(fields[1], 10); + break; + + case 'throttled_time': + acc.time_throttled_nanos = parseInt(fields[1], 10); + break; + } + + return acc; + }, stat); + } catch (err) { + if (err.code === 'ENOENT') { + return stat; + } + + throw err; + } +} diff --git a/src/core/server/metrics/collectors/collector.mock.ts b/src/core/server/metrics/collectors/collector.mock.ts new file mode 100644 index 0000000000000..2a942e1fafe63 --- /dev/null +++ b/src/core/server/metrics/collectors/collector.mock.ts @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { MetricsCollector } from './types'; + +const createCollector = (collectReturnValue: any = {}): jest.Mocked> => { + const collector: jest.Mocked> = { + collect: jest.fn().mockResolvedValue(collectReturnValue), + reset: jest.fn(), + }; + + return collector; +}; + +export const metricsCollectorMock = { + create: createCollector, +}; diff --git a/src/core/server/metrics/collectors/index.ts b/src/core/server/metrics/collectors/index.ts index f58ab02e63881..4540cb79be74b 100644 --- a/src/core/server/metrics/collectors/index.ts +++ b/src/core/server/metrics/collectors/index.ts @@ -18,6 +18,6 @@ */ export { OpsProcessMetrics, OpsOsMetrics, OpsServerMetrics, MetricsCollector } from './types'; -export { OsMetricsCollector } from './os'; +export { OsMetricsCollector, OpsMetricsCollectorOptions } from './os'; export { ProcessMetricsCollector } from './process'; export { ServerMetricsCollector } from './server'; diff --git a/src/core/server/saved_objects/schema/index.ts b/src/core/server/metrics/collectors/os.test.mocks.ts similarity index 77% rename from src/core/server/saved_objects/schema/index.ts rename to src/core/server/metrics/collectors/os.test.mocks.ts index d30bbb8d34cd3..ee02b8c802151 100644 --- a/src/core/server/saved_objects/schema/index.ts +++ b/src/core/server/metrics/collectors/os.test.mocks.ts @@ -17,4 +17,9 @@ * under the License. */ -export { SavedObjectsSchema, SavedObjectsSchemaDefinition } from './schema'; +import { metricsCollectorMock } from './collector.mock'; + +export const cgroupCollectorMock = metricsCollectorMock.create(); +jest.doMock('./cgroup', () => ({ + OsCgroupMetricsCollector: jest.fn(() => cgroupCollectorMock), +})); diff --git a/src/core/server/metrics/collectors/os.test.ts b/src/core/server/metrics/collectors/os.test.ts index 7d5a6da90b7d6..5e52cecb76be3 100644 --- a/src/core/server/metrics/collectors/os.test.ts +++ b/src/core/server/metrics/collectors/os.test.ts @@ -20,6 +20,7 @@ jest.mock('getos', () => (cb: Function) => cb(null, { dist: 'distrib', release: 'release' })); import os from 'os'; +import { cgroupCollectorMock } from './os.test.mocks'; import { OsMetricsCollector } from './os'; describe('OsMetricsCollector', () => { @@ -27,6 +28,8 @@ describe('OsMetricsCollector', () => { beforeEach(() => { collector = new OsMetricsCollector(); + cgroupCollectorMock.collect.mockReset(); + cgroupCollectorMock.reset.mockReset(); }); afterEach(() => { @@ -96,4 +99,9 @@ describe('OsMetricsCollector', () => { '15m': fifteenMinLoad, }); }); + + it('calls the cgroup sub-collector', async () => { + await collector.collect(); + expect(cgroupCollectorMock.collect).toHaveBeenCalled(); + }); }); diff --git a/src/core/server/metrics/collectors/os.ts b/src/core/server/metrics/collectors/os.ts index 59bef9d8ddd2b..eae49278405a9 100644 --- a/src/core/server/metrics/collectors/os.ts +++ b/src/core/server/metrics/collectors/os.ts @@ -21,10 +21,22 @@ import os from 'os'; import getosAsync, { LinuxOs } from 'getos'; import { promisify } from 'util'; import { OpsOsMetrics, MetricsCollector } from './types'; +import { OsCgroupMetricsCollector } from './cgroup'; const getos = promisify(getosAsync); +export interface OpsMetricsCollectorOptions { + cpuPath?: string; + cpuAcctPath?: string; +} + export class OsMetricsCollector implements MetricsCollector { + private readonly cgroupCollector: OsCgroupMetricsCollector; + + constructor(options: OpsMetricsCollectorOptions = {}) { + this.cgroupCollector = new OsCgroupMetricsCollector(options); + } + public async collect(): Promise { const platform = os.platform(); const load = os.loadavg(); @@ -43,20 +55,30 @@ export class OsMetricsCollector implements MetricsCollector { used_in_bytes: os.totalmem() - os.freemem(), }, uptime_in_millis: os.uptime() * 1000, + ...(await this.getDistroStats(platform)), + ...(await this.cgroupCollector.collect()), }; + return metrics; + } + + public reset() {} + + private async getDistroStats( + platform: string + ): Promise> { if (platform === 'linux') { try { const distro = (await getos()) as LinuxOs; - metrics.distro = distro.dist; - metrics.distroRelease = `${distro.dist}-${distro.release}`; + return { + distro: distro.dist, + distroRelease: `${distro.dist}-${distro.release}`, + }; } catch (e) { // ignore errors } } - return metrics; + return {}; } - - public reset() {} } diff --git a/src/core/server/metrics/collectors/types.ts b/src/core/server/metrics/collectors/types.ts index 73e8975a6b362..77ea13a1f0787 100644 --- a/src/core/server/metrics/collectors/types.ts +++ b/src/core/server/metrics/collectors/types.ts @@ -85,6 +85,33 @@ export interface OpsOsMetrics { }; /** the OS uptime */ uptime_in_millis: number; + + /** cpu accounting metrics, undefined when not running in a cgroup */ + cpuacct?: { + /** name of this process's cgroup */ + control_group: string; + /** cpu time used by this process's cgroup */ + usage_nanos: number; + }; + + /** cpu cgroup metrics, undefined when not running in a cgroup */ + cpu?: { + /** name of this process's cgroup */ + control_group: string; + /** the length of the cfs period */ + cfs_period_micros: number; + /** total available run-time within a cfs period */ + cfs_quota_micros: number; + /** current stats on the cfs periods */ + stat: { + /** number of cfs periods that elapsed */ + number_of_elapsed_periods: number; + /** number of times the cgroup has been throttled */ + number_of_times_throttled: number; + /** total amount of time the cgroup has been throttled for */ + time_throttled_nanos: number; + }; + }; } /** diff --git a/src/core/server/metrics/metrics_service.mock.ts b/src/core/server/metrics/metrics_service.mock.ts index 769f6ee2a549a..2af653004a479 100644 --- a/src/core/server/metrics/metrics_service.mock.ts +++ b/src/core/server/metrics/metrics_service.mock.ts @@ -21,20 +21,18 @@ import { MetricsService } from './metrics_service'; import { InternalMetricsServiceSetup, InternalMetricsServiceStart, + MetricsServiceSetup, MetricsServiceStart, } from './types'; const createInternalSetupContractMock = () => { - const setupContract: jest.Mocked = {}; - return setupContract; -}; - -const createStartContractMock = () => { - const startContract: jest.Mocked = { + const setupContract: jest.Mocked = { + collectionInterval: 30000, getOpsMetrics$: jest.fn(), }; - startContract.getOpsMetrics$.mockReturnValue( + setupContract.getOpsMetrics$.mockReturnValue( new BehaviorSubject({ + collected_at: new Date('2020-01-01 01:00:00'), process: { memory: { heap: { total_in_bytes: 1, used_in_bytes: 1, size_limit: 1 }, @@ -56,11 +54,21 @@ const createStartContractMock = () => { concurrent_connections: 1, }) ); + return setupContract; +}; + +const createSetupContractMock = () => { + const startContract: jest.Mocked = createInternalSetupContractMock(); return startContract; }; const createInternalStartContractMock = () => { - const startContract: jest.Mocked = createStartContractMock(); + const startContract: jest.Mocked = createInternalSetupContractMock(); + return startContract; +}; + +const createStartContractMock = () => { + const startContract: jest.Mocked = createInternalSetupContractMock(); return startContract; }; @@ -77,7 +85,7 @@ const createMock = () => { export const metricsServiceMock = { create: createMock, - createSetupContract: createStartContractMock, + createSetupContract: createSetupContractMock, createStartContract: createStartContractMock, createInternalSetupContract: createInternalSetupContractMock, createInternalStartContract: createInternalStartContractMock, diff --git a/src/core/server/metrics/metrics_service.ts b/src/core/server/metrics/metrics_service.ts index f28fb21aaac0d..d4696b3aa9aaf 100644 --- a/src/core/server/metrics/metrics_service.ts +++ b/src/core/server/metrics/metrics_service.ts @@ -17,7 +17,7 @@ * under the License. */ -import { Subject } from 'rxjs'; +import { ReplaySubject } from 'rxjs'; import { first } from 'rxjs/operators'; import { CoreService } from '../../types'; import { CoreContext } from '../core_context'; @@ -37,26 +37,21 @@ export class MetricsService private readonly logger: Logger; private metricsCollector?: OpsMetricsCollector; private collectInterval?: NodeJS.Timeout; - private metrics$ = new Subject(); + private metrics$ = new ReplaySubject(); + private service?: InternalMetricsServiceSetup; constructor(private readonly coreContext: CoreContext) { this.logger = coreContext.logger.get('metrics'); } public async setup({ http }: MetricsServiceSetupDeps): Promise { - this.metricsCollector = new OpsMetricsCollector(http.server); - return {}; - } - - public async start(): Promise { - if (!this.metricsCollector) { - throw new Error('#setup() needs to be run first'); - } const config = await this.coreContext.configService .atPath(opsConfig.path) .pipe(first()) .toPromise(); + this.metricsCollector = new OpsMetricsCollector(http.server, config.cGroupOverrides); + await this.refreshMetrics(); this.collectInterval = setInterval(() => { @@ -65,9 +60,20 @@ export class MetricsService const metricsObservable = this.metrics$.asObservable(); - return { + this.service = { + collectionInterval: config.interval.asMilliseconds(), getOpsMetrics$: () => metricsObservable, }; + + return this.service; + } + + public async start(): Promise { + if (!this.service) { + throw new Error('#setup() needs to be run first'); + } + + return this.service; } private async refreshMetrics() { diff --git a/src/core/server/metrics/ops_config.ts b/src/core/server/metrics/ops_config.ts index bd6ae5cc5474d..5f3f67e931c38 100644 --- a/src/core/server/metrics/ops_config.ts +++ b/src/core/server/metrics/ops_config.ts @@ -23,6 +23,10 @@ export const opsConfig = { path: 'ops', schema: schema.object({ interval: schema.duration({ defaultValue: '5s' }), + cGroupOverrides: schema.object({ + cpuPath: schema.maybe(schema.string()), + cpuAcctPath: schema.maybe(schema.string()), + }), }), }; diff --git a/src/core/server/metrics/ops_metrics_collector.test.ts b/src/core/server/metrics/ops_metrics_collector.test.ts index 9e76895b14578..7aa3f7cd3baf0 100644 --- a/src/core/server/metrics/ops_metrics_collector.test.ts +++ b/src/core/server/metrics/ops_metrics_collector.test.ts @@ -30,7 +30,7 @@ describe('OpsMetricsCollector', () => { beforeEach(() => { const hapiServer = httpServiceMock.createInternalSetupContract().server; - collector = new OpsMetricsCollector(hapiServer); + collector = new OpsMetricsCollector(hapiServer, {}); mockOsCollector.collect.mockResolvedValue('osMetrics'); }); @@ -51,6 +51,7 @@ describe('OpsMetricsCollector', () => { expect(mockServerCollector.collect).toHaveBeenCalledTimes(1); expect(metrics).toEqual({ + collected_at: expect.any(Date), process: 'processMetrics', os: 'osMetrics', requests: 'serverRequestsMetrics', diff --git a/src/core/server/metrics/ops_metrics_collector.ts b/src/core/server/metrics/ops_metrics_collector.ts index 525515dba1457..af74caa6cb386 100644 --- a/src/core/server/metrics/ops_metrics_collector.ts +++ b/src/core/server/metrics/ops_metrics_collector.ts @@ -21,6 +21,7 @@ import { Server as HapiServer } from 'hapi'; import { ProcessMetricsCollector, OsMetricsCollector, + OpsMetricsCollectorOptions, ServerMetricsCollector, MetricsCollector, } from './collectors'; @@ -31,9 +32,9 @@ export class OpsMetricsCollector implements MetricsCollector { private readonly osCollector: OsMetricsCollector; private readonly serverCollector: ServerMetricsCollector; - constructor(server: HapiServer) { + constructor(server: HapiServer, opsOptions: OpsMetricsCollectorOptions) { this.processCollector = new ProcessMetricsCollector(); - this.osCollector = new OsMetricsCollector(); + this.osCollector = new OsMetricsCollector(opsOptions); this.serverCollector = new ServerMetricsCollector(server); } @@ -44,6 +45,7 @@ export class OpsMetricsCollector implements MetricsCollector { this.serverCollector.collect(), ]); return { + collected_at: new Date(), process, os, ...server, diff --git a/src/core/server/metrics/types.ts b/src/core/server/metrics/types.ts index cbf0acacd6bab..c177b3ed25115 100644 --- a/src/core/server/metrics/types.ts +++ b/src/core/server/metrics/types.ts @@ -20,14 +20,15 @@ import { Observable } from 'rxjs'; import { OpsProcessMetrics, OpsOsMetrics, OpsServerMetrics } from './collectors'; -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface MetricsServiceSetup {} /** * APIs to retrieves metrics gathered and exposed by the core platform. * * @public */ -export interface MetricsServiceStart { +export interface MetricsServiceSetup { + /** Interval metrics are collected in milliseconds */ + readonly collectionInterval: number; + /** * Retrieve an observable emitting the {@link OpsMetrics} gathered. * The observable will emit an initial value during core's `start` phase, and a new value every fixed interval of time, @@ -42,6 +43,12 @@ export interface MetricsServiceStart { */ getOpsMetrics$: () => Observable; } +/** + * {@inheritdoc MetricsServiceSetup} + * + * @public + */ +export type MetricsServiceStart = MetricsServiceSetup; export type InternalMetricsServiceSetup = MetricsServiceSetup; export type InternalMetricsServiceStart = MetricsServiceStart; @@ -53,6 +60,8 @@ export type InternalMetricsServiceStart = MetricsServiceStart; * @public */ export interface OpsMetrics { + /** Time metrics were recorded at. */ + collected_at: Date; /** Process related metrics */ process: OpsProcessMetrics; /** OS related metrics */ diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index fa2659ca130a0..af0b0e19b3227 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -185,6 +185,9 @@ export function createPluginSetupContext( status: { core$: deps.status.core$, overall$: deps.status.overall$, + set: deps.status.plugins.set.bind(null, plugin.name), + dependencies$: deps.status.plugins.getDependenciesStatus$(plugin.name), + derivedStatus$: deps.status.plugins.getDerivedStatus$(plugin.name), }, uiSettings: { register: deps.uiSettings.register, @@ -233,6 +236,7 @@ export function createPluginStartContext( getTypeRegistry: deps.savedObjects.getTypeRegistry, }, metrics: { + collectionInterval: deps.metrics.collectionInterval, getOpsMetrics$: deps.metrics.getOpsMetrics$, }, uiSettings: { diff --git a/src/core/server/plugins/plugins_system.test.ts b/src/core/server/plugins/plugins_system.test.ts index 7af77491df1ab..71ac31db13f92 100644 --- a/src/core/server/plugins/plugins_system.test.ts +++ b/src/core/server/plugins/plugins_system.test.ts @@ -100,15 +100,27 @@ test('getPluginDependencies returns dependency tree of symbols', () => { pluginsSystem.addPlugin(createPlugin('no-dep')); expect(pluginsSystem.getPluginDependencies()).toMatchInlineSnapshot(` - Map { - Symbol(plugin-a) => Array [ - Symbol(no-dep), - ], - Symbol(plugin-b) => Array [ - Symbol(plugin-a), - Symbol(no-dep), - ], - Symbol(no-dep) => Array [], + Object { + "asNames": Map { + "plugin-a" => Array [ + "no-dep", + ], + "plugin-b" => Array [ + "plugin-a", + "no-dep", + ], + "no-dep" => Array [], + }, + "asOpaqueIds": Map { + Symbol(plugin-a) => Array [ + Symbol(no-dep), + ], + Symbol(plugin-b) => Array [ + Symbol(plugin-a), + Symbol(no-dep), + ], + Symbol(no-dep) => Array [], + }, } `); }); diff --git a/src/core/server/plugins/plugins_system.ts b/src/core/server/plugins/plugins_system.ts index f5c1b35d678a3..b2acd9a6fd04b 100644 --- a/src/core/server/plugins/plugins_system.ts +++ b/src/core/server/plugins/plugins_system.ts @@ -20,10 +20,11 @@ import { CoreContext } from '../core_context'; import { Logger } from '../logging'; import { PluginWrapper } from './plugin'; -import { DiscoveredPlugin, PluginName, PluginOpaqueId } from './types'; +import { DiscoveredPlugin, PluginName } from './types'; import { createPluginSetupContext, createPluginStartContext } from './plugin_context'; import { PluginsServiceSetupDeps, PluginsServiceStartDeps } from './plugins_service'; import { withTimeout } from '../../utils'; +import { PluginDependencies } from '.'; const Sec = 1000; /** @internal */ @@ -45,9 +46,19 @@ export class PluginsSystem { * @returns a ReadonlyMap of each plugin and an Array of its available dependencies * @internal */ - public getPluginDependencies(): ReadonlyMap { - // Return dependency map of opaque ids - return new Map( + public getPluginDependencies(): PluginDependencies { + const asNames = new Map( + [...this.plugins].map(([name, plugin]) => [ + plugin.name, + [ + ...new Set([ + ...plugin.requiredPlugins, + ...plugin.optionalPlugins.filter((optPlugin) => this.plugins.has(optPlugin)), + ]), + ].map((depId) => this.plugins.get(depId)!.name), + ]) + ); + const asOpaqueIds = new Map( [...this.plugins].map(([name, plugin]) => [ plugin.opaqueId, [ @@ -58,6 +69,8 @@ export class PluginsSystem { ].map((depId) => this.plugins.get(depId)!.opaqueId), ]) ); + + return { asNames, asOpaqueIds }; } public async setupPlugins(deps: PluginsServiceSetupDeps) { diff --git a/src/core/server/plugins/types.ts b/src/core/server/plugins/types.ts index eb2a9ca3daf5f..517261b5bc9bb 100644 --- a/src/core/server/plugins/types.ts +++ b/src/core/server/plugins/types.ts @@ -93,6 +93,12 @@ export type PluginName = string; /** @public */ export type PluginOpaqueId = symbol; +/** @internal */ +export interface PluginDependencies { + asNames: ReadonlyMap; + asOpaqueIds: ReadonlyMap; +} + /** * Describes the set of required and optional properties plugin can define in its * mandatory JSON manifest file. diff --git a/src/core/server/saved_objects/__snapshots__/utils.test.ts.snap b/src/core/server/saved_objects/__snapshots__/utils.test.ts.snap deleted file mode 100644 index 7cd0297e57857..0000000000000 --- a/src/core/server/saved_objects/__snapshots__/utils.test.ts.snap +++ /dev/null @@ -1,184 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`convertLegacyTypes converts the legacy mappings using default values if no schemas are specified 1`] = ` -Array [ - Object { - "convertToAliasScript": undefined, - "hidden": false, - "indexPattern": undefined, - "management": undefined, - "mappings": Object { - "properties": Object { - "fieldA": Object { - "type": "text", - }, - }, - }, - "migrations": Object {}, - "name": "typeA", - "namespaceType": "single", - }, - Object { - "convertToAliasScript": undefined, - "hidden": false, - "indexPattern": undefined, - "management": undefined, - "mappings": Object { - "properties": Object { - "fieldB": Object { - "type": "text", - }, - }, - }, - "migrations": Object {}, - "name": "typeB", - "namespaceType": "single", - }, - Object { - "convertToAliasScript": undefined, - "hidden": false, - "indexPattern": undefined, - "management": undefined, - "mappings": Object { - "properties": Object { - "fieldC": Object { - "type": "text", - }, - }, - }, - "migrations": Object {}, - "name": "typeC", - "namespaceType": "single", - }, -] -`; - -exports[`convertLegacyTypes merges everything when all are present 1`] = ` -Array [ - Object { - "convertToAliasScript": undefined, - "hidden": true, - "indexPattern": "myIndex", - "management": undefined, - "mappings": Object { - "properties": Object { - "fieldA": Object { - "type": "text", - }, - }, - }, - "migrations": Object { - "1.0.0": [Function], - "2.0.4": [Function], - }, - "name": "typeA", - "namespaceType": "agnostic", - }, - Object { - "convertToAliasScript": "some alias script", - "hidden": false, - "indexPattern": undefined, - "management": undefined, - "mappings": Object { - "properties": Object { - "anotherFieldB": Object { - "type": "boolean", - }, - "fieldB": Object { - "type": "text", - }, - }, - }, - "migrations": Object {}, - "name": "typeB", - "namespaceType": "single", - }, - Object { - "convertToAliasScript": undefined, - "hidden": false, - "indexPattern": undefined, - "management": undefined, - "mappings": Object { - "properties": Object { - "fieldC": Object { - "type": "text", - }, - }, - }, - "migrations": Object { - "1.5.3": [Function], - }, - "name": "typeC", - "namespaceType": "single", - }, -] -`; - -exports[`convertLegacyTypes merges the mappings and the schema to create the type when schema exists for the type 1`] = ` -Array [ - Object { - "convertToAliasScript": undefined, - "hidden": true, - "indexPattern": "fooBar", - "management": undefined, - "mappings": Object { - "properties": Object { - "fieldA": Object { - "type": "text", - }, - }, - }, - "migrations": Object {}, - "name": "typeA", - "namespaceType": "agnostic", - }, - Object { - "convertToAliasScript": undefined, - "hidden": false, - "indexPattern": "barBaz", - "management": undefined, - "mappings": Object { - "properties": Object { - "fieldB": Object { - "type": "text", - }, - }, - }, - "migrations": Object {}, - "name": "typeB", - "namespaceType": "multiple", - }, - Object { - "convertToAliasScript": undefined, - "hidden": false, - "indexPattern": undefined, - "management": undefined, - "mappings": Object { - "properties": Object { - "fieldC": Object { - "type": "text", - }, - }, - }, - "migrations": Object {}, - "name": "typeC", - "namespaceType": "single", - }, - Object { - "convertToAliasScript": undefined, - "hidden": false, - "indexPattern": "bazQux", - "management": undefined, - "mappings": Object { - "properties": Object { - "fieldD": Object { - "type": "text", - }, - }, - }, - "migrations": Object {}, - "name": "typeD", - "namespaceType": "agnostic", - }, -] -`; diff --git a/src/core/server/saved_objects/index.ts b/src/core/server/saved_objects/index.ts index a294b28753f7b..f2bae29c4743b 100644 --- a/src/core/server/saved_objects/index.ts +++ b/src/core/server/saved_objects/index.ts @@ -19,8 +19,6 @@ export * from './service'; -export { SavedObjectsSchema } from './schema'; - export * from './import'; export { diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts index 4fc94d1992869..4cc4f696d307c 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts @@ -48,7 +48,6 @@ describe('DocumentMigrator', () => { return { kibanaVersion: '25.2.3', typeRegistry: createRegistry(), - validateDoc: _.noop, log: mockLogger, }; } @@ -60,7 +59,6 @@ describe('DocumentMigrator', () => { name: 'foo', migrations: _.noop as any, }), - validateDoc: _.noop, log: mockLogger, }; expect(() => new DocumentMigrator(invalidDefinition)).toThrow( @@ -77,7 +75,6 @@ describe('DocumentMigrator', () => { bar: (doc) => doc, }, }), - validateDoc: _.noop, log: mockLogger, }; expect(() => new DocumentMigrator(invalidDefinition)).toThrow( @@ -94,7 +91,6 @@ describe('DocumentMigrator', () => { '1.2.3': 23 as any, }, }), - validateDoc: _.noop, log: mockLogger, }; expect(() => new DocumentMigrator(invalidDefinition)).toThrow( @@ -633,27 +629,6 @@ describe('DocumentMigrator', () => { bbb: '3.2.3', }); }); - - test('fails if the validate doc throws', () => { - const migrator = new DocumentMigrator({ - ...testOpts(), - typeRegistry: createRegistry({ - name: 'aaa', - migrations: { - '2.3.4': (d) => set(d, 'attributes.counter', 42), - }, - }), - validateDoc: (d) => { - if ((d.attributes as any).counter === 42) { - throw new Error('Meaningful!'); - } - }, - }); - - const doc = { id: '1', type: 'foo', attributes: {}, migrationVersion: {}, aaa: {} }; - - expect(() => migrator.migrate(doc)).toThrow(/Meaningful/); - }); }); function renameAttr(path: string, newPath: string) { diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.ts b/src/core/server/saved_objects/migrations/core/document_migrator.ts index c50f755fda994..345704fbfd783 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -73,12 +73,9 @@ import { SavedObjectMigrationFn } from '../types'; export type TransformFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc; -type ValidateDoc = (doc: SavedObjectUnsanitizedDoc) => void; - interface DocumentMigratorOptions { kibanaVersion: string; typeRegistry: ISavedObjectTypeRegistry; - validateDoc: ValidateDoc; log: Logger; } @@ -113,19 +110,16 @@ export class DocumentMigrator implements VersionedTransformer { * @param {DocumentMigratorOptions} opts * @prop {string} kibanaVersion - The current version of Kibana * @prop {SavedObjectTypeRegistry} typeRegistry - The type registry to get type migrations from - * @prop {ValidateDoc} validateDoc - A function which, given a document throws an error if it is - * not up to date. This is used to ensure we don't let unmigrated documents slip through. * @prop {Logger} log - The migration logger * @memberof DocumentMigrator */ - constructor({ typeRegistry, kibanaVersion, log, validateDoc }: DocumentMigratorOptions) { + constructor({ typeRegistry, kibanaVersion, log }: DocumentMigratorOptions) { validateMigrationDefinition(typeRegistry); this.migrations = buildActiveMigrations(typeRegistry, log); this.transformDoc = buildDocumentTransform({ kibanaVersion, migrations: this.migrations, - validateDoc, }); } @@ -231,21 +225,16 @@ function buildActiveMigrations( * Creates a function which migrates and validates any document that is passed to it. */ function buildDocumentTransform({ - kibanaVersion, migrations, - validateDoc, }: { kibanaVersion: string; migrations: ActiveMigrations; - validateDoc: ValidateDoc; }): TransformFn { return function transformAndValidate(doc: SavedObjectUnsanitizedDoc) { const result = doc.migrationVersion ? applyMigrations(doc, migrations) : markAsUpToDate(doc, migrations); - validateDoc(result); - // In order to keep tests a bit more stable, we won't // tack on an empy migrationVersion to docs that have // no migrations defined. diff --git a/src/core/server/saved_objects/migrations/core/index_migrator.test.ts b/src/core/server/saved_objects/migrations/core/index_migrator.test.ts index df89137a1d798..13f771c16bc67 100644 --- a/src/core/server/saved_objects/migrations/core/index_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/core/index_migrator.test.ts @@ -369,6 +369,30 @@ describe('IndexMigrator', () => { ], }); }); + + test('rejects when the migration function throws an error', async () => { + const { client } = testOpts; + const migrateDoc = jest.fn((doc: SavedObjectUnsanitizedDoc) => { + throw new Error('error migrating document'); + }); + + testOpts.documentMigrator = { + migrationVersion: { foo: '1.2.3' }, + migrate: migrateDoc, + }; + + withIndex(client, { + numOutOfDate: 1, + docs: [ + [{ _id: 'foo:1', _source: { type: 'foo', foo: { name: 'Bar' } } }], + [{ _id: 'foo:2', _source: { type: 'foo', foo: { name: 'Baz' } } }], + ], + }); + + await expect(new IndexMigrator(testOpts).migrate()).rejects.toThrowErrorMatchingInlineSnapshot( + `"error migrating document"` + ); + }); }); function withIndex( diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts index 4c9d2e870a7bb..83dc042d2b96b 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.test.ts @@ -90,4 +90,18 @@ describe('migrateRawDocs', () => { expect(logger.error).toBeCalledTimes(1); }); + + test('rejects when the transform function throws an error', async () => { + const transform = jest.fn((doc: any) => { + throw new Error('error during transform'); + }); + await expect( + migrateRawDocs( + new SavedObjectsSerializer(new SavedObjectTypeRegistry()), + transform, + [{ _id: 'a:b', _source: { type: 'a', a: { name: 'AAA' } } }], + createSavedObjectsMigrationLoggerMock() + ) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"error during transform"`); + }); }); diff --git a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts index 2bdf59d25dc74..5a5048d8ad88f 100644 --- a/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/core/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -78,10 +78,14 @@ function transformNonBlocking( ): (doc: SavedObjectUnsanitizedDoc) => Promise { // promises aren't enough to unblock the event loop return (doc: SavedObjectUnsanitizedDoc) => - new Promise((resolve) => { + new Promise((resolve, reject) => { // set immediate is though setImmediate(() => { - resolve(transform(doc)); + try { + resolve(transform(doc)); + } catch (e) { + reject(e); + } }); }); } diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts index cc443093e30a3..7eb2cfefe4620 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts @@ -134,7 +134,6 @@ const mockOptions = () => { const options: MockedOptions = { logger: loggingSystemMock.create().get(), kibanaVersion: '8.2.3', - savedObjectValidations: {}, typeRegistry: createRegistry([ { name: 'testtype', diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index 85b9099308807..18a385c6994b8 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -28,7 +28,6 @@ import { BehaviorSubject } from 'rxjs'; import { Logger } from '../../../logging'; import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings'; import { SavedObjectUnsanitizedDoc, SavedObjectsSerializer } from '../../serialization'; -import { docValidator, PropertyValidators } from '../../validation'; import { buildActiveMappings, IndexMigrator, MigrationResult, MigrationStatus } from '../core'; import { DocumentMigrator, VersionedTransformer } from '../core/document_migrator'; import { MigrationEsClient } from '../core/'; @@ -44,7 +43,6 @@ export interface KibanaMigratorOptions { kibanaConfig: KibanaConfigType; kibanaVersion: string; logger: Logger; - savedObjectValidations: PropertyValidators; } export type IKibanaMigrator = Pick; @@ -80,7 +78,6 @@ export class KibanaMigrator { typeRegistry, kibanaConfig, savedObjectsConfig, - savedObjectValidations, kibanaVersion, logger, }: KibanaMigratorOptions) { @@ -94,7 +91,6 @@ export class KibanaMigrator { this.documentMigrator = new DocumentMigrator({ kibanaVersion, typeRegistry, - validateDoc: docValidator(savedObjectValidations || {}), log: this.log, }); // Building the active mappings (and associated md5sums) is an expensive @@ -124,9 +120,17 @@ export class KibanaMigrator { Array<{ status: string }> > { if (this.migrationResult === undefined || rerun) { - this.status$.next({ status: 'running' }); + // Reruns are only used by CI / EsArchiver. Publishing status updates on reruns results in slowing down CI + // unnecessarily, so we skip it in this case. + if (!rerun) { + this.status$.next({ status: 'running' }); + } + this.migrationResult = this.runMigrationsInternal().then((result) => { - this.status$.next({ status: 'completed', result }); + // Similar to above, don't publish status updates when rerunning in CI. + if (!rerun) { + this.status$.next({ status: 'completed', result }); + } return result; }); } diff --git a/src/core/server/saved_objects/saved_objects_service.mock.ts b/src/core/server/saved_objects/saved_objects_service.mock.ts index 6f5ecb1eb464b..e3d44c20dd190 100644 --- a/src/core/server/saved_objects/saved_objects_service.mock.ts +++ b/src/core/server/saved_objects/saved_objects_service.mock.ts @@ -26,8 +26,7 @@ import { SavedObjectsServiceSetup, SavedObjectsServiceStart, } from './saved_objects_service'; -import { mockKibanaMigrator } from './migrations/kibana/kibana_migrator.mock'; -import { savedObjectsClientProviderMock } from './service/lib/scoped_client_provider.mock'; + import { savedObjectsRepositoryMock } from './service/lib/repository.mock'; import { savedObjectsClientMock } from './service/saved_objects_client.mock'; import { typeRegistryMock } from './saved_objects_type_registry.mock'; @@ -54,11 +53,7 @@ const createStartContractMock = () => { }; const createInternalStartContractMock = () => { - const internalStartContract: jest.Mocked = { - ...createStartContractMock(), - clientProvider: savedObjectsClientProviderMock.create(), - migrator: mockKibanaMigrator.create(), - }; + const internalStartContract: jest.Mocked = createStartContractMock(); return internalStartContract; }; diff --git a/src/core/server/saved_objects/saved_objects_service.test.ts b/src/core/server/saved_objects/saved_objects_service.test.ts index 8df6a07318c45..d6b30889eba5f 100644 --- a/src/core/server/saved_objects/saved_objects_service.test.ts +++ b/src/core/server/saved_objects/saved_objects_service.test.ts @@ -33,7 +33,6 @@ import { Env } from '../config'; import { configServiceMock } from '../mocks'; import { elasticsearchServiceMock } from '../elasticsearch/elasticsearch_service.mock'; import { elasticsearchClientMock } from '../elasticsearch/client/mocks'; -import { legacyServiceMock } from '../legacy/legacy_service.mock'; import { httpServiceMock } from '../http/http_service.mock'; import { httpServerMock } from '../http/http_server.mocks'; import { SavedObjectsClientFactoryProvider } from './service/lib'; @@ -65,7 +64,6 @@ describe('SavedObjectsService', () => { return { http: httpServiceMock.createInternalSetupContract(), elasticsearch: elasticsearchMock, - legacyPlugins: legacyServiceMock.createDiscoverPlugins(), }; }; @@ -239,8 +237,7 @@ describe('SavedObjectsService', () => { await soService.setup(createSetupDeps()); expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(0); - const startContract = await soService.start(createStartDeps()); - expect(startContract.migrator).toBe(migratorInstanceMock); + await soService.start(createStartDeps()); expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1); }); diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index f05e912b12ad8..5cc59d55a254e 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -23,12 +23,10 @@ import { CoreService } from '../../types'; import { SavedObjectsClient, SavedObjectsClientProvider, - ISavedObjectsClientProvider, SavedObjectsClientProviderOptions, } from './'; import { KibanaMigrator, IKibanaMigrator } from './migrations'; import { CoreContext } from '../core_context'; -import { LegacyServiceDiscoverPlugins } from '../legacy'; import { ElasticsearchClient, IClusterClient, @@ -49,9 +47,7 @@ import { SavedObjectsClientWrapperFactory, } from './service/lib/scoped_client_provider'; import { Logger } from '../logging'; -import { convertLegacyTypes } from './utils'; import { SavedObjectTypeRegistry, ISavedObjectTypeRegistry } from './saved_objects_type_registry'; -import { PropertyValidators } from './validation'; import { SavedObjectsSerializer } from './serialization'; import { registerRoutes } from './routes'; import { ServiceStatus } from '../status'; @@ -67,9 +63,6 @@ import { createMigrationEsClient } from './migrations/core/'; * the factory provided to `setClientFactory` and wrapped by all wrappers * registered through `addClientWrapper`. * - * All the setup APIs will throw if called after the service has started, and therefor cannot be used - * from legacy plugin code. Legacy plugins should use the legacy savedObject service until migrated. - * * @example * ```ts * import { SavedObjectsClient, CoreSetup } from 'src/core/server'; @@ -155,9 +148,6 @@ export interface SavedObjectsServiceSetup { * } * } * ``` - * - * @remarks The type definition is an aggregation of the legacy savedObjects `schema`, `mappings` and `migration` concepts. - * This API is the single entry point to register saved object types in the new platform. */ registerType: (type: SavedObjectsType) => void; @@ -230,16 +220,7 @@ export interface SavedObjectsServiceStart { getTypeRegistry: () => ISavedObjectTypeRegistry; } -export interface InternalSavedObjectsServiceStart extends SavedObjectsServiceStart { - /** - * @deprecated Exposed only for injecting into Legacy - */ - migrator: IKibanaMigrator; - /** - * @deprecated Exposed only for injecting into Legacy - */ - clientProvider: ISavedObjectsClientProvider; -} +export type InternalSavedObjectsServiceStart = SavedObjectsServiceStart; /** * Factory provided when invoking a {@link SavedObjectsClientFactoryProvider | client factory provider} @@ -271,7 +252,6 @@ export interface SavedObjectsRepositoryFactory { /** @internal */ export interface SavedObjectsSetupDeps { http: InternalHttpServiceSetup; - legacyPlugins: LegacyServiceDiscoverPlugins; elasticsearch: InternalElasticsearchServiceSetup; } @@ -296,9 +276,8 @@ export class SavedObjectsService private clientFactoryProvider?: SavedObjectsClientFactoryProvider; private clientFactoryWrappers: WrappedClientFactoryWrapper[] = []; - private migrator$ = new Subject(); + private migrator$ = new Subject(); private typeRegistry = new SavedObjectTypeRegistry(); - private validations: PropertyValidators = {}; private started = false; constructor(private readonly coreContext: CoreContext) { @@ -310,13 +289,6 @@ export class SavedObjectsService this.setupDeps = setupDeps; - const legacyTypes = convertLegacyTypes( - setupDeps.legacyPlugins.uiExports, - setupDeps.legacyPlugins.pluginExtendedConfig - ); - legacyTypes.forEach((type) => this.typeRegistry.registerType(type)); - this.validations = setupDeps.legacyPlugins.uiExports.savedObjectValidations || {}; - const savedObjectsConfig = await this.coreContext.configService .atPath('savedObjects') .pipe(first()) @@ -471,8 +443,6 @@ export class SavedObjectsService this.started = true; return { - migrator, - clientProvider, getScopedClient: clientProvider.getClient.bind(clientProvider), createScopedRepository: repositoryFactory.createScopedRepository, createInternalRepository: repositoryFactory.createInternalRepository, @@ -488,13 +458,12 @@ export class SavedObjectsService savedObjectsConfig: SavedObjectsMigrationConfigType, client: IClusterClient, migrationsRetryDelay?: number - ): KibanaMigrator { + ): IKibanaMigrator { return new KibanaMigrator({ typeRegistry: this.typeRegistry, logger: this.logger, kibanaVersion: this.coreContext.env.packageInfo.version, savedObjectsConfig, - savedObjectValidations: this.validations, kibanaConfig, client: createMigrationEsClient(client.asInternalUser, this.logger, migrationsRetryDelay), }); diff --git a/src/core/server/saved_objects/schema/schema.test.ts b/src/core/server/saved_objects/schema/schema.test.ts deleted file mode 100644 index f2daa13e43fce..0000000000000 --- a/src/core/server/saved_objects/schema/schema.test.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { SavedObjectsSchema, SavedObjectsSchemaDefinition } from './schema'; - -describe('#isNamespaceAgnostic', () => { - const expectResult = (expected: boolean, schemaDefinition?: SavedObjectsSchemaDefinition) => { - const schema = new SavedObjectsSchema(schemaDefinition); - const result = schema.isNamespaceAgnostic('foo'); - expect(result).toBe(expected); - }; - - it(`returns false when no schema is defined`, () => { - expectResult(false); - }); - - it(`returns false for unknown types`, () => { - expectResult(false, { bar: {} }); - }); - - it(`returns false for non-namespace-agnostic type`, () => { - expectResult(false, { foo: { isNamespaceAgnostic: false } }); - expectResult(false, { foo: { isNamespaceAgnostic: undefined } }); - }); - - it(`returns true for explicitly namespace-agnostic type`, () => { - expectResult(true, { foo: { isNamespaceAgnostic: true } }); - }); -}); - -describe('#isSingleNamespace', () => { - const expectResult = (expected: boolean, schemaDefinition?: SavedObjectsSchemaDefinition) => { - const schema = new SavedObjectsSchema(schemaDefinition); - const result = schema.isSingleNamespace('foo'); - expect(result).toBe(expected); - }; - - it(`returns true when no schema is defined`, () => { - expectResult(true); - }); - - it(`returns true for unknown types`, () => { - expectResult(true, { bar: {} }); - }); - - it(`returns false for explicitly namespace-agnostic type`, () => { - expectResult(false, { foo: { isNamespaceAgnostic: true } }); - }); - - it(`returns false for explicitly multi-namespace type`, () => { - expectResult(false, { foo: { multiNamespace: true } }); - }); - - it(`returns true for non-namespace-agnostic and non-multi-namespace type`, () => { - expectResult(true, { foo: { isNamespaceAgnostic: false, multiNamespace: false } }); - expectResult(true, { foo: { isNamespaceAgnostic: false, multiNamespace: undefined } }); - expectResult(true, { foo: { isNamespaceAgnostic: undefined, multiNamespace: false } }); - expectResult(true, { foo: { isNamespaceAgnostic: undefined, multiNamespace: undefined } }); - }); -}); - -describe('#isMultiNamespace', () => { - const expectResult = (expected: boolean, schemaDefinition?: SavedObjectsSchemaDefinition) => { - const schema = new SavedObjectsSchema(schemaDefinition); - const result = schema.isMultiNamespace('foo'); - expect(result).toBe(expected); - }; - - it(`returns false when no schema is defined`, () => { - expectResult(false); - }); - - it(`returns false for unknown types`, () => { - expectResult(false, { bar: {} }); - }); - - it(`returns false for explicitly namespace-agnostic type`, () => { - expectResult(false, { foo: { isNamespaceAgnostic: true } }); - }); - - it(`returns false for non-multi-namespace type`, () => { - expectResult(false, { foo: { multiNamespace: false } }); - expectResult(false, { foo: { multiNamespace: undefined } }); - }); - - it(`returns true for non-namespace-agnostic and explicitly multi-namespace type`, () => { - expectResult(true, { foo: { isNamespaceAgnostic: false, multiNamespace: true } }); - expectResult(true, { foo: { isNamespaceAgnostic: undefined, multiNamespace: true } }); - }); -}); diff --git a/src/core/server/saved_objects/schema/schema.ts b/src/core/server/saved_objects/schema/schema.ts deleted file mode 100644 index ba1905158e822..0000000000000 --- a/src/core/server/saved_objects/schema/schema.ts +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { LegacyConfig } from '../../legacy'; - -/** - * @deprecated - * @internal - **/ -interface SavedObjectsSchemaTypeDefinition { - isNamespaceAgnostic?: boolean; - multiNamespace?: boolean; - hidden?: boolean; - indexPattern?: ((config: LegacyConfig) => string) | string; - convertToAliasScript?: string; -} - -/** - * @deprecated - * @internal - **/ -export interface SavedObjectsSchemaDefinition { - [type: string]: SavedObjectsSchemaTypeDefinition; -} - -/** - * @deprecated This is only used by the {@link SavedObjectsLegacyService | legacy savedObjects service} - * @internal - **/ -export class SavedObjectsSchema { - private readonly definition?: SavedObjectsSchemaDefinition; - constructor(schemaDefinition?: SavedObjectsSchemaDefinition) { - this.definition = schemaDefinition; - } - - public isHiddenType(type: string) { - if (this.definition && this.definition.hasOwnProperty(type)) { - return Boolean(this.definition[type].hidden); - } - - return false; - } - - public getIndexForType(config: LegacyConfig, type: string): string | undefined { - if (this.definition != null && this.definition.hasOwnProperty(type)) { - const { indexPattern } = this.definition[type]; - return typeof indexPattern === 'function' ? indexPattern(config) : indexPattern; - } else { - return undefined; - } - } - - public getConvertToAliasScript(type: string): string | undefined { - if (this.definition != null && this.definition.hasOwnProperty(type)) { - return this.definition[type].convertToAliasScript; - } - } - - public isNamespaceAgnostic(type: string) { - // if no plugins have registered a Saved Objects Schema, - // this.schema will be undefined, and no types are namespace agnostic - if (!this.definition) { - return false; - } - - const typeSchema = this.definition[type]; - if (!typeSchema) { - return false; - } - return Boolean(typeSchema.isNamespaceAgnostic); - } - - public isSingleNamespace(type: string) { - // if no plugins have registered a Saved Objects Schema, - // this.schema will be undefined, and all types are namespace isolated - if (!this.definition) { - return true; - } - - const typeSchema = this.definition[type]; - if (!typeSchema) { - return true; - } - return !Boolean(typeSchema.isNamespaceAgnostic) && !Boolean(typeSchema.multiNamespace); - } - - public isMultiNamespace(type: string) { - // if no plugins have registered a Saved Objects Schema, - // this.schema will be undefined, and no types are multi-namespace - if (!this.definition) { - return false; - } - - const typeSchema = this.definition[type]; - if (!typeSchema) { - return false; - } - return !Boolean(typeSchema.isNamespaceAgnostic) && Boolean(typeSchema.multiNamespace); - } -} diff --git a/src/core/server/saved_objects/service/index.ts b/src/core/server/saved_objects/service/index.ts index 9f625b4732e26..271d4dd67d43e 100644 --- a/src/core/server/saved_objects/service/index.ts +++ b/src/core/server/saved_objects/service/index.ts @@ -17,37 +17,6 @@ * under the License. */ -import { Readable } from 'stream'; -import { SavedObjectsClientProvider } from './lib'; -import { SavedObjectsClient } from './saved_objects_client'; -import { SavedObjectsExportOptions } from '../export'; -import { SavedObjectsImportOptions, SavedObjectsImportResponse } from '../import'; -import { SavedObjectsSchema } from '../schema'; -import { SavedObjectsResolveImportErrorsOptions } from '../import/types'; - -/** - * @internal - * @deprecated - */ -export interface SavedObjectsLegacyService { - // ATTENTION: these types are incomplete - addScopedSavedObjectsClientWrapperFactory: SavedObjectsClientProvider['addClientWrapperFactory']; - setScopedSavedObjectsClientFactory: SavedObjectsClientProvider['setClientFactory']; - getScopedSavedObjectsClient: SavedObjectsClientProvider['getClient']; - SavedObjectsClient: typeof SavedObjectsClient; - types: string[]; - schema: SavedObjectsSchema; - getSavedObjectsRepository(...rest: any[]): any; - importExport: { - objectLimit: number; - importSavedObjects(options: SavedObjectsImportOptions): Promise; - resolveImportErrors( - options: SavedObjectsResolveImportErrorsOptions - ): Promise; - getSortedObjectsForExport(options: SavedObjectsExportOptions): Promise; - }; -} - export { SavedObjectsRepository, SavedObjectsClientProvider, diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js index b1d6028465713..f2e3b3e633cd6 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.js +++ b/src/core/server/saved_objects/service/lib/repository.test.js @@ -153,7 +153,6 @@ describe('SavedObjectsRepository', () => { typeRegistry: registry, kibanaVersion: '2.0.0', log: {}, - validateDoc: jest.fn(), }); const getMockGetResponse = ({ type, id, references, namespace, originId }) => ({ diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index dd25989725f3e..e3fb7d2306469 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -31,7 +31,7 @@ import { getSearchDsl } from './search_dsl'; import { includedFields } from './included_fields'; import { SavedObjectsErrorHelpers, DecoratedError } from './errors'; import { decodeRequestVersion, encodeVersion, encodeHitVersion } from '../../version'; -import { KibanaMigrator } from '../../migrations'; +import { IKibanaMigrator } from '../../migrations'; import { SavedObjectsSerializer, SavedObjectSanitizedDoc, @@ -85,7 +85,7 @@ export interface SavedObjectsRepositoryOptions { client: ElasticsearchClient; typeRegistry: SavedObjectTypeRegistry; serializer: SavedObjectsSerializer; - migrator: KibanaMigrator; + migrator: IKibanaMigrator; allowedTypes: string[]; } @@ -120,7 +120,7 @@ export type ISavedObjectsRepository = Pick) => { path: string; uiCapabilitiesPath: string }; } - -/** - * @internal - * @deprecated - */ -export interface SavedObjectsLegacyUiExports { - savedObjectMappings: SavedObjectsLegacyMapping[]; - savedObjectMigrations: SavedObjectsLegacyMigrationDefinitions; - savedObjectSchemas: SavedObjectsLegacySchemaDefinitions; - savedObjectValidations: PropertyValidators; - savedObjectsManagement: SavedObjectsLegacyManagementDefinition; -} - -/** - * @internal - * @deprecated - */ -export interface SavedObjectsLegacyMapping { - pluginId: string; - properties: SavedObjectsTypeMappingDefinitions; -} - -/** - * @internal - * @deprecated Use {@link SavedObjectsTypeManagementDefinition | management definition} when registering - * from new platform plugins - */ -export interface SavedObjectsLegacyManagementDefinition { - [key: string]: SavedObjectsLegacyManagementTypeDefinition; -} - -/** - * @internal - * @deprecated - */ -export interface SavedObjectsLegacyManagementTypeDefinition { - isImportableAndExportable?: boolean; - defaultSearchField?: string; - icon?: string; - getTitle?: (savedObject: SavedObject) => string; - getEditUrl?: (savedObject: SavedObject) => string; - getInAppUrl?: (savedObject: SavedObject) => { path: string; uiCapabilitiesPath: string }; -} - -/** - * @internal - * @deprecated - */ -export interface SavedObjectsLegacyMigrationDefinitions { - [type: string]: SavedObjectLegacyMigrationMap; -} - -/** - * @internal - * @deprecated - */ -export interface SavedObjectLegacyMigrationMap { - [version: string]: SavedObjectLegacyMigrationFn; -} - -/** - * @internal - * @deprecated - */ -export type SavedObjectLegacyMigrationFn = ( - doc: SavedObjectUnsanitizedDoc, - log: SavedObjectsMigrationLogger -) => SavedObjectUnsanitizedDoc; - -/** - * @internal - * @deprecated - */ -interface SavedObjectsLegacyTypeSchema { - isNamespaceAgnostic?: boolean; - /** Cannot be used in conjunction with `isNamespaceAgnostic` */ - multiNamespace?: boolean; - hidden?: boolean; - indexPattern?: ((config: LegacyConfig) => string) | string; - convertToAliasScript?: string; -} - -/** - * @internal - * @deprecated - */ -export interface SavedObjectsLegacySchemaDefinitions { - [type: string]: SavedObjectsLegacyTypeSchema; -} diff --git a/src/core/server/saved_objects/utils.test.ts b/src/core/server/saved_objects/utils.test.ts deleted file mode 100644 index 21229bee489c2..0000000000000 --- a/src/core/server/saved_objects/utils.test.ts +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { legacyServiceMock } from '../legacy/legacy_service.mock'; -import { convertLegacyTypes, convertTypesToLegacySchema } from './utils'; -import { SavedObjectsLegacyUiExports, SavedObjectsType } from './types'; -import { LegacyConfig, SavedObjectMigrationContext } from 'kibana/server'; -import { SavedObjectUnsanitizedDoc } from './serialization'; - -describe('convertLegacyTypes', () => { - let legacyConfig: ReturnType; - - beforeEach(() => { - legacyConfig = legacyServiceMock.createLegacyConfig(); - }); - - it('converts the legacy mappings using default values if no schemas are specified', () => { - const uiExports: SavedObjectsLegacyUiExports = { - savedObjectMappings: [ - { - pluginId: 'pluginA', - properties: { - typeA: { - properties: { - fieldA: { type: 'text' }, - }, - }, - typeB: { - properties: { - fieldB: { type: 'text' }, - }, - }, - }, - }, - { - pluginId: 'pluginB', - properties: { - typeC: { - properties: { - fieldC: { type: 'text' }, - }, - }, - }, - }, - ], - savedObjectMigrations: {}, - savedObjectSchemas: {}, - savedObjectValidations: {}, - savedObjectsManagement: {}, - }; - - const converted = convertLegacyTypes(uiExports, legacyConfig); - expect(converted).toMatchSnapshot(); - }); - - it('merges the mappings and the schema to create the type when schema exists for the type', () => { - const uiExports: SavedObjectsLegacyUiExports = { - savedObjectMappings: [ - { - pluginId: 'pluginA', - properties: { - typeA: { - properties: { - fieldA: { type: 'text' }, - }, - }, - }, - }, - { - pluginId: 'pluginB', - properties: { - typeB: { - properties: { - fieldB: { type: 'text' }, - }, - }, - }, - }, - { - pluginId: 'pluginC', - properties: { - typeC: { - properties: { - fieldC: { type: 'text' }, - }, - }, - }, - }, - { - pluginId: 'pluginD', - properties: { - typeD: { - properties: { - fieldD: { type: 'text' }, - }, - }, - }, - }, - ], - savedObjectMigrations: {}, - savedObjectSchemas: { - typeA: { - indexPattern: 'fooBar', - hidden: true, - isNamespaceAgnostic: true, - }, - typeB: { - indexPattern: 'barBaz', - hidden: false, - multiNamespace: true, - }, - typeD: { - indexPattern: 'bazQux', - hidden: false, - // if both isNamespaceAgnostic and multiNamespace are true, the resulting namespaceType is 'agnostic' - isNamespaceAgnostic: true, - multiNamespace: true, - }, - }, - savedObjectValidations: {}, - savedObjectsManagement: {}, - }; - - const converted = convertLegacyTypes(uiExports, legacyConfig); - expect(converted).toMatchSnapshot(); - }); - - it('invokes indexPattern to retrieve the index when it is a function', () => { - const indexPatternAccessor: (config: LegacyConfig) => string = jest.fn((config) => { - config.get('foo.bar'); - return 'myIndex'; - }); - - const uiExports: SavedObjectsLegacyUiExports = { - savedObjectMappings: [ - { - pluginId: 'pluginA', - properties: { - typeA: { - properties: { - fieldA: { type: 'text' }, - }, - }, - }, - }, - ], - savedObjectMigrations: {}, - savedObjectSchemas: { - typeA: { - indexPattern: indexPatternAccessor, - hidden: true, - isNamespaceAgnostic: true, - }, - }, - savedObjectValidations: {}, - savedObjectsManagement: {}, - }; - - const converted = convertLegacyTypes(uiExports, legacyConfig); - - expect(indexPatternAccessor).toHaveBeenCalledWith(legacyConfig); - expect(legacyConfig.get).toHaveBeenCalledWith('foo.bar'); - expect(converted.length).toEqual(1); - expect(converted[0].indexPattern).toEqual('myIndex'); - }); - - it('import migrations from the uiExports', () => { - const migrationsA = { - '1.0.0': jest.fn(), - '2.0.4': jest.fn(), - }; - const migrationsB = { - '1.5.3': jest.fn(), - }; - - const uiExports: SavedObjectsLegacyUiExports = { - savedObjectMappings: [ - { - pluginId: 'pluginA', - properties: { - typeA: { - properties: { - fieldA: { type: 'text' }, - }, - }, - }, - }, - { - pluginId: 'pluginB', - properties: { - typeB: { - properties: { - fieldC: { type: 'text' }, - }, - }, - }, - }, - ], - savedObjectMigrations: { - typeA: migrationsA, - typeB: migrationsB, - }, - savedObjectSchemas: {}, - savedObjectValidations: {}, - savedObjectsManagement: {}, - }; - - const converted = convertLegacyTypes(uiExports, legacyConfig); - expect(converted.length).toEqual(2); - expect(Object.keys(converted[0]!.migrations!)).toEqual(Object.keys(migrationsA)); - expect(Object.keys(converted[1]!.migrations!)).toEqual(Object.keys(migrationsB)); - }); - - it('converts the migration to the new format', () => { - const legacyMigration = jest.fn(); - const migrationsA = { - '1.0.0': legacyMigration, - }; - - const uiExports: SavedObjectsLegacyUiExports = { - savedObjectMappings: [ - { - pluginId: 'pluginA', - properties: { - typeA: { - properties: { - fieldA: { type: 'text' }, - }, - }, - }, - }, - ], - savedObjectMigrations: { - typeA: migrationsA, - }, - savedObjectSchemas: {}, - savedObjectValidations: {}, - savedObjectsManagement: {}, - }; - - const converted = convertLegacyTypes(uiExports, legacyConfig); - expect(Object.keys(converted[0]!.migrations!)).toEqual(['1.0.0']); - - const migration = converted[0]!.migrations!['1.0.0']!; - - const doc = {} as SavedObjectUnsanitizedDoc; - const context = { log: {} } as SavedObjectMigrationContext; - migration(doc, context); - - expect(legacyMigration).toHaveBeenCalledTimes(1); - expect(legacyMigration).toHaveBeenCalledWith(doc, context.log); - }); - - it('imports type management information', () => { - const uiExports: SavedObjectsLegacyUiExports = { - savedObjectMappings: [ - { - pluginId: 'pluginA', - properties: { - typeA: { - properties: { - fieldA: { type: 'text' }, - }, - }, - }, - }, - { - pluginId: 'pluginB', - properties: { - typeB: { - properties: { - fieldB: { type: 'text' }, - }, - }, - typeC: { - properties: { - fieldC: { type: 'text' }, - }, - }, - }, - }, - ], - savedObjectsManagement: { - typeA: { - isImportableAndExportable: true, - icon: 'iconA', - defaultSearchField: 'searchFieldA', - getTitle: (savedObject) => savedObject.id, - }, - typeB: { - isImportableAndExportable: false, - icon: 'iconB', - getEditUrl: (savedObject) => `/some-url/${savedObject.id}`, - getInAppUrl: (savedObject) => ({ path: 'path', uiCapabilitiesPath: 'ui-path' }), - }, - }, - savedObjectMigrations: {}, - savedObjectSchemas: {}, - savedObjectValidations: {}, - }; - - const converted = convertLegacyTypes(uiExports, legacyConfig); - expect(converted.length).toEqual(3); - const [typeA, typeB, typeC] = converted; - - expect(typeA.management).toEqual({ - importableAndExportable: true, - icon: 'iconA', - defaultSearchField: 'searchFieldA', - getTitle: uiExports.savedObjectsManagement.typeA.getTitle, - }); - - expect(typeB.management).toEqual({ - importableAndExportable: false, - icon: 'iconB', - getEditUrl: uiExports.savedObjectsManagement.typeB.getEditUrl, - getInAppUrl: uiExports.savedObjectsManagement.typeB.getInAppUrl, - }); - - expect(typeC.management).toBeUndefined(); - }); - - it('merges everything when all are present', () => { - const uiExports: SavedObjectsLegacyUiExports = { - savedObjectMappings: [ - { - pluginId: 'pluginA', - properties: { - typeA: { - properties: { - fieldA: { type: 'text' }, - }, - }, - typeB: { - properties: { - fieldB: { type: 'text' }, - anotherFieldB: { type: 'boolean' }, - }, - }, - }, - }, - { - pluginId: 'pluginB', - properties: { - typeC: { - properties: { - fieldC: { type: 'text' }, - }, - }, - }, - }, - ], - savedObjectMigrations: { - typeA: { - '1.0.0': jest.fn(), - '2.0.4': jest.fn(), - }, - typeC: { - '1.5.3': jest.fn(), - }, - }, - savedObjectSchemas: { - typeA: { - indexPattern: jest.fn((config) => { - config.get('foo.bar'); - return 'myIndex'; - }), - hidden: true, - isNamespaceAgnostic: true, - }, - typeB: { - convertToAliasScript: 'some alias script', - hidden: false, - }, - }, - savedObjectValidations: {}, - savedObjectsManagement: {}, - }; - - const converted = convertLegacyTypes(uiExports, legacyConfig); - expect(converted).toMatchSnapshot(); - }); -}); - -describe('convertTypesToLegacySchema', () => { - it('converts types to the legacy schema format', () => { - const types: SavedObjectsType[] = [ - { - name: 'typeA', - hidden: false, - namespaceType: 'agnostic', - mappings: { properties: {} }, - convertToAliasScript: 'some script', - }, - { - name: 'typeB', - hidden: true, - namespaceType: 'single', - indexPattern: 'myIndex', - mappings: { properties: {} }, - }, - { - name: 'typeC', - hidden: false, - namespaceType: 'multiple', - mappings: { properties: {} }, - }, - ]; - expect(convertTypesToLegacySchema(types)).toEqual({ - typeA: { - hidden: false, - isNamespaceAgnostic: true, - multiNamespace: false, - convertToAliasScript: 'some script', - }, - typeB: { - hidden: true, - isNamespaceAgnostic: false, - multiNamespace: false, - indexPattern: 'myIndex', - }, - typeC: { - hidden: false, - isNamespaceAgnostic: false, - multiNamespace: true, - }, - }); - }); -}); diff --git a/src/core/server/saved_objects/utils.ts b/src/core/server/saved_objects/utils.ts deleted file mode 100644 index af7c08d1fbfcc..0000000000000 --- a/src/core/server/saved_objects/utils.ts +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { LegacyConfig } from '../legacy'; -import { SavedObjectMigrationMap } from './migrations'; -import { - SavedObjectsNamespaceType, - SavedObjectsType, - SavedObjectsLegacyUiExports, - SavedObjectLegacyMigrationMap, - SavedObjectsLegacyManagementTypeDefinition, - SavedObjectsTypeManagementDefinition, -} from './types'; -import { SavedObjectsSchemaDefinition } from './schema'; - -/** - * Converts the legacy savedObjects mappings, schema, and migrations - * to actual {@link SavedObjectsType | saved object types} - */ -export const convertLegacyTypes = ( - { - savedObjectMappings = [], - savedObjectMigrations = {}, - savedObjectSchemas = {}, - savedObjectsManagement = {}, - }: SavedObjectsLegacyUiExports, - legacyConfig: LegacyConfig -): SavedObjectsType[] => { - return savedObjectMappings.reduce((types, { properties }) => { - return [ - ...types, - ...Object.entries(properties).map(([type, mappings]) => { - const schema = savedObjectSchemas[type]; - const migrations = savedObjectMigrations[type]; - const management = savedObjectsManagement[type]; - const namespaceType = (schema?.isNamespaceAgnostic - ? 'agnostic' - : schema?.multiNamespace - ? 'multiple' - : 'single') as SavedObjectsNamespaceType; - return { - name: type, - hidden: schema?.hidden ?? false, - namespaceType, - mappings, - indexPattern: - typeof schema?.indexPattern === 'function' - ? schema.indexPattern(legacyConfig) - : schema?.indexPattern, - convertToAliasScript: schema?.convertToAliasScript, - migrations: convertLegacyMigrations(migrations ?? {}), - management: management ? convertLegacyTypeManagement(management) : undefined, - }; - }), - ]; - }, [] as SavedObjectsType[]); -}; - -/** - * Convert {@link SavedObjectsType | saved object types} to the legacy {@link SavedObjectsSchemaDefinition | schema} format - */ -export const convertTypesToLegacySchema = ( - types: SavedObjectsType[] -): SavedObjectsSchemaDefinition => { - return types.reduce((schema, type) => { - return { - ...schema, - [type.name]: { - isNamespaceAgnostic: type.namespaceType === 'agnostic', - multiNamespace: type.namespaceType === 'multiple', - hidden: type.hidden, - indexPattern: type.indexPattern, - convertToAliasScript: type.convertToAliasScript, - }, - }; - }, {} as SavedObjectsSchemaDefinition); -}; - -const convertLegacyMigrations = ( - legacyMigrations: SavedObjectLegacyMigrationMap -): SavedObjectMigrationMap => { - return Object.entries(legacyMigrations).reduce((migrated, [version, migrationFn]) => { - return { - ...migrated, - [version]: (doc, context) => migrationFn(doc, context.log), - }; - }, {} as SavedObjectMigrationMap); -}; - -const convertLegacyTypeManagement = ( - legacyTypeManagement: SavedObjectsLegacyManagementTypeDefinition -): SavedObjectsTypeManagementDefinition => { - return { - importableAndExportable: legacyTypeManagement.isImportableAndExportable, - defaultSearchField: legacyTypeManagement.defaultSearchField, - icon: legacyTypeManagement.icon, - getTitle: legacyTypeManagement.getTitle, - getEditUrl: legacyTypeManagement.getEditUrl, - getInAppUrl: legacyTypeManagement.getInAppUrl, - }; -}; diff --git a/src/core/server/saved_objects/validation/index.ts b/src/core/server/saved_objects/validation/index.ts deleted file mode 100644 index b1b33f91d3fd4..0000000000000 --- a/src/core/server/saved_objects/validation/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* - * This is the core logic for validating saved object properties. The saved object client - * and migrations consume this in order to validate saved object documents prior to - * persisting them. - */ - -interface SavedObjectDoc { - type: string; - [prop: string]: any; -} - -/** - * A dictionary of property name -> validation function. The property name - * is generally the document's type (e.g. "dashboard"), but will also - * match other properties. - * - * For example, the "acl" and "dashboard" validators both apply to the - * following saved object: { type: "dashboard", attributes: {}, acl: "sdlaj3w" } - * - * @export - * @interface Validators - */ -export interface PropertyValidators { - [prop: string]: ValidateDoc; -} - -export type ValidateDoc = (doc: SavedObjectDoc) => void; - -/** - * Creates a function which uses a dictionary of property validators to validate - * individual saved object documents. - * - * @export - * @param {Validators} validators - * @param {SavedObjectDoc} doc - */ -export function docValidator(validators: PropertyValidators = {}): ValidateDoc { - return function validateDoc(doc: SavedObjectDoc) { - Object.keys(doc) - .concat(doc.type) - .forEach((prop) => { - const validator = validators[prop]; - if (validator) { - validator(doc); - } - }); - }; -} diff --git a/src/core/server/saved_objects/validation/readme.md b/src/core/server/saved_objects/validation/readme.md deleted file mode 100644 index 3b9f17c37fd0b..0000000000000 --- a/src/core/server/saved_objects/validation/readme.md +++ /dev/null @@ -1,63 +0,0 @@ -# Saved Object Validations - -The saved object client supports validation of documents during create / bulkCreate operations. - -This allows us tighter control over what documents get written to the saved object index, and helps us keep the index in a healthy state. - -## Creating validations - -Plugin authors can write their own validations by adding a `validations` property to their uiExports. A validation is nothing more than a dictionary of `{[prop: string]: validationFunction}` where: - -* `prop` - a root-property on a saved object document -* `validationFunction` - a function that takes a document and throws an error if it does not meet expectations. - -## Example - -```js -// In myFanciPlugin... -uiExports: { - validations: { - myProperty(doc) { - if (doc.attributes.someField === undefined) { - throw new Error(`Document ${doc.id} did not define "someField"`); - } - }, - - someOtherProp(doc) { - if (doc.attributes.counter < 0) { - throw new Error(`Document ${doc.id} cannot have a negative counter.`); - } - }, - }, -}, -``` - -In this example, `myFanciPlugin` defines validations for two properties: `myProperty` and `someOtherProp`. - -This means that no other plugin can define validations for myProperty or someOtherProp. - -The `myProperty` validation would run for any doc that has a `type="myProperty"` or for any doc that has a root-level property of `myProperty`. e.g. it would apply to all documents in the following array: - -```js -[ - { - type: 'foo', - attributes: { stuff: 'here' }, - myProperty: 'shazm!', - }, - { - type: 'myProperty', - attributes: { shazm: true }, - }, -]; -``` - -Validating properties other than just 'type' allows us to support potential future saved object scenarios in which plugins might want to annotate other plugin documents, such as a security plugin adding an acl to another document: - -```js -{ - type: 'dashboard', - attributes: { stuff: 'here' }, - acl: '342343', -} -``` diff --git a/src/core/server/saved_objects/validation/validation.test.ts b/src/core/server/saved_objects/validation/validation.test.ts deleted file mode 100644 index 71e220280ba5f..0000000000000 --- a/src/core/server/saved_objects/validation/validation.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { docValidator } from './index'; - -describe('docValidator', () => { - test('does not run validators that have no application to the doc', () => { - const validators = { - foo: () => { - throw new Error('Boom!'); - }, - }; - expect(() => docValidator(validators)({ type: 'shoo', bar: 'hi' })).not.toThrow(); - }); - - test('validates the doc type', () => { - const validators = { - foo: () => { - throw new Error('Boom!'); - }, - }; - expect(() => docValidator(validators)({ type: 'foo' })).toThrow(/Boom!/); - }); - - test('validates various props', () => { - const validators = { - a: jest.fn(), - b: jest.fn(), - c: jest.fn(), - }; - docValidator(validators)({ type: 'a', b: 'foo' }); - - expect(validators.c).not.toHaveBeenCalled(); - - expect(validators.a.mock.calls).toEqual([[{ type: 'a', b: 'foo' }]]); - expect(validators.b.mock.calls).toEqual([[{ type: 'a', b: 'foo' }]]); - }); -}); diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 081554cd17f25..aef1bda9ccf4e 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1411,19 +1411,30 @@ export interface LegacyServiceStartDeps { plugins: Record; } -// Warning: (ae-forgotten-export) The symbol "SavedObjectsLegacyUiExports" needs to be exported by the entry point index.d.ts -// // @internal @deprecated (undocumented) -export type LegacyUiExports = SavedObjectsLegacyUiExports & { +export interface LegacyUiExports { + // Warning: (ae-forgotten-export) The symbol "VarsProvider" needs to be exported by the entry point index.d.ts + // + // (undocumented) defaultInjectedVarProviders?: VarsProvider[]; + // Warning: (ae-forgotten-export) The symbol "VarsReplacer" needs to be exported by the entry point index.d.ts + // + // (undocumented) injectedVarsReplacers?: VarsReplacer[]; + // Warning: (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts + // + // (undocumented) navLinkSpecs?: LegacyNavLinkSpec[] | null; + // Warning: (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts + // + // (undocumented) uiAppSpecs?: Array; + // (undocumented) unknown?: [{ pluginSpec: LegacyPluginSpec; type: unknown; }]; -}; +} // Warning: (ae-forgotten-export) The symbol "lifecycleResponseFactory" needs to be exported by the entry point index.d.ts // @@ -1520,10 +1531,10 @@ export interface LogRecord { timestamp: Date; } -// Warning: (ae-missing-release-tag) "MetricsServiceSetup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface MetricsServiceSetup { + readonly collectionInterval: number; + getOpsMetrics$: () => Observable; } // @public @deprecated (undocumented) @@ -1610,6 +1621,7 @@ export interface OnPreRoutingToolkit { // @public export interface OpsMetrics { + collected_at: Date; concurrent_connections: OpsServerMetrics['concurrent_connections']; os: OpsOsMetrics; process: OpsProcessMetrics; @@ -1619,6 +1631,20 @@ export interface OpsMetrics { // @public export interface OpsOsMetrics { + cpu?: { + control_group: string; + cfs_period_micros: number; + cfs_quota_micros: number; + stat: { + number_of_elapsed_periods: number; + number_of_times_throttled: number; + time_throttled_nanos: number; + }; + }; + cpuacct?: { + control_group: string; + usage_nanos: number; + }; distro?: string; distroRelease?: string; load: { @@ -2437,33 +2463,6 @@ export interface SavedObjectsIncrementCounterOptions extends SavedObjectsBaseOpt refresh?: MutatingOperationRefreshSetting; } -// @internal @deprecated (undocumented) -export interface SavedObjectsLegacyService { - // Warning: (ae-forgotten-export) The symbol "SavedObjectsClientProvider" needs to be exported by the entry point index.d.ts - // - // (undocumented) - addScopedSavedObjectsClientWrapperFactory: SavedObjectsClientProvider['addClientWrapperFactory']; - // (undocumented) - getSavedObjectsRepository(...rest: any[]): any; - // (undocumented) - getScopedSavedObjectsClient: SavedObjectsClientProvider['getClient']; - // (undocumented) - importExport: { - objectLimit: number; - importSavedObjects(options: SavedObjectsImportOptions): Promise; - resolveImportErrors(options: SavedObjectsResolveImportErrorsOptions): Promise; - getSortedObjectsForExport(options: SavedObjectsExportOptions): Promise; - }; - // (undocumented) - SavedObjectsClient: typeof SavedObjectsClient; - // (undocumented) - schema: SavedObjectsSchema; - // (undocumented) - setScopedSavedObjectsClientFactory: SavedObjectsClientProvider['setClientFactory']; - // (undocumented) - types: string[]; -} - // @public export interface SavedObjectsMappingProperties { // (undocumented) @@ -2517,10 +2516,10 @@ export class SavedObjectsRepository { bulkUpdate(objects: Array>, options?: SavedObjectsBulkUpdateOptions): Promise>; checkConflicts(objects?: SavedObjectsCheckConflictsObject[], options?: SavedObjectsBaseOptions): Promise; create(type: string, attributes: T, options?: SavedObjectsCreateOptions): Promise>; - // Warning: (ae-forgotten-export) The symbol "KibanaMigrator" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "IKibanaMigrator" needs to be exported by the entry point index.d.ts // // @internal - static createRepository(migrator: KibanaMigrator, typeRegistry: SavedObjectTypeRegistry, indexName: string, client: ElasticsearchClient, includedHiddenTypes?: string[], injectedConstructor?: any): ISavedObjectsRepository; + static createRepository(migrator: IKibanaMigrator, typeRegistry: SavedObjectTypeRegistry, indexName: string, client: ElasticsearchClient, includedHiddenTypes?: string[], injectedConstructor?: any): ISavedObjectsRepository; delete(type: string, id: string, options?: SavedObjectsDeleteOptions): Promise<{}>; deleteByNamespace(namespace: string, options?: SavedObjectsDeleteByNamespaceOptions): Promise; deleteFromNamespaces(type: string, id: string, namespaces: string[], options?: SavedObjectsDeleteFromNamespacesOptions): Promise; @@ -2548,24 +2547,6 @@ export interface SavedObjectsResolveImportErrorsOptions { typeRegistry: ISavedObjectTypeRegistry; } -// @internal @deprecated (undocumented) -export class SavedObjectsSchema { - // Warning: (ae-forgotten-export) The symbol "SavedObjectsSchemaDefinition" needs to be exported by the entry point index.d.ts - constructor(schemaDefinition?: SavedObjectsSchemaDefinition); - // (undocumented) - getConvertToAliasScript(type: string): string | undefined; - // (undocumented) - getIndexForType(config: LegacyConfig, type: string): string | undefined; - // (undocumented) - isHiddenType(type: string): boolean; - // (undocumented) - isMultiNamespace(type: string): boolean; - // (undocumented) - isNamespaceAgnostic(type: string): boolean; - // (undocumented) - isSingleNamespace(type: string): boolean; -} - // @public export class SavedObjectsSerializer { // @internal @@ -2797,10 +2778,17 @@ export type SharedGlobalConfig = RecursiveReadonly<{ // @public export type StartServicesAccessor = () => Promise<[CoreStart, TPluginsStart, TStart]>; +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ServiceStatusSetup" +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ServiceStatusSetup" +// // @public export interface StatusServiceSetup { core$: Observable; + dependencies$: Observable>; + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "StatusSetup" + derivedStatus$: Observable; overall$: Observable; + set(status$: Observable): void; } // @public @@ -2888,13 +2876,9 @@ export const validBodyOutput: readonly ["data", "stream"]; // Warnings were encountered during analysis: // // src/core/server/http/router/response.ts:316:3 - (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts -// src/core/server/legacy/types.ts:132:3 - (ae-forgotten-export) The symbol "VarsProvider" needs to be exported by the entry point index.d.ts -// src/core/server/legacy/types.ts:133:3 - (ae-forgotten-export) The symbol "VarsReplacer" needs to be exported by the entry point index.d.ts -// src/core/server/legacy/types.ts:134:3 - (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts -// src/core/server/legacy/types.ts:135:3 - (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts -// src/core/server/legacy/types.ts:136:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts -// src/core/server/plugins/types.ts:266:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts -// src/core/server/plugins/types.ts:266:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts -// src/core/server/plugins/types.ts:268:3 - (ae-forgotten-export) The symbol "PathConfigType" needs to be exported by the entry point index.d.ts +// src/core/server/legacy/types.ts:135:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts +// src/core/server/plugins/types.ts:272:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts +// src/core/server/plugins/types.ts:272:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts +// src/core/server/plugins/types.ts:274:3 - (ae-forgotten-export) The symbol "PathConfigType" needs to be exported by the entry point index.d.ts ``` diff --git a/src/core/server/server.test.ts b/src/core/server/server.test.ts index 417f66a2988c2..8bf16d9130ef5 100644 --- a/src/core/server/server.test.ts +++ b/src/core/server/server.test.ts @@ -49,7 +49,7 @@ const rawConfigService = rawConfigServiceMock.create({}); beforeEach(() => { mockConfigService.atPath.mockReturnValue(new BehaviorSubject({ autoListen: true })); mockPluginsService.discover.mockResolvedValue({ - pluginTree: new Map(), + pluginTree: { asOpaqueIds: new Map(), asNames: new Map() }, uiPlugins: { internal: new Map(), public: new Map(), browserConfigs: new Map() }, }); }); @@ -98,7 +98,7 @@ test('injects legacy dependency to context#setup()', async () => { [pluginB, [pluginA]], ]); mockPluginsService.discover.mockResolvedValue({ - pluginTree: pluginDependencies, + pluginTree: { asOpaqueIds: pluginDependencies, asNames: new Map() }, uiPlugins: { internal: new Map(), public: new Map(), browserConfigs: new Map() }, }); diff --git a/src/core/server/server.ts b/src/core/server/server.ts index cc6d8171e7a03..a02b0f51b559f 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -121,10 +121,13 @@ export class Server { const contextServiceSetup = this.context.setup({ // We inject a fake "legacy plugin" with dependencies on every plugin so that legacy plugins: - // 1) Can access context from any NP plugin + // 1) Can access context from any KP plugin // 2) Can register context providers that will only be available to other legacy plugins and will not leak into // New Platform plugins. - pluginDependencies: new Map([...pluginTree, [this.legacy.legacyId, [...pluginTree.keys()]]]), + pluginDependencies: new Map([ + ...pluginTree.asOpaqueIds, + [this.legacy.legacyId, [...pluginTree.asOpaqueIds.keys()]], + ]), }); const auditTrailSetup = this.auditTrail.setup(); @@ -142,7 +145,6 @@ export class Server { const savedObjectsSetup = await this.savedObjects.setup({ http: httpSetup, elasticsearch: elasticsearchServiceSetup, - legacyPlugins, }); const uiSettingsSetup = await this.uiSettings.setup({ @@ -154,6 +156,7 @@ export class Server { const statusSetup = await this.status.setup({ elasticsearch: elasticsearchServiceSetup, + pluginDependencies: pluginTree.asNames, savedObjects: savedObjectsSetup, }); diff --git a/src/core/server/status/get_summary_status.test.ts b/src/core/server/status/get_summary_status.test.ts index 7516e82ee784d..d97083162b502 100644 --- a/src/core/server/status/get_summary_status.test.ts +++ b/src/core/server/status/get_summary_status.test.ts @@ -94,6 +94,38 @@ describe('getSummaryStatus', () => { describe('summary', () => { describe('when a single service is at highest level', () => { it('returns all information about that single service', () => { + expect( + getSummaryStatus( + Object.entries({ + s1: degraded, + s2: { + level: ServiceStatusLevels.unavailable, + summary: 'Lorem ipsum', + meta: { + custom: { data: 'here' }, + }, + }, + }) + ) + ).toEqual({ + level: ServiceStatusLevels.unavailable, + summary: '[s2]: Lorem ipsum', + detail: 'See the status page for more information', + meta: { + affectedServices: { + s2: { + level: ServiceStatusLevels.unavailable, + summary: 'Lorem ipsum', + meta: { + custom: { data: 'here' }, + }, + }, + }, + }, + }); + }); + + it('allows the single service to override the detail and documentationUrl fields', () => { expect( getSummaryStatus( Object.entries({ @@ -115,7 +147,17 @@ describe('getSummaryStatus', () => { detail: 'Vivamus pulvinar sem ac luctus ultrices.', documentationUrl: 'http://helpmenow.com/problem1', meta: { - custom: { data: 'here' }, + affectedServices: { + s2: { + level: ServiceStatusLevels.unavailable, + summary: 'Lorem ipsum', + detail: 'Vivamus pulvinar sem ac luctus ultrices.', + documentationUrl: 'http://helpmenow.com/problem1', + meta: { + custom: { data: 'here' }, + }, + }, + }, }, }); }); diff --git a/src/core/server/status/get_summary_status.ts b/src/core/server/status/get_summary_status.ts index 748a54f0bf8bb..8d97cdbd9b15b 100644 --- a/src/core/server/status/get_summary_status.ts +++ b/src/core/server/status/get_summary_status.ts @@ -23,62 +23,60 @@ import { ServiceStatus, ServiceStatusLevels, ServiceStatusLevel } from './types' * Returns a single {@link ServiceStatus} that summarizes the most severe status level from a group of statuses. * @param statuses */ -export const getSummaryStatus = (statuses: Array<[string, ServiceStatus]>): ServiceStatus => { - const grouped = groupByLevel(statuses); - const highestSeverityLevel = getHighestSeverityLevel(grouped.keys()); - const highestSeverityGroup = grouped.get(highestSeverityLevel)!; +export const getSummaryStatus = ( + statuses: Array<[string, ServiceStatus]>, + { allAvailableSummary = `All services are available` }: { allAvailableSummary?: string } = {} +): ServiceStatus => { + const { highestLevel, highestStatuses } = highestLevelSummary(statuses); - if (highestSeverityLevel === ServiceStatusLevels.available) { + if (highestLevel === ServiceStatusLevels.available) { return { level: ServiceStatusLevels.available, - summary: `All services are available`, + summary: allAvailableSummary, }; - } else if (highestSeverityGroup.size === 1) { - const [serviceName, status] = [...highestSeverityGroup.entries()][0]; + } else if (highestStatuses.length === 1) { + const [serviceName, status] = highestStatuses[0]! as [string, ServiceStatus]; return { ...status, summary: `[${serviceName}]: ${status.summary!}`, + // TODO: include URL to status page + detail: status.detail ?? `See the status page for more information`, + meta: { + affectedServices: { [serviceName]: status }, + }, }; } else { return { - level: highestSeverityLevel, - summary: `[${highestSeverityGroup.size}] services are ${highestSeverityLevel.toString()}`, + level: highestLevel, + summary: `[${highestStatuses.length}] services are ${highestLevel.toString()}`, // TODO: include URL to status page detail: `See the status page for more information`, meta: { - affectedServices: Object.fromEntries([...highestSeverityGroup]), + affectedServices: Object.fromEntries(highestStatuses), }, }; } }; -const groupByLevel = ( - statuses: Array<[string, ServiceStatus]> -): Map> => { - const byLevel = new Map>(); +type StatusPair = [string, ServiceStatus]; - for (const [serviceName, status] of statuses) { - let levelMap = byLevel.get(status.level); - if (!levelMap) { - levelMap = new Map(); - byLevel.set(status.level, levelMap); - } +const highestLevelSummary = ( + statuses: StatusPair[] +): { highestLevel: ServiceStatusLevel; highestStatuses: StatusPair[] } => { + let highestLevel: ServiceStatusLevel = ServiceStatusLevels.available; + let highestStatuses: StatusPair[] = []; - levelMap.set(serviceName, status); + for (const pair of statuses) { + if (pair[1].level === highestLevel) { + highestStatuses.push(pair); + } else if (pair[1].level > highestLevel) { + highestLevel = pair[1].level; + highestStatuses = [pair]; + } } - return byLevel; -}; - -const getHighestSeverityLevel = (levels: Iterable): ServiceStatusLevel => { - const sorted = [...levels].sort((a, b) => { - if (a < b) { - return -1; - } else if (a > b) { - return 1; - } else { - return 0; - } - }); - return sorted[sorted.length - 1] ?? ServiceStatusLevels.available; + return { + highestLevel, + highestStatuses, + }; }; diff --git a/src/core/server/status/plugins_status.test.ts b/src/core/server/status/plugins_status.test.ts new file mode 100644 index 0000000000000..a75dc8c283698 --- /dev/null +++ b/src/core/server/status/plugins_status.test.ts @@ -0,0 +1,338 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { PluginName } from '../plugins'; +import { PluginsStatusService } from './plugins_status'; +import { of, Observable, BehaviorSubject } from 'rxjs'; +import { ServiceStatusLevels, CoreStatus, ServiceStatus } from './types'; +import { first } from 'rxjs/operators'; +import { ServiceStatusLevelSnapshotSerializer } from './test_utils'; + +expect.addSnapshotSerializer(ServiceStatusLevelSnapshotSerializer); + +describe('PluginStatusService', () => { + const coreAllAvailable$: Observable = of({ + elasticsearch: { level: ServiceStatusLevels.available, summary: 'elasticsearch avail' }, + savedObjects: { level: ServiceStatusLevels.available, summary: 'savedObjects avail' }, + }); + const coreOneDegraded$: Observable = of({ + elasticsearch: { level: ServiceStatusLevels.available, summary: 'elasticsearch avail' }, + savedObjects: { level: ServiceStatusLevels.degraded, summary: 'savedObjects degraded' }, + }); + const coreOneCriticalOneDegraded$: Observable = of({ + elasticsearch: { level: ServiceStatusLevels.critical, summary: 'elasticsearch critical' }, + savedObjects: { level: ServiceStatusLevels.degraded, summary: 'savedObjects degraded' }, + }); + const pluginDependencies: Map = new Map([ + ['a', []], + ['b', ['a']], + ['c', ['a', 'b']], + ]); + + describe('getDerivedStatus$', () => { + it(`defaults to core's most severe status`, async () => { + const serviceAvailable = new PluginsStatusService({ + core$: coreAllAvailable$, + pluginDependencies, + }); + expect(await serviceAvailable.getDerivedStatus$('a').pipe(first()).toPromise()).toEqual({ + level: ServiceStatusLevels.available, + summary: 'All dependencies are available', + }); + + const serviceDegraded = new PluginsStatusService({ + core$: coreOneDegraded$, + pluginDependencies, + }); + expect(await serviceDegraded.getDerivedStatus$('a').pipe(first()).toPromise()).toEqual({ + level: ServiceStatusLevels.degraded, + summary: '[savedObjects]: savedObjects degraded', + detail: 'See the status page for more information', + meta: expect.any(Object), + }); + + const serviceCritical = new PluginsStatusService({ + core$: coreOneCriticalOneDegraded$, + pluginDependencies, + }); + expect(await serviceCritical.getDerivedStatus$('a').pipe(first()).toPromise()).toEqual({ + level: ServiceStatusLevels.critical, + summary: '[elasticsearch]: elasticsearch critical', + detail: 'See the status page for more information', + meta: expect.any(Object), + }); + }); + + it(`provides a summary status when core and dependencies are at same severity level`, async () => { + const service = new PluginsStatusService({ core$: coreOneDegraded$, pluginDependencies }); + service.set('a', of({ level: ServiceStatusLevels.degraded, summary: 'a is degraded' })); + expect(await service.getDerivedStatus$('b').pipe(first()).toPromise()).toEqual({ + level: ServiceStatusLevels.degraded, + summary: '[2] services are degraded', + detail: 'See the status page for more information', + meta: expect.any(Object), + }); + }); + + it(`allows dependencies status to take precedence over lower severity core statuses`, async () => { + const service = new PluginsStatusService({ core$: coreOneDegraded$, pluginDependencies }); + service.set('a', of({ level: ServiceStatusLevels.unavailable, summary: 'a is not working' })); + expect(await service.getDerivedStatus$('b').pipe(first()).toPromise()).toEqual({ + level: ServiceStatusLevels.unavailable, + summary: '[a]: a is not working', + detail: 'See the status page for more information', + meta: expect.any(Object), + }); + }); + + it(`allows core status to take precedence over lower severity dependencies statuses`, async () => { + const service = new PluginsStatusService({ + core$: coreOneCriticalOneDegraded$, + pluginDependencies, + }); + service.set('a', of({ level: ServiceStatusLevels.unavailable, summary: 'a is not working' })); + expect(await service.getDerivedStatus$('b').pipe(first()).toPromise()).toEqual({ + level: ServiceStatusLevels.critical, + summary: '[elasticsearch]: elasticsearch critical', + detail: 'See the status page for more information', + meta: expect.any(Object), + }); + }); + + it(`allows a severe dependency status to take precedence over a less severe dependency status`, async () => { + const service = new PluginsStatusService({ core$: coreOneDegraded$, pluginDependencies }); + service.set('a', of({ level: ServiceStatusLevels.degraded, summary: 'a is degraded' })); + service.set('b', of({ level: ServiceStatusLevels.unavailable, summary: 'b is not working' })); + expect(await service.getDerivedStatus$('c').pipe(first()).toPromise()).toEqual({ + level: ServiceStatusLevels.unavailable, + summary: '[b]: b is not working', + detail: 'See the status page for more information', + meta: expect.any(Object), + }); + }); + }); + + describe('getAll$', () => { + it('defaults to empty record if no plugins', async () => { + const service = new PluginsStatusService({ + core$: coreAllAvailable$, + pluginDependencies: new Map(), + }); + expect(await service.getAll$().pipe(first()).toPromise()).toEqual({}); + }); + + it('defaults to core status when no plugin statuses are set', async () => { + const serviceAvailable = new PluginsStatusService({ + core$: coreAllAvailable$, + pluginDependencies, + }); + expect(await serviceAvailable.getAll$().pipe(first()).toPromise()).toEqual({ + a: { level: ServiceStatusLevels.available, summary: 'All dependencies are available' }, + b: { level: ServiceStatusLevels.available, summary: 'All dependencies are available' }, + c: { level: ServiceStatusLevels.available, summary: 'All dependencies are available' }, + }); + + const serviceDegraded = new PluginsStatusService({ + core$: coreOneDegraded$, + pluginDependencies, + }); + expect(await serviceDegraded.getAll$().pipe(first()).toPromise()).toEqual({ + a: { + level: ServiceStatusLevels.degraded, + summary: '[savedObjects]: savedObjects degraded', + detail: 'See the status page for more information', + meta: expect.any(Object), + }, + b: { + level: ServiceStatusLevels.degraded, + summary: '[2] services are degraded', + detail: 'See the status page for more information', + meta: expect.any(Object), + }, + c: { + level: ServiceStatusLevels.degraded, + summary: '[3] services are degraded', + detail: 'See the status page for more information', + meta: expect.any(Object), + }, + }); + + const serviceCritical = new PluginsStatusService({ + core$: coreOneCriticalOneDegraded$, + pluginDependencies, + }); + expect(await serviceCritical.getAll$().pipe(first()).toPromise()).toEqual({ + a: { + level: ServiceStatusLevels.critical, + summary: '[elasticsearch]: elasticsearch critical', + detail: 'See the status page for more information', + meta: expect.any(Object), + }, + b: { + level: ServiceStatusLevels.critical, + summary: '[2] services are critical', + detail: 'See the status page for more information', + meta: expect.any(Object), + }, + c: { + level: ServiceStatusLevels.critical, + summary: '[3] services are critical', + detail: 'See the status page for more information', + meta: expect.any(Object), + }, + }); + }); + + it('uses the manually set status level if plugin specifies one', async () => { + const service = new PluginsStatusService({ core$: coreOneDegraded$, pluginDependencies }); + service.set('a', of({ level: ServiceStatusLevels.available, summary: 'a status' })); + + expect(await service.getAll$().pipe(first()).toPromise()).toEqual({ + a: { level: ServiceStatusLevels.available, summary: 'a status' }, // a is available depsite savedObjects being degraded + b: { + level: ServiceStatusLevels.degraded, + summary: '[savedObjects]: savedObjects degraded', + detail: 'See the status page for more information', + meta: expect.any(Object), + }, + c: { + level: ServiceStatusLevels.degraded, + summary: '[2] services are degraded', + detail: 'See the status page for more information', + meta: expect.any(Object), + }, + }); + }); + + it('updates when a new plugin status observable is set', async () => { + const service = new PluginsStatusService({ + core$: coreAllAvailable$, + pluginDependencies: new Map([['a', []]]), + }); + const statusUpdates: Array> = []; + const subscription = service + .getAll$() + .subscribe((pluginStatuses) => statusUpdates.push(pluginStatuses)); + + service.set('a', of({ level: ServiceStatusLevels.degraded, summary: 'a degraded' })); + service.set('a', of({ level: ServiceStatusLevels.unavailable, summary: 'a unavailable' })); + service.set('a', of({ level: ServiceStatusLevels.available, summary: 'a available' })); + subscription.unsubscribe(); + + expect(statusUpdates).toEqual([ + { a: { level: ServiceStatusLevels.available, summary: 'All dependencies are available' } }, + { a: { level: ServiceStatusLevels.degraded, summary: 'a degraded' } }, + { a: { level: ServiceStatusLevels.unavailable, summary: 'a unavailable' } }, + { a: { level: ServiceStatusLevels.available, summary: 'a available' } }, + ]); + }); + }); + + describe('getDependenciesStatus$', () => { + it('only includes dependencies of specified plugin', async () => { + const service = new PluginsStatusService({ + core$: coreAllAvailable$, + pluginDependencies, + }); + expect(await service.getDependenciesStatus$('a').pipe(first()).toPromise()).toEqual({}); + expect(await service.getDependenciesStatus$('b').pipe(first()).toPromise()).toEqual({ + a: { level: ServiceStatusLevels.available, summary: 'All dependencies are available' }, + }); + expect(await service.getDependenciesStatus$('c').pipe(first()).toPromise()).toEqual({ + a: { level: ServiceStatusLevels.available, summary: 'All dependencies are available' }, + b: { level: ServiceStatusLevels.available, summary: 'All dependencies are available' }, + }); + }); + + it('uses the manually set status level if plugin specifies one', async () => { + const service = new PluginsStatusService({ core$: coreOneDegraded$, pluginDependencies }); + service.set('a', of({ level: ServiceStatusLevels.available, summary: 'a status' })); + + expect(await service.getDependenciesStatus$('c').pipe(first()).toPromise()).toEqual({ + a: { level: ServiceStatusLevels.available, summary: 'a status' }, // a is available depsite savedObjects being degraded + b: { + level: ServiceStatusLevels.degraded, + summary: '[savedObjects]: savedObjects degraded', + detail: 'See the status page for more information', + meta: expect.any(Object), + }, + }); + }); + + it('throws error if unknown plugin passed', () => { + const service = new PluginsStatusService({ core$: coreAllAvailable$, pluginDependencies }); + expect(() => { + service.getDependenciesStatus$('dont-exist'); + }).toThrowError(); + }); + + it('debounces events in quick succession', async () => { + const service = new PluginsStatusService({ + core$: coreAllAvailable$, + pluginDependencies, + }); + const available: ServiceStatus = { + level: ServiceStatusLevels.available, + summary: 'a available', + }; + const degraded: ServiceStatus = { + level: ServiceStatusLevels.degraded, + summary: 'a degraded', + }; + const pluginA$ = new BehaviorSubject(available); + service.set('a', pluginA$); + + const statusUpdates: Array> = []; + const subscription = service + .getDependenciesStatus$('b') + .subscribe((status) => statusUpdates.push(status)); + const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + + pluginA$.next(degraded); + pluginA$.next(available); + pluginA$.next(degraded); + pluginA$.next(available); + pluginA$.next(degraded); + pluginA$.next(available); + pluginA$.next(degraded); + // Waiting for the debounce timeout should cut a new update + await delay(500); + pluginA$.next(available); + await delay(500); + subscription.unsubscribe(); + + expect(statusUpdates).toMatchInlineSnapshot(` + Array [ + Object { + "a": Object { + "level": degraded, + "summary": "a degraded", + }, + }, + Object { + "a": Object { + "level": available, + "summary": "a available", + }, + }, + ] + `); + }); + }); +}); diff --git a/src/core/server/status/plugins_status.ts b/src/core/server/status/plugins_status.ts new file mode 100644 index 0000000000000..113d59b327c11 --- /dev/null +++ b/src/core/server/status/plugins_status.ts @@ -0,0 +1,98 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { BehaviorSubject, Observable, combineLatest, of } from 'rxjs'; +import { map, distinctUntilChanged, switchMap, debounceTime } from 'rxjs/operators'; +import { isDeepStrictEqual } from 'util'; + +import { PluginName } from '../plugins'; +import { ServiceStatus, CoreStatus } from './types'; +import { getSummaryStatus } from './get_summary_status'; + +interface Deps { + core$: Observable; + pluginDependencies: ReadonlyMap; +} + +export class PluginsStatusService { + private readonly pluginStatuses = new Map>(); + private readonly update$ = new BehaviorSubject(true); + constructor(private readonly deps: Deps) {} + + public set(plugin: PluginName, status$: Observable) { + this.pluginStatuses.set(plugin, status$); + this.update$.next(true); // trigger all existing Observables to update from the new source Observable + } + + public getAll$(): Observable> { + return this.getPluginStatuses$([...this.deps.pluginDependencies.keys()]); + } + + public getDependenciesStatus$(plugin: PluginName): Observable> { + const dependencies = this.deps.pluginDependencies.get(plugin); + if (!dependencies) { + throw new Error(`Unknown plugin: ${plugin}`); + } + + return this.getPluginStatuses$(dependencies).pipe( + // Prevent many emissions at once from dependency status resolution from making this too noisy + debounceTime(500) + ); + } + + public getDerivedStatus$(plugin: PluginName): Observable { + return combineLatest([this.deps.core$, this.getDependenciesStatus$(plugin)]).pipe( + map(([coreStatus, pluginStatuses]) => { + return getSummaryStatus( + [...Object.entries(coreStatus), ...Object.entries(pluginStatuses)], + { + allAvailableSummary: `All dependencies are available`, + } + ); + }) + ); + } + + private getPluginStatuses$(plugins: PluginName[]): Observable> { + if (plugins.length === 0) { + return of({}); + } + + return this.update$.pipe( + switchMap(() => { + const pluginStatuses = plugins + .map( + (depName) => + [depName, this.pluginStatuses.get(depName) ?? this.getDerivedStatus$(depName)] as [ + PluginName, + Observable + ] + ) + .map(([pName, status$]) => + status$.pipe(map((status) => [pName, status] as [PluginName, ServiceStatus])) + ); + + return combineLatest(pluginStatuses).pipe( + map((statuses) => Object.fromEntries(statuses)), + distinctUntilChanged(isDeepStrictEqual) + ); + }) + ); + } +} diff --git a/src/core/server/status/status_service.mock.ts b/src/core/server/status/status_service.mock.ts index 47ef8659b4079..42b3eecdca310 100644 --- a/src/core/server/status/status_service.mock.ts +++ b/src/core/server/status/status_service.mock.ts @@ -40,6 +40,9 @@ const createSetupContractMock = () => { const setupContract: jest.Mocked = { core$: new BehaviorSubject(availableCoreStatus), overall$: new BehaviorSubject(available), + set: jest.fn(), + dependencies$: new BehaviorSubject({}), + derivedStatus$: new BehaviorSubject(available), }; return setupContract; @@ -50,6 +53,11 @@ const createInternalSetupContractMock = () => { core$: new BehaviorSubject(availableCoreStatus), overall$: new BehaviorSubject(available), isStatusPageAnonymous: jest.fn().mockReturnValue(false), + plugins: { + set: jest.fn(), + getDependenciesStatus$: jest.fn(), + getDerivedStatus$: jest.fn(), + }, }; return setupContract; diff --git a/src/core/server/status/status_service.test.ts b/src/core/server/status/status_service.test.ts index 863fe34e8ecea..dcb1e0a559f5d 100644 --- a/src/core/server/status/status_service.test.ts +++ b/src/core/server/status/status_service.test.ts @@ -34,6 +34,7 @@ describe('StatusService', () => { service = new StatusService(mockCoreContext.create()); }); + const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); const available: ServiceStatus = { level: ServiceStatusLevels.available, summary: 'Available', @@ -53,6 +54,7 @@ describe('StatusService', () => { savedObjects: { status$: of(degraded), }, + pluginDependencies: new Map(), }); expect(await setup.core$.pipe(first()).toPromise()).toEqual({ elasticsearch: available, @@ -68,6 +70,7 @@ describe('StatusService', () => { savedObjects: { status$: of(degraded), }, + pluginDependencies: new Map(), }); const subResult1 = await setup.core$.pipe(first()).toPromise(); const subResult2 = await setup.core$.pipe(first()).toPromise(); @@ -96,6 +99,7 @@ describe('StatusService', () => { savedObjects: { status$: savedObjects$, }, + pluginDependencies: new Map(), }); const statusUpdates: CoreStatus[] = []; @@ -158,6 +162,7 @@ describe('StatusService', () => { savedObjects: { status$: of(degraded), }, + pluginDependencies: new Map(), }); expect(await setup.overall$.pipe(first()).toPromise()).toMatchObject({ level: ServiceStatusLevels.degraded, @@ -173,6 +178,7 @@ describe('StatusService', () => { savedObjects: { status$: of(degraded), }, + pluginDependencies: new Map(), }); const subResult1 = await setup.overall$.pipe(first()).toPromise(); const subResult2 = await setup.overall$.pipe(first()).toPromise(); @@ -201,26 +207,95 @@ describe('StatusService', () => { savedObjects: { status$: savedObjects$, }, + pluginDependencies: new Map(), }); const statusUpdates: ServiceStatus[] = []; const subscription = setup.overall$.subscribe((status) => statusUpdates.push(status)); + // Wait for timers to ensure that duplicate events are still filtered out regardless of debouncing. elasticsearch$.next(available); + await delay(500); elasticsearch$.next(available); + await delay(500); elasticsearch$.next({ level: ServiceStatusLevels.available, summary: `Wow another summary`, }); + await delay(500); savedObjects$.next(degraded); + await delay(500); savedObjects$.next(available); + await delay(500); savedObjects$.next(available); + await delay(500); subscription.unsubscribe(); expect(statusUpdates).toMatchInlineSnapshot(` Array [ Object { + "detail": "See the status page for more information", "level": degraded, + "meta": Object { + "affectedServices": Object { + "savedObjects": Object { + "level": degraded, + "summary": "This is degraded!", + }, + }, + }, + "summary": "[savedObjects]: This is degraded!", + }, + Object { + "level": available, + "summary": "All services are available", + }, + ] + `); + }); + + it('debounces events in quick succession', async () => { + const savedObjects$ = new BehaviorSubject(available); + const setup = await service.setup({ + elasticsearch: { + status$: new BehaviorSubject(available), + }, + savedObjects: { + status$: savedObjects$, + }, + pluginDependencies: new Map(), + }); + + const statusUpdates: ServiceStatus[] = []; + const subscription = setup.overall$.subscribe((status) => statusUpdates.push(status)); + + // All of these should debounced into a single `available` status + savedObjects$.next(degraded); + savedObjects$.next(available); + savedObjects$.next(degraded); + savedObjects$.next(available); + savedObjects$.next(degraded); + savedObjects$.next(available); + savedObjects$.next(degraded); + // Waiting for the debounce timeout should cut a new update + await delay(500); + savedObjects$.next(available); + await delay(500); + subscription.unsubscribe(); + + expect(statusUpdates).toMatchInlineSnapshot(` + Array [ + Object { + "detail": "See the status page for more information", + "level": degraded, + "meta": Object { + "affectedServices": Object { + "savedObjects": Object { + "level": degraded, + "summary": "This is degraded!", + }, + }, + }, "summary": "[savedObjects]: This is degraded!", }, Object { diff --git a/src/core/server/status/status_service.ts b/src/core/server/status/status_service.ts index aea335e64babf..8fe65eddb61d3 100644 --- a/src/core/server/status/status_service.ts +++ b/src/core/server/status/status_service.ts @@ -18,7 +18,7 @@ */ import { Observable, combineLatest } from 'rxjs'; -import { map, distinctUntilChanged, shareReplay, take } from 'rxjs/operators'; +import { map, distinctUntilChanged, shareReplay, take, debounceTime } from 'rxjs/operators'; import { isDeepStrictEqual } from 'util'; import { CoreService } from '../../types'; @@ -26,13 +26,16 @@ import { CoreContext } from '../core_context'; import { Logger } from '../logging'; import { InternalElasticsearchServiceSetup } from '../elasticsearch'; import { InternalSavedObjectsServiceSetup } from '../saved_objects'; +import { PluginName } from '../plugins'; import { config, StatusConfigType } from './status_config'; import { ServiceStatus, CoreStatus, InternalStatusServiceSetup } from './types'; import { getSummaryStatus } from './get_summary_status'; +import { PluginsStatusService } from './plugins_status'; interface SetupDeps { elasticsearch: Pick; + pluginDependencies: ReadonlyMap; savedObjects: Pick; } @@ -40,26 +43,44 @@ export class StatusService implements CoreService { private readonly logger: Logger; private readonly config$: Observable; + private pluginsStatus?: PluginsStatusService; + constructor(coreContext: CoreContext) { this.logger = coreContext.logger.get('status'); this.config$ = coreContext.configService.atPath(config.path); } - public async setup(core: SetupDeps) { + public async setup({ elasticsearch, pluginDependencies, savedObjects }: SetupDeps) { const statusConfig = await this.config$.pipe(take(1)).toPromise(); - const core$ = this.setupCoreStatus(core); - const overall$: Observable = core$.pipe( - map((coreStatus) => { - const summary = getSummaryStatus(Object.entries(coreStatus)); + const core$ = this.setupCoreStatus({ elasticsearch, savedObjects }); + this.pluginsStatus = new PluginsStatusService({ core$, pluginDependencies }); + + const overall$: Observable = combineLatest( + core$, + this.pluginsStatus.getAll$() + ).pipe( + // Prevent many emissions at once from dependency status resolution from making this too noisy + debounceTime(500), + map(([coreStatus, pluginsStatus]) => { + const summary = getSummaryStatus([ + ...Object.entries(coreStatus), + ...Object.entries(pluginsStatus), + ]); this.logger.debug(`Recalculated overall status`, { status: summary }); return summary; }), - distinctUntilChanged(isDeepStrictEqual) + distinctUntilChanged(isDeepStrictEqual), + shareReplay(1) ); return { core$, overall$, + plugins: { + set: this.pluginsStatus.set.bind(this.pluginsStatus), + getDependenciesStatus$: this.pluginsStatus.getDependenciesStatus$.bind(this.pluginsStatus), + getDerivedStatus$: this.pluginsStatus.getDerivedStatus$.bind(this.pluginsStatus), + }, isStatusPageAnonymous: () => statusConfig.allowAnonymous, }; } @@ -68,7 +89,10 @@ export class StatusService implements CoreService { public stop() {} - private setupCoreStatus({ elasticsearch, savedObjects }: SetupDeps): Observable { + private setupCoreStatus({ + elasticsearch, + savedObjects, + }: Pick): Observable { return combineLatest([elasticsearch.status$, savedObjects.status$]).pipe( map(([elasticsearchStatus, savedObjectsStatus]) => ({ elasticsearch: elasticsearchStatus, diff --git a/src/core/server/status/types.ts b/src/core/server/status/types.ts index 2ecf11deb2960..f884b80316fa8 100644 --- a/src/core/server/status/types.ts +++ b/src/core/server/status/types.ts @@ -19,6 +19,7 @@ import { Observable } from 'rxjs'; import { deepFreeze } from '../../utils'; +import { PluginName } from '../plugins'; /** * The current status of a service at a point in time. @@ -116,6 +117,60 @@ export interface CoreStatus { /** * API for accessing status of Core and this plugin's dependencies as well as for customizing this plugin's status. + * + * @remarks + * By default, a plugin inherits it's current status from the most severe status level of any Core services and any + * plugins that it depends on. This default status is available on the + * {@link ServiceStatusSetup.derivedStatus$ | core.status.derviedStatus$} API. + * + * Plugins may customize their status calculation by calling the {@link ServiceStatusSetup.set | core.status.set} API + * with an Observable. Within this Observable, a plugin may choose to only depend on the status of some of its + * dependencies, to ignore severe status levels of particular Core services they are not concerned with, or to make its + * status dependent on other external services. + * + * @example + * Customize a plugin's status to only depend on the status of SavedObjects: + * ```ts + * core.status.set( + * core.status.core$.pipe( + * . map((coreStatus) => { + * return coreStatus.savedObjects; + * }) ; + * ); + * ); + * ``` + * + * @example + * Customize a plugin's status to include an external service: + * ```ts + * const externalStatus$ = interval(1000).pipe( + * switchMap(async () => { + * const resp = await fetch(`https://myexternaldep.com/_healthz`); + * const body = await resp.json(); + * if (body.ok) { + * return of({ level: ServiceStatusLevels.available, summary: 'External Service is up'}); + * } else { + * return of({ level: ServiceStatusLevels.available, summary: 'External Service is unavailable'}); + * } + * }), + * catchError((error) => { + * of({ level: ServiceStatusLevels.unavailable, summary: `External Service is down`, meta: { error }}) + * }) + * ); + * + * core.status.set( + * combineLatest([core.status.derivedStatus$, externalStatus$]).pipe( + * map(([derivedStatus, externalStatus]) => { + * if (externalStatus.level > derivedStatus) { + * return externalStatus; + * } else { + * return derivedStatus; + * } + * }) + * ) + * ); + * ``` + * * @public */ export interface StatusServiceSetup { @@ -134,9 +189,43 @@ export interface StatusServiceSetup { * only depend on the statuses of {@link StatusServiceSetup.core$ | Core} or their dependencies. */ overall$: Observable; + + /** + * Allows a plugin to specify a custom status dependent on its own criteria. + * Completely overrides the default inherited status. + * + * @remarks + * See the {@link StatusServiceSetup.derivedStatus$} API for leveraging the default status + * calculation that is provided by Core. + */ + set(status$: Observable): void; + + /** + * Current status for all plugins this plugin depends on. + * Each key of the `Record` is a plugin id. + */ + dependencies$: Observable>; + + /** + * The status of this plugin as derived from its dependencies. + * + * @remarks + * By default, plugins inherit this derived status from their dependencies. + * Calling {@link StatusSetup.set} overrides this default status. + * + * This may emit multliple times for a single status change event as propagates + * through the dependency tree + */ + derivedStatus$: Observable; } /** @internal */ -export interface InternalStatusServiceSetup extends StatusServiceSetup { +export interface InternalStatusServiceSetup extends Pick { isStatusPageAnonymous: () => boolean; + // Namespaced under `plugins` key to improve clarity that these are APIs for plugins specifically. + plugins: { + set(plugin: PluginName, status$: Observable): void; + getDependenciesStatus$(plugin: PluginName): Observable>; + getDerivedStatus$(plugin: PluginName): Observable; + }; } diff --git a/src/core/server/ui_settings/create_or_upgrade_saved_config/integration_tests/create_or_upgrade.test.ts b/src/core/server/ui_settings/create_or_upgrade_saved_config/integration_tests/create_or_upgrade.test.ts index 61b71f8c5de07..c7d5413ecca56 100644 --- a/src/core/server/ui_settings/create_or_upgrade_saved_config/integration_tests/create_or_upgrade.test.ts +++ b/src/core/server/ui_settings/create_or_upgrade_saved_config/integration_tests/create_or_upgrade.test.ts @@ -36,8 +36,6 @@ describe('createOrUpgradeSavedConfig()', () => { let esServer: TestElasticsearchUtils; let kbn: TestKibanaUtils; - let kbnServer: TestKibanaUtils['kbnServer']; - beforeAll(async function () { servers = createTestServers({ adjustTimeout: (t) => { @@ -46,10 +44,8 @@ describe('createOrUpgradeSavedConfig()', () => { }); esServer = await servers.startES(); kbn = await servers.startKibana(); - kbnServer = kbn.kbnServer; - const savedObjects = kbnServer.server.savedObjects; - savedObjectsClient = savedObjects.getScopedSavedObjectsClient( + savedObjectsClient = kbn.coreStart.savedObjects.getScopedClient( httpServerMock.createKibanaRequest() ); diff --git a/src/core/server/ui_settings/integration_tests/lib/servers.ts b/src/core/server/ui_settings/integration_tests/lib/servers.ts index 297deb0233c57..0bdc821f42581 100644 --- a/src/core/server/ui_settings/integration_tests/lib/servers.ts +++ b/src/core/server/ui_settings/integration_tests/lib/servers.ts @@ -68,8 +68,7 @@ export function getServices() { const callCluster = esServer.es.getCallCluster(); - const savedObjects = kbnServer.server.savedObjects; - const savedObjectsClient = savedObjects.getScopedSavedObjectsClient( + const savedObjectsClient = kbn.coreStart.savedObjects.getScopedClient( httpServerMock.createKibanaRequest() ); diff --git a/src/core/test_helpers/kbn_server.ts b/src/core/test_helpers/kbn_server.ts index a494c6aa31d6f..488c4b919d3e4 100644 --- a/src/core/test_helpers/kbn_server.ts +++ b/src/core/test_helpers/kbn_server.ts @@ -32,6 +32,7 @@ import { resolve } from 'path'; import { BehaviorSubject } from 'rxjs'; import supertest from 'supertest'; +import { CoreStart } from 'src/core/server'; import { LegacyAPICaller } from '../server/elasticsearch'; import { CliArgs, Env } from '../server/config'; import { Root } from '../server/root'; @@ -170,6 +171,7 @@ export interface TestElasticsearchUtils { export interface TestKibanaUtils { root: Root; + coreStart: CoreStart; kbnServer: KbnServer; stop: () => Promise; } @@ -289,13 +291,14 @@ export function createTestServers({ const root = createRootWithCorePlugins(kbnSettings); await root.setup(); - await root.start(); + const coreStart = await root.start(); const kbnServer = getKbnServer(root); return { root, kbnServer, + coreStart, stop: async () => await root.shutdown(), }; }, diff --git a/src/legacy/core_plugins/elasticsearch/index.js b/src/legacy/core_plugins/elasticsearch/index.js index 599886788604b..f90f490d68035 100644 --- a/src/legacy/core_plugins/elasticsearch/index.js +++ b/src/legacy/core_plugins/elasticsearch/index.js @@ -16,18 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -import { first } from 'rxjs/operators'; import { Cluster } from './server/lib/cluster'; import { createProxy } from './server/lib/create_proxy'; export default function (kibana) { - let defaultVars; - return new kibana.Plugin({ require: [], - uiExports: { injectDefaultVars: () => defaultVars }, - async init(server) { // All methods that ES plugin exposes are synchronous so we should get the first // value from all observables here to be able to synchronously return and create @@ -36,16 +31,6 @@ export default function (kibana) { const adminCluster = new Cluster(client); const dataCluster = new Cluster(client); - const esConfig = await server.newPlatform.__internals.elasticsearch.legacy.config$ - .pipe(first()) - .toPromise(); - - defaultVars = { - esRequestTimeout: esConfig.requestTimeout.asMilliseconds(), - esShardTimeout: esConfig.shardTimeout.asMilliseconds(), - esApiVersion: esConfig.apiVersion, - }; - const clusters = new Map(); server.expose('getCluster', (name) => { if (name === 'admin') { diff --git a/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts b/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts index e51a355cbc8d2..e1ed2f57375a4 100644 --- a/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts +++ b/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts @@ -18,14 +18,10 @@ */ import { Server } from '../../server/kbn_server'; import { Capabilities } from '../../../core/server'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SavedObjectsLegacyManagementDefinition } from '../../../core/server/saved_objects/types'; export type InitPluginFunction = (server: Server) => void; export interface UiExports { injectDefaultVars?: (server: Server) => { [key: string]: any }; - savedObjectsManagement?: SavedObjectsLegacyManagementDefinition; - mappings?: unknown; } export interface PluginSpecOptions { diff --git a/src/legacy/plugin_discovery/types.ts b/src/legacy/plugin_discovery/types.ts index 283806f69599a..700ca6fa68c95 100644 --- a/src/legacy/plugin_discovery/types.ts +++ b/src/legacy/plugin_discovery/types.ts @@ -19,11 +19,6 @@ import { Server } from '../server/kbn_server'; import { Capabilities } from '../../core/server'; -// Disable lint errors for imports from src/core/* until SavedObjects migration is complete -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SavedObjectsSchemaDefinition } from '../../core/server/saved_objects/schema'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SavedObjectsLegacyManagementDefinition } from '../../core/server/saved_objects/types'; import { AppCategory } from '../../core/types'; /** @@ -70,8 +65,6 @@ export interface LegacyPluginOptions { home: string[]; mappings: any; migrations: any; - savedObjectSchemas: SavedObjectsSchemaDefinition; - savedObjectsManagement: SavedObjectsLegacyManagementDefinition; visTypes: string[]; embeddableActions?: string[]; embeddableFactories?: string[]; diff --git a/src/legacy/server/kbn_server.d.ts b/src/legacy/server/kbn_server.d.ts index 69fb63fbbd87f..663542618375a 100644 --- a/src/legacy/server/kbn_server.d.ts +++ b/src/legacy/server/kbn_server.d.ts @@ -17,33 +17,24 @@ * under the License. */ -import { ResponseObject, Server } from 'hapi'; -import { UnwrapPromise } from '@kbn/utility-types'; +import { Server } from 'hapi'; import { TelemetryCollectionManagerPluginSetup } from 'src/plugins/telemetry_collection_manager/server'; import { - ConfigService, CoreSetup, CoreStart, - ElasticsearchServiceSetup, EnvironmentMode, LoggerFactory, - SavedObjectsClientContract, - SavedObjectsLegacyService, - SavedObjectsClientProviderOptions, - IUiSettingsClient, PackageInfo, - LegacyRequest, LegacyServiceSetupDeps, - LegacyServiceStartDeps, LegacyServiceDiscoverPlugins, } from '../../core/server'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { LegacyConfig, ILegacyService, ILegacyInternals } from '../../core/server/legacy'; +import { LegacyConfig, ILegacyInternals } from '../../core/server/legacy'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { UiPlugins } from '../../core/server/plugins'; -import { CallClusterWithRequest, ElasticsearchPlugin } from '../core_plugins/elasticsearch'; +import { ElasticsearchPlugin } from '../core_plugins/elasticsearch'; import { UsageCollectionSetup } from '../../plugins/usage_collection/server'; import { HomeServerPluginSetup } from '../../plugins/home/server'; @@ -61,16 +52,9 @@ declare module 'hapi' { interface Server { config: () => KibanaConfig; - savedObjects: SavedObjectsLegacyService; logWithMetadata: (tags: string[], message: string, meta: Record) => void; newPlatform: KbnServer['newPlatform']; } - - interface Request { - getSavedObjectsClient(options?: SavedObjectsClientProviderOptions): SavedObjectsClientContract; - getBasePath(): string; - getUiSettingsService(): IUiSettingsClient; - } } type KbnMixinFunc = (kbnServer: KbnServer, server: Server, config: any) => Promise | void; @@ -86,11 +70,9 @@ export interface KibanaCore { __internals: { elasticsearch: LegacyServiceSetupDeps['core']['elasticsearch']; hapiServer: LegacyServiceSetupDeps['core']['http']['server']; - kibanaMigrator: LegacyServiceStartDeps['core']['savedObjects']['migrator']; legacy: ILegacyInternals; rendering: LegacyServiceSetupDeps['core']['rendering']; uiPlugins: UiPlugins; - savedObjectsClientProvider: LegacyServiceStartDeps['core']['savedObjects']['clientProvider']; }; env: { mode: Readonly; @@ -149,6 +131,3 @@ export default class KbnServer { // Re-export commonly used hapi types. export { Server, Request, ResponseToolkit } from 'hapi'; - -// Re-export commonly accessed api types. -export { SavedObjectsLegacyService, SavedObjectsClient } from 'src/core/server'; diff --git a/src/legacy/server/kbn_server.js b/src/legacy/server/kbn_server.js index 4692262d99bb5..a5eefd140c8fa 100644 --- a/src/legacy/server/kbn_server.js +++ b/src/legacy/server/kbn_server.js @@ -33,7 +33,6 @@ import pidMixin from './pid'; import configCompleteMixin from './config/complete'; import { optimizeMixin } from '../../optimize'; import * as Plugins from './plugins'; -import { savedObjectsMixin } from './saved_objects/saved_objects_mixin'; import { uiMixin } from '../ui'; import { i18nMixin } from './i18n'; @@ -108,9 +107,6 @@ export default class KbnServer { uiMixin, - // setup saved object routes - savedObjectsMixin, - // setup routes that serve the @kbn/optimizer output optimizeMixin, diff --git a/src/legacy/server/saved_objects/saved_objects_mixin.js b/src/legacy/server/saved_objects/saved_objects_mixin.js deleted file mode 100644 index 96cf2058839cf..0000000000000 --- a/src/legacy/server/saved_objects/saved_objects_mixin.js +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -// Disable lint errors for imports from src/core/server/saved_objects until SavedObjects migration is complete -/* eslint-disable @kbn/eslint/no-restricted-paths */ -import { SavedObjectsSchema } from '../../../core/server/saved_objects/schema'; -import { - SavedObjectsClient, - SavedObjectsRepository, - exportSavedObjectsToStream, - importSavedObjectsFromStream, - resolveSavedObjectsImportErrors, -} from '../../../core/server/saved_objects'; -import { convertTypesToLegacySchema } from '../../../core/server/saved_objects/utils'; - -export function savedObjectsMixin(kbnServer, server) { - const migrator = kbnServer.newPlatform.__internals.kibanaMigrator; - const typeRegistry = kbnServer.newPlatform.start.core.savedObjects.getTypeRegistry(); - const mappings = migrator.getActiveMappings(); - const allTypes = typeRegistry.getAllTypes().map((t) => t.name); - const visibleTypes = typeRegistry.getVisibleTypes().map((t) => t.name); - const schema = new SavedObjectsSchema(convertTypesToLegacySchema(typeRegistry.getAllTypes())); - - server.decorate('server', 'kibanaMigrator', migrator); - - const serializer = kbnServer.newPlatform.start.core.savedObjects.createSerializer(); - - const createRepository = (callCluster, includedHiddenTypes = []) => { - if (typeof callCluster !== 'function') { - throw new TypeError('Repository requires a "callCluster" function to be provided.'); - } - // throw an exception if an extraType is not defined. - includedHiddenTypes.forEach((type) => { - if (!allTypes.includes(type)) { - throw new Error(`Missing mappings for saved objects type '${type}'`); - } - }); - const combinedTypes = visibleTypes.concat(includedHiddenTypes); - const allowedTypes = [...new Set(combinedTypes)]; - - const config = server.config(); - - return new SavedObjectsRepository({ - index: config.get('kibana.index'), - migrator, - mappings, - typeRegistry, - serializer, - allowedTypes, - callCluster, - }); - }; - - const provider = kbnServer.newPlatform.__internals.savedObjectsClientProvider; - - const service = { - types: visibleTypes, - SavedObjectsClient, - SavedObjectsRepository, - getSavedObjectsRepository: createRepository, - getScopedSavedObjectsClient: (...args) => provider.getClient(...args), - setScopedSavedObjectsClientFactory: (...args) => provider.setClientFactory(...args), - addScopedSavedObjectsClientWrapperFactory: (...args) => - provider.addClientWrapperFactory(...args), - importExport: { - objectLimit: server.config().get('savedObjects.maxImportExportSize'), - importSavedObjects: importSavedObjectsFromStream, - resolveImportErrors: resolveSavedObjectsImportErrors, - getSortedObjectsForExport: exportSavedObjectsToStream, - }, - schema, - }; - server.decorate('server', 'savedObjects', service); - - const savedObjectsClientCache = new WeakMap(); - server.decorate('request', 'getSavedObjectsClient', function (options) { - const request = this; - - if (savedObjectsClientCache.has(request)) { - return savedObjectsClientCache.get(request); - } - - const savedObjectsClient = server.savedObjects.getScopedSavedObjectsClient(request, options); - - savedObjectsClientCache.set(request, savedObjectsClient); - return savedObjectsClient; - }); -} diff --git a/src/legacy/server/saved_objects/saved_objects_mixin.test.js b/src/legacy/server/saved_objects/saved_objects_mixin.test.js deleted file mode 100644 index d1d6c052ad589..0000000000000 --- a/src/legacy/server/saved_objects/saved_objects_mixin.test.js +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { savedObjectsMixin } from './saved_objects_mixin'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { mockKibanaMigrator } from '../../../core/server/saved_objects/migrations/kibana/kibana_migrator.mock'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { savedObjectsClientProviderMock } from '../../../core/server/saved_objects/service/lib/scoped_client_provider.mock'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { convertLegacyTypes } from '../../../core/server/saved_objects/utils'; -import { SavedObjectTypeRegistry } from '../../../core/server'; -import { coreMock } from '../../../core/server/mocks'; - -const mockConfig = { - get: jest.fn().mockReturnValue('anything'), -}; - -const savedObjectMappings = [ - { - pluginId: 'testtype', - properties: { - testtype: { - properties: { - name: { type: 'keyword' }, - }, - }, - }, - }, - { - pluginId: 'testtype2', - properties: { - doc1: { - properties: { - name: { type: 'keyword' }, - }, - }, - doc2: { - properties: { - name: { type: 'keyword' }, - }, - }, - }, - }, - { - pluginId: 'secretPlugin', - properties: { - hiddentype: { - properties: { - secret: { type: 'keyword' }, - }, - }, - }, - }, -]; - -const savedObjectSchemas = { - hiddentype: { - hidden: true, - }, - doc1: { - indexPattern: 'other-index', - }, -}; - -const savedObjectTypes = convertLegacyTypes( - { - savedObjectMappings, - savedObjectSchemas, - savedObjectMigrations: {}, - }, - mockConfig -); - -const typeRegistry = new SavedObjectTypeRegistry(); -savedObjectTypes.forEach((type) => typeRegistry.registerType(type)); - -const migrator = mockKibanaMigrator.create({ - types: savedObjectTypes, -}); - -describe('Saved Objects Mixin', () => { - let mockKbnServer; - let mockServer; - const mockCallCluster = jest.fn(); - const stubCallCluster = jest.fn(); - const config = { - 'kibana.index': 'kibana.index', - 'savedObjects.maxImportExportSize': 10000, - }; - const stubConfig = jest.fn((key) => { - return config[key]; - }); - - beforeEach(() => { - const clientProvider = savedObjectsClientProviderMock.create(); - mockServer = { - log: jest.fn(), - route: jest.fn(), - decorate: jest.fn(), - config: () => { - return { - get: stubConfig, - }; - }, - plugins: { - elasticsearch: { - getCluster: () => { - return { - callWithRequest: mockCallCluster, - callWithInternalUser: stubCallCluster, - }; - }, - waitUntilReady: jest.fn(), - }, - }, - }; - - const coreStart = coreMock.createStart(); - coreStart.savedObjects.getTypeRegistry.mockReturnValue(typeRegistry); - - mockKbnServer = { - newPlatform: { - __internals: { - kibanaMigrator: migrator, - savedObjectsClientProvider: clientProvider, - }, - setup: { - core: coreMock.createSetup(), - }, - start: { - core: coreStart, - }, - }, - server: mockServer, - ready: () => {}, - pluginSpecs: { - some: () => { - return true; - }, - }, - uiExports: { - savedObjectMappings, - savedObjectSchemas, - }, - }; - }); - - describe('Saved object service', () => { - let service; - - beforeEach(async () => { - await savedObjectsMixin(mockKbnServer, mockServer); - const call = mockServer.decorate.mock.calls.filter( - ([objName, methodName]) => objName === 'server' && methodName === 'savedObjects' - ); - service = call[0][2]; - }); - - it('should return all but hidden types', async () => { - expect(service).toBeDefined(); - expect(service.types).toEqual(['testtype', 'doc1', 'doc2']); - }); - - const mockCallEs = jest.fn(); - describe('repository creation', () => { - it('should not allow a repository with an undefined type', () => { - expect(() => { - service.getSavedObjectsRepository(mockCallEs, ['extraType']); - }).toThrow(new Error("Missing mappings for saved objects type 'extraType'")); - }); - - it('should create a repository without hidden types', () => { - const repository = service.getSavedObjectsRepository(mockCallEs); - expect(repository).toBeDefined(); - expect(repository._allowedTypes).toEqual(['testtype', 'doc1', 'doc2']); - }); - - it('should create a repository with a unique list of allowed types', () => { - const repository = service.getSavedObjectsRepository(mockCallEs, ['doc1', 'doc1', 'doc1']); - expect(repository._allowedTypes).toEqual(['testtype', 'doc1', 'doc2']); - }); - - it('should create a repository with extraTypes minus duplicate', () => { - const repository = service.getSavedObjectsRepository(mockCallEs, [ - 'hiddentype', - 'hiddentype', - ]); - expect(repository._allowedTypes).toEqual(['testtype', 'doc1', 'doc2', 'hiddentype']); - }); - - it('should not allow a repository without a callCluster function', () => { - expect(() => { - service.getSavedObjectsRepository({}); - }).toThrow(new Error('Repository requires a "callCluster" function to be provided.')); - }); - }); - - describe('get client', () => { - it('should have a method to get the client', () => { - expect(service).toHaveProperty('getScopedSavedObjectsClient'); - }); - - it('should have a method to set the client factory', () => { - expect(service).toHaveProperty('setScopedSavedObjectsClientFactory'); - }); - - it('should have a method to add a client wrapper factory', () => { - expect(service).toHaveProperty('addScopedSavedObjectsClientWrapperFactory'); - }); - - it('should allow you to set a scoped saved objects client factory', () => { - expect(() => { - service.setScopedSavedObjectsClientFactory({}); - }).not.toThrowError(); - }); - - it('should allow you to add a scoped saved objects client wrapper factory', () => { - expect(() => { - service.addScopedSavedObjectsClientWrapperFactory({}); - }).not.toThrowError(); - }); - }); - - describe('#getSavedObjectsClient', () => { - let getSavedObjectsClient; - - beforeEach(() => { - savedObjectsMixin(mockKbnServer, mockServer); - const call = mockServer.decorate.mock.calls.filter( - ([objName, methodName]) => objName === 'request' && methodName === 'getSavedObjectsClient' - ); - getSavedObjectsClient = call[0][2]; - }); - - it('should be callable', () => { - mockServer.savedObjects = service; - getSavedObjectsClient = getSavedObjectsClient.bind({}); - expect(() => { - getSavedObjectsClient(); - }).not.toThrowError(); - }); - - it('should use cached request object', () => { - mockServer.savedObjects = service; - getSavedObjectsClient = getSavedObjectsClient.bind({ _test: 'me' }); - const savedObjectsClient = getSavedObjectsClient(); - expect(getSavedObjectsClient()).toEqual(savedObjectsClient); - }); - }); - }); -}); diff --git a/src/legacy/ui/ui_exports/__tests__/collect_ui_exports.js b/src/legacy/ui/ui_exports/__tests__/collect_ui_exports.js deleted file mode 100644 index 5b2af9f82333c..0000000000000 --- a/src/legacy/ui/ui_exports/__tests__/collect_ui_exports.js +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; - -import { PluginPack } from '../../../plugin_discovery'; - -import { collectUiExports } from '../collect_ui_exports'; - -const specs = new PluginPack({ - path: '/dev/null', - pkg: { - name: 'test', - version: 'kibana', - }, - provider({ Plugin }) { - return [ - new Plugin({ - id: 'test', - uiExports: { - savedObjectSchemas: { - foo: { - isNamespaceAgnostic: true, - }, - }, - }, - }), - new Plugin({ - id: 'test2', - uiExports: { - savedObjectSchemas: { - bar: { - isNamespaceAgnostic: true, - }, - }, - }, - }), - ]; - }, -}).getPluginSpecs(); - -describe('plugin discovery', () => { - describe('collectUiExports()', () => { - it('merges uiExports from all provided plugin specs', () => { - const uiExports = collectUiExports(specs); - - expect(uiExports.savedObjectSchemas).to.eql({ - foo: { - isNamespaceAgnostic: true, - }, - bar: { - isNamespaceAgnostic: true, - }, - }); - }); - - it(`throws an error when migrations and mappings aren't defined in the same plugin`, () => { - const invalidSpecs = new PluginPack({ - path: '/dev/null', - pkg: { - name: 'test', - version: 'kibana', - }, - provider({ Plugin }) { - return [ - new Plugin({ - id: 'test', - uiExports: { - mappings: { - 'test-type': { - properties: {}, - }, - }, - }, - }), - new Plugin({ - id: 'test2', - uiExports: { - migrations: { - 'test-type': { - '1.2.3': (doc) => { - return doc; - }, - }, - }, - }, - }), - ]; - }, - }).getPluginSpecs(); - expect(() => collectUiExports(invalidSpecs)).to.throwError((err) => { - expect(err).to.be.a(Error); - expect(err).to.have.property( - 'message', - 'Migrations and mappings must be defined together in the uiExports of a single plugin. ' + - 'test2 defines migrations for types test-type but does not define their mappings.' - ); - }); - }); - }); -}); diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js index cd8dcf5aff71d..e3b7c1e0c3ff9 100644 --- a/src/legacy/ui/ui_render/ui_render_mixin.js +++ b/src/legacy/ui/ui_render/ui_render_mixin.js @@ -193,13 +193,11 @@ export function uiRenderMixin(kbnServer, server, config) { async function renderApp(h) { const app = { getId: () => 'core' }; const { http } = kbnServer.newPlatform.setup.core; - const { - rendering, - legacy, - savedObjectsClientProvider: savedObjects, - } = kbnServer.newPlatform.__internals; + const { savedObjects } = kbnServer.newPlatform.start.core; + const { rendering, legacy } = kbnServer.newPlatform.__internals; + const req = KibanaRequest.from(h.request); const uiSettings = kbnServer.newPlatform.start.core.uiSettings.asScopedToClient( - savedObjects.getClient(h.request) + savedObjects.getScopedClient(req) ); const vars = await legacy.getVars(app.getId(), h.request, { apmConfig: getApmConfig(h.request.path), diff --git a/src/legacy/utils/index.js b/src/legacy/utils/index.js index 529b1ddfd8a4d..e2e2331b3aea6 100644 --- a/src/legacy/utils/index.js +++ b/src/legacy/utils/index.js @@ -17,8 +17,6 @@ * under the License. */ -export { BinderBase } from './binder'; -export { BinderFor } from './binder_for'; export { deepCloneWithBuffers } from './deep_clone_with_buffers'; export { unset } from './unset'; export { IS_KIBANA_DISTRIBUTABLE } from './artifact_type'; diff --git a/src/plugins/dashboard/public/application/actions/open_replace_panel_flyout.tsx b/src/plugins/dashboard/public/application/actions/open_replace_panel_flyout.tsx index c676ca052d687..54a294fd2f4ac 100644 --- a/src/plugins/dashboard/public/application/actions/open_replace_panel_flyout.tsx +++ b/src/plugins/dashboard/public/application/actions/open_replace_panel_flyout.tsx @@ -60,7 +60,8 @@ export async function openReplacePanelFlyout(options: { /> ), { - 'data-test-subj': 'replacePanelFlyout', + 'data-test-subj': 'dashboardReplacePanel', + ownFocus: true, } ); } diff --git a/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx b/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx index 0000f63c48c2d..4e228bc1a7a06 100644 --- a/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx +++ b/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx @@ -19,16 +19,15 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; -import _ from 'lodash'; -import { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui'; +import { EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui'; import { NotificationsStart, Toast } from 'src/core/public'; import { DashboardPanelState } from '../embeddable'; import { - IContainer, - IEmbeddable, EmbeddableInput, EmbeddableOutput, EmbeddableStart, + IContainer, + IEmbeddable, SavedObjectEmbeddableInput, } from '../../embeddable_plugin'; @@ -122,7 +121,7 @@ export class ReplacePanelFlyout extends React.Component { const panelToReplace = 'Replace panel ' + this.props.panelToRemove.getTitle() + ' with:'; return ( - + <>

@@ -131,7 +130,7 @@ export class ReplacePanelFlyout extends React.Component { {savedObjectsFinder} - + ); } } diff --git a/src/plugins/data/common/constants.ts b/src/plugins/data/common/constants.ts index 22db1552e4303..43120583bd3a4 100644 --- a/src/plugins/data/common/constants.ts +++ b/src/plugins/data/common/constants.ts @@ -32,6 +32,7 @@ export const UI_SETTINGS = { COURIER_MAX_CONCURRENT_SHARD_REQUESTS: 'courier:maxConcurrentShardRequests', COURIER_BATCH_SEARCHES: 'courier:batchSearches', SEARCH_INCLUDE_FROZEN: 'search:includeFrozen', + SEARCH_TIMEOUT: 'search:timeout', HISTOGRAM_BAR_TARGET: 'histogram:barTarget', HISTOGRAM_MAX_BARS: 'histogram:maxBars', HISTORY_LIMIT: 'history:limit', diff --git a/src/plugins/data/common/field_formats/converters/duration.test.ts b/src/plugins/data/common/field_formats/converters/duration.test.ts index d6205d54bd702..69163842f3498 100644 --- a/src/plugins/data/common/field_formats/converters/duration.test.ts +++ b/src/plugins/data/common/field_formats/converters/duration.test.ts @@ -24,11 +24,16 @@ describe('Duration Format', () => { inputFormat: 'seconds', outputFormat: 'humanize', outputPrecision: undefined, + showSuffix: undefined, fixtures: [ { input: -60, output: 'minus a minute', }, + { + input: 1, + output: 'a few seconds', + }, { input: 60, output: 'a minute', @@ -44,6 +49,7 @@ describe('Duration Format', () => { inputFormat: 'minutes', outputFormat: 'humanize', outputPrecision: undefined, + showSuffix: undefined, fixtures: [ { input: -60, @@ -64,6 +70,7 @@ describe('Duration Format', () => { inputFormat: 'minutes', outputFormat: 'asHours', outputPrecision: undefined, + showSuffix: undefined, fixtures: [ { input: -60, @@ -84,6 +91,7 @@ describe('Duration Format', () => { inputFormat: 'seconds', outputFormat: 'asSeconds', outputPrecision: 0, + showSuffix: undefined, fixtures: [ { input: -60, @@ -104,6 +112,7 @@ describe('Duration Format', () => { inputFormat: 'seconds', outputFormat: 'asSeconds', outputPrecision: 2, + showSuffix: undefined, fixtures: [ { input: -60, @@ -124,15 +133,34 @@ describe('Duration Format', () => { ], }); + testCase({ + inputFormat: 'seconds', + outputFormat: 'asSeconds', + outputPrecision: 0, + showSuffix: true, + fixtures: [ + { + input: -60, + output: '-60 Seconds', + }, + { + input: -32.333, + output: '-32 Seconds', + }, + ], + }); + function testCase({ inputFormat, outputFormat, outputPrecision, + showSuffix, fixtures, }: { inputFormat: string; outputFormat: string; outputPrecision: number | undefined; + showSuffix: boolean | undefined; fixtures: any[]; }) { fixtures.forEach((fixture: Record) => { @@ -143,7 +171,7 @@ describe('Duration Format', () => { outputPrecision ? `, ${outputPrecision} decimals` : '' }`, () => { const duration = new DurationFormat( - { inputFormat, outputFormat, outputPrecision }, + { inputFormat, outputFormat, outputPrecision, showSuffix }, jest.fn() ); expect(duration.convert(input)).toBe(output); diff --git a/src/plugins/data/common/field_formats/converters/duration.ts b/src/plugins/data/common/field_formats/converters/duration.ts index 53c2aba98120e..a3ce3d4dfd795 100644 --- a/src/plugins/data/common/field_formats/converters/duration.ts +++ b/src/plugins/data/common/field_formats/converters/duration.ts @@ -190,6 +190,7 @@ export class DurationFormat extends FieldFormat { const inputFormat = this.param('inputFormat'); const outputFormat = this.param('outputFormat') as keyof Duration; const outputPrecision = this.param('outputPrecision'); + const showSuffix = Boolean(this.param('showSuffix')); const human = this.isHuman(); const prefix = val < 0 && human @@ -200,6 +201,9 @@ export class DurationFormat extends FieldFormat { const duration = parseInputAsDuration(val, inputFormat) as Record; const formatted = duration[outputFormat](); const precise = human ? formatted : formatted.toFixed(outputPrecision); - return prefix + precise; + const type = outputFormats.find(({ method }) => method === outputFormat); + const suffix = showSuffix && type ? ` ${type.text}` : ''; + + return prefix + precise + suffix; }; } diff --git a/src/plugins/data/common/search/es_search/index.ts b/src/plugins/data/common/search/es_search/index.ts index 54757b53b8665..d8f7b5091eb8f 100644 --- a/src/plugins/data/common/search/es_search/index.ts +++ b/src/plugins/data/common/search/es_search/index.ts @@ -17,10 +17,4 @@ * under the License. */ -export { - ISearchRequestParams, - IEsSearchRequest, - IEsSearchResponse, - ES_SEARCH_STRATEGY, - ISearchOptions, -} from './types'; +export * from './types'; diff --git a/src/plugins/data/common/search/es_search/types.ts b/src/plugins/data/common/search/es_search/types.ts index 89faa5b7119c8..81124c1e095f7 100644 --- a/src/plugins/data/common/search/es_search/types.ts +++ b/src/plugins/data/common/search/es_search/types.ts @@ -53,3 +53,6 @@ export interface IEsSearchResponse extends IKibanaSearchResponse { isPartial?: boolean; rawResponse: SearchResponse; } + +export const isEsResponse = (response: any): response is IEsSearchResponse => + response && response.rawResponse; diff --git a/src/plugins/data/common/search/index.ts b/src/plugins/data/common/search/index.ts index 3bfb0ddb89aa9..061974d860246 100644 --- a/src/plugins/data/common/search/index.ts +++ b/src/plugins/data/common/search/index.ts @@ -22,11 +22,4 @@ export * from './es_search'; export * from './expressions'; export * from './tabify'; export * from './types'; - -export { - IEsSearchRequest, - IEsSearchResponse, - ES_SEARCH_STRATEGY, - ISearchRequestParams, - ISearchOptions, -} from './es_search'; +export * from './es_search'; diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index f7b4111df5172..553ee6bde5f2d 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -429,6 +429,7 @@ export { TimeHistory, TimefilterContract, TimeHistoryContract, + QueryStateChange, } from './query'; export { diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index a3de45189a85d..27d4ea49f9eb1 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -693,7 +693,6 @@ export const getKbnTypeNames: () => string[]; // // @public (undocumented) export function getSearchParamsFromRequest(searchRequest: SearchRequest, dependencies: { - esShardTimeout: number; getConfig: GetConfigFn; }): ISearchRequestParams; @@ -1465,6 +1464,17 @@ export interface QueryState { time?: TimeRange; } +// Warning: (ae-forgotten-export) The symbol "QueryStateChangePartial" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "QueryStateChange" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface QueryStateChange extends QueryStateChangePartial { + // (undocumented) + appFilters?: boolean; + // (undocumented) + globalFilters?: boolean; +} + // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "QueryStringInput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1682,8 +1692,8 @@ export const search: { // Warning: (ae-missing-release-tag) "SearchBar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const SearchBar: React.ComponentClass, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "indexPatterns" | "dataTestSubj" | "customSubmitButton" | "screenTitle" | "showQueryBar" | "showQueryInput" | "showFilterBar" | "showDatePicker" | "showAutoRefreshOnly" | "isRefreshPaused" | "dateRangeFrom" | "dateRangeTo" | "showSaveQuery" | "savedQuery" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated" | "onClearSavedQuery" | "indicateNoData" | "timeHistory" | "onFiltersUpdated">, any> & { - WrappedComponent: React.ComponentType & ReactIntl.InjectedIntlProps>; +export const SearchBar: React.ComponentClass, "query" | "isLoading" | "filters" | "onRefresh" | "onRefreshChange" | "refreshInterval" | "indexPatterns" | "dataTestSubj" | "timeHistory" | "customSubmitButton" | "screenTitle" | "showQueryBar" | "showQueryInput" | "showFilterBar" | "showDatePicker" | "showAutoRefreshOnly" | "isRefreshPaused" | "dateRangeFrom" | "dateRangeTo" | "showSaveQuery" | "savedQuery" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated" | "onClearSavedQuery" | "indicateNoData" | "onFiltersUpdated">, any> & { + WrappedComponent: React.ComponentType & ReactIntl.InjectedIntlProps>; }; // Warning: (ae-forgotten-export) The symbol "SearchBarOwnProps" needs to be exported by the entry point index.d.ts @@ -1715,7 +1725,7 @@ export interface SearchError { // // @public (undocumented) export class SearchInterceptor { - constructor(deps: SearchInterceptorDeps, requestTimeout?: number | undefined); + constructor(deps: SearchInterceptorDeps); // @internal protected abortController: AbortController; // @internal (undocumented) @@ -1729,13 +1739,14 @@ export class SearchInterceptor { protected longRunningToast?: Toast; // @internal protected pendingCount$: BehaviorSubject; - // (undocumented) - protected readonly requestTimeout?: number | undefined; - // (undocumented) + // @internal (undocumented) protected runSearch(request: IEsSearchRequest, signal: AbortSignal, strategy?: string): Observable; search(request: IEsSearchRequest, options?: ISearchOptions): Observable; - // (undocumented) - protected setupTimers(options?: ISearchOptions): { + // @internal (undocumented) + protected setupAbortSignal({ abortSignal, timeout, }: { + abortSignal?: AbortSignal; + timeout?: number; + }): { combinedSignal: AbortSignal; cleanup: () => void; }; @@ -1906,6 +1917,7 @@ export const UI_SETTINGS: { readonly COURIER_MAX_CONCURRENT_SHARD_REQUESTS: "courier:maxConcurrentShardRequests"; readonly COURIER_BATCH_SEARCHES: "courier:batchSearches"; readonly SEARCH_INCLUDE_FROZEN: "search:includeFrozen"; + readonly SEARCH_TIMEOUT: "search:timeout"; readonly HISTOGRAM_BAR_TARGET: "histogram:barTarget"; readonly HISTOGRAM_MAX_BARS: "histogram:maxBars"; readonly HISTORY_LIMIT: "history:limit"; diff --git a/src/plugins/data/public/search/fetch/get_search_params.test.ts b/src/plugins/data/public/search/fetch/get_search_params.test.ts index 1ecb879b1602d..5e83e1f57bb6d 100644 --- a/src/plugins/data/public/search/fetch/get_search_params.test.ts +++ b/src/plugins/data/public/search/fetch/get_search_params.test.ts @@ -25,44 +25,12 @@ function getConfigStub(config: any = {}): GetConfigFn { } describe('getSearchParams', () => { - test('includes rest_total_hits_as_int', () => { - const config = getConfigStub(); + test('includes custom preference', () => { + const config = getConfigStub({ + [UI_SETTINGS.COURIER_SET_REQUEST_PREFERENCE]: 'custom', + [UI_SETTINGS.COURIER_CUSTOM_REQUEST_PREFERENCE]: 'aaa', + }); const searchParams = getSearchParams(config); - expect(searchParams.rest_total_hits_as_int).toBe(true); - }); - - test('includes ignore_unavailable', () => { - const config = getConfigStub(); - const searchParams = getSearchParams(config); - expect(searchParams.ignore_unavailable).toBe(true); - }); - - test('includes ignore_throttled according to search:includeFrozen', () => { - let config = getConfigStub({ [UI_SETTINGS.SEARCH_INCLUDE_FROZEN]: true }); - let searchParams = getSearchParams(config); - expect(searchParams.ignore_throttled).toBe(false); - - config = getConfigStub({ [UI_SETTINGS.SEARCH_INCLUDE_FROZEN]: false }); - searchParams = getSearchParams(config); - expect(searchParams.ignore_throttled).toBe(true); - }); - - test('includes max_concurrent_shard_requests according to courier:maxConcurrentShardRequests', () => { - let config = getConfigStub({ [UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS]: 0 }); - let searchParams = getSearchParams(config); - expect(searchParams.max_concurrent_shard_requests).toBe(undefined); - - config = getConfigStub({ [UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS]: 5 }); - searchParams = getSearchParams(config); - expect(searchParams.max_concurrent_shard_requests).toBe(5); - }); - - test('includes timeout according to esShardTimeout if greater than 0', () => { - const config = getConfigStub(); - let searchParams = getSearchParams(config, 0); - expect(searchParams.timeout).toBe(undefined); - - searchParams = getSearchParams(config, 100); - expect(searchParams.timeout).toBe('100ms'); + expect(searchParams.preference).toBe('aaa'); }); }); diff --git a/src/plugins/data/public/search/fetch/get_search_params.ts b/src/plugins/data/public/search/fetch/get_search_params.ts index 5e0395189f647..ed87c4813951c 100644 --- a/src/plugins/data/public/search/fetch/get_search_params.ts +++ b/src/plugins/data/public/search/fetch/get_search_params.ts @@ -22,26 +22,12 @@ import { SearchRequest } from './types'; const sessionId = Date.now(); -export function getSearchParams(getConfig: GetConfigFn, esShardTimeout: number = 0) { +export function getSearchParams(getConfig: GetConfigFn) { return { - rest_total_hits_as_int: true, - ignore_unavailable: true, - ignore_throttled: getIgnoreThrottled(getConfig), - max_concurrent_shard_requests: getMaxConcurrentShardRequests(getConfig), preference: getPreference(getConfig), - timeout: getTimeout(esShardTimeout), }; } -export function getIgnoreThrottled(getConfig: GetConfigFn) { - return !getConfig(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); -} - -export function getMaxConcurrentShardRequests(getConfig: GetConfigFn) { - const maxConcurrentShardRequests = getConfig(UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS); - return maxConcurrentShardRequests > 0 ? maxConcurrentShardRequests : undefined; -} - export function getPreference(getConfig: GetConfigFn) { const setRequestPreference = getConfig(UI_SETTINGS.COURIER_SET_REQUEST_PREFERENCE); if (setRequestPreference === 'sessionId') return sessionId; @@ -50,19 +36,15 @@ export function getPreference(getConfig: GetConfigFn) { : undefined; } -export function getTimeout(esShardTimeout: number) { - return esShardTimeout > 0 ? `${esShardTimeout}ms` : undefined; -} - /** @public */ // TODO: Could provide this on runtime contract with dependencies // already wired up. export function getSearchParamsFromRequest( searchRequest: SearchRequest, - dependencies: { esShardTimeout: number; getConfig: GetConfigFn } + dependencies: { getConfig: GetConfigFn } ): ISearchRequestParams { - const { esShardTimeout, getConfig } = dependencies; - const searchParams = getSearchParams(getConfig, esShardTimeout); + const { getConfig } = dependencies; + const searchParams = getSearchParams(getConfig); return { index: searchRequest.index.title || searchRequest.index, diff --git a/src/plugins/data/public/search/fetch/index.ts b/src/plugins/data/public/search/fetch/index.ts index 79cdad1897f9c..4b8511edfc26f 100644 --- a/src/plugins/data/public/search/fetch/index.ts +++ b/src/plugins/data/public/search/fetch/index.ts @@ -18,14 +18,7 @@ */ export * from './types'; -export { - getSearchParams, - getSearchParamsFromRequest, - getPreference, - getTimeout, - getIgnoreThrottled, - getMaxConcurrentShardRequests, -} from './get_search_params'; +export { getSearchParams, getSearchParamsFromRequest, getPreference } from './get_search_params'; export { RequestFailure } from './request_error'; export { handleResponse } from './handle_response'; diff --git a/src/plugins/data/public/search/legacy/call_client.test.ts b/src/plugins/data/public/search/legacy/call_client.test.ts index 38f3ab200da90..943a02d22088d 100644 --- a/src/plugins/data/public/search/legacy/call_client.test.ts +++ b/src/plugins/data/public/search/legacy/call_client.test.ts @@ -60,7 +60,6 @@ describe('callClient', () => { http: coreMock.createStart().http, legacySearchService: {}, config: { get: jest.fn() }, - esShardTimeout: 0, loadingCount$: new BehaviorSubject(0), } as FetchHandlers; diff --git a/src/plugins/data/public/search/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor.test.ts index da60f39b522ac..84db69a83a005 100644 --- a/src/plugins/data/public/search/search_interceptor.test.ts +++ b/src/plugins/data/public/search/search_interceptor.test.ts @@ -32,15 +32,12 @@ jest.useFakeTimers(); describe('SearchInterceptor', () => { beforeEach(() => { mockCoreSetup = coreMock.createSetup(); - searchInterceptor = new SearchInterceptor( - { - toasts: mockCoreSetup.notifications.toasts, - startServices: mockCoreSetup.getStartServices(), - uiSettings: mockCoreSetup.uiSettings, - http: mockCoreSetup.http, - }, - 1000 - ); + searchInterceptor = new SearchInterceptor({ + toasts: mockCoreSetup.notifications.toasts, + startServices: mockCoreSetup.getStartServices(), + uiSettings: mockCoreSetup.uiSettings, + http: mockCoreSetup.http, + }); }); describe('search', () => { diff --git a/src/plugins/data/public/search/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor.ts index c6c03267163c9..0a6d60afed2f7 100644 --- a/src/plugins/data/public/search/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor.ts @@ -18,7 +18,16 @@ */ import { trimEnd } from 'lodash'; -import { BehaviorSubject, throwError, timer, Subscription, defer, from, Observable } from 'rxjs'; +import { + BehaviorSubject, + throwError, + timer, + Subscription, + defer, + from, + Observable, + NEVER, +} from 'rxjs'; import { finalize, filter } from 'rxjs/operators'; import { Toast, CoreStart, ToastsSetup, CoreSetup } from 'kibana/public'; import { getCombinedSignal, AbortError } from '../../common/utils'; @@ -71,17 +80,10 @@ export class SearchInterceptor { */ protected application!: CoreStart['application']; - /** - * This class should be instantiated with a `requestTimeout` corresponding with how many ms after - * requests are initiated that they should automatically cancel. - * @param toasts The `core.notifications.toasts` service - * @param application The `core.application` service - * @param requestTimeout Usually config value `elasticsearch.requestTimeout` + /* + * @internal */ - constructor( - protected readonly deps: SearchInterceptorDeps, - protected readonly requestTimeout?: number - ) { + constructor(protected readonly deps: SearchInterceptorDeps) { this.deps.http.addLoadingCountSource(this.pendingCount$); this.deps.startServices.then(([coreStart]) => { @@ -94,7 +96,6 @@ export class SearchInterceptor { .pipe(filter((count) => count === 0)) .subscribe(this.hideToast); } - /** * Returns an `Observable` over the current number of pending searches. This could mean that one * of the search requests is still in flight, or that it has only received partial responses. @@ -103,6 +104,9 @@ export class SearchInterceptor { return this.pendingCount$.asObservable(); } + /** + * @internal + */ protected runSearch( request: IEsSearchRequest, signal: AbortSignal, @@ -136,7 +140,9 @@ export class SearchInterceptor { return throwError(new AbortError()); } - const { combinedSignal, cleanup } = this.setupTimers(options); + const { combinedSignal, cleanup } = this.setupAbortSignal({ + abortSignal: options?.abortSignal, + }); this.pendingCount$.next(this.pendingCount$.getValue() + 1); return this.runSearch(request, combinedSignal, options?.strategy).pipe( @@ -148,11 +154,20 @@ export class SearchInterceptor { }); } - protected setupTimers(options?: ISearchOptions) { + /** + * @internal + */ + protected setupAbortSignal({ + abortSignal, + timeout, + }: { + abortSignal?: AbortSignal; + timeout?: number; + }) { // Schedule this request to automatically timeout after some interval const timeoutController = new AbortController(); const { signal: timeoutSignal } = timeoutController; - const timeout$ = timer(this.requestTimeout); + const timeout$ = timeout ? timer(timeout) : NEVER; const subscription = timeout$.subscribe(() => { timeoutController.abort(); }); @@ -168,7 +183,7 @@ export class SearchInterceptor { const signals = [ this.abortController.signal, timeoutSignal, - ...(options?.abortSignal ? [options.abortSignal] : []), + ...(abortSignal ? [abortSignal] : []), ]; const combinedSignal = getCombinedSignal(signals); diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index a49d2ef0956ff..f8f4acbe43dfd 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -52,26 +52,19 @@ export class SearchService implements Plugin { { http, getStartServices, injectedMetadata, notifications, uiSettings }: CoreSetup, { expressions, usageCollection }: SearchServiceSetupDependencies ): ISearchSetup { - const esRequestTimeout = injectedMetadata.getInjectedVar('esRequestTimeout') as number; - this.usageCollector = createUsageCollector(getStartServices, usageCollection); /** * A global object that intercepts all searches and provides convenience methods for cancelling * all pending search requests, as well as getting the number of pending search requests. - * TODO: Make this modular so that apps can opt in/out of search collection, or even provide - * their own search collector instances */ - this.searchInterceptor = new SearchInterceptor( - { - toasts: notifications.toasts, - http, - uiSettings, - startServices: getStartServices(), - usageCollector: this.usageCollector!, - }, - esRequestTimeout - ); + this.searchInterceptor = new SearchInterceptor({ + toasts: notifications.toasts, + http, + uiSettings, + startServices: getStartServices(), + usageCollector: this.usageCollector!, + }); expressions.registerFunction(esdsl); expressions.registerType(esRawResponse); @@ -101,8 +94,6 @@ export class SearchService implements Plugin { const searchSourceDependencies: SearchSourceDependencies = { getConfig: uiSettings.get.bind(uiSettings), - // TODO: we don't need this, apply on the server - esShardTimeout: injectedMetadata.getInjectedVar('esShardTimeout') as number, search, http, loadingCount$, diff --git a/src/plugins/data/public/search/search_source/create_search_source.test.ts b/src/plugins/data/public/search/search_source/create_search_source.test.ts index 2820aab67ea3a..bc1c7c06c8806 100644 --- a/src/plugins/data/public/search/search_source/create_search_source.test.ts +++ b/src/plugins/data/public/search/search_source/create_search_source.test.ts @@ -35,7 +35,6 @@ describe('createSearchSource', () => { dependencies = { getConfig: jest.fn(), search: jest.fn(), - esShardTimeout: 30000, http: coreMock.createStart().http, loadingCount$: new BehaviorSubject(0), }; diff --git a/src/plugins/data/public/search/search_source/mocks.ts b/src/plugins/data/public/search/search_source/mocks.ts index bc3e287d9fe80..adf53bee33fe1 100644 --- a/src/plugins/data/public/search/search_source/mocks.ts +++ b/src/plugins/data/public/search/search_source/mocks.ts @@ -53,7 +53,6 @@ export const searchSourceMock = { export const createSearchSourceMock = (fields?: SearchSourceFields) => new SearchSource(fields, { getConfig: uiSettingsServiceMock.createStartContract().get, - esShardTimeout: 30000, search: jest.fn(), http: httpServiceMock.createStartContract(), loadingCount$: new BehaviorSubject(0), diff --git a/src/plugins/data/public/search/search_source/search_source.test.ts b/src/plugins/data/public/search/search_source/search_source.test.ts index a8baed9faa84d..282a33e6d01f7 100644 --- a/src/plugins/data/public/search/search_source/search_source.test.ts +++ b/src/plugins/data/public/search/search_source/search_source.test.ts @@ -68,7 +68,6 @@ describe('SearchSource', () => { searchSourceDependencies = { getConfig: jest.fn(), search: mockSearchMethod, - esShardTimeout: 30000, http: coreMock.createStart().http, loadingCount$: new BehaviorSubject(0), }; diff --git a/src/plugins/data/public/search/search_source/search_source.ts b/src/plugins/data/public/search/search_source/search_source.ts index eec2d9b50eafe..68c7b663b3628 100644 --- a/src/plugins/data/public/search/search_source/search_source.ts +++ b/src/plugins/data/public/search/search_source/search_source.ts @@ -118,7 +118,6 @@ export interface SearchSourceDependencies { getConfig: GetConfigFn; search: ISearchGeneric; http: HttpStart; - esShardTimeout: number; loadingCount$: BehaviorSubject; } @@ -233,10 +232,9 @@ export class SearchSource { * @return {Observable>} */ private fetch$(searchRequest: SearchRequest, options: ISearchOptions) { - const { search, esShardTimeout, getConfig } = this.dependencies; + const { search, getConfig } = this.dependencies; const params = getSearchParamsFromRequest(searchRequest, { - esShardTimeout, getConfig, }); diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index 71ed83290e697..03baff4910309 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -212,8 +212,11 @@ export { ISearchStrategy, ISearchSetup, ISearchStart, + toSnakeCase, getDefaultSearchParams, + getShardTimeout, getTotalLoaded, + shimHitsTotal, usageProvider, SearchUsage, } from './search'; diff --git a/src/plugins/data/server/search/es_search/es_search_strategy.test.ts b/src/plugins/data/server/search/es_search/es_search_strategy.test.ts index c34c3a310814c..504ce728481f0 100644 --- a/src/plugins/data/server/search/es_search/es_search_strategy.test.ts +++ b/src/plugins/data/server/search/es_search/es_search_strategy.test.ts @@ -36,7 +36,14 @@ describe('ES search strategy', () => { }, }); const mockContext = { - core: { elasticsearch: { client: { asCurrentUser: { search: mockApiCaller } } } }, + core: { + uiSettings: { + client: { + get: () => {}, + }, + }, + elasticsearch: { client: { asCurrentUser: { search: mockApiCaller } } }, + }, }; const mockConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$; @@ -59,14 +66,13 @@ describe('ES search strategy', () => { expect(mockApiCaller).toBeCalled(); expect(mockApiCaller.mock.calls[0][0]).toEqual({ ...params, - timeout: '0ms', - ignoreUnavailable: true, - restTotalHitsAsInt: true, + ignore_unavailable: true, + track_total_hits: true, }); }); it('calls the API caller with overridden defaults', async () => { - const params = { index: 'logstash-*', ignoreUnavailable: false, timeout: '1000ms' }; + const params = { index: 'logstash-*', ignore_unavailable: false, timeout: '1000ms' }; const esSearch = await esSearchStrategyProvider(mockConfig$, mockLogger); await esSearch.search((mockContext as unknown) as RequestHandlerContext, { params }); @@ -74,7 +80,7 @@ describe('ES search strategy', () => { expect(mockApiCaller).toBeCalled(); expect(mockApiCaller.mock.calls[0][0]).toEqual({ ...params, - restTotalHitsAsInt: true, + track_total_hits: true, }); }); diff --git a/src/plugins/data/server/search/es_search/es_search_strategy.ts b/src/plugins/data/server/search/es_search/es_search_strategy.ts index eabbf3e3e2600..106f974ed3457 100644 --- a/src/plugins/data/server/search/es_search/es_search_strategy.ts +++ b/src/plugins/data/server/search/es_search/es_search_strategy.ts @@ -22,7 +22,8 @@ import { SearchResponse } from 'elasticsearch'; import { Observable } from 'rxjs'; import { ApiResponse } from '@elastic/elasticsearch'; import { SearchUsage } from '../collectors/usage'; -import { ISearchStrategy, getDefaultSearchParams, getTotalLoaded } from '..'; +import { toSnakeCase } from './to_snake_case'; +import { ISearchStrategy, getDefaultSearchParams, getTotalLoaded, getShardTimeout } from '..'; export const esSearchStrategyProvider = ( config$: Observable, @@ -33,7 +34,7 @@ export const esSearchStrategyProvider = ( search: async (context, request, options) => { logger.debug(`search ${request.params?.index}`); const config = await config$.pipe(first()).toPromise(); - const defaultParams = getDefaultSearchParams(config); + const uiSettingsClient = await context.core.uiSettings.client; // Only default index pattern type is supported here. // See data_enhanced for other type support. @@ -41,10 +42,14 @@ export const esSearchStrategyProvider = ( throw new Error(`Unsupported index pattern type ${request.indexType}`); } - const params = { + // ignoreThrottled is not supported in OSS + const { ignoreThrottled, ...defaultParams } = await getDefaultSearchParams(uiSettingsClient); + + const params = toSnakeCase({ ...defaultParams, + ...getShardTimeout(config), ...request.params, - }; + }); try { const esResponse = (await context.core.elasticsearch.client.asCurrentUser.search( diff --git a/src/plugins/data/server/search/es_search/get_default_search_params.ts b/src/plugins/data/server/search/es_search/get_default_search_params.ts index b2341ccc0f3c8..13607fce51670 100644 --- a/src/plugins/data/server/search/es_search/get_default_search_params.ts +++ b/src/plugins/data/server/search/es_search/get_default_search_params.ts @@ -17,12 +17,28 @@ * under the License. */ -import { SharedGlobalConfig } from '../../../../../core/server'; +import { SharedGlobalConfig, IUiSettingsClient } from '../../../../../core/server'; +import { UI_SETTINGS } from '../../../common/constants'; -export function getDefaultSearchParams(config: SharedGlobalConfig) { +export function getShardTimeout(config: SharedGlobalConfig) { + const timeout = config.elasticsearch.shardTimeout.asMilliseconds(); + return timeout + ? { + timeout: `${timeout}ms`, + } + : {}; +} + +export async function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient) { + const ignoreThrottled = !(await uiSettingsClient.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN)); + const maxConcurrentShardRequests = await uiSettingsClient.get( + UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS + ); return { - timeout: `${config.elasticsearch.shardTimeout.asMilliseconds()}ms`, + maxConcurrentShardRequests: + maxConcurrentShardRequests > 0 ? maxConcurrentShardRequests : undefined, + ignoreThrottled, ignoreUnavailable: true, // Don't fail if the index/indices don't exist - restTotalHitsAsInt: true, // Get the number of hits as an int rather than a range + trackTotalHits: true, }; } diff --git a/src/plugins/data/server/search/es_search/index.ts b/src/plugins/data/server/search/es_search/index.ts index 20006b70730d8..1bd17fc986168 100644 --- a/src/plugins/data/server/search/es_search/index.ts +++ b/src/plugins/data/server/search/es_search/index.ts @@ -17,7 +17,9 @@ * under the License. */ -export { ES_SEARCH_STRATEGY, IEsSearchRequest, IEsSearchResponse } from '../../../common/search'; export { esSearchStrategyProvider } from './es_search_strategy'; -export { getDefaultSearchParams } from './get_default_search_params'; +export * from './get_default_search_params'; export { getTotalLoaded } from './get_total_loaded'; +export * from './to_snake_case'; + +export { ES_SEARCH_STRATEGY, IEsSearchRequest, IEsSearchResponse } from '../../../common'; diff --git a/src/legacy/utils/path_contains.js b/src/plugins/data/server/search/es_search/to_snake_case.ts similarity index 83% rename from src/legacy/utils/path_contains.js rename to src/plugins/data/server/search/es_search/to_snake_case.ts index 60d05c1099554..74f156274cbc6 100644 --- a/src/legacy/utils/path_contains.js +++ b/src/plugins/data/server/search/es_search/to_snake_case.ts @@ -17,8 +17,8 @@ * under the License. */ -import { relative } from 'path'; +import { mapKeys, snakeCase } from 'lodash'; -export default function pathContains(root, child) { - return relative(child, root).slice(0, 2) !== '..'; +export function toSnakeCase(obj: Record) { + return mapKeys(obj, (value, key) => snakeCase(key)); } diff --git a/src/plugins/data/server/search/index.ts b/src/plugins/data/server/search/index.ts index 8a74c51f52f51..b671ed806510b 100644 --- a/src/plugins/data/server/search/index.ts +++ b/src/plugins/data/server/search/index.ts @@ -19,8 +19,10 @@ export { ISearchStrategy, ISearchSetup, ISearchStart, SearchEnhancements } from './types'; -export { getDefaultSearchParams, getTotalLoaded } from './es_search'; +export * from './es_search'; export { usageProvider, SearchUsage } from './collectors'; export * from './aggs'; + +export { shimHitsTotal } from './routes'; diff --git a/src/plugins/data/server/search/routes/index.ts b/src/plugins/data/server/search/routes/index.ts index 2217890ff778e..a290f08f9b843 100644 --- a/src/plugins/data/server/search/routes/index.ts +++ b/src/plugins/data/server/search/routes/index.ts @@ -19,3 +19,4 @@ export * from './msearch'; export * from './search'; +export * from './shim_hits_total'; diff --git a/src/plugins/data/server/search/routes/msearch.test.ts b/src/plugins/data/server/search/routes/msearch.test.ts index 0a52cf23c5472..3a7d67c31b8be 100644 --- a/src/plugins/data/server/search/routes/msearch.test.ts +++ b/src/plugins/data/server/search/routes/msearch.test.ts @@ -48,7 +48,7 @@ describe('msearch route', () => { }); it('handler calls /_msearch with the given request', async () => { - const response = { id: 'yay' }; + const response = { id: 'yay', body: { responses: [{ hits: { total: 5 } }] } }; const mockClient = { transport: { request: jest.fn().mockResolvedValue(response) } }; const mockContext = { core: { @@ -73,7 +73,7 @@ describe('msearch route', () => { expect(mockClient.transport.request.mock.calls[0][0].method).toBe('GET'); expect(mockClient.transport.request.mock.calls[0][0].path).toBe('/_msearch'); expect(mockClient.transport.request.mock.calls[0][0].body).toEqual( - convertRequestBody(mockBody as any, { timeout: '0ms' }) + convertRequestBody(mockBody as any, {}) ); expect(mockResponse.ok).toBeCalled(); expect(mockResponse.ok.mock.calls[0][0]).toEqual({ diff --git a/src/plugins/data/server/search/routes/msearch.ts b/src/plugins/data/server/search/routes/msearch.ts index efb40edd90d58..e1ddb06e4fb6f 100644 --- a/src/plugins/data/server/search/routes/msearch.ts +++ b/src/plugins/data/server/search/routes/msearch.ts @@ -20,10 +20,11 @@ import { first } from 'rxjs/operators'; import { schema } from '@kbn/config-schema'; +import { SearchResponse } from 'elasticsearch'; import { IRouter } from 'src/core/server'; -import { UI_SETTINGS } from '../../../common'; import { SearchRouteDependencies } from '../search_service'; -import { getDefaultSearchParams } from '..'; +import { shimHitsTotal } from './shim_hits_total'; +import { getShardTimeout, getDefaultSearchParams, toSnakeCase } from '..'; interface MsearchHeaders { index: string; @@ -96,30 +97,31 @@ export function registerMsearchRoute(router: IRouter, deps: SearchRouteDependenc // get shardTimeout const config = await deps.globalConfig$.pipe(first()).toPromise(); - const { timeout } = getDefaultSearchParams(config); + const timeout = getShardTimeout(config); - const body = convertRequestBody(request.body, { timeout }); + const body = convertRequestBody(request.body, timeout); + + // trackTotalHits is not supported by msearch + const { trackTotalHits, ...defaultParams } = await getDefaultSearchParams( + context.core.uiSettings.client + ); try { - const ignoreThrottled = !(await context.core.uiSettings.client.get( - UI_SETTINGS.SEARCH_INCLUDE_FROZEN - )); - const maxConcurrentShardRequests = await context.core.uiSettings.client.get( - UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS - ); const response = await client.transport.request({ method: 'GET', path: '/_msearch', body, - querystring: { - rest_total_hits_as_int: true, - ignore_throttled: ignoreThrottled, - max_concurrent_shard_requests: - maxConcurrentShardRequests > 0 ? maxConcurrentShardRequests : undefined, - }, + querystring: toSnakeCase(defaultParams), }); - return res.ok({ body: response }); + return res.ok({ + body: { + ...response, + body: { + responses: response.body.responses?.map((r: SearchResponse) => shimHitsTotal(r)), + }, + }, + }); } catch (err) { return res.customError({ statusCode: err.statusCode || 500, diff --git a/src/plugins/data/server/search/routes/search.ts b/src/plugins/data/server/search/routes/search.ts index 4340285583489..b5d5ec283767d 100644 --- a/src/plugins/data/server/search/routes/search.ts +++ b/src/plugins/data/server/search/routes/search.ts @@ -21,6 +21,8 @@ import { schema } from '@kbn/config-schema'; import { IRouter } from 'src/core/server'; import { getRequestAbortedSignal } from '../../lib'; import { SearchRouteDependencies } from '../search_service'; +import { shimHitsTotal } from './shim_hits_total'; +import { isEsResponse } from '../../../common'; export function registerSearchRoute( router: IRouter, @@ -56,7 +58,17 @@ export function registerSearchRoute( strategy, } ); - return res.ok({ body: response }); + + return res.ok({ + body: { + ...response, + ...(isEsResponse(response) + ? { + rawResponse: shimHitsTotal(response.rawResponse), + } + : {}), + }, + }); } catch (err) { return res.customError({ statusCode: err.statusCode || 500, diff --git a/x-pack/plugins/data_enhanced/server/search/shim_hits_total.test.ts b/src/plugins/data/server/search/routes/shim_hits_total.test.ts similarity index 54% rename from x-pack/plugins/data_enhanced/server/search/shim_hits_total.test.ts rename to src/plugins/data/server/search/routes/shim_hits_total.test.ts index 61740b97299da..0f24735386121 100644 --- a/x-pack/plugins/data_enhanced/server/search/shim_hits_total.test.ts +++ b/src/plugins/data/server/search/routes/shim_hits_total.test.ts @@ -1,7 +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; - * you may not use this file except in compliance with the Elastic License. + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ import { shimHitsTotal } from './shim_hits_total'; diff --git a/src/plugins/data/server/search/routes/shim_hits_total.ts b/src/plugins/data/server/search/routes/shim_hits_total.ts new file mode 100644 index 0000000000000..5f95b21358978 --- /dev/null +++ b/src/plugins/data/server/search/routes/shim_hits_total.ts @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { SearchResponse } from 'elasticsearch'; + +/** + * Temporary workaround until https://github.com/elastic/kibana/issues/26356 is addressed. + * Since we are setting `track_total_hits` in the request, `hits.total` will be an object + * containing the `value`. + * + * @internal + */ +export function shimHitsTotal(response: SearchResponse) { + const total = (response.hits?.total as any)?.value ?? response.hits?.total; + const hits = { ...response.hits, total }; + return { ...response, hits }; +} diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index a4f5f590e1774..cd0369a5c4551 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -446,14 +446,25 @@ export interface Filter { query?: any; } -// Warning: (ae-forgotten-export) The symbol "SharedGlobalConfig" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "IUiSettingsClient" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "getDefaultSearchParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export function getDefaultSearchParams(config: SharedGlobalConfig): { - timeout: string; +export function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient): Promise<{ + maxConcurrentShardRequests: number | undefined; + ignoreThrottled: boolean; ignoreUnavailable: boolean; - restTotalHitsAsInt: boolean; + trackTotalHits: boolean; +}>; + +// Warning: (ae-forgotten-export) The symbol "SharedGlobalConfig" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "getShardTimeout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function getShardTimeout(config: SharedGlobalConfig): { + timeout: string; +} | { + timeout?: undefined; }; // Warning: (ae-missing-release-tag) "getTime" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -873,7 +884,7 @@ export class Plugin implements Plugin_2>; + search: ISearchStart>; fieldFormats: { fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise; }; @@ -989,6 +1000,33 @@ export interface SearchUsage { trackSuccess(duration: number): Promise; } +// @internal +export function shimHitsTotal(response: SearchResponse): { + hits: { + total: any; + max_score: number; + hits: { + _index: string; + _type: string; + _id: string; + _score: number; + _source: any; + _version?: number | undefined; + _explanation?: import("elasticsearch").Explanation | undefined; + fields?: any; + highlight?: any; + inner_hits?: any; + matched_queries?: string[] | undefined; + sort?: string[] | undefined; + }[]; + }; + took: number; + timed_out: boolean; + _scroll_id?: string | undefined; + _shards: import("elasticsearch").ShardsResponse; + aggregations?: any; +}; + // Warning: (ae-missing-release-tag) "shouldReadFieldFromDocValues" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1027,6 +1065,11 @@ export interface TimeRange { to: string; } +// Warning: (ae-missing-release-tag) "toSnakeCase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function toSnakeCase(obj: Record): import("lodash").Dictionary; + // Warning: (ae-missing-release-tag) "UI_SETTINGS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1043,6 +1086,7 @@ export const UI_SETTINGS: { readonly COURIER_MAX_CONCURRENT_SHARD_REQUESTS: "courier:maxConcurrentShardRequests"; readonly COURIER_BATCH_SEARCHES: "courier:batchSearches"; readonly SEARCH_INCLUDE_FROZEN: "search:includeFrozen"; + readonly SEARCH_TIMEOUT: "search:timeout"; readonly HISTOGRAM_BAR_TARGET: "histogram:barTarget"; readonly HISTOGRAM_MAX_BARS: "histogram:maxBars"; readonly HISTORY_LIMIT: "history:limit"; @@ -1091,19 +1135,19 @@ export function usageProvider(core: CoreSetup_2): SearchUsage; // src/plugins/data/server/index.ts:101:26 - (ae-forgotten-export) The symbol "TruncateFormat" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index.ts:127:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index.ts:127:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:222:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:222:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:222:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:222:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:224:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:225:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:234:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:235:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:236:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:240:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:241:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:245:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:248:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:225:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:225:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:225:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:225:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:227:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:228:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:237:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:238:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:239:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:243:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:244:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:248:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:251:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/server/plugin.ts:88:66 - (ae-forgotten-export) The symbol "DataEnhancements" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx b/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx index 0d6fd122ad22c..7a42ed7fad427 100644 --- a/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx +++ b/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx @@ -106,7 +106,7 @@ export const createUseRequestHelpers = (): UseRequestHelpers => { }; const TestComponent = ({ requestConfig }: { requestConfig: UseRequestConfig }) => { - const { isInitialRequest, isLoading, error, data, sendRequest } = useRequest( + const { isInitialRequest, isLoading, error, data, resendRequest } = useRequest( httpClient as HttpSetup, requestConfig ); @@ -115,7 +115,7 @@ export const createUseRequestHelpers = (): UseRequestHelpers => { hookResult.isLoading = isLoading; hookResult.error = error; hookResult.data = data; - hookResult.sendRequest = sendRequest; + hookResult.resendRequest = resendRequest; return null; }; diff --git a/src/plugins/es_ui_shared/public/request/use_request.test.ts b/src/plugins/es_ui_shared/public/request/use_request.test.ts index f7902218d9314..2a639f93b47b4 100644 --- a/src/plugins/es_ui_shared/public/request/use_request.test.ts +++ b/src/plugins/es_ui_shared/public/request/use_request.test.ts @@ -102,7 +102,7 @@ describe('useRequest hook', () => { setupSuccessRequest(); expect(hookResult.isInitialRequest).toBe(true); - hookResult.sendRequest(); + hookResult.resendRequest(); await completeRequest(); expect(hookResult.isInitialRequest).toBe(false); }); @@ -148,7 +148,7 @@ describe('useRequest hook', () => { expect(hookResult.error).toBe(getErrorResponse().error); act(() => { - hookResult.sendRequest(); + hookResult.resendRequest(); }); expect(hookResult.isLoading).toBe(true); expect(hookResult.error).toBe(getErrorResponse().error); @@ -183,7 +183,7 @@ describe('useRequest hook', () => { expect(hookResult.data).toBe(getSuccessResponse().data); act(() => { - hookResult.sendRequest(); + hookResult.resendRequest(); }); expect(hookResult.isLoading).toBe(true); expect(hookResult.data).toBe(getSuccessResponse().data); @@ -215,7 +215,7 @@ describe('useRequest hook', () => { }); describe('callbacks', () => { - describe('sendRequest', () => { + describe('resendRequest', () => { it('sends the request', async () => { const { setupSuccessRequest, completeRequest, hookResult, getSendRequestSpy } = helpers; setupSuccessRequest(); @@ -224,7 +224,7 @@ describe('useRequest hook', () => { expect(getSendRequestSpy().callCount).toBe(1); await act(async () => { - hookResult.sendRequest(); + hookResult.resendRequest(); await completeRequest(); }); expect(getSendRequestSpy().callCount).toBe(2); @@ -239,17 +239,17 @@ describe('useRequest hook', () => { await advanceTime(REQUEST_TIME); expect(getSendRequestSpy().callCount).toBe(1); act(() => { - hookResult.sendRequest(); + hookResult.resendRequest(); }); // The manual request resolves, and we'll send yet another one... await advanceTime(REQUEST_TIME); expect(getSendRequestSpy().callCount).toBe(2); act(() => { - hookResult.sendRequest(); + hookResult.resendRequest(); }); - // At this point, we've moved forward 3s. The poll is set at 2s. If sendRequest didn't + // At this point, we've moved forward 3s. The poll is set at 2s. If resendRequest didn't // reset the poll, the request call count would be 4, not 3. await advanceTime(REQUEST_TIME); expect(getSendRequestSpy().callCount).toBe(3); @@ -291,14 +291,14 @@ describe('useRequest hook', () => { const HALF_REQUEST_TIME = REQUEST_TIME * 0.5; setupSuccessRequest({ pollIntervalMs: REQUEST_TIME }); - // Before the original request resolves, we make a manual sendRequest call. + // Before the original request resolves, we make a manual resendRequest call. await advanceTime(HALF_REQUEST_TIME); expect(getSendRequestSpy().callCount).toBe(0); act(() => { - hookResult.sendRequest(); + hookResult.resendRequest(); }); - // The original quest resolves but it's been marked as outdated by the the manual sendRequest + // The original quest resolves but it's been marked as outdated by the the manual resendRequest // call "interrupts", so data is left undefined. await advanceTime(HALF_REQUEST_TIME); expect(getSendRequestSpy().callCount).toBe(1); diff --git a/src/plugins/es_ui_shared/public/request/use_request.ts b/src/plugins/es_ui_shared/public/request/use_request.ts index 481843bf40e88..e04f84a67b8a3 100644 --- a/src/plugins/es_ui_shared/public/request/use_request.ts +++ b/src/plugins/es_ui_shared/public/request/use_request.ts @@ -20,11 +20,7 @@ import { useEffect, useCallback, useState, useRef, useMemo } from 'react'; import { HttpSetup } from '../../../../../src/core/public'; -import { - sendRequest as sendStatelessRequest, - SendRequestConfig, - SendRequestResponse, -} from './send_request'; +import { sendRequest, SendRequestConfig } from './send_request'; export interface UseRequestConfig extends SendRequestConfig { pollIntervalMs?: number; @@ -37,7 +33,7 @@ export interface UseRequestResponse { isLoading: boolean; error: E | null; data?: D | null; - sendRequest: () => Promise>; + resendRequest: () => void; } export const useRequest = ( @@ -80,7 +76,7 @@ export const useRequest = ( /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [path, method, queryStringified, bodyStringified]); - const sendRequest = useCallback(async () => { + const resendRequest = useCallback(async () => { // If we're on an interval, this allows us to reset it if the user has manually requested the // data, to avoid doubled-up requests. clearPollInterval(); @@ -91,7 +87,7 @@ export const useRequest = ( // "old" error/data or loading state when a new request is in-flight. setIsLoading(true); - const response = await sendStatelessRequest(httpClient, requestBody); + const response = await sendRequest(httpClient, requestBody); const { data: serializedResponseData, error: responseError } = response; const isOutdatedRequest = requestId !== requestCountRef.current; @@ -99,7 +95,7 @@ export const useRequest = ( // Ignore outdated or irrelevant data. if (isOutdatedRequest || isUnmounted) { - return { data: null, error: null }; + return; } setError(responseError); @@ -112,8 +108,6 @@ export const useRequest = ( } // Setting isLoading to false also acts as a signal for scheduling the next poll request. setIsLoading(false); - - return { data: serializedResponseData, error: responseError }; }, [requestBody, httpClient, deserializer, clearPollInterval]); const scheduleRequest = useCallback(() => { @@ -121,19 +115,19 @@ export const useRequest = ( clearPollInterval(); if (pollIntervalMs) { - pollIntervalIdRef.current = setTimeout(sendRequest, pollIntervalMs); + pollIntervalIdRef.current = setTimeout(resendRequest, pollIntervalMs); } - }, [pollIntervalMs, sendRequest, clearPollInterval]); + }, [pollIntervalMs, resendRequest, clearPollInterval]); - // Send the request on component mount and whenever the dependencies of sendRequest() change. + // Send the request on component mount and whenever the dependencies of resendRequest() change. useEffect(() => { - sendRequest(); - }, [sendRequest]); + resendRequest(); + }, [resendRequest]); // Schedule the next poll request when the previous one completes. useEffect(() => { // When a request completes, attempt to schedule the next one. Note that we aren't re-scheduling - // a request whenever sendRequest's dependencies change. isLoading isn't set to false until the + // a request whenever resendRequest's dependencies change. isLoading isn't set to false until the // initial request has completed, so we won't schedule a request on mount. if (!isLoading) { scheduleRequest(); @@ -156,6 +150,6 @@ export const useRequest = ( isLoading, error, data, - sendRequest, // Gives the user the ability to manually request data + resendRequest, // Gives the user the ability to manually request data }; }; diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_array.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_array.ts index 3688421964d2e..d0ac0d4ab28c3 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_array.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/components/use_array.ts @@ -17,18 +17,25 @@ * under the License. */ -import { useState, useEffect, useRef, useCallback } from 'react'; +import { useEffect, useRef, useCallback, useMemo } from 'react'; +import { FormHook, FieldConfig } from '../types'; +import { getFieldValidityAndErrorMessage } from '../helpers'; import { useFormContext } from '../form_context'; +import { useField, InternalFieldConfig } from '../hooks'; interface Props { path: string; initialNumberOfItems?: number; readDefaultValueOnForm?: boolean; + validations?: FieldConfig['validations']; children: (args: { items: ArrayItem[]; + error: string | null; addItem: () => void; removeItem: (id: number) => void; + moveItem: (sourceIdx: number, destinationIdx: number) => void; + form: FormHook; }) => JSX.Element; } @@ -56,32 +63,62 @@ export interface ArrayItem { export const UseArray = ({ path, initialNumberOfItems, + validations, readDefaultValueOnForm = true, children, }: Props) => { - const didMountRef = useRef(false); - const form = useFormContext(); - const defaultValues = readDefaultValueOnForm && (form.getFieldDefaultValue(path) as any[]); + const isMounted = useRef(false); const uniqueId = useRef(0); - const getInitialItemsFromValues = (values: any[]): ArrayItem[] => - values.map((_, index) => ({ + const form = useFormContext(); + const { getFieldDefaultValue } = form; + + const getNewItemAtIndex = useCallback( + (index: number): ArrayItem => ({ id: uniqueId.current++, path: `${path}[${index}]`, - isNew: false, - })); + isNew: true, + }), + [path] + ); + + const fieldDefaultValue = useMemo(() => { + const defaultValues = readDefaultValueOnForm + ? (getFieldDefaultValue(path) as any[]) + : undefined; - const getNewItemAtIndex = (index: number): ArrayItem => ({ - id: uniqueId.current++, - path: `${path}[${index}]`, - isNew: true, - }); + const getInitialItemsFromValues = (values: any[]): ArrayItem[] => + values.map((_, index) => ({ + id: uniqueId.current++, + path: `${path}[${index}]`, + isNew: false, + })); - const initialState = defaultValues - ? getInitialItemsFromValues(defaultValues) - : new Array(initialNumberOfItems).fill('').map((_, i) => getNewItemAtIndex(i)); + return defaultValues + ? getInitialItemsFromValues(defaultValues) + : new Array(initialNumberOfItems).fill('').map((_, i) => getNewItemAtIndex(i)); + }, [path, initialNumberOfItems, readDefaultValueOnForm, getFieldDefaultValue, getNewItemAtIndex]); - const [items, setItems] = useState(initialState); + // Create a new hook field with the "hasValue" set to false so we don't use its value to build the final form data. + // Apart from that the field behaves like a normal field and is hooked into the form validation lifecycle. + const fieldConfigBase: FieldConfig & InternalFieldConfig = { + defaultValue: fieldDefaultValue, + errorDisplayDelay: 0, + isIncludedInOutput: false, + }; + + const fieldConfig: FieldConfig & InternalFieldConfig = validations + ? { validations, ...fieldConfigBase } + : fieldConfigBase; + + const field = useField(form, path, fieldConfig); + const { setValue, value, isChangingValue, errors } = field; + + // Derived state from the field + const error = useMemo(() => { + const { errorMessage } = getFieldValidityAndErrorMessage({ isChangingValue, errors }); + return errorMessage; + }, [isChangingValue, errors]); const updatePaths = useCallback( (_rows: ArrayItem[]) => { @@ -96,29 +133,51 @@ export const UseArray = ({ [path] ); - const addItem = () => { - setItems((previousItems) => { + const addItem = useCallback(() => { + setValue((previousItems) => { const itemIndex = previousItems.length; return [...previousItems, getNewItemAtIndex(itemIndex)]; }); - }; + }, [setValue, getNewItemAtIndex]); - const removeItem = (id: number) => { - setItems((previousItems) => { - const updatedItems = previousItems.filter((item) => item.id !== id); - return updatePaths(updatedItems); - }); - }; + const removeItem = useCallback( + (id: number) => { + setValue((previousItems) => { + const updatedItems = previousItems.filter((item) => item.id !== id); + return updatePaths(updatedItems); + }); + }, + [setValue, updatePaths] + ); - useEffect(() => { - if (didMountRef.current) { - setItems((prev) => { - return updatePaths(prev); + const moveItem = useCallback( + (sourceIdx: number, destinationIdx: number) => { + setValue((previousItems) => { + const nextItems = [...previousItems]; + const removed = nextItems.splice(sourceIdx, 1)[0]; + nextItems.splice(destinationIdx, 0, removed); + return updatePaths(nextItems); }); - } else { - didMountRef.current = true; + }, + [setValue, updatePaths] + ); + + useEffect(() => { + if (!isMounted.current) { + return; } - }, [path, updatePaths]); - return children({ items, addItem, removeItem }); + setValue((prev) => { + return updatePaths(prev); + }); + }, [path, updatePaths, setValue]); + + useEffect(() => { + isMounted.current = true; + return () => { + isMounted.current = false; + }; + }, []); + + return children({ items: value, error, form, addItem, removeItem, moveItem }); }; diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/helpers.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/helpers.ts index 7ea42f81b43cb..a148dc543542b 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/helpers.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/helpers.ts @@ -19,9 +19,10 @@ import { FieldHook } from './types'; -export const getFieldValidityAndErrorMessage = ( - field: FieldHook -): { isInvalid: boolean; errorMessage: string | null } => { +export const getFieldValidityAndErrorMessage = (field: { + isChangingValue: FieldHook['isChangingValue']; + errors: FieldHook['errors']; +}): { isInvalid: boolean; errorMessage: string | null } => { const isInvalid = !field.isChangingValue && field.errors.length > 0; const errorMessage = !field.isChangingValue && field.errors.length ? field.errors[0].message : null; diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/index.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/index.ts index 45c11dd6272e4..aa9610dd85ae3 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/index.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/index.ts @@ -17,6 +17,6 @@ * under the License. */ -export { useField } from './use_field'; +export { useField, InternalFieldConfig } from './use_field'; export { useForm } from './use_form'; export { useFormData } from './use_form_data'; diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts index f01c7226ea4ce..bb4aae6eccae8 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_field.ts @@ -22,16 +22,22 @@ import { useMemo, useState, useEffect, useRef, useCallback } from 'react'; import { FormHook, FieldHook, FieldConfig, FieldValidateResponse, ValidationError } from '../types'; import { FIELD_TYPES, VALIDATION_TYPES } from '../constants'; +export interface InternalFieldConfig { + initialValue?: T; + isIncludedInOutput?: boolean; +} + export const useField = ( form: FormHook, path: string, - config: FieldConfig & { initialValue?: T } = {}, + config: FieldConfig & InternalFieldConfig = {}, valueChangeListener?: (value: T) => void ) => { const { type = FIELD_TYPES.TEXT, defaultValue = '', // The value to use a fallback mecanism when no initial value is passed initialValue = config.defaultValue ?? '', // The value explicitly passed + isIncludedInOutput = true, label = '', labelAppend = '', helpText = '', @@ -201,7 +207,7 @@ export const useField = ( validationTypeToValidate, }: { formData: any; - value: unknown; + value: T; validationTypeToValidate?: string; }): ValidationError[] | Promise => { if (!validations) { @@ -234,7 +240,7 @@ export const useField = ( } inflightValidation.current = validator({ - value: (valueToValidate as unknown) as string, + value: valueToValidate, errors: validationErrors, form: { getFormData, getFields }, formData, @@ -280,7 +286,7 @@ export const useField = ( } const validationResult = validator({ - value: (valueToValidate as unknown) as string, + value: valueToValidate, errors: validationErrors, form: { getFormData, getFields }, formData, @@ -388,9 +394,15 @@ export const useField = ( */ const setValue: FieldHook['setValue'] = useCallback( (newValue) => { - const formattedValue = formatInputValue(newValue); - setStateValue(formattedValue); - return formattedValue; + setStateValue((prev) => { + let formattedValue: T; + if (typeof newValue === 'function') { + formattedValue = formatInputValue((newValue as Function)(prev)); + } else { + formattedValue = formatInputValue(newValue); + } + return formattedValue; + }); }, [formatInputValue] ); @@ -496,6 +508,7 @@ export const useField = ( clearErrors, validate, reset, + __isIncludedInOutput: isIncludedInOutput, __serializeValue: serializeValue, }; }, [ @@ -511,6 +524,7 @@ export const useField = ( isValidating, isValidated, isChangingValue, + isIncludedInOutput, onChange, getErrorsMessages, setValue, diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts index 7b72a9eeacf7b..b390c17d3c2ff 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts @@ -95,19 +95,25 @@ export function useForm( const fieldsToArray = useCallback(() => Object.values(fieldsRefs.current), []); - const stripEmptyFields = useCallback( - (fields: FieldsMap): FieldsMap => { - if (formOptions.stripEmptyFields) { - return Object.entries(fields).reduce((acc, [key, field]) => { - if (typeof field.value !== 'string' || field.value.trim() !== '') { - acc[key] = field; - } + const getFieldsForOutput = useCallback( + (fields: FieldsMap, opts: { stripEmptyFields: boolean }): FieldsMap => { + return Object.entries(fields).reduce((acc, [key, field]) => { + if (!field.__isIncludedInOutput) { return acc; - }, {} as FieldsMap); - } - return fields; + } + + if (opts.stripEmptyFields) { + const isFieldEmpty = typeof field.value === 'string' && field.value.trim() === ''; + if (isFieldEmpty) { + return acc; + } + } + + acc[key] = field; + return acc; + }, {} as FieldsMap); }, - [formOptions] + [] ); const updateFormDataAt: FormHook['__updateFormDataAt'] = useCallback( @@ -133,8 +139,10 @@ export function useForm( const getFormData: FormHook['getFormData'] = useCallback( (getDataOptions: Parameters['getFormData']>[0] = { unflatten: true }) => { if (getDataOptions.unflatten) { - const nonEmptyFields = stripEmptyFields(fieldsRefs.current); - const fieldsValue = mapFormFields(nonEmptyFields, (field) => field.__serializeValue()); + const fieldsToOutput = getFieldsForOutput(fieldsRefs.current, { + stripEmptyFields: formOptions.stripEmptyFields, + }); + const fieldsValue = mapFormFields(fieldsToOutput, (field) => field.__serializeValue()); return serializer ? (serializer(unflattenObject(fieldsValue)) as T) : (unflattenObject(fieldsValue) as T); @@ -148,7 +156,7 @@ export function useForm( {} as T ); }, - [stripEmptyFields, serializer] + [getFieldsForOutput, formOptions.stripEmptyFields, serializer] ); const getErrors: FormHook['getErrors'] = useCallback(() => { diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts index 4b343ec5e9f2e..18b8f478f7c0e 100644 --- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts +++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/types.ts @@ -108,15 +108,18 @@ export interface FieldHook { errorCode?: string; }) => string | null; onChange: (event: ChangeEvent<{ name?: string; value: string; checked?: boolean }>) => void; - setValue: (value: T) => T; + setValue: (value: T | ((prevValue: T) => T)) => void; setErrors: (errors: ValidationError[]) => void; clearErrors: (type?: string | string[]) => void; validate: (validateData?: { formData?: any; - value?: unknown; + value?: T; validationType?: string; }) => FieldValidateResponse | Promise; reset: (options?: { resetValue?: boolean; defaultValue?: T }) => unknown | undefined; + // Flag to indicate if the field value will be included in the form data outputted + // when calling form.getFormData(); + __isIncludedInOutput: boolean; __serializeValue: (rawValue?: unknown) => unknown; } @@ -127,7 +130,7 @@ export interface FieldConfig { readonly helpText?: string | ReactNode; readonly type?: HTMLInputElement['type']; readonly defaultValue?: ValueType; - readonly validations?: Array>; + readonly validations?: Array>; readonly formatters?: FormatterFunc[]; readonly deserializer?: SerializerFunc; readonly serializer?: SerializerFunc; @@ -163,8 +166,8 @@ export interface ValidationFuncArg { errors: readonly ValidationError[]; } -export type ValidationFunc = ( - data: ValidationFuncArg +export type ValidationFunc = ( + data: ValidationFuncArg ) => ValidationError | void | undefined | Promise | void | undefined>; export interface FieldValidateResponse { @@ -184,8 +187,8 @@ type FormatterFunc = (value: any, formData: FormData) => unknown; // string | number | boolean | string[] ... type FieldValue = unknown; -export interface ValidationConfig { - validator: ValidationFunc; +export interface ValidationConfig { + validator: ValidationFunc; type?: string; /** * By default all validation are blockers, which means that if they fail, the field is invalid. diff --git a/src/plugins/home/public/application/components/welcome.tsx b/src/plugins/home/public/application/components/welcome.tsx index cacb507009c70..404185de3d2ea 100644 --- a/src/plugins/home/public/application/components/welcome.tsx +++ b/src/plugins/home/public/application/components/welcome.tsx @@ -76,7 +76,7 @@ export class Welcome extends React.Component { componentDidMount() { const { telemetry } = this.props; this.services.trackUiMetric(METRIC_TYPE.LOADED, 'welcomeScreenMount'); - if (telemetry) { + if (telemetry?.telemetryService.userCanChangeSettings) { telemetry.telemetryNotifications.setOptedInNoticeSeen(); } document.addEventListener('keydown', this.hideOnEsc); @@ -88,7 +88,7 @@ export class Welcome extends React.Component { private renderTelemetryEnabledOrDisabledText = () => { const { telemetry } = this.props; - if (!telemetry) { + if (!telemetry || !telemetry.telemetryService.userCanChangeSettings) { return null; } diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap index b606e60949af5..c617c3b43039b 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/field_format_editor/editors/duration/__snapshots__/duration.test.tsx.snap @@ -203,6 +203,26 @@ exports[`DurationFormatEditor should render non-human readable output normally 1 value={2} /> + + + } + onChange={[Function]} + /> + {!(format as DurationFormat).isHuman() ? ( - - } - isInvalid={!!error} - error={hasDecimalError ? error : null} - > - { - this.onChange({ outputPrecision: e.target.value ? Number(e.target.value) : null }); - }} + <> + + } isInvalid={!!error} - /> - + error={hasDecimalError ? error : null} + > + { + this.onChange({ + outputPrecision: e.target.value ? Number(e.target.value) : null, + }); + }} + isInvalid={!!error} + /> + + + + } + checked={Boolean(formatParams.showSuffix)} + onChange={(e) => { + this.onChange({ showSuffix: !formatParams.showSuffix }); + }} + /> + + ) : null} diff --git a/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts index 6efe872553583..2e79cdaa7fc6b 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts @@ -66,6 +66,7 @@ export const applicationUsageSchema = { csm: commonSchema, canvas: commonSchema, dashboard_mode: commonSchema, // It's a forward app so we'll likely never report it + enterpriseSearch: commonSchema, appSearch: commonSchema, workplaceSearch: commonSchema, graph: commonSchema, diff --git a/src/plugins/kibana_usage_collection/server/collectors/ops_stats/index.test.ts b/src/plugins/kibana_usage_collection/server/collectors/ops_stats/index.test.ts index 359d3a396665d..a527d4d03c6fc 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/ops_stats/index.test.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/ops_stats/index.test.ts @@ -39,6 +39,7 @@ describe('telemetry_ops_stats', () => { const callCluster = jest.fn(); const metric: OpsMetrics = { + collected_at: new Date('2020-01-01 01:00:00'), process: { memory: { heap: { diff --git a/src/plugins/kibana_usage_collection/server/collectors/ops_stats/ops_stats_collector.ts b/src/plugins/kibana_usage_collection/server/collectors/ops_stats/ops_stats_collector.ts index 6e8b71d675f7b..d3be601540582 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/ops_stats/ops_stats_collector.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/ops_stats/ops_stats_collector.ts @@ -18,13 +18,13 @@ */ import { Observable } from 'rxjs'; -import { cloneDeep } from 'lodash'; +import { cloneDeep, omit } from 'lodash'; import moment from 'moment'; import { OpsMetrics } from 'kibana/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { KIBANA_STATS_TYPE } from '../../../common/constants'; -interface OpsStatsMetrics extends Omit { +interface OpsStatsMetrics extends Omit { timestamp: string; response_times: { average: number; @@ -52,9 +52,9 @@ export function getOpsStatsCollector( // @ts-expect-error delete metrics.requests.statusCodes; lastMetrics = { - ...metrics, + ...omit(metrics, ['collected_at']), response_times: responseTimes, - timestamp: moment.utc().toISOString(), + timestamp: moment.utc(metrics.collected_at).toISOString(), }; }); diff --git a/src/plugins/kibana_usage_collection/server/collectors/ui_metric/index.test.ts b/src/plugins/kibana_usage_collection/server/collectors/ui_metric/index.test.ts index fca685ef4b805..d6f40a2a6867f 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/ui_metric/index.test.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/ui_metric/index.test.ts @@ -73,6 +73,11 @@ describe('telemetry_ui_metric', () => { { id: 'testAppName:testKeyName1', attributes: { count: 3 } }, { id: 'testAppName:testKeyName2', attributes: { count: 5 } }, { id: 'testAppName2:testKeyName3', attributes: { count: 1 } }, + { + id: + 'kibana-user_agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0', + attributes: { count: 1 }, + }, ], total: 3, } as any; @@ -86,6 +91,12 @@ describe('telemetry_ui_metric', () => { { key: 'testKeyName2', value: 5 }, ], testAppName2: [{ key: 'testKeyName3', value: 1 }], + 'kibana-user_agent': [ + { + key: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0', + value: 1, + }, + ], }); }); }); diff --git a/src/plugins/kibana_usage_collection/server/collectors/ui_metric/telemetry_ui_metric_collector.ts b/src/plugins/kibana_usage_collection/server/collectors/ui_metric/telemetry_ui_metric_collector.ts index ec2f1bfdfc25f..46768813b1970 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/ui_metric/telemetry_ui_metric_collector.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/ui_metric/telemetry_ui_metric_collector.ts @@ -66,9 +66,9 @@ export function registerUiMetricUsageCollector( attributes: { count }, } = rawUiMetric; - const [appName, metricType] = id.split(':'); + const [appName, ...metricType] = id.split(':'); - const pair = { key: metricType, value: count }; + const pair = { key: metricType.join(':'), value: count }; return { ...accum, [appName]: [...(accum[appName] || []), pair], diff --git a/src/plugins/navigation/public/top_nav_menu/top_nav_menu.tsx b/src/plugins/navigation/public/top_nav_menu/top_nav_menu.tsx index a1a40b49cc8f0..b284c60bac5de 100644 --- a/src/plugins/navigation/public/top_nav_menu/top_nav_menu.tsx +++ b/src/plugins/navigation/public/top_nav_menu/top_nav_menu.tsx @@ -23,39 +23,44 @@ import classNames from 'classnames'; import { MountPoint } from '../../../../core/public'; import { MountPointPortal } from '../../../kibana_react/public'; -import { StatefulSearchBarProps, DataPublicPluginStart } from '../../../data/public'; +import { + StatefulSearchBarProps, + DataPublicPluginStart, + SearchBarProps, +} from '../../../data/public'; import { TopNavMenuData } from './top_nav_menu_data'; import { TopNavMenuItem } from './top_nav_menu_item'; -export type TopNavMenuProps = StatefulSearchBarProps & { - config?: TopNavMenuData[]; - showSearchBar?: boolean; - showQueryBar?: boolean; - showQueryInput?: boolean; - showDatePicker?: boolean; - showFilterBar?: boolean; - data?: DataPublicPluginStart; - className?: string; - /** - * If provided, the menu part of the component will be rendered as a portal inside the given mount point. - * - * This is meant to be used with the `setHeaderActionMenu` core API. - * - * @example - * ```ts - * export renderApp = ({ element, history, setHeaderActionMenu }: AppMountParameters) => { - * const topNavConfig = ...; // TopNavMenuProps - * return ( - * - * - * - * - * ) - * } - * ``` - */ - setMenuMountPoint?: (menuMount: MountPoint | undefined) => void; -}; +export type TopNavMenuProps = StatefulSearchBarProps & + Omit & { + config?: TopNavMenuData[]; + showSearchBar?: boolean; + showQueryBar?: boolean; + showQueryInput?: boolean; + showDatePicker?: boolean; + showFilterBar?: boolean; + data?: DataPublicPluginStart; + className?: string; + /** + * If provided, the menu part of the component will be rendered as a portal inside the given mount point. + * + * This is meant to be used with the `setHeaderActionMenu` core API. + * + * @example + * ```ts + * export renderApp = ({ element, history, setHeaderActionMenu }: AppMountParameters) => { + * const topNavConfig = ...; // TopNavMenuProps + * return ( + * + * + * + * + * ) + * } + * ``` + */ + setMenuMountPoint?: (menuMount: MountPoint | undefined) => void; + }; /* * Top Nav Menu is a convenience wrapper component for: diff --git a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx index 3b9efbee22ba6..9cdef8b9392bb 100644 --- a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx +++ b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx @@ -294,7 +294,7 @@ export class SavedObjectSaveModal extends React.Component id="savedObjects.saveModal.duplicateTitleDescription" defaultMessage="Saving '{title}' creates a duplicate title." values={{ - title: this.props.title, + title: this.state.title, }} />

diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap index 9ad82723c1161..0a330d074fd42 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/flyout.test.tsx.snap @@ -122,6 +122,8 @@ exports[`Flyout conflicts should allow conflict resolution 1`] = ` grow={false} > @@ -420,6 +422,8 @@ exports[`Flyout legacy conflicts should allow conflict resolution 1`] = ` grow={false} > @@ -553,7 +557,7 @@ exports[`Flyout should render import step 1`] = ` hasEmptyLabelSpace={false} label={ @@ -603,6 +607,8 @@ exports[`Flyout should render import step 1`] = ` grow={false} > diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/header.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/header.test.tsx.snap index 642a5030e4ec0..038e1aaf2d8f5 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/header.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/header.test.tsx.snap @@ -92,7 +92,7 @@ exports[`Header should render normally 1`] = ` color="subdued" > diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.test.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.test.tsx index 32462e1e2184d..cc9d2ed160241 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.test.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.test.tsx @@ -267,6 +267,10 @@ describe('Flyout', () => { expect(component.state('status')).toBe('success'); expect(component.find('EuiFlyout ImportSummary')).toMatchSnapshot(); + const cancelButton = await component.find( + 'EuiButtonEmpty[data-test-subj="importSavedObjectsCancelBtn"]' + ); + expect(cancelButton.prop('disabled')).toBe(true); }); }); diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx index eddca18f9e283..47d82077294cc 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/flyout.tsx @@ -729,7 +729,7 @@ export class Flyout extends Component { label={ } > @@ -756,7 +756,7 @@ export class Flyout extends Component { } renderFooter() { - const { status } = this.state; + const { isLegacyFile, status } = this.state; const { done, close } = this.props; let confirmButton; @@ -773,7 +773,7 @@ export class Flyout extends Component { } else if (this.hasUnmatchedReferences) { confirmButton = ( { } else { confirmButton = ( { return ( - +

diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_mode_control.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_mode_control.tsx index ac8099893d00e..4000d620465a8 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_mode_control.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_mode_control.tsx @@ -51,8 +51,7 @@ const createNewCopiesDisabled = { tooltip: i18n.translate( 'savedObjectsManagement.objectsTable.importModeControl.createNewCopies.disabledText', { - defaultMessage: - 'Check if each object was previously copied or imported into the destination space.', + defaultMessage: 'Check if objects were previously copied or imported.', } ), }; @@ -64,21 +63,23 @@ const createNewCopiesEnabled = { ), tooltip: i18n.translate( 'savedObjectsManagement.objectsTable.importModeControl.createNewCopies.enabledText', - { defaultMessage: 'All imported objects will be created with new random IDs.' } + { + defaultMessage: 'Use this option to create one or more copies of the object.', + } ), }; const overwriteEnabled = { id: 'overwriteEnabled', label: i18n.translate( 'savedObjectsManagement.objectsTable.importModeControl.overwrite.enabledLabel', - { defaultMessage: 'Automatically try to overwrite conflicts' } + { defaultMessage: 'Automatically overwrite conflicts' } ), }; const overwriteDisabled = { id: 'overwriteDisabled', label: i18n.translate( 'savedObjectsManagement.objectsTable.importModeControl.overwrite.disabledLabel', - { defaultMessage: 'Request action when conflict occurs' } + { defaultMessage: 'Request action on conflict' } ), }; const importOptionsTitle = i18n.translate( diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_summary.test.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_summary.test.tsx index ed65131b0fc6b..20ac5a903ef22 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_summary.test.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_summary.test.tsx @@ -70,7 +70,7 @@ describe('ImportSummary', () => { const wrapper = shallowWithI18nProvider(); expect(findHeader(wrapper).childAt(0).props()).toEqual( - expect.objectContaining({ values: { importCount: 1 } }) + expect.not.objectContaining({ values: expect.anything() }) // no importCount for singular ); const countCreated = findCountCreated(wrapper); expect(countCreated).toHaveLength(1); @@ -90,7 +90,7 @@ describe('ImportSummary', () => { const wrapper = shallowWithI18nProvider(); expect(findHeader(wrapper).childAt(0).props()).toEqual( - expect.objectContaining({ values: { importCount: 1 } }) + expect.not.objectContaining({ values: expect.anything() }) // no importCount for singular ); expect(findCountCreated(wrapper)).toHaveLength(0); const countOverwritten = findCountOverwritten(wrapper); @@ -110,7 +110,7 @@ describe('ImportSummary', () => { const wrapper = shallowWithI18nProvider(); expect(findHeader(wrapper).childAt(0).props()).toEqual( - expect.objectContaining({ values: { importCount: 1 } }) + expect.not.objectContaining({ values: expect.anything() }) // no importCount for singular ); expect(findCountCreated(wrapper)).toHaveLength(0); expect(findCountOverwritten(wrapper)).toHaveLength(0); diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_summary.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_summary.tsx index 7949f7d18d350..e2ce3c3695b17 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_summary.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/import_summary.tsx @@ -141,7 +141,7 @@ const getCountIndicators = (importItems: ImportItem[]) => { ); }; -const getStatusIndicator = ({ outcome, errorMessage }: ImportItem) => { +const getStatusIndicator = ({ outcome, errorMessage = 'Error' }: ImportItem) => { switch (outcome) { case 'created': return ( @@ -168,8 +168,8 @@ const getStatusIndicator = ({ outcome, errorMessage }: ImportItem) => { type={'alert'} color={'danger'} content={i18n.translate('savedObjectsManagement.importSummary.errorOutcomeLabel', { - defaultMessage: 'Error{message}', - values: { message: errorMessage ? `: ${errorMessage}` : '' }, + defaultMessage: '{errorMessage}', + values: { errorMessage }, })} /> ); @@ -194,11 +194,18 @@ export const ImportSummary = ({ failedImports, successfulImports }: ImportSummar } >

- + {importItems.length === 1 ? ( + + ) : ( + + )}

diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/overwrite_modal.test.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/overwrite_modal.test.tsx index c93bc9e5038df..7576b62552aa2 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/overwrite_modal.test.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/overwrite_modal.test.tsx @@ -40,7 +40,7 @@ describe('OverwriteModal', () => { const wrapper = shallowWithI18nProvider(); expect(wrapper.find('p').text()).toMatchInlineSnapshot( - `"\\"baz\\" conflicts with an existing object, are you sure you want to overwrite it?"` + `"\\"baz\\" conflicts with an existing object. Overwrite it?"` ); expect(wrapper.find('EuiSuperSelect')).toHaveLength(0); }); @@ -82,7 +82,7 @@ describe('OverwriteModal', () => { const wrapper = shallowWithI18nProvider(); expect(wrapper.find('p').text()).toMatchInlineSnapshot( - `"\\"baz\\" conflicts with multiple existing objects, do you want to overwrite one of them?"` + `"\\"baz\\" conflicts with multiple existing objects. Overwrite one?"` ); expect(wrapper.find('EuiSuperSelect')).toHaveLength(1); }); diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/overwrite_modal.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/overwrite_modal.tsx index dbe95161cbeae..bf27d407fbe94 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/overwrite_modal.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/overwrite_modal.tsx @@ -98,15 +98,13 @@ export const OverwriteModal = ({ conflict, onFinish }: OverwriteModalProps) => { const bodyText = error.type === 'conflict' ? i18n.translate('savedObjectsManagement.objectsTable.overwriteModal.body.conflict', { - defaultMessage: - '"{title}" conflicts with an existing object, are you sure you want to overwrite it?', + defaultMessage: '"{title}" conflicts with an existing object. Overwrite it?', values: { title }, }) : i18n.translate( 'savedObjectsManagement.objectsTable.overwriteModal.body.ambiguousConflict', { - defaultMessage: - '"{title}" conflicts with multiple existing objects, do you want to overwrite one of them?', + defaultMessage: '"{title}" conflicts with multiple existing objects. Overwrite one?', values: { title }, } ); diff --git a/src/plugins/telemetry/public/mocks.ts b/src/plugins/telemetry/public/mocks.ts index dd7e5a4cc4ce3..5f38b27144d02 100644 --- a/src/plugins/telemetry/public/mocks.ts +++ b/src/plugins/telemetry/public/mocks.ts @@ -48,6 +48,7 @@ export function mockTelemetryService({ banner: true, allowChangingOptInStatus: true, telemetryNotifyUserAboutOptInDefault: true, + userCanChangeSettings: true, ...configOverride, }; diff --git a/src/plugins/telemetry/public/plugin.ts b/src/plugins/telemetry/public/plugin.ts index 3846e7cb96a19..9fefa2ebdd02e 100644 --- a/src/plugins/telemetry/public/plugin.ts +++ b/src/plugins/telemetry/public/plugin.ts @@ -25,6 +25,7 @@ import { PluginInitializerContext, SavedObjectsClientContract, SavedObjectsBatchResponse, + ApplicationStart, } from '../../../core/public'; import { TelemetrySender, TelemetryService, TelemetryNotifications } from './services'; @@ -61,6 +62,7 @@ export interface TelemetryPluginConfig { optInStatusUrl: string; sendUsageFrom: 'browser' | 'server'; telemetryNotifyUserAboutOptInDefault?: boolean; + userCanChangeSettings?: boolean; } export class TelemetryPlugin implements Plugin { @@ -69,6 +71,7 @@ export class TelemetryPlugin implements Plugin) { this.currentKibanaVersion = initializerContext.env.packageInfo.version; @@ -91,6 +94,9 @@ export class TelemetryPlugin implements Plugin { expect(telemetryService.setUserHasSeenNotice).toBeCalledTimes(1); }); }); + +describe('shouldShowOptedInNoticeBanner', () => { + it("should return true because a banner hasn't been shown, the notice hasn't been seen and the user has privileges to edit saved objects", () => { + const telemetryService = mockTelemetryService(); + telemetryService.getUserShouldSeeOptInNotice = jest.fn().mockReturnValue(true); + const telemetryNotifications = mockTelemetryNotifications({ telemetryService }); + expect(telemetryNotifications.shouldShowOptedInNoticeBanner()).toBe(true); + }); + + it('should return false because the banner is already on screen', () => { + const telemetryService = mockTelemetryService(); + telemetryService.getUserShouldSeeOptInNotice = jest.fn().mockReturnValue(true); + const telemetryNotifications = mockTelemetryNotifications({ telemetryService }); + telemetryNotifications['optedInNoticeBannerId'] = 'bruce-banner'; + expect(telemetryNotifications.shouldShowOptedInNoticeBanner()).toBe(false); + }); + + it("should return false because the banner has already been seen or the user doesn't have privileges to change saved objects", () => { + const telemetryService = mockTelemetryService(); + telemetryService.getUserShouldSeeOptInNotice = jest.fn().mockReturnValue(false); + const telemetryNotifications = mockTelemetryNotifications({ telemetryService }); + expect(telemetryNotifications.shouldShowOptedInNoticeBanner()).toBe(false); + }); +}); diff --git a/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts b/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts index bf25bb592db82..fc44a4db7cf5e 100644 --- a/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts +++ b/src/plugins/telemetry/public/services/telemetry_notifications/telemetry_notifications.ts @@ -39,9 +39,9 @@ export class TelemetryNotifications { } public shouldShowOptedInNoticeBanner = (): boolean => { - const userHasSeenOptedInNotice = this.telemetryService.getUserHasSeenOptedInNotice(); + const userShouldSeeOptInNotice = this.telemetryService.getUserShouldSeeOptInNotice(); const bannerOnScreen = typeof this.optedInNoticeBannerId !== 'undefined'; - return !bannerOnScreen && userHasSeenOptedInNotice; + return !bannerOnScreen && userShouldSeeOptInNotice; }; public renderOptedInNoticeBanner = (): void => { diff --git a/src/plugins/telemetry/public/services/telemetry_service.test.ts b/src/plugins/telemetry/public/services/telemetry_service.test.ts index 16faa0cfc7536..655bbfe746c2a 100644 --- a/src/plugins/telemetry/public/services/telemetry_service.test.ts +++ b/src/plugins/telemetry/public/services/telemetry_service.test.ts @@ -184,15 +184,15 @@ describe('TelemetryService', () => { describe('setUserHasSeenNotice', () => { it('should hit the API and change the config', async () => { const telemetryService = mockTelemetryService({ - config: { telemetryNotifyUserAboutOptInDefault: undefined }, + config: { telemetryNotifyUserAboutOptInDefault: undefined, userCanChangeSettings: true }, }); expect(telemetryService.userHasSeenOptedInNotice).toBe(undefined); - expect(telemetryService.getUserHasSeenOptedInNotice()).toBe(false); + expect(telemetryService.getUserShouldSeeOptInNotice()).toBe(false); await telemetryService.setUserHasSeenNotice(); expect(telemetryService['http'].put).toBeCalledTimes(1); expect(telemetryService.userHasSeenOptedInNotice).toBe(true); - expect(telemetryService.getUserHasSeenOptedInNotice()).toBe(true); + expect(telemetryService.getUserShouldSeeOptInNotice()).toBe(true); }); it('should show a toast notification if the request fail', async () => { @@ -207,12 +207,33 @@ describe('TelemetryService', () => { }); expect(telemetryService.userHasSeenOptedInNotice).toBe(undefined); - expect(telemetryService.getUserHasSeenOptedInNotice()).toBe(false); + expect(telemetryService.getUserShouldSeeOptInNotice()).toBe(false); await telemetryService.setUserHasSeenNotice(); expect(telemetryService['http'].put).toBeCalledTimes(1); expect(telemetryService['notifications'].toasts.addError).toBeCalledTimes(1); expect(telemetryService.userHasSeenOptedInNotice).toBe(false); - expect(telemetryService.getUserHasSeenOptedInNotice()).toBe(false); + expect(telemetryService.getUserShouldSeeOptInNotice()).toBe(false); + }); + }); + + describe('getUserShouldSeeOptInNotice', () => { + it('returns whether the user can update the telemetry config (has SavedObjects access)', () => { + const telemetryService = mockTelemetryService({ + config: { userCanChangeSettings: undefined }, + }); + expect(telemetryService.config.userCanChangeSettings).toBe(undefined); + expect(telemetryService.userCanChangeSettings).toBe(false); + expect(telemetryService.getUserShouldSeeOptInNotice()).toBe(false); + + telemetryService.userCanChangeSettings = false; + expect(telemetryService.config.userCanChangeSettings).toBe(false); + expect(telemetryService.userCanChangeSettings).toBe(false); + expect(telemetryService.getUserShouldSeeOptInNotice()).toBe(false); + + telemetryService.userCanChangeSettings = true; + expect(telemetryService.config.userCanChangeSettings).toBe(true); + expect(telemetryService.userCanChangeSettings).toBe(true); + expect(telemetryService.getUserShouldSeeOptInNotice()).toBe(true); }); }); }); diff --git a/src/plugins/telemetry/public/services/telemetry_service.ts b/src/plugins/telemetry/public/services/telemetry_service.ts index 6d87a74197fe5..c807aa9e1d35e 100644 --- a/src/plugins/telemetry/public/services/telemetry_service.ts +++ b/src/plugins/telemetry/public/services/telemetry_service.ts @@ -87,9 +87,25 @@ export class TelemetryService { return telemetryUrl; }; - public getUserHasSeenOptedInNotice = () => { - return this.config.telemetryNotifyUserAboutOptInDefault || false; - }; + /** + * Returns if an user should be shown the notice about Opt-In/Out telemetry. + * The decision is made based on whether any user has already dismissed the message or + * the user can't actually change the settings (in which case, there's no point on bothering them) + */ + public getUserShouldSeeOptInNotice(): boolean { + return ( + (this.config.telemetryNotifyUserAboutOptInDefault && this.config.userCanChangeSettings) ?? + false + ); + } + + public get userCanChangeSettings() { + return this.config.userCanChangeSettings ?? false; + } + + public set userCanChangeSettings(userCanChangeSettings: boolean) { + this.config = { ...this.config, userCanChangeSettings }; + } public getIsOptedIn = () => { return this.isOptedIn; diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index acd575badbe5b..5bce03a292760 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -414,6 +414,34 @@ } } }, + "enterpriseSearch": { + "properties": { + "clicks_total": { + "type": "long" + }, + "clicks_7_days": { + "type": "long" + }, + "clicks_30_days": { + "type": "long" + }, + "clicks_90_days": { + "type": "long" + }, + "minutes_on_screen_total": { + "type": "float" + }, + "minutes_on_screen_7_days": { + "type": "float" + }, + "minutes_on_screen_30_days": { + "type": "float" + }, + "minutes_on_screen_90_days": { + "type": "float" + } + } + }, "appSearch": { "properties": { "clicks_total": { diff --git a/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap b/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap index dd4ee61fd1148..ab29656c557c2 100644 --- a/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap +++ b/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap @@ -228,7 +228,6 @@ exports[`TelemetryManagementSectionComponent renders null because allowChangingO "getIsOptedIn": [Function], "getOptInStatusUrl": [Function], "getTelemetryUrl": [Function], - "getUserHasSeenOptedInNotice": [Function], "http": Object { "addLoadingCountSource": [MockFunction], "anonymousPaths": Object { @@ -430,7 +429,6 @@ exports[`TelemetryManagementSectionComponent renders null because query does not "getIsOptedIn": [Function], "getOptInStatusUrl": [Function], "getTelemetryUrl": [Function], - "getUserHasSeenOptedInNotice": [Function], "http": Object { "addLoadingCountSource": [MockFunction], "anonymousPaths": Object { diff --git a/src/plugins/timelion/server/plugin.ts b/src/plugins/timelion/server/plugin.ts index fe77ebeb0866d..d5a5ec4640d4b 100644 --- a/src/plugins/timelion/server/plugin.ts +++ b/src/plugins/timelion/server/plugin.ts @@ -42,7 +42,7 @@ const showWarningMessageIfTimelionSheetWasFound = (core: CoreStart, logger: Logg ({ total }) => total && logger.warn( - 'Deprecated since 7.0, the Timelion app will be removed in 8.0. To continue using your Timelion worksheets, migrate them to a dashboard. See https://www.elastic.co/guide/en/kibana/master/timelion.html#timelion-deprecation.' + 'Deprecated since 7.0, the Timelion app will be removed in 8.0. To continue using your Timelion worksheets, migrate them to a dashboard. See https://www.elastic.co/guide/en/kibana/master/dashboard.html#timelion-deprecation.' ) ); }; diff --git a/src/plugins/ui_actions/public/tests/test_samples/hello_world_action.tsx b/src/plugins/ui_actions/public/tests/test_samples/hello_world_action.tsx index 8fff231a867bf..a4cfe172dd109 100644 --- a/src/plugins/ui_actions/public/tests/test_samples/hello_world_action.tsx +++ b/src/plugins/ui_actions/public/tests/test_samples/hello_world_action.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; -import { EuiFlyout, EuiFlexGroup, EuiFlexItem, EuiBadge } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiBadge, EuiFlyoutBody } from '@elastic/eui'; import { CoreStart } from 'src/core/public'; import { createAction, ActionByType } from '../../actions'; import { toMountPoint, reactToUiComponent } from '../../../../kibana_react/public'; @@ -49,14 +49,11 @@ export function createHelloWorldAction( getIconType: () => 'lock', MenuItem: UiMenuItem, execute: async () => { - const flyoutSession = overlays.openFlyout( - toMountPoint( - flyoutSession && flyoutSession.close()}> - Hello World, I am a hello world action! - - ), + overlays.openFlyout( + toMountPoint(Hello World, I am a hello world action!), { 'data-test-subj': 'helloWorldAction', + ownFocus: true, } ); }, diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js b/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js index 4b5aab85cfc4e..c5fc4b7b93269 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js +++ b/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js @@ -100,9 +100,17 @@ describe('es', () => { expect(agg.time_buckets.date_histogram.time_zone).to.equal('Etc/UTC'); }); - it('sets the field and interval', () => { + it('sets the field', () => { expect(agg.time_buckets.date_histogram.field).to.equal('@timestamp'); - expect(agg.time_buckets.date_histogram.interval).to.equal('1y'); + }); + + it('sets the interval for calendar_interval correctly', () => { + expect(agg.time_buckets.date_histogram).to.have.property('calendar_interval', '1y'); + }); + + it('sets the interval for fixed_interval correctly', () => { + const a = createDateAgg({ timefield: '@timestamp', interval: '24h' }, tlConfig); + expect(a.time_buckets.date_histogram).to.have.property('fixed_interval', '24h'); }); it('sets min_doc_count to 0', () => { diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/lib/create_date_agg.js b/src/plugins/vis_type_timelion/server/series_functions/es/lib/create_date_agg.js index 904fe69cbc57c..b36f37ac5cc9d 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/lib/create_date_agg.js +++ b/src/plugins/vis_type_timelion/server/series_functions/es/lib/create_date_agg.js @@ -19,6 +19,8 @@ import _ from 'lodash'; import { buildAggBody } from './agg_body'; +import { search } from '../../../../../../plugins/data/server'; +const { dateHistogramInterval } = search.aggs; export default function createDateAgg(config, tlConfig, scriptedFields) { const dateAgg = { @@ -26,13 +28,13 @@ export default function createDateAgg(config, tlConfig, scriptedFields) { meta: { type: 'time_buckets' }, date_histogram: { field: config.timefield, - interval: config.interval, time_zone: tlConfig.time.timezone, extended_bounds: { min: tlConfig.time.from, max: tlConfig.time.to, }, min_doc_count: 0, + ...dateHistogramInterval(config.interval), }, }, }; diff --git a/src/plugins/vis_type_vega/public/data_model/search_api.ts b/src/plugins/vis_type_vega/public/data_model/search_api.ts index 8a1541ecae0d4..4ea25af549249 100644 --- a/src/plugins/vis_type_vega/public/data_model/search_api.ts +++ b/src/plugins/vis_type_vega/public/data_model/search_api.ts @@ -51,9 +51,6 @@ export class SearchAPI { searchRequests.map((request) => { const requestId = request.name; const params = getSearchParamsFromRequest(request, { - esShardTimeout: this.dependencies.injectedMetadata.getInjectedVar( - 'esShardTimeout' - ) as number, getConfig: this.dependencies.uiSettings.get.bind(this.dependencies.uiSettings), }); diff --git a/src/plugins/vis_type_vega/public/plugin.ts b/src/plugins/vis_type_vega/public/plugin.ts index 00c6b2e3c8d5b..4b8ff8e2cb43a 100644 --- a/src/plugins/vis_type_vega/public/plugin.ts +++ b/src/plugins/vis_type_vega/public/plugin.ts @@ -78,7 +78,6 @@ export class VegaPlugin implements Plugin, void> { ) { setInjectedVars({ enableExternalUrls: this.initializerContext.config.get().enableExternalUrls, - esShardTimeout: core.injectedMetadata.getInjectedVar('esShardTimeout') as number, emsTileLayerId: core.injectedMetadata.getInjectedVar('emsTileLayerId', true), }); setUISettings(core.uiSettings); diff --git a/src/plugins/vis_type_vega/public/services.ts b/src/plugins/vis_type_vega/public/services.ts index acd02a6dd42f8..dfb2c96e9f894 100644 --- a/src/plugins/vis_type_vega/public/services.ts +++ b/src/plugins/vis_type_vega/public/services.ts @@ -48,7 +48,6 @@ export const [getSavedObjects, setSavedObjects] = createGetterSetter('InjectedVars'); diff --git a/src/plugins/vis_type_vega/public/vega_visualization.test.js b/src/plugins/vis_type_vega/public/vega_visualization.test.js index 0912edf9503a6..1bf625af76207 100644 --- a/src/plugins/vis_type_vega/public/vega_visualization.test.js +++ b/src/plugins/vis_type_vega/public/vega_visualization.test.js @@ -82,7 +82,6 @@ describe('VegaVisualizations', () => { setInjectedVars({ emsTileLayerId: {}, enableExternalUrls: true, - esShardTimeout: 10000, }); setData(dataPluginStart); setSavedObjects(coreStart.savedObjects); diff --git a/tasks/config/run.js b/tasks/config/run.js index 132b51765b3ed..148be6ea8afaa 100644 --- a/tasks/config/run.js +++ b/tasks/config/run.js @@ -154,12 +154,6 @@ module.exports = function () { args: ['scripts/test_hardening.js'], }), - test_package_safer_lodash_set: scriptWithGithubChecks({ - title: '@elastic/safer-lodash-set tests', - cmd: YARN, - args: ['--cwd', 'packages/elastic-safer-lodash-set', 'test'], - }), - apiIntegrationTests: scriptWithGithubChecks({ title: 'API integration tests', cmd: NODE, diff --git a/tasks/jenkins.js b/tasks/jenkins.js index adfb6f0f46868..90efadf41c435 100644 --- a/tasks/jenkins.js +++ b/tasks/jenkins.js @@ -38,7 +38,6 @@ module.exports = function (grunt) { 'run:test_jest_integration', 'run:test_projects', 'run:test_hardening', - 'run:test_package_safer_lodash_set', 'run:apiIntegrationTests', ]); }; diff --git a/test/api_integration/apis/saved_objects/migrations.ts b/test/api_integration/apis/saved_objects/migrations.ts index 9997d9710e212..99a58620b17f5 100644 --- a/test/api_integration/apis/saved_objects/migrations.ts +++ b/test/api_integration/apis/saved_objects/migrations.ts @@ -379,14 +379,12 @@ async function migrateIndex({ index, migrations, mappingProperties, - validateDoc, obsoleteIndexTemplatePattern, }: { esClient: ElasticsearchClient; index: string; migrations: Record; mappingProperties: SavedObjectsTypeMappingDefinitions; - validateDoc?: (doc: any) => void; obsoleteIndexTemplatePattern?: string; }) { const typeRegistry = new SavedObjectTypeRegistry(); @@ -396,7 +394,6 @@ async function migrateIndex({ const documentMigrator = new DocumentMigrator({ kibanaVersion: '99.9.9', typeRegistry, - validateDoc: validateDoc || _.noop, log: getLogMock(), }); diff --git a/test/api_integration/apis/stats/stats.js b/test/api_integration/apis/stats/stats.js index a40427fea8b94..0972f0ebebf0c 100644 --- a/test/api_integration/apis/stats/stats.js +++ b/test/api_integration/apis/stats/stats.js @@ -55,7 +55,12 @@ const assertStatsAndMetrics = (body) => { export default function ({ getService }) { const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + describe('kibana stats api', () => { + before('make sure there are some saved objects', () => esArchiver.load('saved_objects/basic')); + after('cleanup saved objects changes', () => esArchiver.unload('saved_objects/basic')); + describe('basic', () => { it('should return the stats without cluster_uuid with no query string params', () => { return supertest diff --git a/test/api_integration/apis/telemetry/telemetry_local.js b/test/api_integration/apis/telemetry/telemetry_local.js index 8b10f412fae27..d2d61705b763d 100644 --- a/test/api_integration/apis/telemetry/telemetry_local.js +++ b/test/api_integration/apis/telemetry/telemetry_local.js @@ -38,8 +38,12 @@ function flatKeys(source) { export default function ({ getService }) { const supertest = getService('supertest'); const es = getService('es'); + const esArchiver = getService('esArchiver'); describe('/api/telemetry/v2/clusters/_stats', () => { + before('make sure there are some saved objects', () => esArchiver.load('saved_objects/basic')); + after('cleanup saved objects changes', () => esArchiver.unload('saved_objects/basic')); + before('create some telemetry-data tracked indices', async () => { return es.indices.create({ index: 'filebeat-telemetry_tests_logs' }); }); diff --git a/test/functional/apps/management/_create_index_pattern_wizard.js b/test/functional/apps/management/_create_index_pattern_wizard.js index 9760527371408..8b11a02099f61 100644 --- a/test/functional/apps/management/_create_index_pattern_wizard.js +++ b/test/functional/apps/management/_create_index_pattern_wizard.js @@ -66,6 +66,18 @@ export default function ({ getService, getPageObjects }) { await PageObjects.settings.createIndexPattern('alias1', false); }); + + after(async () => { + await es.transport.request({ + path: '/_aliases', + method: 'POST', + body: { actions: [{ remove: { index: 'blogs', alias: 'alias1' } }] }, + }); + await es.transport.request({ + path: '/blogs', + method: 'DELETE', + }); + }); }); }); } diff --git a/test/scripts/test/safer_lodash_set.sh b/test/scripts/test/safer_lodash_set.sh deleted file mode 100755 index 4d7f9c28210d1..0000000000000 --- a/test/scripts/test/safer_lodash_set.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -yarn run grunt run:test_package_safer_lodash_set diff --git a/vars/tasks.groovy b/vars/tasks.groovy index 52641ce31f0be..edd2c0aa47401 100644 --- a/vars/tasks.groovy +++ b/vars/tasks.groovy @@ -34,7 +34,6 @@ def test() { kibanaPipeline.scriptTask('Jest Unit Tests', 'test/scripts/test/jest_unit.sh'), kibanaPipeline.scriptTask('API Integration Tests', 'test/scripts/test/api_integration.sh'), - kibanaPipeline.scriptTask('@elastic/safer-lodash-set Tests', 'test/scripts/test/safer_lodash_set.sh'), kibanaPipeline.scriptTask('X-Pack SIEM cyclic dependency', 'test/scripts/test/xpack_siem_cyclic_dependency.sh'), kibanaPipeline.scriptTask('X-Pack List cyclic dependency', 'test/scripts/test/xpack_list_cyclic_dependency.sh'), kibanaPipeline.scriptTask('X-Pack Jest Unit Tests', 'test/scripts/test/xpack_jest_unit.sh'), diff --git a/x-pack/package.json b/x-pack/package.json index 899eca1095923..3a074ba1f1d7d 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -195,7 +195,7 @@ "jsdom": "13.1.0", "jsondiffpatch": "0.4.1", "jsts": "^1.6.2", - "kea": "2.2.0-rc.4", + "kea": "^2.2.0", "loader-utils": "^1.2.3", "lz-string": "^1.4.4", "madge": "3.4.4", diff --git a/x-pack/plugins/actions/README.md b/x-pack/plugins/actions/README.md index 868f6f180cc91..3bc8acead6c13 100644 --- a/x-pack/plugins/actions/README.md +++ b/x-pack/plugins/actions/README.md @@ -19,7 +19,7 @@ Table of Contents - [Usage](#usage) - [Kibana Actions Configuration](#kibana-actions-configuration) - [Configuration Options](#configuration-options) - - [Adding Built-in Action Types to allowedHosts](#adding-built-in-action-types-to-hosts-allow-list) + - [Adding Built-in Action Types to allowedHosts](#adding-built-in-action-types-to-allowedhosts) - [Configuration Utilities](#configuration-utilities) - [Action types](#action-types) - [Methods](#methods) @@ -74,13 +74,21 @@ Table of Contents - [`secrets`](#secrets-7) - [`params`](#params-7) - [`subActionParams (pushToService)`](#subactionparams-pushtoservice-1) + - [`subActionParams (issueTypes)`](#subactionparams-issuetypes) + - [`subActionParams (pushToService)`](#subactionparams-pushtoservice-2) - [IBM Resilient](#ibm-resilient) - [`config`](#config-8) - [`secrets`](#secrets-8) - [`params`](#params-8) - - [`subActionParams (pushToService)`](#subactionparams-pushtoservice-2) + - [`subActionParams (pushToService)`](#subactionparams-pushtoservice-3) - [Command Line Utility](#command-line-utility) - [Developing New Action Types](#developing-new-action-types) + - [licensing](#licensing) + - [plugin location](#plugin-location) + - [documentation](#documentation) + - [tests](#tests) + - [action type config and secrets](#action-type-config-and-secrets) + - [user interface](#user-interface) ## Terminology @@ -103,12 +111,12 @@ Implemented under the [Actions Config](./server/actions_config.ts). Built-In-Actions are configured using the _xpack.actions_ namespoace under _kibana.yml_, and have the following configuration options: -| Namespaced Key | Description | Type | -| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| _xpack.actions._**enabled** | Feature toggle which enabled Actions in Kibana. | boolean | -| _xpack.actions._**allowedHosts** | Which _hostnames_ are allowed for the Built-In-Action? This list should contain hostnames of every external service you wish to interact with using Webhooks, Email or any other built in Action. Note that you may use the string "\*" in place of a specific hostname to enable Kibana to target any URL, but keep in mind the potential use of such a feature to execute [SSRF](https://www.owasp.org/index.php/Server_Side_Request_Forgery) attacks from your server. | Array | -| _xpack.actions._**enabledActionTypes** | A list of _actionTypes_ id's that are enabled. A "\*" may be used as an element to indicate all registered actionTypes should be enabled. The actionTypes registered for Kibana are `.server-log`, `.slack`, `.email`, `.index`, `.pagerduty`, `.webhook`. Default: `["*"]` | Array | -| _xpack.actions._**preconfigured** | A object of action id / preconfigured actions. Default: `{}` | Array | +| Namespaced Key | Description | Type | +| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| _xpack.actions._**enabled** | Feature toggle which enabled Actions in Kibana. | boolean | +| _xpack.actions._**allowedHosts** | Which _hostnames_ are allowed for the Built-In-Action? This list should contain hostnames of every external service you wish to interact with using Webhooks, Email or any other built in Action. Note that you may use the string "\*" in place of a specific hostname to enable Kibana to target any URL, but keep in mind the potential use of such a feature to execute [SSRF](https://www.owasp.org/index.php/Server_Side_Request_Forgery) attacks from your server. | Array | +| _xpack.actions._**enabledActionTypes** | A list of _actionTypes_ id's that are enabled. A "\*" may be used as an element to indicate all registered actionTypes should be enabled. The actionTypes registered for Kibana are `.server-log`, `.slack`, `.email`, `.index`, `.pagerduty`, `.webhook`. Default: `["*"]` | Array | +| _xpack.actions._**preconfigured** | A object of action id / preconfigured actions. Default: `{}` | Array | #### Adding Built-in Action Types to allowedHosts @@ -120,14 +128,14 @@ Uniquely, the _PagerDuty Action Type_ has been configured to support the service This module provides a Utilities for interacting with the configuration. -| Method | Arguments | Description | Return Type | -| ------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | -| isUriAllowed | _uri_: The URI you wish to validate is allowed | Validates whether the URI is allowed. This checks the configuration and validates that the hostname of the URI is in the list of allowed Hosts and returns `true` if it is allowed. If the configuration says that all URI's are allowed (using an "\*") then it will always return `true`. | Boolean | -| isHostnameAllowed | _hostname_: The Hostname you wish to validate is allowed | Validates whether the Hostname is allowed. This checks the configuration and validates that the hostname is in the list of allowed Hosts and returns `true` if it is allowed. If the configuration says that all Hostnames are allowed (using an "\*") then it will always return `true`. | Boolean | -| isActionTypeEnabled | _actionType_: The actionType to check to see if it's enabled | Returns true if the actionType is enabled, otherwise false. | Boolean | -| ensureUriAllowed | _uri_: The URI you wish to validate is allowed | Validates whether the URI is allowed. This checks the configuration and validates that the hostname of the URI is in the list of allowed Hosts and throws an error if it is not allowed. If the configuration says that all URI's are allowed (using an "\*") then it will never throw. | No return value, throws if URI isn't allowed | -| ensureHostnameAllowed | _hostname_: The Hostname you wish to validate is allowed | Validates whether the Hostname is allowed. This checks the configuration and validates that the hostname is in the list of allowed Hosts and throws an error if it is not allowed. If the configuration says that all Hostnames are allowed (using an "\*") then it will never throw | No return value, throws if Hostname isn't allowed . | -| ensureActionTypeEnabled | _actionType_: The actionType to check to see if it's enabled | Throws an error if the actionType is not enabled | No return value, throws if actionType isn't enabled | +| Method | Arguments | Description | Return Type | +| ----------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | +| isUriAllowed | _uri_: The URI you wish to validate is allowed | Validates whether the URI is allowed. This checks the configuration and validates that the hostname of the URI is in the list of allowed Hosts and returns `true` if it is allowed. If the configuration says that all URI's are allowed (using an "\*") then it will always return `true`. | Boolean | +| isHostnameAllowed | _hostname_: The Hostname you wish to validate is allowed | Validates whether the Hostname is allowed. This checks the configuration and validates that the hostname is in the list of allowed Hosts and returns `true` if it is allowed. If the configuration says that all Hostnames are allowed (using an "\*") then it will always return `true`. | Boolean | +| isActionTypeEnabled | _actionType_: The actionType to check to see if it's enabled | Returns true if the actionType is enabled, otherwise false. | Boolean | +| ensureUriAllowed | _uri_: The URI you wish to validate is allowed | Validates whether the URI is allowed. This checks the configuration and validates that the hostname of the URI is in the list of allowed Hosts and throws an error if it is not allowed. If the configuration says that all URI's are allowed (using an "\*") then it will never throw. | No return value, throws if URI isn't allowed | +| ensureHostnameAllowed | _hostname_: The Hostname you wish to validate is allowed | Validates whether the Hostname is allowed. This checks the configuration and validates that the hostname is in the list of allowed Hosts and throws an error if it is not allowed. If the configuration says that all Hostnames are allowed (using an "\*") then it will never throw | No return value, throws if Hostname isn't allowed . | +| ensureActionTypeEnabled | _actionType_: The actionType to check to see if it's enabled | Throws an error if the actionType is not enabled | No return value, throws if actionType isn't enabled | ## Action types @@ -442,7 +450,7 @@ The config and params properties are modelled after the [Watcher Index Action](h | index | The Elasticsearch index to index into. | string _(optional)_ | | doc_id | The optional \_id of the document. | string _(optional)_ | | execution_time_field | The field that will store/index the action execution time. | string _(optional)_ | -| refresh | Setting of the refresh policy for the write request. | boolean _(optional)_ | +| refresh | Setting of the refresh policy for the write request. | boolean _(optional)_ | ### `secrets` @@ -450,9 +458,9 @@ This action type has no `secrets` properties. ### `params` -| Property | Description | Type | -| --------- | ---------------------------------------- | ------------------- | -| documents | JSON object that describes the [document](https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started-index.html#getting-started-batch-processing). | object[] | +| Property | Description | Type | +| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| documents | JSON object that describes the [document](https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started-index.html#getting-started-batch-processing). | object[] | --- @@ -529,10 +537,10 @@ The ServiceNow action uses the [V2 Table API](https://developer.servicenow.com/a ### `config` -| Property | Description | Type | -| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -| apiUrl | ServiceNow instance URL. | string | -| casesConfiguration | Case configuration object. The object should contain an attribute called `mapping`. A `mapping` is an array of objects. Each mapping object should be of the form `{ source: string, target: string, actionType: string }`. `source` is the Case field. `target` is the ServiceNow field where `source` will be mapped to. `actionType` can be one of `nothing`, `overwrite` or `append`. For example the `{ source: 'title', target: 'short_description', actionType: 'overwrite' }` record, inside mapping array, means that the title of a case will be mapped to the short description of an incident in ServiceNow and will be overwrite on each update. | object | +| Property | Description | Type | +| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- | +| apiUrl | ServiceNow instance URL. | string | +| incidentConfiguration | Optional property and specific to **Cases only**. If defined, the object should contain an attribute called `mapping`. A `mapping` is an array of objects. Each mapping object should be of the form `{ source: string, target: string, actionType: string }`. `source` is the Case field. `target` is the ServiceNow field where `source` will be mapped to. `actionType` can be one of `nothing`, `overwrite` or `append`. For example the `{ source: 'title', target: 'short_description', actionType: 'overwrite' }` record, inside mapping array, means that the title of a case will be mapped to the short description of an incident in ServiceNow and will be overwrite on each update. | object _(optional)_ | ### `secrets` @@ -550,13 +558,17 @@ The ServiceNow action uses the [V2 Table API](https://developer.servicenow.com/a #### `subActionParams (pushToService)` -| Property | Description | Type | -| ----------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| caseId | The case id | string | -| title | The title of the case | string _(optional)_ | -| description | The description of the case | string _(optional)_ | -| comments | The comments of the case. A comment is of the form `{ commentId: string, version: string, comment: string }` | object[] _(optional)_ | -| externalId | The id of the incident in ServiceNow . If presented the incident will be update. Otherwise a new incident will be created. | string _(optional)_ | +| Property | Description | Type | +| ------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| savedObjectId | The id of the saved object. | string | +| title | The title of the case. | string _(optional)_ | +| description | The description of the case. | string _(optional)_ | +| comment | A comment. | string _(optional)_ | +| comments | The comments of the case. A comment is of the form `{ commentId: string, version: string, comment: string }`. | object[] _(optional)_ | +| externalId | The id of the incident in ServiceNow. If presented the incident will be update. Otherwise a new incident will be created. | string _(optional)_ | +| severity | The name of the severity in ServiceNow. | string _(optional)_ | +| urgency | The name of the urgency in ServiceNow. | string _(optional)_ | +| impact | The name of the impact in ServiceNow. | string _(optional)_ | --- @@ -568,34 +580,47 @@ The Jira action uses the [V2 API](https://developer.atlassian.com/cloud/jira/pla ### `config` -| Property | Description | Type | -| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -| apiUrl | Jira instance URL. | string | -| casesConfiguration | Case configuration object. The object should contain an attribute called `mapping`. A `mapping` is an array of objects. Each mapping object should be of the form `{ source: string, target: string, actionType: string }`. `source` is the Case field. `target` is the Jira field where `source` will be mapped to. `actionType` can be one of `nothing`, `overwrite` or `append`. For example the `{ source: 'title', target: 'summary', actionType: 'overwrite' }` record, inside mapping array, means that the title of a case will be mapped to the short description of an incident in Jira and will be overwrite on each update. | object | +| Property | Description | Type | +| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| apiUrl | Jira instance URL. | string | +| incidentConfiguration | Optional property and specific to **Cases only**. if defined, the object should contain an attribute called `mapping`. A `mapping` is an array of objects. Each mapping object should be of the form `{ source: string, target: string, actionType: string }`. `source` is the Case field. `target` is the Jira field where `source` will be mapped to. `actionType` can be one of `nothing`, `overwrite` or `append`. For example the `{ source: 'title', target: 'summary', actionType: 'overwrite' }` record, inside mapping array, means that the title of a case will be mapped to the short description of an incident in Jira and will be overwrite on each update. | object _(optional)_ | ### `secrets` -| Property | Description | Type | -| -------- | --------------------------------------- | ------ | -| email | email for HTTP Basic authentication | string | -| apiToken | API token for HTTP Basic authentication | string | +| Property | Description | Type | +| -------- | ----------------------------------------------------- | ------ | +| email | email (or username) for HTTP Basic authentication | string | +| apiToken | API token (or password) for HTTP Basic authentication | string | ### `params` -| Property | Description | Type | -| --------------- | ------------------------------------------------------------------------------------ | ------ | -| subAction | The sub action to perform. It can be `pushToService`, `handshake`, and `getIncident` | string | -| subActionParams | The parameters of the sub action | object | +| Property | Description | Type | +| --------------- | ----------------------------------------------------------------------------------------------------------------------- | ------ | +| subAction | The sub action to perform. It can be `pushToService`, `handshake`, `getIncident`, `issueTypes`, and `fieldsByIssueType` | string | +| subActionParams | The parameters of the sub action | object | + +#### `subActionParams (pushToService)` + +| Property | Description | Type | +| ------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------- | +| savedObjectId | The id of the saved object | string | +| title | The title of the case | string _(optional)_ | +| description | The description of the case | string _(optional)_ | +| externalId | The id of the incident in Jira. If presented the incident will be update. Otherwise a new incident will be created. | string _(optional)_ | +| issueType | The id of the issue type in Jira. | string _(optional)_ | +| priority | The name of the priority in Jira. Example: `Medium`. | string _(optional)_ | +| labels | An array of labels. | string[] _(optional)_ | +| comments | The comments of the case. A comment is of the form `{ commentId: string, version: string, comment: string }` | object[] _(optional)_ | + +#### `subActionParams (issueTypes)` + +No parameters for `issueTypes` sub-action. Provide an empty object `{}`. #### `subActionParams (pushToService)` -| Property | Description | Type | -| ----------- | ------------------------------------------------------------------------------------------------------------------- | --------------------- | -| caseId | The case id | string | -| title | The title of the case | string _(optional)_ | -| description | The description of the case | string _(optional)_ | -| comments | The comments of the case. A comment is of the form `{ commentId: string, version: string, comment: string }` | object[] _(optional)_ | -| externalId | The id of the incident in Jira. If presented the incident will be update. Otherwise a new incident will be created. | string _(optional)_ | +| Property | Description | Type | +| -------- | -------------------------------- | ------ | +| id | The id of the issue type in Jira | string | ## IBM Resilient @@ -603,10 +628,10 @@ ID: `.resilient` ### `config` -| Property | Description | Type | -| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | -| apiUrl | IBM Resilient instance URL. | string | -| casesConfiguration | Case configuration object. The object should contain an attribute called `mapping`. A `mapping` is an array of objects. Each mapping object should be of the form `{ source: string, target: string, actionType: string }`. `source` is the Case field. `target` is the Jira field where `source` will be mapped to. `actionType` can be one of `nothing`, `overwrite` or `append`. For example the `{ source: 'title', target: 'summary', actionType: 'overwrite' }` record, inside mapping array, means that the title of a case will be mapped to the short description of an incident in IBM Resilient and will be overwrite on each update. | object | +| Property | Description | Type | +| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | +| apiUrl | IBM Resilient instance URL. | string | +| incidentConfiguration | Case configuration object. The object should contain an attribute called `mapping`. A `mapping` is an array of objects. Each mapping object should be of the form `{ source: string, target: string, actionType: string }`. `source` is the Case field. `target` is the Jira field where `source` will be mapped to. `actionType` can be one of `nothing`, `overwrite` or `append`. For example the `{ source: 'title', target: 'summary', actionType: 'overwrite' }` record, inside mapping array, means that the title of a case will be mapped to the short description of an incident in IBM Resilient and will be overwrite on each update. | object | ### `secrets` @@ -624,13 +649,13 @@ ID: `.resilient` #### `subActionParams (pushToService)` -| Property | Description | Type | -| ----------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------- | -| caseId | The case id | string | -| title | The title of the case | string _(optional)_ | -| description | The description of the case | string _(optional)_ | -| comments | The comments of the case. A comment is of the form `{ commentId: string, version: string, comment: string }` | object[] _(optional)_ | -| externalId | The id of the incident in IBM Resilient. If presented the incident will be update. Otherwise a new incident will be created. | string _(optional)_ | +| Property | Description | Type | +| ------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------- | +| savedObjectId | The id of the saved object | string | +| title | The title of the case | string _(optional)_ | +| description | The description of the case | string _(optional)_ | +| comments | The comments of the case. A comment is of the form `{ commentId: string, version: string, comment: string }` | object[] _(optional)_ | +| externalId | The id of the incident in IBM Resilient. If presented the incident will be update. Otherwise a new incident will be created. | string _(optional)_ | # Command Line Utility @@ -660,30 +685,30 @@ Consider working with the alerting team on early structure /design feedback of n ## licensing -Currently actions are licensed as "basic" if the action only interacts with the stack, eg the server log and es index actions. Other actions are at least "gold" level. +Currently actions are licensed as "basic" if the action only interacts with the stack, eg the server log and es index actions. Other actions are at least "gold" level. ## plugin location -Currently actions that are licensed as "basic" **MUST** be implemented in the actions plugin, other actions can be implemented in any other plugin that pre-reqs the actions plugin. If the new action is generic across the stack, it probably belongs in the actions plugin, but if your action is very specific to a plugin/solution, it might be easiest to implement it in the plugin/solution. Keep in mind that if Kibana is run without the plugin being enabled, any actions defined in that plugin will not run, nor will those actions be available via APIs or UI. +Currently actions that are licensed as "basic" **MUST** be implemented in the actions plugin, other actions can be implemented in any other plugin that pre-reqs the actions plugin. If the new action is generic across the stack, it probably belongs in the actions plugin, but if your action is very specific to a plugin/solution, it might be easiest to implement it in the plugin/solution. Keep in mind that if Kibana is run without the plugin being enabled, any actions defined in that plugin will not run, nor will those actions be available via APIs or UI. -Actions that take URLs or hostnames should check that those values are allowed. The allowed host list utilities are currently internal to the actions plugin, and so such actions will need to be implemented in the actions plugin. Longer-term, we will expose these utilities so they can be used by alerts implemented in other plugins; see [issue #64659](https://github.com/elastic/kibana/issues/64659). +Actions that take URLs or hostnames should check that those values are allowed. The allowed host list utilities are currently internal to the actions plugin, and so such actions will need to be implemented in the actions plugin. Longer-term, we will expose these utilities so they can be used by alerts implemented in other plugins; see [issue #64659](https://github.com/elastic/kibana/issues/64659). ## documentation -You should also create some asciidoc for the new action type. An entry should be made in the action type index - [`docs/user/alerting/action-types.asciidoc`](../../../docs/user/alerting/action-types.asciidoc) which points to a new document for the action type that should be in the directory [`docs/user/alerting/action-types`](../../../docs/user/alerting/action-types). +You should also create some asciidoc for the new action type. An entry should be made in the action type index - [`docs/user/alerting/action-types.asciidoc`](../../../docs/user/alerting/action-types.asciidoc) which points to a new document for the action type that should be in the directory [`docs/user/alerting/action-types`](../../../docs/user/alerting/action-types). ## tests -The action type should have both jest tests and functional tests. For functional tests, if your action interacts with a 3rd party service via HTTP, you may be able to create a simulator for your service, to test with. See the existing functional test servers in the directory [`x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server`](../../test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server) +The action type should have both jest tests and functional tests. For functional tests, if your action interacts with a 3rd party service via HTTP, you may be able to create a simulator for your service, to test with. See the existing functional test servers in the directory [`x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server`](../../test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server) ## action type config and secrets -Action types must define `config` and `secrets` which are used to create connectors. This data should be described with `@kbn/config-schema` object schemas, and you **MUST NOT** use `schema.maybe()` to define properties. +Action types must define `config` and `secrets` which are used to create connectors. This data should be described with `@kbn/config-schema` object schemas, and you **MUST NOT** use `schema.maybe()` to define properties. -This is due to the fact that the structures are persisted in saved objects, which performs partial updates on the persisted data. If a property value is already persisted, but an update either doesn't include the property, or sets it to `undefined`, the persisted value will not be changed. Beyond this being a semantic error in general, it also ends up invalidating the encryption used to save secrets, and will render the secrets will not be able to be unencrypted later. +This is due to the fact that the structures are persisted in saved objects, which performs partial updates on the persisted data. If a property value is already persisted, but an update either doesn't include the property, or sets it to `undefined`, the persisted value will not be changed. Beyond this being a semantic error in general, it also ends up invalidating the encryption used to save secrets, and will render the secrets will not be able to be unencrypted later. -Instead of `schema.maybe()`, use `schema.nullable()`, which is the same as `schema.maybe()` except that when passed an `undefined` value, the object returned from the validation will be set to `null`. The resulting type will be `property-type | null`, whereas with `schema.maybe()` it would be `property-type | undefined`. +Instead of `schema.maybe()`, use `schema.nullable()`, which is the same as `schema.maybe()` except that when passed an `undefined` value, the object returned from the validation will be set to `null`. The resulting type will be `property-type | null`, whereas with `schema.maybe()` it would be `property-type | undefined`. ## user interface -In order to make this action usable in the Kibana UI, you will need to provide all the UI editing aspects of the action. The existing action type user interfaces are defined in [`x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types`](../triggers_actions_ui/public/application/components/builtin_action_types). For more information, see the [UI documentation](../triggers_actions_ui/README.md#create-and-register-new-action-type-ui). +In order to make this action usable in the Kibana UI, you will need to provide all the UI editing aspects of the action. The existing action type user interfaces are defined in [`x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types`](../triggers_actions_ui/public/application/components/builtin_action_types). For more information, see the [UI documentation](../triggers_actions_ui/README.md#create-and-register-new-action-type-ui). diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_shema.ts b/x-pack/plugins/actions/server/builtin_action_types/case/common_schema.ts similarity index 72% rename from x-pack/plugins/actions/server/builtin_action_types/servicenow/case_shema.ts rename to x-pack/plugins/actions/server/builtin_action_types/case/common_schema.ts index 2df8c8156cde8..5a23eb89339e6 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_shema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/common_schema.ts @@ -22,13 +22,20 @@ export const IncidentConfigurationSchema = schema.object({ mapping: schema.arrayOf(MapRecordSchema), }); +export const UserSchema = schema.object({ + fullName: schema.nullable(schema.string()), + username: schema.nullable(schema.string()), +}); + export const EntityInformation = { - createdAt: schema.maybe(schema.string()), - createdBy: schema.maybe(schema.any()), + createdAt: schema.nullable(schema.string()), + createdBy: schema.nullable(UserSchema), updatedAt: schema.nullable(schema.string()), - updatedBy: schema.nullable(schema.any()), + updatedBy: schema.nullable(UserSchema), }; +export const EntityInformationSchema = schema.object(EntityInformation); + export const CommentSchema = schema.object({ commentId: schema.string(), comment: schema.string(), diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts b/x-pack/plugins/actions/server/builtin_action_types/case/common_types.ts similarity index 53% rename from x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts rename to x-pack/plugins/actions/server/builtin_action_types/case/common_types.ts index 49b85f9254af9..cca83fb88ca92 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/common_types.ts @@ -6,15 +6,11 @@ import { TypeOf } from '@kbn/config-schema'; import { - ExecutorSubActionGetIncidentParamsSchema, - ExecutorSubActionHandshakeParamsSchema, -} from './schema'; -import { IncidentConfigurationSchema, MapRecordSchema } from './case_shema'; -import { - PushToServiceApiParams, - ExternalServiceIncidentResponse, - ExternalServiceParams, -} from './types'; + IncidentConfigurationSchema, + MapRecordSchema, + CommentSchema, + EntityInformationSchema, +} from './common_schema'; export interface CreateCommentRequest { [key: string]: string; @@ -22,6 +18,8 @@ export interface CreateCommentRequest { export type IncidentConfiguration = TypeOf; export type MapRecord = TypeOf; +export type Comment = TypeOf; +export type EntityInformation = TypeOf; export interface ExternalServiceCommentResponse { commentId: string; @@ -29,18 +27,6 @@ export interface ExternalServiceCommentResponse { externalCommentId?: string; } -export type ExecutorSubActionGetIncidentParams = TypeOf< - typeof ExecutorSubActionGetIncidentParamsSchema ->; - -export type ExecutorSubActionHandshakeParams = TypeOf< - typeof ExecutorSubActionHandshakeParamsSchema ->; - -export interface PushToServiceResponse extends ExternalServiceIncidentResponse { - comments?: ExternalServiceCommentResponse[]; -} - export interface PipedField { key: string; value: string; @@ -48,10 +34,10 @@ export interface PipedField { pipes: string[]; } -export interface TransformFieldsArgs { - params: PushToServiceApiParams; +export interface TransformFieldsArgs { + params: P; fields: PipedField[]; - currentIncident?: ExternalServiceParams; + currentIncident?: S; } export interface TransformerArgs { diff --git a/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts b/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts index d895bf386a367..701bbea14fde8 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts @@ -51,10 +51,7 @@ export const buildMap = (mapping: MapRecord[]): Map => { }, new Map()); }; -export const mapParams = ( - params: Partial, - mapping: Map -): AnyParams => { +export const mapParams = (params: T, mapping: Map): AnyParams => { return Object.keys(params).reduce((prev: AnyParams, curr: string): AnyParams => { const field = mapping.get(curr); if (field) { @@ -106,7 +103,10 @@ export const createConnectorExecutor = ({ const { comments, externalId, ...restParams } = pushToServiceParams; const mapping = buildMap(config.casesConfiguration.mapping); - const externalCase = mapParams(restParams, mapping); + const externalCase = mapParams( + restParams as ExecutorSubActionPushParams, + mapping + ); data = await api.pushToService({ externalService, diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/api.test.ts index bcfb82077d286..4495c37f758ee 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/api.test.ts @@ -4,15 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { api } from '../case/api'; +import { Logger } from '../../../../../../src/core/server'; import { externalServiceMock, mapping, apiParams } from './mocks'; -import { ExternalService } from '../case/types'; +import { ExternalService } from './types'; +import { api } from './api'; +let mockedLogger: jest.Mocked; describe('api', () => { let externalService: jest.Mocked; beforeEach(() => { externalService = externalServiceMock.create(); + jest.clearAllMocks(); }); afterEach(() => { @@ -20,10 +23,15 @@ describe('api', () => { }); describe('pushToService', () => { - describe('create incident', () => { + describe('create incident - cases', () => { test('it creates an incident', async () => { const params = { ...apiParams, externalId: null }; - const res = await api.pushToService({ externalService, mapping, params }); + const res = await api.pushToService({ + externalService, + mapping, + params, + logger: mockedLogger, + }); expect(res).toEqual({ id: 'incident-1', @@ -45,7 +53,12 @@ describe('api', () => { test('it creates an incident without comments', async () => { const params = { ...apiParams, externalId: null, comments: [] }; - const res = await api.pushToService({ externalService, mapping, params }); + const res = await api.pushToService({ + externalService, + mapping, + params, + logger: mockedLogger, + }); expect(res).toEqual({ id: 'incident-1', @@ -57,7 +70,7 @@ describe('api', () => { test('it calls createIncident correctly', async () => { const params = { ...apiParams, externalId: null }; - await api.pushToService({ externalService, mapping, params }); + await api.pushToService({ externalService, mapping, params, logger: mockedLogger }); expect(externalService.createIncident).toHaveBeenCalledWith({ incident: { @@ -69,9 +82,25 @@ describe('api', () => { expect(externalService.updateIncident).not.toHaveBeenCalled(); }); + test('it calls createIncident correctly without mapping', async () => { + const params = { ...apiParams, externalId: null }; + await api.pushToService({ externalService, mapping: null, params, logger: mockedLogger }); + + expect(externalService.createIncident).toHaveBeenCalledWith({ + incident: { + description: 'Incident description', + summary: 'Incident title', + issueType: '10006', + labels: ['kibana', 'elastic'], + priority: 'High', + }, + }); + expect(externalService.updateIncident).not.toHaveBeenCalled(); + }); + test('it calls createComment correctly', async () => { const params = { ...apiParams, externalId: null }; - await api.pushToService({ externalService, mapping, params }); + await api.pushToService({ externalService, mapping, params, logger: mockedLogger }); expect(externalService.createComment).toHaveBeenCalledTimes(2); expect(externalService.createComment).toHaveBeenNthCalledWith(1, { incidentId: 'incident-1', @@ -89,7 +118,6 @@ describe('api', () => { username: 'elastic', }, }, - field: 'comments', }); expect(externalService.createComment).toHaveBeenNthCalledWith(2, { @@ -108,14 +136,59 @@ describe('api', () => { username: 'elastic', }, }, - field: 'comments', + }); + }); + + test('it calls createComment correctly without mapping', async () => { + const params = { ...apiParams, externalId: null }; + await api.pushToService({ externalService, mapping: null, params, logger: mockedLogger }); + expect(externalService.createComment).toHaveBeenCalledTimes(2); + expect(externalService.createComment).toHaveBeenNthCalledWith(1, { + incidentId: 'incident-1', + comment: { + commentId: 'case-comment-1', + comment: 'A comment', + createdAt: '2020-04-27T10:59:46.202Z', + createdBy: { + fullName: 'Elastic User', + username: 'elastic', + }, + updatedAt: '2020-04-27T10:59:46.202Z', + updatedBy: { + fullName: 'Elastic User', + username: 'elastic', + }, + }, + }); + + expect(externalService.createComment).toHaveBeenNthCalledWith(2, { + incidentId: 'incident-1', + comment: { + commentId: 'case-comment-2', + comment: 'Another comment', + createdAt: '2020-04-27T10:59:46.202Z', + createdBy: { + fullName: 'Elastic User', + username: 'elastic', + }, + updatedAt: '2020-04-27T10:59:46.202Z', + updatedBy: { + fullName: 'Elastic User', + username: 'elastic', + }, + }, }); }); }); describe('update incident', () => { test('it updates an incident', async () => { - const res = await api.pushToService({ externalService, mapping, params: apiParams }); + const res = await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(res).toEqual({ id: 'incident-1', @@ -137,7 +210,12 @@ describe('api', () => { test('it updates an incident without comments', async () => { const params = { ...apiParams, comments: [] }; - const res = await api.pushToService({ externalService, mapping, params }); + const res = await api.pushToService({ + externalService, + mapping, + params, + logger: mockedLogger, + }); expect(res).toEqual({ id: 'incident-1', @@ -149,7 +227,7 @@ describe('api', () => { test('it calls updateIncident correctly', async () => { const params = { ...apiParams }; - await api.pushToService({ externalService, mapping, params }); + await api.pushToService({ externalService, mapping, params, logger: mockedLogger }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', @@ -162,9 +240,26 @@ describe('api', () => { expect(externalService.createIncident).not.toHaveBeenCalled(); }); + test('it calls updateIncident correctly without mapping', async () => { + const params = { ...apiParams }; + await api.pushToService({ externalService, mapping: null, params, logger: mockedLogger }); + + expect(externalService.updateIncident).toHaveBeenCalledWith({ + incidentId: 'incident-3', + incident: { + description: 'Incident description', + summary: 'Incident title', + issueType: '10006', + labels: ['kibana', 'elastic'], + priority: 'High', + }, + }); + expect(externalService.createIncident).not.toHaveBeenCalled(); + }); + test('it calls createComment correctly', async () => { const params = { ...apiParams }; - await api.pushToService({ externalService, mapping, params }); + await api.pushToService({ externalService, mapping, params, logger: mockedLogger }); expect(externalService.createComment).toHaveBeenCalledTimes(2); expect(externalService.createComment).toHaveBeenNthCalledWith(1, { incidentId: 'incident-1', @@ -182,7 +277,6 @@ describe('api', () => { username: 'elastic', }, }, - field: 'comments', }); expect(externalService.createComment).toHaveBeenNthCalledWith(2, { @@ -201,7 +295,87 @@ describe('api', () => { username: 'elastic', }, }, - field: 'comments', + }); + }); + + test('it calls createComment correctly without mapping', async () => { + const params = { ...apiParams }; + await api.pushToService({ externalService, mapping: null, params, logger: mockedLogger }); + expect(externalService.createComment).toHaveBeenCalledTimes(2); + expect(externalService.createComment).toHaveBeenNthCalledWith(1, { + incidentId: 'incident-1', + comment: { + commentId: 'case-comment-1', + comment: 'A comment', + createdAt: '2020-04-27T10:59:46.202Z', + createdBy: { + fullName: 'Elastic User', + username: 'elastic', + }, + updatedAt: '2020-04-27T10:59:46.202Z', + updatedBy: { + fullName: 'Elastic User', + username: 'elastic', + }, + }, + }); + + expect(externalService.createComment).toHaveBeenNthCalledWith(2, { + incidentId: 'incident-1', + comment: { + commentId: 'case-comment-2', + comment: 'Another comment', + createdAt: '2020-04-27T10:59:46.202Z', + createdBy: { + fullName: 'Elastic User', + username: 'elastic', + }, + updatedAt: '2020-04-27T10:59:46.202Z', + updatedBy: { + fullName: 'Elastic User', + username: 'elastic', + }, + }, + }); + }); + }); + + describe('issueTypes', () => { + test('it returns the issue types correctly', async () => { + const res = await api.issueTypes({ + externalService, + params: {}, + }); + expect(res).toEqual([ + { + id: '10006', + name: 'Task', + }, + { + id: '10007', + name: 'Bug', + }, + ]); + }); + }); + + describe('fieldsByIssueType', () => { + test('it returns the fields correctly', async () => { + const res = await api.fieldsByIssueType({ + externalService, + params: { id: '10006' }, + }); + expect(res).toEqual({ + summary: { allowedValues: [], defaultValue: {} }, + priority: { + allowedValues: [ + { + name: 'Medium', + id: '3', + }, + ], + defaultValue: { name: 'Medium', id: '3' }, + }, }); }); }); @@ -228,7 +402,12 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -260,7 +439,12 @@ describe('api', () => { actionType: 'nothing', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -291,7 +475,12 @@ describe('api', () => { actionType: 'append', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -324,7 +513,12 @@ describe('api', () => { actionType: 'nothing', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: {}, @@ -352,7 +546,12 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -382,7 +581,12 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -414,7 +618,12 @@ describe('api', () => { actionType: 'nothing', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -445,7 +654,12 @@ describe('api', () => { actionType: 'append', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -478,7 +692,12 @@ describe('api', () => { actionType: 'append', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -509,7 +728,12 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + logger: mockedLogger, + }); expect(externalService.createComment).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/api.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/api.ts index 3db66e5884af4..da47a4bfb839b 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/api.ts @@ -4,4 +4,179 @@ * you may not use this file except in compliance with the Elastic License. */ -export { api } from '../case/api'; +import { flow } from 'lodash'; +import { + ExternalServiceParams, + PushToServiceApiHandlerArgs, + HandshakeApiHandlerArgs, + GetIncidentApiHandlerArgs, + ExternalServiceApi, + Incident, + GetFieldsByIssueTypeHandlerArgs, + GetIssueTypesHandlerArgs, + PushToServiceApiParams, +} from './types'; + +// TODO: to remove, need to support Case +import { transformers } from '../case/transformers'; +import { TransformFieldsArgs, Comment, EntityInformation } from '../case/common_types'; + +import { PushToServiceResponse } from './types'; +import { prepareFieldsForTransformation } from '../case/utils'; + +const handshakeHandler = async ({ + externalService, + mapping, + params, +}: HandshakeApiHandlerArgs) => {}; + +const getIncidentHandler = async ({ + externalService, + mapping, + params, +}: GetIncidentApiHandlerArgs) => {}; + +const getIssueTypesHandler = async ({ externalService }: GetIssueTypesHandlerArgs) => { + const res = await externalService.getIssueTypes(); + return res; +}; + +const getFieldsByIssueTypeHandler = async ({ + externalService, + params, +}: GetFieldsByIssueTypeHandlerArgs) => { + const { id } = params; + const res = await externalService.getFieldsByIssueType(id); + return res; +}; + +const pushToServiceHandler = async ({ + externalService, + mapping, + params, + logger, +}: PushToServiceApiHandlerArgs): Promise => { + const { externalId, comments } = params; + const updateIncident = externalId ? true : false; + const defaultPipes = updateIncident ? ['informationUpdated'] : ['informationCreated']; + let currentIncident: ExternalServiceParams | undefined; + let res: PushToServiceResponse; + + if (externalId) { + try { + currentIncident = await externalService.getIncident(externalId); + } catch (ex) { + logger.debug( + `Retrieving Incident by id ${externalId} from Jira failed with exception: ${ex}` + ); + } + } + + let incident: Incident; + // TODO: should be removed later but currently keep it for the Case implementation support + if (mapping) { + const fields = prepareFieldsForTransformation({ + externalCase: params.externalObject, + mapping, + defaultPipes, + }); + + incident = transformFields({ + params, + fields, + currentIncident, + }); + } else { + const { title, description, priority, labels, issueType } = params; + incident = { summary: title, description, priority, labels, issueType }; + } + + if (externalId != null) { + res = await externalService.updateIncident({ + incidentId: externalId, + incident, + }); + } else { + res = await externalService.createIncident({ + incident: { + ...incident, + }, + }); + } + + if (comments && Array.isArray(comments) && comments.length > 0) { + if (mapping && mapping.get('comments')?.actionType === 'nothing') { + return res; + } + + const commentsTransformed = mapping + ? transformComments(comments, ['informationAdded']) + : comments; + + res.comments = []; + for (const currentComment of commentsTransformed) { + const comment = await externalService.createComment({ + incidentId: res.id, + comment: currentComment, + }); + res.comments = [ + ...(res.comments ?? []), + { + commentId: comment.commentId, + pushedDate: comment.pushedDate, + }, + ]; + } + } + + return res; +}; + +export const transformFields = ({ + params, + fields, + currentIncident, +}: TransformFieldsArgs): Incident => { + return fields.reduce((prev, cur) => { + const transform = flow(...cur.pipes.map((p) => transformers[p])); + return { + ...prev, + [cur.key]: transform({ + value: cur.value, + date: params.updatedAt ?? params.createdAt, + user: getEntity(params), + previousValue: currentIncident ? currentIncident[cur.key] : '', + }).value, + }; + }, {} as Incident); +}; + +export const transformComments = (comments: Comment[], pipes: string[]): Comment[] => { + return comments.map((c) => ({ + ...c, + comment: flow(...pipes.map((p) => transformers[p]))({ + value: c.comment, + date: c.updatedAt ?? c.createdAt, + user: getEntity(c), + }).value, + })); +}; + +export const getEntity = (entity: EntityInformation): string => + (entity.updatedBy != null + ? entity.updatedBy.fullName + ? entity.updatedBy.fullName + : entity.updatedBy.username + : entity.createdBy != null + ? entity.createdBy.fullName + ? entity.createdBy.fullName + : entity.createdBy.username + : '') ?? ''; + +export const api: ExternalServiceApi = { + handshake: handshakeHandler, + pushToService: pushToServiceHandler, + getIncident: getIncidentHandler, + issueTypes: getIssueTypesHandler, + fieldsByIssueType: getFieldsByIssueTypeHandler, +}; diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/config.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/config.ts deleted file mode 100644 index 54f28e447010a..0000000000000 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/config.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * 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 { ExternalServiceConfiguration } from '../case/types'; -import * as i18n from './translations'; - -export const config: ExternalServiceConfiguration = { - id: '.jira', - name: i18n.NAME, - minimumLicenseRequired: 'gold', -}; diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/index.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/index.ts index 66be0bad02d7b..d3346557f3684 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/index.ts @@ -4,33 +4,138 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Logger } from '../../../../../../src/core/server'; -import { createConnector } from '../case/utils'; -import { ActionType } from '../../types'; +import { curry } from 'lodash'; +import { schema } from '@kbn/config-schema'; -import { api } from './api'; -import { config } from './config'; import { validate } from './validators'; -import { createExternalService } from './service'; -import { JiraSecretConfiguration, JiraPublicConfiguration } from './schema'; +import { + ExternalIncidentServiceConfiguration, + ExternalIncidentServiceSecretConfiguration, + ExecutorParamsSchema, +} from './schema'; import { ActionsConfigurationUtilities } from '../../actions_config'; +import { ActionType, ActionTypeExecutorOptions, ActionTypeExecutorResult } from '../../types'; +import { createExternalService } from './service'; +import { api } from './api'; +import { + ExecutorParams, + ExecutorSubActionPushParams, + JiraPublicConfigurationType, + JiraSecretConfigurationType, + JiraExecutorResultData, + ExecutorSubActionGetFieldsByIssueTypeParams, + ExecutorSubActionGetIssueTypesParams, +} from './types'; +import * as i18n from './translations'; +import { Logger } from '../../../../../../src/core/server'; -export function getActionType({ - logger, - configurationUtilities, -}: { +// TODO: to remove, need to support Case +import { buildMap, mapParams } from '../case/utils'; + +interface GetActionTypeParams { logger: Logger; configurationUtilities: ActionsConfigurationUtilities; -}): ActionType { - return createConnector({ - api, - config, - validate, - createExternalService, - validationSchema: { - config: JiraPublicConfiguration, - secrets: JiraSecretConfiguration, +} + +const supportedSubActions: string[] = ['pushToService', 'issueTypes', 'fieldsByIssueType']; + +// action type definition +export function getActionType( + params: GetActionTypeParams +): ActionType< + JiraPublicConfigurationType, + JiraSecretConfigurationType, + ExecutorParams, + JiraExecutorResultData | {} +> { + const { logger, configurationUtilities } = params; + return { + id: '.jira', + minimumLicenseRequired: 'gold', + name: i18n.NAME, + validate: { + config: schema.object(ExternalIncidentServiceConfiguration, { + validate: curry(validate.config)(configurationUtilities), + }), + secrets: schema.object(ExternalIncidentServiceSecretConfiguration, { + validate: curry(validate.secrets)(configurationUtilities), + }), + params: ExecutorParamsSchema, + }, + executor: curry(executor)({ logger }), + }; +} + +// action executor +async function executor( + { logger }: { logger: Logger }, + execOptions: ActionTypeExecutorOptions< + JiraPublicConfigurationType, + JiraSecretConfigurationType, + ExecutorParams + > +): Promise> { + const { actionId, config, params, secrets } = execOptions; + const { subAction, subActionParams } = params as ExecutorParams; + let data: JiraExecutorResultData | null = null; + + const externalService = createExternalService( + { + config, + secrets, }, logger, - })({ configurationUtilities }); + execOptions.proxySettings + ); + + if (!api[subAction]) { + const errorMessage = `[Action][ExternalService] Unsupported subAction type ${subAction}.`; + logger.error(errorMessage); + throw new Error(errorMessage); + } + + if (!supportedSubActions.includes(subAction)) { + const errorMessage = `[Action][ExternalService] subAction ${subAction} not implemented.`; + logger.error(errorMessage); + throw new Error(errorMessage); + } + + if (subAction === 'pushToService') { + const pushToServiceParams = subActionParams as ExecutorSubActionPushParams; + + const { comments, externalId, ...restParams } = pushToServiceParams; + const incidentConfiguration = config.incidentConfiguration; + const mapping = incidentConfiguration ? buildMap(incidentConfiguration.mapping) : null; + const externalObject = + config.incidentConfiguration && mapping + ? mapParams(restParams as ExecutorSubActionPushParams, mapping) + : {}; + + data = await api.pushToService({ + externalService, + mapping, + params: { ...pushToServiceParams, externalObject }, + logger, + }); + + logger.debug(`response push to service for incident id: ${data.id}`); + } + + if (subAction === 'issueTypes') { + const getIssueTypesParams = subActionParams as ExecutorSubActionGetIssueTypesParams; + data = await api.issueTypes({ + externalService, + params: getIssueTypesParams, + }); + } + + if (subAction === 'fieldsByIssueType') { + const getFieldsByIssueTypeParams = subActionParams as ExecutorSubActionGetFieldsByIssueTypeParams; + data = await api.fieldsByIssueType({ + externalService, + params: getFieldsByIssueTypeParams, + }); + } + + return { status: 'ok', data: data ?? {}, actionId }; } diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts index 709d490a5227f..e7841996fedef 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts @@ -4,12 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - ExternalService, - PushToServiceApiParams, - ExecutorSubActionPushParams, - MapRecord, -} from '../case/types'; +import { ExternalService, PushToServiceApiParams, ExecutorSubActionPushParams } from './types'; + +import { MapRecord } from '../case/common_types'; const createMock = (): jest.Mocked => { const service = { @@ -40,6 +37,30 @@ const createMock = (): jest.Mocked => { }) ), createComment: jest.fn(), + findIncidents: jest.fn(), + getCapabilities: jest.fn(), + getIssueTypes: jest.fn().mockImplementation(() => [ + { + id: '10006', + name: 'Task', + }, + { + id: '10007', + name: 'Bug', + }, + ]), + getFieldsByIssueType: jest.fn().mockImplementation(() => ({ + summary: { allowedValues: [], defaultValue: {} }, + priority: { + allowedValues: [ + { + name: 'Medium', + id: '3', + }, + ], + defaultValue: { name: 'Medium', id: '3' }, + }, + })), }; service.createComment.mockImplementationOnce(() => @@ -96,6 +117,9 @@ const executorParams: ExecutorSubActionPushParams = { updatedBy: { fullName: 'Elastic User', username: 'elastic' }, title: 'Incident title', description: 'Incident description', + labels: ['kibana', 'elastic'], + priority: 'High', + issueType: '10006', comments: [ { commentId: 'case-comment-1', @@ -118,7 +142,7 @@ const executorParams: ExecutorSubActionPushParams = { const apiParams: PushToServiceApiParams = { ...executorParams, - externalCase: { summary: 'Incident title', description: 'Incident description' }, + externalObject: { summary: 'Incident title', description: 'Incident description' }, }; export { externalServiceMock, mapping, executorParams, apiParams }; diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/schema.ts index 9c831e75d91c1..07c8e22812b27 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/schema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/schema.ts @@ -5,18 +5,85 @@ */ import { schema } from '@kbn/config-schema'; -import { ExternalIncidentServiceConfiguration } from '../case/schema'; +import { + CommentSchema, + EntityInformation, + IncidentConfigurationSchema, +} from '../case/common_schema'; -export const JiraPublicConfiguration = { +export const ExternalIncidentServiceConfiguration = { + apiUrl: schema.string(), projectKey: schema.string(), - ...ExternalIncidentServiceConfiguration, + // TODO: to remove - set it optional for the current stage to support Case Jira implementation + incidentConfiguration: schema.nullable(IncidentConfigurationSchema), + isCaseOwned: schema.nullable(schema.boolean()), }; -export const JiraPublicConfigurationSchema = schema.object(JiraPublicConfiguration); +export const ExternalIncidentServiceConfigurationSchema = schema.object( + ExternalIncidentServiceConfiguration +); -export const JiraSecretConfiguration = { +export const ExternalIncidentServiceSecretConfiguration = { email: schema.string(), apiToken: schema.string(), }; -export const JiraSecretConfigurationSchema = schema.object(JiraSecretConfiguration); +export const ExternalIncidentServiceSecretConfigurationSchema = schema.object( + ExternalIncidentServiceSecretConfiguration +); + +export const ExecutorSubActionSchema = schema.oneOf([ + schema.literal('getIncident'), + schema.literal('pushToService'), + schema.literal('handshake'), + schema.literal('issueTypes'), + schema.literal('fieldsByIssueType'), +]); + +export const ExecutorSubActionPushParamsSchema = schema.object({ + savedObjectId: schema.string(), + title: schema.string(), + description: schema.nullable(schema.string()), + externalId: schema.nullable(schema.string()), + issueType: schema.nullable(schema.string()), + priority: schema.nullable(schema.string()), + labels: schema.nullable(schema.arrayOf(schema.string())), + // TODO: modify later to string[] - need for support Case schema + comments: schema.nullable(schema.arrayOf(CommentSchema)), + ...EntityInformation, +}); + +export const ExecutorSubActionGetIncidentParamsSchema = schema.object({ + externalId: schema.string(), +}); + +// Reserved for future implementation +export const ExecutorSubActionHandshakeParamsSchema = schema.object({}); +export const ExecutorSubActionGetCapabilitiesParamsSchema = schema.object({}); +export const ExecutorSubActionGetIssueTypesParamsSchema = schema.object({}); +export const ExecutorSubActionGetFieldsByIssueTypeParamsSchema = schema.object({ + id: schema.string(), +}); + +export const ExecutorParamsSchema = schema.oneOf([ + schema.object({ + subAction: schema.literal('getIncident'), + subActionParams: ExecutorSubActionGetIncidentParamsSchema, + }), + schema.object({ + subAction: schema.literal('handshake'), + subActionParams: ExecutorSubActionHandshakeParamsSchema, + }), + schema.object({ + subAction: schema.literal('pushToService'), + subActionParams: ExecutorSubActionPushParamsSchema, + }), + schema.object({ + subAction: schema.literal('issueTypes'), + subActionParams: ExecutorSubActionGetIssueTypesParamsSchema, + }), + schema.object({ + subAction: schema.literal('fieldsByIssueType'), + subActionParams: ExecutorSubActionGetFieldsByIssueTypeParamsSchema, + }), +]); diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts index 547595b4c183f..2439c507c3328 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts @@ -8,11 +8,15 @@ import axios from 'axios'; import { createExternalService } from './service'; import * as utils from '../lib/axios_utils'; -import { ExternalService } from '../case/types'; +import { ExternalService } from './types'; import { Logger } from '../../../../../../src/core/server'; import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; const logger = loggingSystemMock.create().get() as jest.Mocked; +interface ResponseError extends Error { + response?: { data: { errors: Record } }; +} + jest.mock('axios'); jest.mock('../lib/axios_utils', () => { const originalUtils = jest.requireActual('../lib/axios_utils'); @@ -25,6 +29,72 @@ jest.mock('../lib/axios_utils', () => { axios.create = jest.fn(() => axios); const requestMock = utils.request as jest.Mock; +const issueTypesResponse = { + data: { + projects: [ + { + issuetypes: [ + { + id: '10006', + name: 'Task', + }, + { + id: '10007', + name: 'Bug', + }, + ], + }, + ], + }, +}; + +const fieldsResponse = { + data: { + projects: [ + { + issuetypes: [ + { + id: '10006', + name: 'Task', + fields: { + summary: { fieldId: 'summary' }, + priority: { + fieldId: 'priority', + allowedValues: [ + { + name: 'Highest', + id: '1', + }, + { + name: 'High', + id: '2', + }, + { + name: 'Medium', + id: '3', + }, + { + name: 'Low', + id: '4', + }, + { + name: 'Lowest', + id: '5', + }, + ], + defaultValue: { + name: 'Medium', + id: '3', + }, + }, + }, + }, + ], + }, + ], + }, +}; + describe('Jira service', () => { let service: ExternalService; @@ -116,19 +186,24 @@ describe('Jira service', () => { test('it should throw an error', async () => { requestMock.mockImplementation(() => { - throw new Error('An error has occurred'); + const error: ResponseError = new Error('An error has occurred'); + error.response = { data: { errors: { summary: 'Required field' } } }; + throw error; }); expect(service.getIncident('1')).rejects.toThrow( - 'Unable to get incident with id 1. Error: An error has occurred' + '[Action][Jira]: Unable to get incident with id 1. Error: An error has occurred Reason: Required field' ); }); }); describe('createIncident', () => { test('it creates the incident correctly', async () => { - // The response from Jira when creating an issue contains only the key and the id. - // The service makes two calls when creating an issue. One to create and one to get - // the created incident with all the necessary fields. + /* The response from Jira when creating an issue contains only the key and the id. + The function makes the following calls when creating an issue: + 1. Get issueTypes to set a default ONLY when incident.issueType is missing + 2. Create the issue. + 3. Get the created issue with all the necessary fields. + */ requestMock.mockImplementationOnce(() => ({ data: { id: '1', key: 'CK-1', fields: { summary: 'title', description: 'description' } }, })); @@ -138,7 +213,13 @@ describe('Jira service', () => { })); const res = await service.createIncident({ - incident: { summary: 'title', description: 'desc' }, + incident: { + summary: 'title', + description: 'desc', + labels: [], + issueType: '10006', + priority: 'High', + }, }); expect(res).toEqual({ @@ -149,6 +230,68 @@ describe('Jira service', () => { }); }); + test('it creates the incident correctly without issue type', async () => { + /* The response from Jira when creating an issue contains only the key and the id. + The function makes the following calls when creating an issue: + 1. Get issueTypes to set a default ONLY when incident.issueType is missing + 2. Create the issue. + 3. Get the created issue with all the necessary fields. + */ + // getIssueType mocks + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }, + })); + + // getIssueType mocks + requestMock.mockImplementationOnce(() => issueTypesResponse); + + requestMock.mockImplementationOnce(() => ({ + data: { id: '1', key: 'CK-1', fields: { summary: 'title', description: 'description' } }, + })); + + requestMock.mockImplementationOnce(() => ({ + data: { id: '1', key: 'CK-1', fields: { created: '2020-04-27T10:59:46.202Z' } }, + })); + + const res = await service.createIncident({ + incident: { + summary: 'title', + description: 'desc', + labels: [], + priority: 'High', + issueType: null, + }, + }); + + expect(res).toEqual({ + title: 'CK-1', + id: '1', + pushedDate: '2020-04-27T10:59:46.202Z', + url: 'https://siem-kibana.atlassian.net/browse/CK-1', + }); + + expect(requestMock).toHaveBeenCalledWith({ + axios, + url: 'https://siem-kibana.atlassian.net/rest/api/2/issue', + logger, + method: 'post', + data: { + fields: { + summary: 'title', + description: 'desc', + project: { key: 'CK' }, + issuetype: { id: '10006' }, + labels: [], + priority: { name: 'High' }, + }, + }, + }); + }); + test('it should call request with correct arguments', async () => { requestMock.mockImplementation(() => ({ data: { @@ -159,7 +302,13 @@ describe('Jira service', () => { })); await service.createIncident({ - incident: { summary: 'title', description: 'desc' }, + incident: { + summary: 'title', + description: 'desc', + labels: [], + issueType: '10006', + priority: 'High', + }, }); expect(requestMock).toHaveBeenCalledWith({ @@ -172,7 +321,9 @@ describe('Jira service', () => { summary: 'title', description: 'desc', project: { key: 'CK' }, - issuetype: { name: 'Task' }, + issuetype: { id: '10006' }, + labels: [], + priority: { name: 'High' }, }, }, }); @@ -180,14 +331,24 @@ describe('Jira service', () => { test('it should throw an error', async () => { requestMock.mockImplementation(() => { - throw new Error('An error has occurred'); + const error: ResponseError = new Error('An error has occurred'); + error.response = { data: { errors: { summary: 'Required field' } } }; + throw error; }); expect( service.createIncident({ - incident: { summary: 'title', description: 'desc' }, + incident: { + summary: 'title', + description: 'desc', + labels: [], + issueType: '10006', + priority: 'High', + }, }) - ).rejects.toThrow('[Action][Jira]: Unable to create incident. Error: An error has occurred'); + ).rejects.toThrow( + '[Action][Jira]: Unable to create incident. Error: An error has occurred. Reason: Required field' + ); }); }); @@ -203,7 +364,13 @@ describe('Jira service', () => { const res = await service.updateIncident({ incidentId: '1', - incident: { summary: 'title', description: 'desc' }, + incident: { + summary: 'title', + description: 'desc', + labels: [], + issueType: '10006', + priority: 'High', + }, }); expect(res).toEqual({ @@ -225,7 +392,13 @@ describe('Jira service', () => { await service.updateIncident({ incidentId: '1', - incident: { summary: 'title', description: 'desc' }, + incident: { + summary: 'title', + description: 'desc', + labels: [], + issueType: '10006', + priority: 'High', + }, }); expect(requestMock).toHaveBeenCalledWith({ @@ -233,22 +406,39 @@ describe('Jira service', () => { logger, method: 'put', url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/1', - data: { fields: { summary: 'title', description: 'desc' } }, + data: { + fields: { + summary: 'title', + description: 'desc', + labels: [], + priority: { name: 'High' }, + issuetype: { id: '10006' }, + project: { key: 'CK' }, + }, + }, }); }); test('it should throw an error', async () => { requestMock.mockImplementation(() => { - throw new Error('An error has occurred'); + const error: ResponseError = new Error('An error has occurred'); + error.response = { data: { errors: { summary: 'Required field' } } }; + throw error; }); expect( service.updateIncident({ incidentId: '1', - incident: { summary: 'title', description: 'desc' }, + incident: { + summary: 'title', + description: 'desc', + labels: [], + issueType: '10006', + priority: 'High', + }, }) ).rejects.toThrow( - '[Action][Jira]: Unable to update incident with id 1. Error: An error has occurred' + '[Action][Jira]: Unable to update incident with id 1. Error: An error has occurred. Reason: Required field' ); }); }); @@ -265,8 +455,14 @@ describe('Jira service', () => { const res = await service.createComment({ incidentId: '1', - comment: { comment: 'comment', commentId: 'comment-1' }, - field: 'comments', + comment: { + comment: 'comment', + commentId: 'comment-1', + createdBy: null, + createdAt: null, + updatedAt: null, + updatedBy: null, + }, }); expect(res).toEqual({ @@ -287,8 +483,14 @@ describe('Jira service', () => { await service.createComment({ incidentId: '1', - comment: { comment: 'comment', commentId: 'comment-1' }, - field: 'my_field', + comment: { + comment: 'comment', + commentId: 'comment-1', + createdBy: null, + createdAt: null, + updatedAt: null, + updatedBy: null, + }, }); expect(requestMock).toHaveBeenCalledWith({ @@ -302,18 +504,416 @@ describe('Jira service', () => { test('it should throw an error', async () => { requestMock.mockImplementation(() => { - throw new Error('An error has occurred'); + const error: ResponseError = new Error('An error has occurred'); + error.response = { data: { errors: { summary: 'Required field' } } }; + throw error; }); expect( service.createComment({ incidentId: '1', - comment: { comment: 'comment', commentId: 'comment-1' }, - field: 'comments', + comment: { + comment: 'comment', + commentId: 'comment-1', + createdBy: null, + createdAt: null, + updatedAt: null, + updatedBy: null, + }, }) ).rejects.toThrow( - '[Action][Jira]: Unable to create comment at incident with id 1. Error: An error has occurred' + '[Action][Jira]: Unable to create comment at incident with id 1. Error: An error has occurred. Reason: Required field' + ); + }); + }); + + describe('getCapabilities', () => { + test('it should return the capabilities', async () => { + requestMock.mockImplementation(() => ({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }, + })); + const res = await service.getCapabilities(); + expect(res).toEqual({ + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }); + }); + + test('it should call request with correct arguments', async () => { + requestMock.mockImplementation(() => ({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }, + })); + + await service.getCapabilities(); + + expect(requestMock).toHaveBeenCalledWith({ + axios, + logger, + method: 'get', + url: 'https://siem-kibana.atlassian.net/rest/capabilities', + }); + }); + + test('it should throw an error', async () => { + requestMock.mockImplementation(() => { + const error: ResponseError = new Error('An error has occurred'); + error.response = { data: { errors: { capabilities: 'Could not get capabilities' } } }; + throw error; + }); + + expect(service.getCapabilities()).rejects.toThrow( + '[Action][Jira]: Unable to get capabilities. Error: An error has occurred. Reason: Could not get capabilities' ); }); }); + + describe('getIssueTypes', () => { + describe('Old API', () => { + test('it should return the issue types', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }, + })); + + requestMock.mockImplementationOnce(() => issueTypesResponse); + + const res = await service.getIssueTypes(); + + expect(res).toEqual([ + { + id: '10006', + name: 'Task', + }, + { + id: '10007', + name: 'Bug', + }, + ]); + }); + + test('it should call request with correct arguments', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }, + })); + + requestMock.mockImplementationOnce(() => issueTypesResponse); + + await service.getIssueTypes(); + + expect(requestMock).toHaveBeenLastCalledWith({ + axios, + logger, + method: 'get', + url: + 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta?projectKeys=CK&expand=projects.issuetypes.fields', + }); + }); + + test('it should throw an error', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }, + })); + + requestMock.mockImplementation(() => { + const error: ResponseError = new Error('An error has occurred'); + error.response = { data: { errors: { issuetypes: 'Could not get issue types' } } }; + throw error; + }); + + expect(service.getIssueTypes()).rejects.toThrow( + '[Action][Jira]: Unable to get issue types. Error: An error has occurred. Reason: Could not get issue types' + ); + }); + }); + describe('New API', () => { + test('it should return the issue types', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + 'list-project-issuetypes': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }, + }, + })); + + requestMock.mockImplementationOnce(() => ({ + data: { + values: issueTypesResponse.data.projects[0].issuetypes, + }, + })); + + const res = await service.getIssueTypes(); + + expect(res).toEqual([ + { + id: '10006', + name: 'Task', + }, + { + id: '10007', + name: 'Bug', + }, + ]); + }); + + test('it should call request with correct arguments', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + 'list-project-issuetypes': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }, + }, + })); + + requestMock.mockImplementationOnce(() => ({ + data: { + values: issueTypesResponse.data.projects[0].issuetypes, + }, + })); + + await service.getIssueTypes(); + + expect(requestMock).toHaveBeenLastCalledWith({ + axios, + logger, + method: 'get', + url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta/CK/issuetypes', + }); + }); + + test('it should throw an error', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + 'list-project-issuetypes': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }, + }, + })); + + requestMock.mockImplementation(() => { + const error: ResponseError = new Error('An error has occurred'); + error.response = { data: { errors: { issuetypes: 'Could not get issue types' } } }; + throw error; + }); + + expect(service.getIssueTypes()).rejects.toThrow( + '[Action][Jira]: Unable to get issue types. Error: An error has occurred. Reason: Could not get issue types' + ); + }); + }); + }); + + describe('getFieldsByIssueType', () => { + describe('Old API', () => { + test('it should return the fields', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }, + })); + + requestMock.mockImplementationOnce(() => fieldsResponse); + + const res = await service.getFieldsByIssueType('10006'); + + expect(res).toEqual({ + priority: { + allowedValues: [ + { id: '1', name: 'Highest' }, + { id: '2', name: 'High' }, + { id: '3', name: 'Medium' }, + { id: '4', name: 'Low' }, + { id: '5', name: 'Lowest' }, + ], + defaultValue: { id: '3', name: 'Medium' }, + }, + summary: { allowedValues: [], defaultValue: {} }, + }); + }); + + test('it should call request with correct arguments', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }, + })); + + requestMock.mockImplementationOnce(() => fieldsResponse); + + await service.getFieldsByIssueType('10006'); + + expect(requestMock).toHaveBeenLastCalledWith({ + axios, + logger, + method: 'get', + url: + 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta?projectKeys=CK&issuetypeIds=10006&expand=projects.issuetypes.fields', + }); + }); + + test('it should throw an error', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }, + })); + + requestMock.mockImplementation(() => { + const error: ResponseError = new Error('An error has occurred'); + error.response = { data: { errors: { fields: 'Could not get fields' } } }; + throw error; + }); + + expect(service.getFieldsByIssueType('10006')).rejects.toThrow( + '[Action][Jira]: Unable to get fields. Error: An error has occurred. Reason: Could not get fields' + ); + }); + }); + + describe('New API', () => { + test('it should return the fields', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + 'list-project-issuetypes': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }, + }, + })); + + requestMock.mockImplementationOnce(() => ({ + data: { + values: [ + { fieldId: 'summary' }, + { + fieldId: 'priority', + allowedValues: [ + { + name: 'Medium', + id: '3', + }, + ], + defaultValue: { + name: 'Medium', + id: '3', + }, + }, + ], + }, + })); + + const res = await service.getFieldsByIssueType('10006'); + + expect(res).toEqual({ + priority: { + allowedValues: [{ id: '3', name: 'Medium' }], + defaultValue: { id: '3', name: 'Medium' }, + }, + summary: { allowedValues: [], defaultValue: {} }, + }); + }); + + test('it should call request with correct arguments', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + 'list-project-issuetypes': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }, + }, + })); + + requestMock.mockImplementationOnce(() => ({ + data: { + values: [ + { fieldId: 'summary' }, + { + fieldId: 'priority', + allowedValues: [ + { + name: 'Medium', + id: '3', + }, + ], + defaultValue: { + name: 'Medium', + id: '3', + }, + }, + ], + }, + })); + + await service.getFieldsByIssueType('10006'); + + expect(requestMock).toHaveBeenLastCalledWith({ + axios, + logger, + method: 'get', + url: 'https://siem-kibana.atlassian.net/rest/api/2/issue/createmeta/CK/issuetypes/10006', + }); + }); + + test('it should throw an error', async () => { + requestMock.mockImplementationOnce(() => ({ + data: { + capabilities: { + 'list-project-issuetypes': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }, + }, + })); + + requestMock.mockImplementation(() => { + const error: ResponseError = new Error('An error has occurred'); + error.response = { data: { errors: { issuetypes: 'Could not get issue types' } } }; + throw error; + }); + + expect(service.getFieldsByIssueType('10006')).rejects.toThrow( + '[Action][Jira]: Unable to get fields. Error: An error has occurred. Reason: Could not get issue types' + ); + }); + }); + }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts index aec73cfb375ed..84b6e70d2a100 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts @@ -6,14 +6,20 @@ import axios from 'axios'; -import { ExternalServiceCredentials, ExternalService, ExternalServiceParams } from '../case/types'; import { Logger } from '../../../../../../src/core/server'; import { + ExternalServiceCredentials, + ExternalService, + CreateIncidentParams, + UpdateIncidentParams, JiraPublicConfigurationType, JiraSecretConfigurationType, - CreateIncidentRequest, - UpdateIncidentRequest, - CreateCommentRequest, + Fields, + CreateCommentParams, + Incident, + ResponseError, + ExternalServiceCommentResponse, + ExternalServiceIncidentResponse, } from './types'; import * as i18n from './translations'; @@ -22,11 +28,12 @@ import { ProxySettings } from '../../types'; const VERSION = '2'; const BASE_URL = `rest/api/${VERSION}`; -const INCIDENT_URL = `issue`; -const COMMENT_URL = `comment`; +const CAPABILITIES_URL = `rest/capabilities`; const VIEW_INCIDENT_URL = `browse`; +const createMetaCapabilities = ['list-project-issuetypes', 'list-issuetype-fields']; + export const createExternalService = ( { config, secrets }: ExternalServiceCredentials, logger: Logger, @@ -39,8 +46,13 @@ export const createExternalService = ( throw Error(`[Action]${i18n.NAME}: Wrong configuration.`); } - const incidentUrl = `${url}/${BASE_URL}/${INCIDENT_URL}`; - const commentUrl = `${incidentUrl}/{issueId}/${COMMENT_URL}`; + const incidentUrl = `${url}/${BASE_URL}/issue`; + const capabilitiesUrl = `${url}/${CAPABILITIES_URL}`; + const commentUrl = `${incidentUrl}/{issueId}/comment`; + const getIssueTypesOldAPIURL = `${url}/${BASE_URL}/issue/createmeta?projectKeys=${projectKey}&expand=projects.issuetypes.fields`; + const getIssueTypeFieldsOldAPIURL = `${url}/${BASE_URL}/issue/createmeta?projectKeys=${projectKey}&issuetypeIds={issueTypeId}&expand=projects.issuetypes.fields`; + const getIssueTypesUrl = `${url}/${BASE_URL}/issue/createmeta/${projectKey}/issuetypes`; + const getIssueTypeFieldsUrl = `${url}/${BASE_URL}/issue/createmeta/${projectKey}/issuetypes/{issueTypeId}`; const axiosInstance = axios.create({ auth: { username: email, password: apiToken }, }); @@ -52,6 +64,60 @@ export const createExternalService = ( const getCommentsURL = (issueId: string) => { return commentUrl.replace('{issueId}', issueId); }; + const createGetIssueTypeFieldsUrl = (uri: string, issueTypeId: string) => { + return uri.replace('{issueTypeId}', issueTypeId); + }; + + const createFields = (key: string, incident: Incident): Fields => { + let fields: Fields = { + summary: incident.summary, + project: { key }, + }; + + if (incident.issueType) { + fields = { ...fields, issuetype: { id: incident.issueType } }; + } + + if (incident.description) { + fields = { ...fields, description: incident.description }; + } + + if (incident.labels) { + fields = { ...fields, labels: incident.labels }; + } + + if (incident.priority) { + fields = { ...fields, priority: { name: incident.priority } }; + } + + return fields; + }; + + const createErrorMessage = (errors: ResponseError) => { + return Object.entries(errors).reduce((errorMessage, [, value]) => { + const msg = errorMessage.length > 0 ? `${errorMessage} ${value}` : value; + return msg; + }, ''); + }; + + const hasSupportForNewAPI = (capabilities: { capabilities?: {} }) => + createMetaCapabilities.every((c) => Object.keys(capabilities?.capabilities ?? {}).includes(c)); + + const normalizeIssueTypes = (issueTypes: Array<{ id: string; name: string }>) => + issueTypes.map((type) => ({ id: type.id, name: type.name })); + + const normalizeFields = (fields: { + [key: string]: { allowedValues?: Array<{}>; defaultValue?: {} }; + }) => + Object.keys(fields ?? {}).reduce((fieldsAcc, fieldKey) => { + return { + ...fieldsAcc, + [fieldKey]: { + allowedValues: fields[fieldKey]?.allowedValues ?? [], + defaultValue: fields[fieldKey]?.defaultValue ?? {}, + }, + }; + }, {}); const getIncident = async (id: string) => { try { @@ -67,23 +133,46 @@ export const createExternalService = ( return { ...rest, ...fields }; } catch (error) { throw new Error( - getErrorMessage(i18n.NAME, `Unable to get incident with id ${id}. Error: ${error.message}`) + getErrorMessage( + i18n.NAME, + `Unable to get incident with id ${id}. Error: ${ + error.message + } Reason: ${createErrorMessage(error.response?.data?.errors ?? {})}` + ) ); } }; - const createIncident = async ({ incident }: ExternalServiceParams) => { - // The response from Jira when creating an issue contains only the key and the id. - // The function makes two calls when creating an issue. One to create the issue and one to get - // the created issue with all the necessary fields. + const createIncident = async ({ + incident, + }: CreateIncidentParams): Promise => { + /* The response from Jira when creating an issue contains only the key and the id. + The function makes the following calls when creating an issue: + 1. Get issueTypes to set a default ONLY when incident.issueType is missing + 2. Create the issue. + 3. Get the created issue with all the necessary fields. + */ + + let issueType = incident.issueType; + + if (!incident.issueType) { + const issueTypes = await getIssueTypes(); + issueType = issueTypes[0]?.id ?? ''; + } + + const fields = createFields(projectKey, { + ...incident, + issueType, + }); + try { - const res = await request({ + const res = await request({ axios: axiosInstance, url: `${incidentUrl}`, logger, method: 'post', data: { - fields: { ...incident, project: { key: projectKey }, issuetype: { name: 'Task' } }, + fields, }, proxySettings, }); @@ -98,23 +187,38 @@ export const createExternalService = ( }; } catch (error) { throw new Error( - getErrorMessage(i18n.NAME, `Unable to create incident. Error: ${error.message}`) + getErrorMessage( + i18n.NAME, + `Unable to create incident. Error: ${error.message}. Reason: ${createErrorMessage( + error.response?.data?.errors ?? {} + )}` + ) ); } }; - const updateIncident = async ({ incidentId, incident }: ExternalServiceParams) => { + const updateIncident = async ({ + incidentId, + incident, + }: UpdateIncidentParams): Promise => { + const incidentWithoutNullValues = Object.entries(incident).reduce( + (obj, [key, value]) => (value != null ? { ...obj, [key]: value } : obj), + {} as Incident + ); + + const fields = createFields(projectKey, incidentWithoutNullValues); + try { - await request({ + await request({ axios: axiosInstance, method: 'put', url: `${incidentUrl}/${incidentId}`, logger, - data: { fields: { ...incident } }, + data: { fields }, proxySettings, }); - const updatedIncident = await getIncident(incidentId); + const updatedIncident = await getIncident(incidentId as string); return { title: updatedIncident.key, @@ -126,15 +230,20 @@ export const createExternalService = ( throw new Error( getErrorMessage( i18n.NAME, - `Unable to update incident with id ${incidentId}. Error: ${error.message}` + `Unable to update incident with id ${incidentId}. Error: ${ + error.message + }. Reason: ${createErrorMessage(error.response?.data?.errors ?? {})}` ) ); } }; - const createComment = async ({ incidentId, comment, field }: ExternalServiceParams) => { + const createComment = async ({ + incidentId, + comment, + }: CreateCommentParams): Promise => { try { - const res = await request({ + const res = await request({ axios: axiosInstance, method: 'post', url: getCommentsURL(incidentId), @@ -152,7 +261,118 @@ export const createExternalService = ( throw new Error( getErrorMessage( i18n.NAME, - `Unable to create comment at incident with id ${incidentId}. Error: ${error.message}` + `Unable to create comment at incident with id ${incidentId}. Error: ${ + error.message + }. Reason: ${createErrorMessage(error.response?.data?.errors ?? {})}` + ) + ); + } + }; + + const getCapabilities = async () => { + try { + const res = await request({ + axios: axiosInstance, + method: 'get', + url: capabilitiesUrl, + logger, + proxySettings, + }); + + return { ...res.data }; + } catch (error) { + throw new Error( + getErrorMessage( + i18n.NAME, + `Unable to get capabilities. Error: ${error.message}. Reason: ${createErrorMessage( + error.response?.data?.errors ?? {} + )}` + ) + ); + } + }; + + const getIssueTypes = async () => { + const capabilitiesResponse = await getCapabilities(); + const supportsNewAPI = hasSupportForNewAPI(capabilitiesResponse); + + try { + if (!supportsNewAPI) { + const res = await request({ + axios: axiosInstance, + method: 'get', + url: getIssueTypesOldAPIURL, + logger, + proxySettings, + }); + + const issueTypes = res.data.projects[0]?.issuetypes ?? []; + return normalizeIssueTypes(issueTypes); + } else { + const res = await request({ + axios: axiosInstance, + method: 'get', + url: getIssueTypesUrl, + logger, + proxySettings, + }); + + const issueTypes = res.data.values; + return normalizeIssueTypes(issueTypes); + } + } catch (error) { + throw new Error( + getErrorMessage( + i18n.NAME, + `Unable to get issue types. Error: ${error.message}. Reason: ${createErrorMessage( + error.response?.data?.errors ?? {} + )}` + ) + ); + } + }; + + const getFieldsByIssueType = async (issueTypeId: string) => { + const capabilitiesResponse = await getCapabilities(); + const supportsNewAPI = hasSupportForNewAPI(capabilitiesResponse); + + try { + if (!supportsNewAPI) { + const res = await request({ + axios: axiosInstance, + method: 'get', + url: createGetIssueTypeFieldsUrl(getIssueTypeFieldsOldAPIURL, issueTypeId), + logger, + proxySettings, + }); + + const fields = res.data.projects[0]?.issuetypes[0]?.fields || {}; + return normalizeFields(fields); + } else { + const res = await request({ + axios: axiosInstance, + method: 'get', + url: createGetIssueTypeFieldsUrl(getIssueTypeFieldsUrl, issueTypeId), + logger, + proxySettings, + }); + + const fields = res.data.values.reduce( + (acc: { [x: string]: {} }, value: { fieldId: string }) => ({ + ...acc, + [value.fieldId]: { ...value }, + }), + {} + ); + return normalizeFields(fields); + } + } catch (error) { + throw new Error( + getErrorMessage( + i18n.NAME, + `Unable to get fields. Error: ${error.message}. Reason: ${createErrorMessage( + error.response?.data?.errors ?? {} + )}` ) ); } @@ -163,5 +383,8 @@ export const createExternalService = ( createIncident, updateIncident, createComment, + getCapabilities, + getIssueTypes, + getFieldsByIssueType, }; }; diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/translations.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/translations.ts index dae0d75952e11..0e71de813eb5d 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/translations.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/translations.ts @@ -9,3 +9,19 @@ import { i18n } from '@kbn/i18n'; export const NAME = i18n.translate('xpack.actions.builtin.case.jiraTitle', { defaultMessage: 'Jira', }); + +export const ALLOWED_HOSTS_ERROR = (message: string) => + i18n.translate('xpack.actions.builtin.jira.configuration.apiAllowedHostsError', { + defaultMessage: 'error configuring connector action: {message}', + values: { + message, + }, + }); + +// TODO: remove when Case mappings will be removed +export const MAPPING_EMPTY = i18n.translate( + 'xpack.actions.builtin.jira.configuration.emptyMapping', + { + defaultMessage: '[incidentConfiguration.mapping]: expected non-empty but got empty', + } +); diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/types.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/types.ts index 8d9c6b92abb3b..5e97f5309f8ee 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/types.ts @@ -4,29 +4,169 @@ * you may not use this file except in compliance with the Elastic License. */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import { TypeOf } from '@kbn/config-schema'; -import { JiraPublicConfigurationSchema, JiraSecretConfigurationSchema } from './schema'; +import { + ExternalIncidentServiceConfigurationSchema, + ExternalIncidentServiceSecretConfigurationSchema, + ExecutorParamsSchema, + ExecutorSubActionPushParamsSchema, + ExecutorSubActionGetIncidentParamsSchema, + ExecutorSubActionHandshakeParamsSchema, + ExecutorSubActionGetCapabilitiesParamsSchema, + ExecutorSubActionGetIssueTypesParamsSchema, + ExecutorSubActionGetFieldsByIssueTypeParamsSchema, +} from './schema'; +import { ActionsConfigurationUtilities } from '../../actions_config'; +import { IncidentConfigurationSchema } from '../case/common_schema'; +import { Comment } from '../case/common_types'; +import { Logger } from '../../../../../../src/core/server'; + +export type JiraPublicConfigurationType = TypeOf; +export type JiraSecretConfigurationType = TypeOf< + typeof ExternalIncidentServiceSecretConfigurationSchema +>; + +export type ExecutorParams = TypeOf; +export type ExecutorSubActionPushParams = TypeOf; + +export type IncidentConfiguration = TypeOf; + +export interface ExternalServiceCredentials { + config: Record; + secrets: Record; +} + +export interface ExternalServiceValidation { + config: (configurationUtilities: ActionsConfigurationUtilities, configObject: any) => void; + secrets: (configurationUtilities: ActionsConfigurationUtilities, secrets: any) => void; +} + +export interface ExternalServiceIncidentResponse { + id: string; + title: string; + url: string; + pushedDate: string; +} + +export interface ExternalServiceCommentResponse { + commentId: string; + pushedDate: string; + externalCommentId?: string; +} + +export type ExternalServiceParams = Record; + +export type Incident = Pick< + ExecutorSubActionPushParams, + 'description' | 'priority' | 'labels' | 'issueType' +> & { summary: string }; + +export interface CreateIncidentParams { + incident: Incident; +} + +export interface UpdateIncidentParams { + incidentId: string; + incident: Incident; +} + +export interface CreateCommentParams { + incidentId: string; + comment: Comment; +} -export type JiraPublicConfigurationType = TypeOf; -export type JiraSecretConfigurationType = TypeOf; +export type GetIssueTypesResponse = Array<{ id: string; name: string }>; +export type GetFieldsByIssueTypeResponse = Record< + string, + { allowedValues: Array<{}>; defaultValue: {} } +>; -interface CreateIncidentBasicRequestArgs { - summary: string; - description: string; +export interface ExternalService { + getIncident: (id: string) => Promise; + createIncident: (params: CreateIncidentParams) => Promise; + updateIncident: (params: UpdateIncidentParams) => Promise; + createComment: (params: CreateCommentParams) => Promise; + getCapabilities: () => Promise; + getIssueTypes: () => Promise; + getFieldsByIssueType: (issueTypeId: string) => Promise; } -interface CreateIncidentRequestArgs extends CreateIncidentBasicRequestArgs { - project: { key: string }; - issuetype: { name: string }; + +export interface PushToServiceApiParams extends ExecutorSubActionPushParams { + externalObject: Record; +} + +export type ExecutorSubActionGetIncidentParams = TypeOf< + typeof ExecutorSubActionGetIncidentParamsSchema +>; + +export type ExecutorSubActionHandshakeParams = TypeOf< + typeof ExecutorSubActionHandshakeParamsSchema +>; + +export type ExecutorSubActionGetCapabilitiesParams = TypeOf< + typeof ExecutorSubActionGetCapabilitiesParamsSchema +>; + +export type ExecutorSubActionGetIssueTypesParams = TypeOf< + typeof ExecutorSubActionGetIssueTypesParamsSchema +>; + +export type ExecutorSubActionGetFieldsByIssueTypeParams = TypeOf< + typeof ExecutorSubActionGetFieldsByIssueTypeParamsSchema +>; + +export interface ExternalServiceApiHandlerArgs { + externalService: ExternalService; + mapping: Map | null; +} + +export interface PushToServiceApiHandlerArgs extends ExternalServiceApiHandlerArgs { + params: PushToServiceApiParams; + logger: Logger; } -export interface CreateIncidentRequest { - fields: CreateIncidentRequestArgs; +export interface GetIncidentApiHandlerArgs extends ExternalServiceApiHandlerArgs { + params: ExecutorSubActionGetIncidentParams; } -export interface UpdateIncidentRequest { - fields: Partial; +export interface HandshakeApiHandlerArgs extends ExternalServiceApiHandlerArgs { + params: ExecutorSubActionHandshakeParams; } -export interface CreateCommentRequest { - body: string; +export interface GetIssueTypesHandlerArgs { + externalService: ExternalService; + params: ExecutorSubActionGetIssueTypesParams; +} + +export interface GetFieldsByIssueTypeHandlerArgs { + externalService: ExternalService; + params: ExecutorSubActionGetFieldsByIssueTypeParams; +} + +export interface PushToServiceResponse extends ExternalServiceIncidentResponse { + comments?: ExternalServiceCommentResponse[]; +} + +export interface ExternalServiceApi { + handshake: (args: HandshakeApiHandlerArgs) => Promise; + pushToService: (args: PushToServiceApiHandlerArgs) => Promise; + getIncident: (args: GetIncidentApiHandlerArgs) => Promise; + issueTypes: (args: GetIssueTypesHandlerArgs) => Promise; + fieldsByIssueType: ( + args: GetFieldsByIssueTypeHandlerArgs + ) => Promise; +} + +export type JiraExecutorResultData = + | PushToServiceResponse + | GetIssueTypesResponse + | GetFieldsByIssueTypeResponse; + +export interface Fields { + [key: string]: string | string[] | { name: string } | { key: string } | { id: string }; +} +export interface ResponseError { + [k: string]: string; } diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/validators.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/validators.ts index 7226071392bc6..58a3e27247fae 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/validators.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/validators.ts @@ -4,8 +4,38 @@ * you may not use this file except in compliance with the Elastic License. */ -import { validateCommonConfig, validateCommonSecrets } from '../case/validators'; -import { ExternalServiceValidation } from '../case/types'; +import { isEmpty } from 'lodash'; +import { ActionsConfigurationUtilities } from '../../actions_config'; +import { + JiraPublicConfigurationType, + JiraSecretConfigurationType, + ExternalServiceValidation, +} from './types'; + +import * as i18n from './translations'; + +export const validateCommonConfig = ( + configurationUtilities: ActionsConfigurationUtilities, + configObject: JiraPublicConfigurationType +) => { + if ( + configObject.incidentConfiguration !== null && + isEmpty(configObject.incidentConfiguration.mapping) + ) { + return i18n.MAPPING_EMPTY; + } + + try { + configurationUtilities.ensureUriAllowed(configObject.apiUrl); + } catch (allowedListError) { + return i18n.ALLOWED_HOSTS_ERROR(allowedListError.message); + } +}; + +export const validateCommonSecrets = ( + configurationUtilities: ActionsConfigurationUtilities, + secrets: JiraSecretConfigurationType +) => {}; export const validate: ExternalServiceValidation = { config: validateCommonConfig, diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts index 0bb096ecd0f62..7a68781bb9a75 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts @@ -91,7 +91,7 @@ describe('api', () => { expect(externalService.updateIncident).not.toHaveBeenCalled(); }); - test('it calls updateIncident correctly', async () => { + test('it calls updateIncident correctly when creating an incident and having comments', async () => { const params = { ...apiParams, externalId: null }; await api.pushToService({ externalService, @@ -103,7 +103,7 @@ describe('api', () => { expect(externalService.updateIncident).toHaveBeenCalledTimes(2); expect(externalService.updateIncident).toHaveBeenNthCalledWith(1, { incident: { - comments: 'A comment', + comments: 'A comment (added at 2020-03-13T08:34:53.450Z by Elastic User)', description: 'Incident description (created at 2020-03-13T08:34:53.450Z by Elastic User)', short_description: @@ -114,7 +114,7 @@ describe('api', () => { expect(externalService.updateIncident).toHaveBeenNthCalledWith(2, { incident: { - comments: 'Another comment', + comments: 'Another comment (added at 2020-03-13T08:34:53.450Z by Elastic User)', description: 'Incident description (created at 2020-03-13T08:34:53.450Z by Elastic User)', short_description: @@ -215,7 +215,7 @@ describe('api', () => { expect(externalService.updateIncident).toHaveBeenNthCalledWith(2, { incident: { - comments: 'A comment', + comments: 'A comment (added at 2020-03-13T08:34:53.450Z by Elastic User)', description: 'Incident description (updated at 2020-03-13T08:34:53.450Z by Elastic User)', short_description: diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index 3281832941558..c8e6147ecef46 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -10,11 +10,13 @@ import { HandshakeApiHandlerArgs, GetIncidentApiHandlerArgs, ExternalServiceApi, + PushToServiceApiParams, + PushToServiceResponse, } from './types'; // TODO: to remove, need to support Case import { transformers } from '../case/transformers'; -import { PushToServiceResponse, TransformFieldsArgs } from './case_types'; +import { TransformFieldsArgs, Comment, EntityInformation } from '../case/common_types'; import { prepareFieldsForTransformation } from '../case/utils'; const handshakeHandler = async ({ @@ -92,9 +94,10 @@ const pushToServiceHandler = async ({ mapping.get('comments')?.actionType !== 'nothing' ) { res.comments = []; + const commentsTransformed = transformComments(comments, ['informationAdded']); const fieldsKey = mapping.get('comments')?.target ?? 'comments'; - for (const currentComment of comments) { + for (const currentComment of commentsTransformed) { await externalService.updateIncident({ incidentId: res.id, incident: { @@ -118,7 +121,7 @@ export const transformFields = ({ params, fields, currentIncident, -}: TransformFieldsArgs): Record => { +}: TransformFieldsArgs): Record => { return fields.reduce((prev, cur) => { const transform = flow(...cur.pipes.map((p) => transformers[p])); return { @@ -126,20 +129,35 @@ export const transformFields = ({ [cur.key]: transform({ value: cur.value, date: params.updatedAt ?? params.createdAt, - user: - (params.updatedBy != null - ? params.updatedBy.fullName - ? params.updatedBy.fullName - : params.updatedBy.username - : params.createdBy.fullName - ? params.createdBy.fullName - : params.createdBy.username) ?? '', + user: getEntity(params), previousValue: currentIncident ? currentIncident[cur.key] : '', }).value, }; }, {}); }; +export const transformComments = (comments: Comment[], pipes: string[]): Comment[] => { + return comments.map((c) => ({ + ...c, + comment: flow(...pipes.map((p) => transformers[p]))({ + value: c.comment, + date: c.updatedAt ?? c.createdAt, + user: getEntity(c), + }).value, + })); +}; + +export const getEntity = (entity: EntityInformation): string => + (entity.updatedBy != null + ? entity.updatedBy.fullName + ? entity.updatedBy.fullName + : entity.updatedBy.username + : entity.createdBy != null + ? entity.createdBy.fullName + ? entity.createdBy.fullName + : entity.createdBy.username + : '') ?? ''; + export const api: ExternalServiceApi = { handshake: handshakeHandler, pushToService: pushToServiceHandler, diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index 3addbe7c54dac..41a577918b18e 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -24,11 +24,11 @@ import { ExecutorSubActionPushParams, ServiceNowPublicConfigurationType, ServiceNowSecretConfigurationType, + PushToServiceResponse, } from './types'; // TODO: to remove, need to support Case import { buildMap, mapParams } from '../case/utils'; -import { PushToServiceResponse } from './case_types'; interface GetActionTypeParams { logger: Logger; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts index 5f22fcd4fdc85..55a14e4528acf 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts @@ -5,7 +5,7 @@ */ import { ExternalService, PushToServiceApiParams, ExecutorSubActionPushParams } from './types'; -import { MapRecord } from './case_types'; +import { MapRecord } from '../case/common_types'; const createMock = (): jest.Mocked => { const service = { diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts index 82afebaaee445..921de42adfcaf 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts @@ -5,7 +5,11 @@ */ import { schema } from '@kbn/config-schema'; -import { CommentSchema, EntityInformation, IncidentConfigurationSchema } from './case_shema'; +import { + CommentSchema, + EntityInformation, + IncidentConfigurationSchema, +} from '../case/common_schema'; export const ExternalIncidentServiceConfiguration = { apiUrl: schema.string(), diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts index 05c7d805a1852..7cc97a241c4bc 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts @@ -10,8 +10,8 @@ export const NAME = i18n.translate('xpack.actions.builtin.servicenowTitle', { defaultMessage: 'ServiceNow', }); -export const WHITE_LISTED_ERROR = (message: string) => - i18n.translate('xpack.actions.builtin.configuration.apiWhitelistError', { +export const ALLOWED_HOSTS_ERROR = (message: string) => + i18n.translate('xpack.actions.builtin.configuration.apiAllowedHostsError', { defaultMessage: 'error configuring connector action: {message}', values: { message, diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts index 0db9b6642ea5c..e8fcfac45d789 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts @@ -16,8 +16,8 @@ import { ExecutorSubActionHandshakeParamsSchema, } from './schema'; import { ActionsConfigurationUtilities } from '../../actions_config'; -import { IncidentConfigurationSchema } from './case_shema'; -import { PushToServiceResponse } from './case_types'; +import { ExternalServiceCommentResponse } from '../case/common_types'; +import { IncidentConfigurationSchema } from '../case/common_schema'; import { Logger } from '../../../../../../src/core/server'; export type ServiceNowPublicConfigurationType = TypeOf< @@ -52,6 +52,9 @@ export interface ExternalServiceIncidentResponse { url: string; pushedDate: string; } +export interface PushToServiceResponse extends ExternalServiceIncidentResponse { + comments?: ExternalServiceCommentResponse[]; +} export type ExternalServiceParams = Record; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts index 6eec3b8d63b86..87bbfd9c7ea95 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts @@ -27,8 +27,8 @@ export const validateCommonConfig = ( try { configurationUtilities.ensureUriAllowed(configObject.apiUrl); - } catch (allowListError) { - return i18n.WHITE_LISTED_ERROR(allowListError.message); + } catch (allowedListError) { + return i18n.ALLOWED_HOSTS_ERROR(allowedListError.message); } }; diff --git a/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap b/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap index f93df9a01dea2..8218eefe738f0 100644 --- a/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap +++ b/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap @@ -478,7 +478,7 @@ exports[`Transaction TRANSACTION_TIME_TO_FIRST_BYTE 1`] = `undefined`; exports[`Transaction TRANSACTION_TYPE 1`] = `"transaction type"`; -exports[`Transaction TRANSACTION_URL 1`] = `undefined`; +exports[`Transaction TRANSACTION_URL 1`] = `"http://www.elastic.co"`; exports[`Transaction URL_FULL 1`] = `"http://www.elastic.co"`; diff --git a/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts b/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts index b322abeb3d597..e1a279714d308 100644 --- a/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts +++ b/x-pack/plugins/apm/common/elasticsearch_fieldnames.ts @@ -97,7 +97,7 @@ export const POD_NAME = 'kubernetes.pod.name'; export const CLIENT_GEO_COUNTRY_ISO_CODE = 'client.geo.country_iso_code'; // RUM Labels -export const TRANSACTION_URL = 'transaction.page.url'; +export const TRANSACTION_URL = 'url.full'; export const CLIENT_GEO = 'client.geo'; export const USER_AGENT_DEVICE = 'user_agent.device.name'; export const USER_AGENT_OS = 'user_agent.os.name'; diff --git a/x-pack/plugins/apm/dev_docs/updating_functional_tests_archives.md b/x-pack/plugins/apm/dev_docs/updating_functional_tests_archives.md new file mode 100644 index 0000000000000..467090fb3c91b --- /dev/null +++ b/x-pack/plugins/apm/dev_docs/updating_functional_tests_archives.md @@ -0,0 +1,8 @@ +### Updating functional tests archives + +Some of our API tests use an archive generated by the [`esarchiver`](https://www.elastic.co/guide/en/kibana/current/development-functional-tests.html) script. Updating the main archive (`apm_8.0.0`) is a scripted process, where a 30m snapshot is downloaded from a cluster running the [APM Integration Testing server](https://github.com/elastic/apm-integration-testing). The script will copy the generated archives into the `fixtures/es_archiver` folders of our test suites (currently `basic` and `trial`). It will also generate a file that contains metadata about the archive, that can be imported to get the time range of the snapshot. + +Usage: +`node x-pack/plugins/apm/scripts/create-functional-tests-archive --es-url=https://admin:changeme@localhost:9200 --kibana-url=https://localhost:5601` + + diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ChartWrapper/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/ChartWrapper/index.tsx index 970365779a0a2..f27a3d56aab55 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/ChartWrapper/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/ChartWrapper/index.tsx @@ -26,11 +26,14 @@ interface Props { * aria-label for accessibility */ 'aria-label'?: string; + + maxWidth?: string; } export function ChartWrapper({ loading = false, height = '100%', + maxWidth, children, ...rest }: Props) { @@ -43,6 +46,7 @@ export function ChartWrapper({ height, opacity, transition: 'opacity 0.2s', + ...(maxWidth ? { maxWidth } : {}), }} {...(rest as HTMLAttributes)} > @@ -52,7 +56,12 @@ export function ChartWrapper({ diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/VisitorBreakdownChart.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/VisitorBreakdownChart.tsx index 9f9ffdf7168b8..213126ba4bf81 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/VisitorBreakdownChart.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/VisitorBreakdownChart.tsx @@ -14,7 +14,7 @@ import { PartitionLayout, Settings, } from '@elastic/charts'; -import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import styled from 'styled-components'; import { EUI_CHARTS_THEME_DARK, EUI_CHARTS_THEME_LIGHT, @@ -22,6 +22,10 @@ import { import { useUiSetting$ } from '../../../../../../../../src/plugins/kibana_react/public'; import { ChartWrapper } from '../ChartWrapper'; +const StyleChart = styled.div` + height: 100%; +`; + interface Props { options?: Array<{ count: number; @@ -32,65 +36,47 @@ interface Props { export function VisitorBreakdownChart({ options }: Props) { const [darkMode] = useUiSetting$('theme:darkMode'); + const euiChartTheme = darkMode + ? EUI_CHARTS_THEME_DARK + : EUI_CHARTS_THEME_LIGHT; + return ( - - - - d.count as number} - valueGetter="percent" - percentFormatter={(d: number) => - `${Math.round((d + Number.EPSILON) * 100) / 100}%` - } - layers={[ - { - groupByRollup: (d: Datum) => d.name, - nodeLabel: (d: Datum) => d, - // fillLabel: { textInvertible: true }, - shape: { - fillColor: (d) => { - const clrs = [ - euiLightVars.euiColorVis1_behindText, - euiLightVars.euiColorVis0_behindText, - euiLightVars.euiColorVis2_behindText, - euiLightVars.euiColorVis3_behindText, - euiLightVars.euiColorVis4_behindText, - euiLightVars.euiColorVis5_behindText, - euiLightVars.euiColorVis6_behindText, - euiLightVars.euiColorVis7_behindText, - euiLightVars.euiColorVis8_behindText, - euiLightVars.euiColorVis9_behindText, - ]; - return clrs[d.sortIndex]; + + + + + d.count as number} + valueGetter="percent" + percentFormatter={(d: number) => + `${Math.round((d + Number.EPSILON) * 100) / 100}%` + } + layers={[ + { + groupByRollup: (d: Datum) => d.name, + shape: { + fillColor: (d) => + euiChartTheme.theme.colors?.vizColors?.[d.sortIndex]!, }, }, - }, - ]} - config={{ - partitionLayout: PartitionLayout.sunburst, - linkLabel: { - maxCount: 32, - fontSize: 14, - }, - fontFamily: 'Arial', - margin: { top: 0, bottom: 0, left: 0, right: 0 }, - minFontSize: 1, - idealFontSizeJump: 1.1, - outerSizeRatio: 0.9, // - 0.5 * Math.random(), - emptySizeRatio: 0, - circlePadding: 4, - }} - /> - + ]} + config={{ + partitionLayout: PartitionLayout.sunburst, + linkLabel: { maximumSection: Infinity, maxCount: 0 }, + margin: { top: 0, bottom: 0, left: 0, right: 0 }, + outerSizeRatio: 1, // - 0.5 * Math.random(), + circlePadding: 4, + clockwiseSectors: false, + }} + /> + + ); } diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx index b2132c50dc6bc..f54a54211359c 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx @@ -45,7 +45,7 @@ export function ClientMetrics() { <>{numeral(data?.pageViews?.value).format('0 a') ?? '-'} diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx index d23e16b3a5b38..f05c07e8512ac 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx @@ -49,15 +49,18 @@ export function RumDashboard() { - - - + + + - + + + + - - - + + + diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdown/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdown/index.tsx index c19e2cd4a3742..e18875f32ff72 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdown/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdown/index.tsx @@ -5,9 +5,9 @@ */ import React from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiSpacer } from '@elastic/eui'; import { VisitorBreakdownChart } from '../Charts/VisitorBreakdownChart'; -import { VisitorBreakdownLabel } from '../translations'; +import { I18LABELS, VisitorBreakdownLabel } from '../translations'; import { useFetcher } from '../../../../hooks/useFetcher'; import { useUrlParams } from '../../../../hooks/useUrlParams'; @@ -37,27 +37,24 @@ export function VisitorBreakdown() { return ( <> - +

{VisitorBreakdownLabel}

+ - - -

Browser

-
-
- - - -

Operating System

+ +

{I18LABELS.browser}

+ +
- - -

Device

+ +

{I18LABELS.operatingSystem}

+ +
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts b/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts index 042e138793f11..660ed5a92a0e6 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts @@ -55,6 +55,15 @@ export const I18LABELS = { coreWebVitals: i18n.translate('xpack.apm.rum.filterGroup.coreWebVitals', { defaultMessage: 'Core web vitals', }), + browser: i18n.translate('xpack.apm.rum.visitorBreakdown.browser', { + defaultMessage: 'Browser', + }), + operatingSystem: i18n.translate( + 'xpack.apm.rum.visitorBreakdown.operatingSystem', + { + defaultMessage: 'Operating system', + } + ), }; export const VisitorBreakdownLabel = i18n.translate( diff --git a/x-pack/plugins/apm/scripts/aggregate-latency-metrics/index.ts b/x-pack/plugins/apm/scripts/aggregate-latency-metrics/index.ts index c3cf363cbec05..ef85112918712 100644 --- a/x-pack/plugins/apm/scripts/aggregate-latency-metrics/index.ts +++ b/x-pack/plugins/apm/scripts/aggregate-latency-metrics/index.ts @@ -4,15 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Client } from '@elastic/elasticsearch'; import { argv } from 'yargs'; import pLimit from 'p-limit'; import pRetry from 'p-retry'; -import { parse, format } from 'url'; import { set } from '@elastic/safer-lodash-set'; import { uniq, without, merge, flatten } from 'lodash'; import * as histogram from 'hdr-histogram-js'; -import { ESSearchResponse } from '../../typings/elasticsearch'; import { HOST_NAME, SERVICE_NAME, @@ -28,6 +25,8 @@ import { } from '../../common/elasticsearch_fieldnames'; import { stampLogger } from '../shared/stamp-logger'; import { createOrUpdateIndex } from '../shared/create-or-update-index'; +import { parseIndexUrl } from '../shared/parse_index_url'; +import { ESClient, getEsClient } from '../shared/get_es_client'; // This script will try to estimate how many latency metric documents // will be created based on the available transaction documents. @@ -125,41 +124,18 @@ export async function aggregateLatencyMetrics() { const source = String(argv.source ?? ''); const dest = String(argv.dest ?? ''); - function getClientOptionsFromIndexUrl( - url: string - ): { node: string; index: string } { - const parsed = parse(url); - const { pathname, ...rest } = parsed; + const sourceOptions = parseIndexUrl(source); - return { - node: format(rest), - index: pathname!.replace('/', ''), - }; - } - - const sourceOptions = getClientOptionsFromIndexUrl(source); - - const sourceClient = new Client({ - node: sourceOptions.node, - ssl: { - rejectUnauthorized: false, - }, - requestTimeout: 120000, - }); + const sourceClient = getEsClient({ node: sourceOptions.node }); - let destClient: Client | undefined; + let destClient: ESClient | undefined; let destOptions: { node: string; index: string } | undefined; const uploadMetrics = !!dest; if (uploadMetrics) { - destOptions = getClientOptionsFromIndexUrl(dest); - destClient = new Client({ - node: destOptions.node, - ssl: { - rejectUnauthorized: false, - }, - }); + destOptions = parseIndexUrl(dest); + destClient = getEsClient({ node: destOptions.node }); const mappings = ( await sourceClient.indices.getMapping({ @@ -298,10 +274,9 @@ export async function aggregateLatencyMetrics() { }, }; - const response = (await sourceClient.search(params)) - .body as ESSearchResponse; + const response = await sourceClient.search(params); - const { aggregations } = response; + const { aggregations } = response.body; if (!aggregations) { return buckets; @@ -333,10 +308,9 @@ export async function aggregateLatencyMetrics() { }, }; - const response = (await sourceClient.search(params)) - .body as ESSearchResponse; + const response = await sourceClient.search(params); - return response.hits.total.value; + return response.body.hits.total.value; } const [buckets, numberOfTransactionDocuments] = await Promise.all([ diff --git a/x-pack/plugins/apm/scripts/create-functional-tests-archive.js b/x-pack/plugins/apm/scripts/create-functional-tests-archive.js new file mode 100644 index 0000000000000..6b3473dc2ac0a --- /dev/null +++ b/x-pack/plugins/apm/scripts/create-functional-tests-archive.js @@ -0,0 +1,18 @@ +/* + * 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. + */ + +// compile typescript on the fly +// eslint-disable-next-line import/no-extraneous-dependencies +require('@babel/register')({ + extensions: ['.js', '.ts'], + plugins: ['@babel/plugin-proposal-optional-chaining'], + presets: [ + '@babel/typescript', + ['@babel/preset-env', { targets: { node: 'current' } }], + ], +}); + +require('./create-functional-tests-archive/index.ts'); diff --git a/x-pack/plugins/apm/scripts/create-functional-tests-archive/index.ts b/x-pack/plugins/apm/scripts/create-functional-tests-archive/index.ts new file mode 100644 index 0000000000000..723ff03dc4995 --- /dev/null +++ b/x-pack/plugins/apm/scripts/create-functional-tests-archive/index.ts @@ -0,0 +1,143 @@ +/* + * 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 { argv } from 'yargs'; +import { execSync } from 'child_process'; +import moment from 'moment'; +import path from 'path'; +import fs from 'fs'; +import { stampLogger } from '../shared/stamp-logger'; + +async function run() { + stampLogger(); + + const archiveName = 'apm_8.0.0'; + + // include important APM data and ML data + const indices = + 'apm-*-transaction,apm-*-span,apm-*-error,apm-*-metric,.ml-anomalies*,.ml-config'; + + const esUrl = argv['es-url'] as string | undefined; + + if (!esUrl) { + throw new Error('--es-url is not set'); + } + const kibanaUrl = argv['kibana-url'] as string | undefined; + + if (!kibanaUrl) { + throw new Error('--kibana-url is not set'); + } + const gte = moment().subtract(1, 'hour').toISOString(); + const lt = moment(gte).add(30, 'minutes').toISOString(); + + // eslint-disable-next-line no-console + console.log(`Archiving from ${gte} to ${lt}...`); + + // APM data uses '@timestamp' (ECS), ML data uses 'timestamp' + + const rangeQueries = [ + { + range: { + '@timestamp': { + gte, + lt, + }, + }, + }, + { + range: { + timestamp: { + gte, + lt, + }, + }, + }, + ]; + + // some of the data is timeless/content + const query = { + bool: { + should: [ + ...rangeQueries, + { + bool: { + must_not: [ + { + exists: { + field: '@timestamp', + }, + }, + { + exists: { + field: 'timestamp', + }, + }, + ], + }, + }, + ], + minimum_should_match: 1, + }, + }; + + const root = path.join(__dirname, '../../../../..'); + const commonDir = path.join(root, 'x-pack/test/apm_api_integration/common'); + const archivesDir = path.join(commonDir, 'fixtures/es_archiver'); + + // create the archive + + execSync( + `node scripts/es_archiver save ${archiveName} ${indices} --dir=${archivesDir} --kibana-url=${kibanaUrl} --es-url=${esUrl} --query='${JSON.stringify( + query + )}'`, + { + cwd: root, + stdio: 'inherit', + } + ); + + const currentConfig = {}; + + // get the current metadata and extend/override metadata for the new archive + const configFilePath = path.join(commonDir, 'archives_metadata.ts'); + + try { + Object.assign(currentConfig, (await import(configFilePath)).default); + } catch (error) { + // do nothing + } + + const newConfig = { + ...currentConfig, + [archiveName]: { + start: gte, + end: lt, + }, + }; + + fs.writeFileSync( + configFilePath, + `export default ${JSON.stringify(newConfig, null, 2)}`, + { encoding: 'utf-8' } + ); + + // run ESLint on the generated metadata files + + execSync('node scripts/eslint **/*/archives_metadata.ts --fix', { + cwd: root, + stdio: 'inherit', + }); +} + +run() + .then(() => { + process.exit(0); + }) + .catch((err) => { + // eslint-disable-next-line no-console + console.log(err); + process.exit(1); + }); diff --git a/x-pack/plugins/apm/scripts/shared/create-or-update-index.ts b/x-pack/plugins/apm/scripts/shared/create-or-update-index.ts index 6d44e12fb00a2..01fa5b0509bcd 100644 --- a/x-pack/plugins/apm/scripts/shared/create-or-update-index.ts +++ b/x-pack/plugins/apm/scripts/shared/create-or-update-index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Client } from '@elastic/elasticsearch'; +import { ESClient } from './get_es_client'; export async function createOrUpdateIndex({ client, @@ -12,7 +12,7 @@ export async function createOrUpdateIndex({ indexName, template, }: { - client: Client; + client: ESClient; clear: boolean; indexName: string; template: any; diff --git a/x-pack/plugins/apm/scripts/shared/get_es_client.ts b/x-pack/plugins/apm/scripts/shared/get_es_client.ts new file mode 100644 index 0000000000000..86dfd92190fdf --- /dev/null +++ b/x-pack/plugins/apm/scripts/shared/get_es_client.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Client } from '@elastic/elasticsearch'; +import { ApiKeyAuth, BasicAuth } from '@elastic/elasticsearch/lib/pool'; +import { ESSearchResponse, ESSearchRequest } from '../../typings/elasticsearch'; + +export type ESClient = ReturnType; + +export function getEsClient({ + node, + auth, +}: { + node: string; + auth?: BasicAuth | ApiKeyAuth; +}) { + const client = new Client({ + node, + ssl: { + rejectUnauthorized: false, + }, + requestTimeout: 120000, + auth, + }); + + return { + ...client, + async search( + request: TSearchRequest + ) { + const response = await client.search(request as any); + + return { + ...response, + body: response.body as ESSearchResponse, + }; + }, + }; +} diff --git a/x-pack/plugins/apm/scripts/shared/parse_index_url.ts b/x-pack/plugins/apm/scripts/shared/parse_index_url.ts new file mode 100644 index 0000000000000..190f7fda396bd --- /dev/null +++ b/x-pack/plugins/apm/scripts/shared/parse_index_url.ts @@ -0,0 +1,17 @@ +/* + * 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 { parse, format } from 'url'; + +export function parseIndexUrl(url: string): { node: string; index: string } { + const parsed = parse(url); + const { pathname, ...rest } = parsed; + + return { + node: format(rest), + index: pathname!.replace('/', ''), + }; +} diff --git a/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts b/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts index 2f3b2a602048c..926b2025f4253 100644 --- a/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts +++ b/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts @@ -5,7 +5,7 @@ */ import { merge } from 'lodash'; -import { Server } from 'hapi'; + import { SavedObjectsClient } from 'src/core/server'; import { PromiseReturnType } from '../../../../../observability/typings/common'; import { @@ -32,10 +32,6 @@ export interface ApmIndicesConfig { export type ApmIndicesName = keyof ApmIndicesConfig; -export type ScopedSavedObjectsClient = ReturnType< - Server['savedObjects']['getScopedSavedObjectsClient'] ->; - async function getApmIndicesSavedObject( savedObjectsClient: ISavedObjectsClient ) { diff --git a/x-pack/plugins/apm/server/routes/typings.ts b/x-pack/plugins/apm/server/routes/typings.ts index 97013273c9bcf..78c820fbf4ecd 100644 --- a/x-pack/plugins/apm/server/routes/typings.ts +++ b/x-pack/plugins/apm/server/routes/typings.ts @@ -13,7 +13,6 @@ import { } from 'src/core/server'; import { PickByValue, Optional } from 'utility-types'; import { Observable } from 'rxjs'; -import { Server } from 'hapi'; import { ObservabilityPluginSetup } from '../../../observability/server'; import { SecurityPluginSetup } from '../../../security/server'; import { MlPluginSetup } from '../../../ml/server'; @@ -57,12 +56,6 @@ export interface Route< }) => Promise; } -export type APMLegacyServer = Pick & { - plugins: { - elasticsearch: Server['plugins']['elasticsearch']; - }; -}; - export type APMRequestHandlerContext< TDecodedParams extends { [key in keyof Params]: any } = {} > = RequestHandlerContext & { diff --git a/x-pack/plugins/case/common/constants.ts b/x-pack/plugins/case/common/constants.ts index bd12c258a5388..15a318002390f 100644 --- a/x-pack/plugins/case/common/constants.ts +++ b/x-pack/plugins/case/common/constants.ts @@ -28,5 +28,11 @@ export const CASE_USER_ACTIONS_URL = `${CASE_DETAILS_URL}/user_actions`; export const ACTION_URL = '/api/actions'; export const ACTION_TYPES_URL = '/api/actions/list_action_types'; export const SERVICENOW_ACTION_TYPE_ID = '.servicenow'; +export const JIRA_ACTION_TYPE_ID = '.jira'; +export const RESILIENT_ACTION_TYPE_ID = '.resilient'; -export const SUPPORTED_CONNECTORS = ['.servicenow', '.jira', '.resilient']; +export const SUPPORTED_CONNECTORS = [ + SERVICENOW_ACTION_TYPE_ID, + JIRA_ACTION_TYPE_ID, + RESILIENT_ACTION_TYPE_ID, +]; diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts b/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts index 28e75dd2f8c32..a22d7ae5cea21 100644 --- a/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts +++ b/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts @@ -12,6 +12,7 @@ import { CASE_CONFIGURE_CONNECTORS_URL, SUPPORTED_CONNECTORS, SERVICENOW_ACTION_TYPE_ID, + JIRA_ACTION_TYPE_ID, } from '../../../../../common/constants'; /* @@ -36,8 +37,9 @@ export function initCaseConfigureGetActionConnector({ caseService, router }: Rou (action) => SUPPORTED_CONNECTORS.includes(action.actionTypeId) && // Need this filtering temporary to display only Case owned ServiceNow connectors - (action.actionTypeId !== SERVICENOW_ACTION_TYPE_ID || - (action.actionTypeId === SERVICENOW_ACTION_TYPE_ID && action.config!.isCaseOwned)) + (![SERVICENOW_ACTION_TYPE_ID, JIRA_ACTION_TYPE_ID].includes(action.actionTypeId) || + ([SERVICENOW_ACTION_TYPE_ID, JIRA_ACTION_TYPE_ID].includes(action.actionTypeId) && + action.config?.isCaseOwned === true)) ); return response.ok({ body: results }); } catch (error) { diff --git a/x-pack/plugins/data_enhanced/common/index.ts b/x-pack/plugins/data_enhanced/common/index.ts index d6a3c73aaf363..012f1204da46a 100644 --- a/x-pack/plugins/data_enhanced/common/index.ts +++ b/x-pack/plugins/data_enhanced/common/index.ts @@ -5,7 +5,6 @@ */ export { - EnhancedSearchParams, IEnhancedEsSearchRequest, IAsyncSearchRequest, ENHANCED_ES_SEARCH_STRATEGY, diff --git a/x-pack/plugins/data_enhanced/common/search/index.ts b/x-pack/plugins/data_enhanced/common/search/index.ts index 2ae422bd6b7d7..696938a403e89 100644 --- a/x-pack/plugins/data_enhanced/common/search/index.ts +++ b/x-pack/plugins/data_enhanced/common/search/index.ts @@ -5,7 +5,6 @@ */ export { - EnhancedSearchParams, IEnhancedEsSearchRequest, IAsyncSearchRequest, ENHANCED_ES_SEARCH_STRATEGY, diff --git a/x-pack/plugins/data_enhanced/common/search/types.ts b/x-pack/plugins/data_enhanced/common/search/types.ts index 0d3d3a69e1e57..24d459ade4bf9 100644 --- a/x-pack/plugins/data_enhanced/common/search/types.ts +++ b/x-pack/plugins/data_enhanced/common/search/types.ts @@ -4,21 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IEsSearchRequest, ISearchRequestParams } from '../../../../../src/plugins/data/common'; +import { IEsSearchRequest } from '../../../../../src/plugins/data/common'; export const ENHANCED_ES_SEARCH_STRATEGY = 'ese'; -export interface EnhancedSearchParams extends ISearchRequestParams { - ignoreThrottled: boolean; -} - export interface IAsyncSearchRequest extends IEsSearchRequest { /** * The ID received from the response from the initial request */ id?: string; - - params?: EnhancedSearchParams; } export interface IEnhancedEsSearchRequest extends IEsSearchRequest { diff --git a/x-pack/plugins/data_enhanced/public/plugin.ts b/x-pack/plugins/data_enhanced/public/plugin.ts index 7f6e3feac0671..ccc93316482c2 100644 --- a/x-pack/plugins/data_enhanced/public/plugin.ts +++ b/x-pack/plugins/data_enhanced/public/plugin.ts @@ -23,6 +23,8 @@ export type DataEnhancedStart = ReturnType; export class DataEnhancedPlugin implements Plugin { + private enhancedSearchInterceptor!: EnhancedSearchInterceptor; + public setup( core: CoreSetup, { data }: DataEnhancedSetupDependencies @@ -32,20 +34,17 @@ export class DataEnhancedPlugin setupKqlQuerySuggestionProvider(core) ); - const enhancedSearchInterceptor = new EnhancedSearchInterceptor( - { - toasts: core.notifications.toasts, - http: core.http, - uiSettings: core.uiSettings, - startServices: core.getStartServices(), - usageCollector: data.search.usageCollector, - }, - core.injectedMetadata.getInjectedVar('esRequestTimeout') as number - ); + this.enhancedSearchInterceptor = new EnhancedSearchInterceptor({ + toasts: core.notifications.toasts, + http: core.http, + uiSettings: core.uiSettings, + startServices: core.getStartServices(), + usageCollector: data.search.usageCollector, + }); data.__enhance({ search: { - searchInterceptor: enhancedSearchInterceptor, + searchInterceptor: this.enhancedSearchInterceptor, }, }); } @@ -53,4 +52,8 @@ export class DataEnhancedPlugin public start(core: CoreStart, plugins: DataEnhancedStartDependencies) { setAutocompleteService(plugins.data.autocomplete); } + + public stop() { + this.enhancedSearchInterceptor.stop(); + } } diff --git a/x-pack/plugins/data_enhanced/public/search/search_interceptor.test.ts b/x-pack/plugins/data_enhanced/public/search/search_interceptor.test.ts index 1e2c7987b7041..261e03887acdb 100644 --- a/x-pack/plugins/data_enhanced/public/search/search_interceptor.test.ts +++ b/x-pack/plugins/data_enhanced/public/search/search_interceptor.test.ts @@ -7,7 +7,7 @@ import { coreMock } from '../../../../../src/core/public/mocks'; import { EnhancedSearchInterceptor } from './search_interceptor'; import { CoreSetup, CoreStart } from 'kibana/public'; -import { AbortError } from '../../../../../src/plugins/data/common'; +import { AbortError, UI_SETTINGS } from '../../../../../src/plugins/data/common'; const timeTravel = (msToRun = 0) => { jest.advanceTimersByTime(msToRun); @@ -43,6 +43,15 @@ describe('EnhancedSearchInterceptor', () => { mockCoreSetup = coreMock.createSetup(); mockCoreStart = coreMock.createStart(); + mockCoreSetup.uiSettings.get.mockImplementation((name: string) => { + switch (name) { + case UI_SETTINGS.SEARCH_TIMEOUT: + return 1000; + default: + return; + } + }); + next.mockClear(); error.mockClear(); complete.mockClear(); @@ -64,16 +73,13 @@ describe('EnhancedSearchInterceptor', () => { ]); }); - searchInterceptor = new EnhancedSearchInterceptor( - { - toasts: mockCoreSetup.notifications.toasts, - startServices: mockPromise as any, - http: mockCoreSetup.http, - uiSettings: mockCoreSetup.uiSettings, - usageCollector: mockUsageCollector, - }, - 1000 - ); + searchInterceptor = new EnhancedSearchInterceptor({ + toasts: mockCoreSetup.notifications.toasts, + startServices: mockPromise as any, + http: mockCoreSetup.http, + uiSettings: mockCoreSetup.uiSettings, + usageCollector: mockUsageCollector, + }); }); describe('search', () => { diff --git a/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts b/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts index 6f7899d1188b4..61cf579d3136b 100644 --- a/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts +++ b/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { throwError, EMPTY, timer, from } from 'rxjs'; +import { throwError, EMPTY, timer, from, Subscription } from 'rxjs'; import { mergeMap, expand, takeUntil, finalize, tap } from 'rxjs/operators'; import { getLongQueryNotification } from './long_query_notification'; import { @@ -17,14 +17,25 @@ import { IAsyncSearchOptions } from '.'; import { IAsyncSearchRequest, ENHANCED_ES_SEARCH_STRATEGY } from '../../common'; export class EnhancedSearchInterceptor extends SearchInterceptor { + private uiSettingsSub: Subscription; + private searchTimeout: number; + /** - * This class should be instantiated with a `requestTimeout` corresponding with how many ms after - * requests are initiated that they should automatically cancel. - * @param deps `SearchInterceptorDeps` - * @param requestTimeout Usually config value `elasticsearch.requestTimeout` + * @internal */ - constructor(deps: SearchInterceptorDeps, requestTimeout?: number) { - super(deps, requestTimeout); + constructor(deps: SearchInterceptorDeps) { + super(deps); + this.searchTimeout = deps.uiSettings.get(UI_SETTINGS.SEARCH_TIMEOUT); + + this.uiSettingsSub = deps.uiSettings + .get$(UI_SETTINGS.SEARCH_TIMEOUT) + .subscribe((timeout: number) => { + this.searchTimeout = timeout; + }); + } + + public stop() { + this.uiSettingsSub.unsubscribe(); } /** @@ -69,12 +80,10 @@ export class EnhancedSearchInterceptor extends SearchInterceptor { ) { let { id } = request; - request.params = { - ignoreThrottled: !this.deps.uiSettings.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN), - ...request.params, - }; - - const { combinedSignal, cleanup } = this.setupTimers(options); + const { combinedSignal, cleanup } = this.setupAbortSignal({ + abortSignal: options.abortSignal, + timeout: this.searchTimeout, + }); const aborted$ = from(toPromise(combinedSignal)); const strategy = options?.strategy || ENHANCED_ES_SEARCH_STRATEGY; @@ -108,7 +117,7 @@ export class EnhancedSearchInterceptor extends SearchInterceptor { // we don't need to send a follow-up request to delete this search. Otherwise, we // send the follow-up request to delete this search, then throw an abort error. if (id !== undefined) { - this.deps.http.delete(`/internal/search/es/${id}`); + this.deps.http.delete(`/internal/search/${strategy}/${id}`); } }, }), diff --git a/x-pack/plugins/data_enhanced/server/plugin.ts b/x-pack/plugins/data_enhanced/server/plugin.ts index f9b6fd4e9ad64..3b05e83d208b7 100644 --- a/x-pack/plugins/data_enhanced/server/plugin.ts +++ b/x-pack/plugins/data_enhanced/server/plugin.ts @@ -19,6 +19,7 @@ import { import { enhancedEsSearchStrategyProvider } from './search'; import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/server'; import { ENHANCED_ES_SEARCH_STRATEGY } from '../common'; +import { getUiSettings } from './ui_settings'; interface SetupDependencies { data: DataPluginSetup; @@ -35,6 +36,8 @@ export class EnhancedDataServerPlugin implements Plugin, deps: SetupDependencies) { const usage = deps.usageCollection ? usageProvider(core) : undefined; + core.uiSettings.register(getUiSettings()); + deps.data.search.registerSearchStrategy( ENHANCED_ES_SEARCH_STRATEGY, enhancedEsSearchStrategyProvider( diff --git a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts index a287f72ca9161..f4f3d894a4576 100644 --- a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts +++ b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.test.ts @@ -5,8 +5,8 @@ */ import { RequestHandlerContext } from '../../../../../src/core/server'; -import { pluginInitializerContextConfigMock } from '../../../../../src/core/server/mocks'; import { enhancedEsSearchStrategyProvider } from './es_search_strategy'; +import { BehaviorSubject } from 'rxjs'; const mockAsyncResponse = { body: { @@ -42,6 +42,11 @@ describe('ES search strategy', () => { }; const mockContext = { core: { + uiSettings: { + client: { + get: jest.fn(), + }, + }, elasticsearch: { client: { asCurrentUser: { @@ -55,7 +60,15 @@ describe('ES search strategy', () => { }, }, }; - const mockConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$; + const mockConfig$ = new BehaviorSubject({ + elasticsearch: { + shardTimeout: { + asMilliseconds: () => { + return 100; + }, + }, + }, + }); beforeEach(() => { mockApiCaller.mockClear(); diff --git a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts index 4ace1c4c5385b..eda6178dc8e5b 100644 --- a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts @@ -5,23 +5,19 @@ */ import { first } from 'rxjs/operators'; -import { mapKeys, snakeCase } from 'lodash'; -import { Observable } from 'rxjs'; import { SearchResponse } from 'elasticsearch'; +import { Observable } from 'rxjs'; +import { SharedGlobalConfig, RequestHandlerContext, Logger } from '../../../../../src/core/server'; import { - SharedGlobalConfig, - RequestHandlerContext, - ElasticsearchClient, - Logger, -} from '../../../../../src/core/server'; -import { - getDefaultSearchParams, getTotalLoaded, ISearchStrategy, SearchUsage, + getDefaultSearchParams, + getShardTimeout, + toSnakeCase, + shimHitsTotal, } from '../../../../../src/plugins/data/server'; import { IEnhancedEsSearchRequest } from '../../common'; -import { shimHitsTotal } from './shim_hits_total'; import { ISearchOptions, IEsSearchResponse } from '../../../../../src/plugins/data/common/search'; function isEnhancedEsSearchResponse(response: any): response is IEsSearchResponse { @@ -39,17 +35,13 @@ export const enhancedEsSearchStrategyProvider = ( options?: ISearchOptions ) => { logger.debug(`search ${JSON.stringify(request.params) || request.id}`); - const config = await config$.pipe(first()).toPromise(); - const client = context.core.elasticsearch.client.asCurrentUser; - const defaultParams = getDefaultSearchParams(config); - const params = { ...defaultParams, ...request.params }; const isAsync = request.indexType !== 'rollup'; try { const response = isAsync - ? await asyncSearch(client, { ...request, params }, options) - : await rollupSearch(client, { ...request, params }, options); + ? await asyncSearch(context, request) + : await rollupSearch(context, request); if ( usage && @@ -75,72 +67,75 @@ export const enhancedEsSearchStrategyProvider = ( }); }; - return { search, cancel }; -}; - -async function asyncSearch( - client: ElasticsearchClient, - request: IEnhancedEsSearchRequest, - options?: ISearchOptions -): Promise { - let esResponse; + async function asyncSearch( + context: RequestHandlerContext, + request: IEnhancedEsSearchRequest + ): Promise { + let esResponse; + const esClient = context.core.elasticsearch.client.asCurrentUser; + const uiSettingsClient = await context.core.uiSettings.client; + + const asyncOptions = { + waitForCompletionTimeout: '100ms', // Wait up to 100ms for the response to return + keepAlive: '1m', // Extend the TTL for this search request by one minute + }; + + // If we have an ID, then just poll for that ID, otherwise send the entire request body + if (!request.id) { + const submitOptions = toSnakeCase({ + batchedReduceSize: 64, // Only report partial results every 64 shards; this should be reduced when we actually display partial results + ...(await getDefaultSearchParams(uiSettingsClient)), + ...asyncOptions, + ...request.params, + }); + + esResponse = await esClient.asyncSearch.submit(submitOptions); + } else { + esResponse = await esClient.asyncSearch.get({ + id: request.id, + ...toSnakeCase(asyncOptions), + }); + } - const asyncOptions = { - waitForCompletionTimeout: '100ms', // Wait up to 100ms for the response to return - keepAlive: '1m', // Extend the TTL for this search request by one minute - }; + const { id, response, is_partial: isPartial, is_running: isRunning } = esResponse.body; + return { + id, + isPartial, + isRunning, + rawResponse: shimHitsTotal(response), + ...getTotalLoaded(response._shards), + }; + } - // If we have an ID, then just poll for that ID, otherwise send the entire request body - if (!request.id) { - const submitOptions = toSnakeCase({ - batchedReduceSize: 64, // Only report partial results every 64 shards; this should be reduced when we actually display partial results - trackTotalHits: true, // Get the exact count of hits - ...asyncOptions, - ...request.params, + const rollupSearch = async function ( + context: RequestHandlerContext, + request: IEnhancedEsSearchRequest + ): Promise { + const esClient = context.core.elasticsearch.client.asCurrentUser; + const uiSettingsClient = await context.core.uiSettings.client; + const config = await config$.pipe(first()).toPromise(); + const { body, index, ...params } = request.params!; + const method = 'POST'; + const path = encodeURI(`/${index}/_rollup_search`); + const querystring = toSnakeCase({ + ...getShardTimeout(config), + ...(await getDefaultSearchParams(uiSettingsClient)), + ...params, }); - esResponse = await client.asyncSearch.submit(submitOptions); - } else { - esResponse = await client.asyncSearch.get({ - id: request.id, - ...toSnakeCase(asyncOptions), + const esResponse = await esClient.transport.request({ + method, + path, + body, + querystring, }); - } - - const { id, response, is_partial: isPartial, is_running: isRunning } = esResponse.body; - return { - id, - isPartial, - isRunning, - rawResponse: shimHitsTotal(response), - ...getTotalLoaded(response._shards), - }; -} -async function rollupSearch( - client: ElasticsearchClient, - request: IEnhancedEsSearchRequest, - options?: ISearchOptions -): Promise { - const { body, index, ...params } = request.params!; - const method = 'POST'; - const path = encodeURI(`/${index}/_rollup_search`); - const querystring = toSnakeCase(params); - - const esResponse = await client.transport.request({ - method, - path, - body, - querystring, - }); - - const response = esResponse.body as SearchResponse; - return { - rawResponse: shimHitsTotal(response), - ...getTotalLoaded(response._shards), + const response = esResponse.body as SearchResponse; + return { + rawResponse: response, + ...getTotalLoaded(response._shards), + }; }; -} -function toSnakeCase(obj: Record) { - return mapKeys(obj, (value, key) => snakeCase(key)); -} + return { search, cancel }; +}; diff --git a/x-pack/plugins/data_enhanced/server/search/shim_hits_total.ts b/x-pack/plugins/data_enhanced/server/search/shim_hits_total.ts deleted file mode 100644 index 10d45be01563a..0000000000000 --- a/x-pack/plugins/data_enhanced/server/search/shim_hits_total.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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'; - -/** - * Temporary workaround until https://github.com/elastic/kibana/issues/26356 is addressed. - * Since we are setting `track_total_hits` in the request, `hits.total` will be an object - * containing the `value`. - */ -export function shimHitsTotal(response: SearchResponse) { - const total = (response.hits?.total as any)?.value ?? response.hits?.total; - const hits = { ...response.hits, total }; - return { ...response, hits }; -} diff --git a/x-pack/plugins/data_enhanced/server/ui_settings.ts b/x-pack/plugins/data_enhanced/server/ui_settings.ts new file mode 100644 index 0000000000000..f2842da8b8337 --- /dev/null +++ b/x-pack/plugins/data_enhanced/server/ui_settings.ts @@ -0,0 +1,28 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { schema } from '@kbn/config-schema'; +import { UiSettingsParams } from 'kibana/server'; +import { UI_SETTINGS } from '../../../../src/plugins/data/server'; + +export function getUiSettings(): Record> { + return { + [UI_SETTINGS.SEARCH_TIMEOUT]: { + name: i18n.translate('xpack.data.advancedSettings.searchTimeout', { + defaultMessage: 'Search Timeout', + }), + value: 600000, + description: i18n.translate('xpack.data.advancedSettings.searchTimeoutDesc', { + defaultMessage: + 'Change the maximum timeout for a search session or set to 0 to disable the timeout and allow queries to run to completion.', + }), + type: 'number', + category: ['search'], + schema: schema.number(), + }, + }; +} diff --git a/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts b/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts index 2d31be65dd30e..4533383ebd80e 100644 --- a/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts +++ b/x-pack/plugins/enterprise_search/common/__mocks__/initial_app_data.ts @@ -7,9 +7,20 @@ export const DEFAULT_INITIAL_APP_DATA = { readOnlyMode: false, ilmEnabled: true, + isFederatedAuth: false, configuredLimits: { - maxDocumentByteSize: 102400, - maxEnginesPerMetaEngine: 15, + appSearch: { + engine: { + maxDocumentByteSize: 102400, + maxEnginesPerMetaEngine: 15, + }, + }, + workplaceSearch: { + customApiSource: { + maxDocumentByteSize: 102400, + totalFields: 64, + }, + }, }, appSearch: { accountId: 'some-id-string', @@ -29,17 +40,16 @@ export const DEFAULT_INITIAL_APP_DATA = { }, }, workplaceSearch: { - canCreateInvitations: true, - isFederatedAuth: false, organization: { name: 'ACME Donuts', defaultOrgName: 'My Organization', }, - fpAccount: { + account: { id: 'some-id-string', groups: ['Default', 'Cats'], isAdmin: true, canCreatePersonalSources: true, + canCreateInvitations: true, isCurated: false, viewedOnboardingPage: true, }, diff --git a/x-pack/plugins/enterprise_search/common/constants.ts b/x-pack/plugins/enterprise_search/common/constants.ts index 05d27d7337a6e..c6ca0d532ce07 100644 --- a/x-pack/plugins/enterprise_search/common/constants.ts +++ b/x-pack/plugins/enterprise_search/common/constants.ts @@ -11,7 +11,24 @@ export const ENTERPRISE_SEARCH_PLUGIN = { NAME: i18n.translate('xpack.enterpriseSearch.productName', { defaultMessage: 'Enterprise Search', }), - URL: '/app/enterprise_search', + NAV_TITLE: i18n.translate('xpack.enterpriseSearch.navTitle', { + defaultMessage: 'Overview', + }), + SUBTITLE: i18n.translate('xpack.enterpriseSearch.featureCatalogue.subtitle', { + defaultMessage: 'Search everything', + }), + DESCRIPTIONS: [ + i18n.translate('xpack.enterpriseSearch.featureCatalogueDescription1', { + defaultMessage: 'Build a powerful search experience.', + }), + i18n.translate('xpack.enterpriseSearch.featureCatalogueDescription2', { + defaultMessage: 'Connect your users to relevant data.', + }), + i18n.translate('xpack.enterpriseSearch.featureCatalogueDescription3', { + defaultMessage: 'Unify your team content.', + }), + ], + URL: '/app/enterprise_search/overview', }; export const APP_SEARCH_PLUGIN = { @@ -23,6 +40,10 @@ export const APP_SEARCH_PLUGIN = { defaultMessage: 'Leverage dashboards, analytics, and APIs for advanced application search made simple.', }), + CARD_DESCRIPTION: i18n.translate('xpack.enterpriseSearch.appSearch.productCardDescription', { + defaultMessage: + 'Elastic App Search provides user-friendly tools to design and deploy a powerful search to your websites or web/mobile applications.', + }), URL: '/app/enterprise_search/app_search', SUPPORT_URL: 'https://discuss.elastic.co/c/enterprise-search/app-search/', }; @@ -36,12 +57,22 @@ export const WORKPLACE_SEARCH_PLUGIN = { defaultMessage: 'Search all documents, files, and sources available across your virtual workplace.', }), + CARD_DESCRIPTION: i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.productCardDescription', + { + defaultMessage: + "Unify all your team's content in one place, with instant connectivity to popular productivity and collaboration tools.", + } + ), URL: '/app/enterprise_search/workplace_search', SUPPORT_URL: 'https://discuss.elastic.co/c/enterprise-search/workplace-search/', }; export const LICENSED_SUPPORT_URL = 'https://support.elastic.co'; -export const JSON_HEADER = { 'Content-Type': 'application/json' }; // This needs specific casing or Chrome throws a 415 error +export const JSON_HEADER = { + 'Content-Type': 'application/json', // This needs specific casing or Chrome throws a 415 error + Accept: 'application/json', // Required for Enterprise Search APIs +}; export const ENGINES_PAGE_SIZE = 10; diff --git a/x-pack/plugins/enterprise_search/common/types/app_search.ts b/x-pack/plugins/enterprise_search/common/types/app_search.ts index 5d6ec079e66e0..72259ecd2343d 100644 --- a/x-pack/plugins/enterprise_search/common/types/app_search.ts +++ b/x-pack/plugins/enterprise_search/common/types/app_search.ts @@ -23,3 +23,10 @@ export interface IRole { availableRoleTypes: string[]; }; } + +export interface IConfiguredLimits { + engine: { + maxDocumentByteSize: number; + maxEnginesPerMetaEngine: number; + }; +} diff --git a/x-pack/plugins/enterprise_search/common/types/index.ts b/x-pack/plugins/enterprise_search/common/types/index.ts index 008afb234a376..d5774adc0d516 100644 --- a/x-pack/plugins/enterprise_search/common/types/index.ts +++ b/x-pack/plugins/enterprise_search/common/types/index.ts @@ -4,18 +4,29 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IAccount as IAppSearchAccount } from './app_search'; -import { IWorkplaceSearchInitialData } from './workplace_search'; +import { + IAccount as IAppSearchAccount, + IConfiguredLimits as IAppSearchConfiguredLimits, +} from './app_search'; +import { + IWorkplaceSearchInitialData, + IConfiguredLimits as IWorkplaceSearchConfiguredLimits, +} from './workplace_search'; export interface IInitialAppData { readOnlyMode?: boolean; ilmEnabled?: boolean; + isFederatedAuth?: boolean; configuredLimits?: IConfiguredLimits; + access?: { + hasAppSearchAccess: boolean; + hasWorkplaceSearchAccess: boolean; + }; appSearch?: IAppSearchAccount; workplaceSearch?: IWorkplaceSearchInitialData; } export interface IConfiguredLimits { - maxDocumentByteSize: number; - maxEnginesPerMetaEngine: number; + appSearch: IAppSearchConfiguredLimits; + workplaceSearch: IWorkplaceSearchConfiguredLimits; } diff --git a/x-pack/plugins/enterprise_search/common/types/workplace_search.ts b/x-pack/plugins/enterprise_search/common/types/workplace_search.ts index bc4e39b0788d9..6c82206706b32 100644 --- a/x-pack/plugins/enterprise_search/common/types/workplace_search.ts +++ b/x-pack/plugins/enterprise_search/common/types/workplace_search.ts @@ -10,6 +10,7 @@ export interface IAccount { isAdmin: boolean; isCurated: boolean; canCreatePersonalSources: boolean; + canCreateInvitations?: boolean; viewedOnboardingPage: boolean; } @@ -19,8 +20,13 @@ export interface IOrganization { } export interface IWorkplaceSearchInitialData { - canCreateInvitations: boolean; - isFederatedAuth: boolean; organization: IOrganization; - fpAccount: IAccount; + account: IAccount; +} + +export interface IConfiguredLimits { + customApiSource: { + maxDocumentByteSize: number; + totalFields: number; + }; } diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts index 779eb1a043e8c..842dcefd3aef8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts @@ -9,7 +9,7 @@ * Jest to accept its use within a jest.mock() */ export const mockHistory = { - createHref: jest.fn(({ pathname }) => `/enterprise_search${pathname}`), + createHref: jest.fn(({ pathname }) => `/app/enterprise_search${pathname}`), push: jest.fn(), location: { pathname: '/current-path', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/assets/app_search.png b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/assets/app_search.png new file mode 100644 index 0000000000000..6cf0639167e2f Binary files /dev/null and b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/assets/app_search.png differ diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/assets/bg_enterprise_search.png b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/assets/bg_enterprise_search.png new file mode 100644 index 0000000000000..1b5e1e489fd96 Binary files /dev/null and b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/assets/bg_enterprise_search.png differ diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/assets/workplace_search.png b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/assets/workplace_search.png new file mode 100644 index 0000000000000..984662b65cb5d Binary files /dev/null and b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/assets/workplace_search.png differ diff --git a/x-pack/plugins/infra/server/lib/snapshot/constants.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/index.ts similarity index 65% rename from x-pack/plugins/infra/server/lib/snapshot/constants.ts rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/index.ts index 0420878dbcf50..df85a10f7e9de 100644 --- a/x-pack/plugins/infra/server/lib/snapshot/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/index.ts @@ -4,6 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -// TODO: Make SNAPSHOT_COMPOSITE_REQUEST_SIZE configurable from kibana.yml - -export const SNAPSHOT_COMPOSITE_REQUEST_SIZE = 75; +export { ProductCard } from './product_card'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.scss b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.scss new file mode 100644 index 0000000000000..d6b6bd3442590 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.scss @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +.productCard { + margin: $euiSizeS; + + &__imageContainer { + max-height: 115px; + overflow: hidden; + background-color: #0076cc; + + @include euiBreakpoint('s', 'm', 'l', 'xl') { + max-height: none; + } + } + + &__image { + width: 100%; + height: auto; + } + + .euiCard__content { + max-width: 350px; + margin-top: $euiSizeL; + + @include euiBreakpoint('s', 'm', 'l', 'xl') { + margin-top: $euiSizeXL; + } + } + + .euiCard__title { + margin-bottom: $euiSizeM; + font-weight: $euiFontWeightBold; + + @include euiBreakpoint('s', 'm', 'l', 'xl') { + margin-bottom: $euiSizeL; + font-size: $euiSizeL; + } + } + + .euiCard__description { + font-weight: $euiFontWeightMedium; + color: $euiColorMediumShade; + margin-bottom: $euiSize; + } + + .euiCard__footer { + margin-bottom: $euiSizeS; + + @include euiBreakpoint('s', 'm', 'l', 'xl') { + margin-bottom: $euiSizeM; + font-size: $euiSizeL; + } + } +} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx new file mode 100644 index 0000000000000..a76b654ccddd0 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { shallow } from 'enzyme'; + +import { EuiCard } from '@elastic/eui'; +import { EuiButton } from '../../../shared/react_router_helpers'; +import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; + +jest.mock('../../../shared/telemetry', () => ({ + sendTelemetry: jest.fn(), +})); +import { sendTelemetry } from '../../../shared/telemetry'; + +import { ProductCard } from './'; + +describe('ProductCard', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders an App Search card', () => { + const wrapper = shallow(); + const card = wrapper.find(EuiCard).dive().shallow(); + + expect(card.find('h2').text()).toEqual('Elastic App Search'); + expect(card.find('.productCard__image').prop('src')).toEqual('as.jpg'); + + const button = card.find(EuiButton); + expect(button.prop('to')).toEqual('/app/enterprise_search/app_search'); + expect(button.prop('data-test-subj')).toEqual('LaunchAppSearchButton'); + + button.simulate('click'); + expect(sendTelemetry).toHaveBeenCalledWith(expect.objectContaining({ metric: 'app_search' })); + }); + + it('renders a Workplace Search card', () => { + const wrapper = shallow(); + const card = wrapper.find(EuiCard).dive().shallow(); + + expect(card.find('h2').text()).toEqual('Elastic Workplace Search'); + expect(card.find('.productCard__image').prop('src')).toEqual('ws.jpg'); + + const button = card.find(EuiButton); + expect(button.prop('to')).toEqual('/app/enterprise_search/workplace_search'); + expect(button.prop('data-test-subj')).toEqual('LaunchWorkplaceSearchButton'); + + button.simulate('click'); + expect(sendTelemetry).toHaveBeenCalledWith( + expect.objectContaining({ metric: 'workplace_search' }) + ); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx new file mode 100644 index 0000000000000..334ca126cabb9 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx @@ -0,0 +1,71 @@ +/* + * 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 React, { useContext } from 'react'; +import upperFirst from 'lodash/upperFirst'; +import snakeCase from 'lodash/snakeCase'; +import { i18n } from '@kbn/i18n'; +import { EuiCard, EuiTextColor } from '@elastic/eui'; + +import { EuiButton } from '../../../shared/react_router_helpers'; +import { sendTelemetry } from '../../../shared/telemetry'; +import { KibanaContext, IKibanaContext } from '../../../index'; + +import './product_card.scss'; + +interface IProductCard { + // Expects product plugin constants (@see common/constants.ts) + product: { + ID: string; + NAME: string; + CARD_DESCRIPTION: string; + URL: string; + }; + image: string; +} + +export const ProductCard: React.FC = ({ product, image }) => { + const { http } = useContext(KibanaContext) as IKibanaContext; + + return ( + + + + } + paddingSize="l" + description={{product.CARD_DESCRIPTION}} + footer={ + + sendTelemetry({ + http, + product: 'enterprise_search', + action: 'clicked', + metric: snakeCase(product.ID), + }) + } + data-test-subj={`Launch${upperFirst(product.ID)}Button`} + > + {i18n.translate('xpack.enterpriseSearch.overview.productCard.button', { + defaultMessage: `Launch {productName}`, + values: { productName: product.NAME }, + })} + + } + /> + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.scss b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.scss new file mode 100644 index 0000000000000..d937943352317 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.scss @@ -0,0 +1,54 @@ +/* + * 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. + */ + +.enterpriseSearchOverview { + padding-top: 78px; + background-image: url('./assets/bg_enterprise_search.png'); + background-repeat: no-repeat; + background-size: 670px; + background-position: center -27px; + + @include euiBreakpoint('m', 'l', 'xl') { + padding-top: 158px; + background-size: 1160px; + background-position: center -48px; + } + + &__header { + text-align: center; + margin: auto; + } + + &__heading { + @include euiBreakpoint('xs', 's') { + font-size: $euiFontSizeXL; + line-height: map-get(map-get($euiTitles, 'm'), 'line-height'); + } + } + + &__subheading { + color: $euiColorMediumShade; + font-size: $euiFontSize; + + @include euiBreakpoint('m', 'l', 'xl') { + font-size: $euiFontSizeL; + margin-bottom: $euiSizeL; + } + } + + // EUI override + .euiTitle + .euiTitle { + margin-top: 0; + + @include euiBreakpoint('m', 'l', 'xl') { + margin-top: $euiSizeS; + } + } + + .enterpriseSearchOverview__card { + flex-basis: 50%; + } +} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx new file mode 100644 index 0000000000000..cd2a22a45bbb4 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx @@ -0,0 +1,50 @@ +/* + * 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 React from 'react'; +import { shallow } from 'enzyme'; + +import { EuiPage } from '@elastic/eui'; + +import { EnterpriseSearch } from './'; +import { ProductCard } from './components/product_card'; + +describe('EnterpriseSearch', () => { + it('renders the overview page and product cards', () => { + const wrapper = shallow( + + ); + + expect(wrapper.find(EuiPage).hasClass('enterpriseSearchOverview')).toBe(true); + expect(wrapper.find(ProductCard)).toHaveLength(2); + }); + + describe('access checks', () => { + it('does not render the App Search card if the user does not have access to AS', () => { + const wrapper = shallow( + + ); + + expect(wrapper.find(ProductCard)).toHaveLength(1); + expect(wrapper.find(ProductCard).prop('product').ID).toEqual('workplaceSearch'); + }); + + it('does not render the Workplace Search card if the user does not have access to WS', () => { + const wrapper = shallow( + + ); + + expect(wrapper.find(ProductCard)).toHaveLength(1); + expect(wrapper.find(ProductCard).prop('product').ID).toEqual('appSearch'); + }); + + it('does not render any cards if the user does not have access', () => { + const wrapper = shallow(); + + expect(wrapper.find(ProductCard)).toHaveLength(0); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx new file mode 100644 index 0000000000000..373f595a6a9ea --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx @@ -0,0 +1,78 @@ +/* + * 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 React from 'react'; +import { + EuiPage, + EuiPageBody, + EuiPageHeader, + EuiPageHeaderSection, + EuiPageContentBody, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { IInitialAppData } from '../../../common/types'; +import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../../../common/constants'; + +import { SetEnterpriseSearchChrome as SetPageChrome } from '../shared/kibana_chrome'; +import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../shared/telemetry'; + +import { ProductCard } from './components/product_card'; + +import AppSearchImage from './assets/app_search.png'; +import WorkplaceSearchImage from './assets/workplace_search.png'; +import './index.scss'; + +export const EnterpriseSearch: React.FC = ({ access = {} }) => { + const { hasAppSearchAccess, hasWorkplaceSearchAccess } = access; + + return ( + + + + + + + + +

+ {i18n.translate('xpack.enterpriseSearch.overview.heading', { + defaultMessage: 'Welcome to Elastic Enterprise Search', + })} +

+
+ +

+ {i18n.translate('xpack.enterpriseSearch.overview.subheading', { + defaultMessage: 'Select a product to get started', + })} +

+
+
+
+ + + {hasAppSearchAccess && ( + + + + )} + {hasWorkplaceSearchAccess && ( + + + + )} + + + +
+
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts index 9e86b239432a7..3c8b3a7218862 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts @@ -37,27 +37,37 @@ describe('useBreadcrumbs', () => { expect(breadcrumb).toEqual([ { text: 'Hello', - href: '/enterprise_search/hello', + href: '/app/enterprise_search/hello', onClick: expect.any(Function), }, { text: 'World', - href: '/enterprise_search/world', + href: '/app/enterprise_search/world', onClick: expect.any(Function), }, ]); }); it('prevents default navigation and uses React Router history on click', () => { - const breadcrumb = useBreadcrumbs([{ text: '', path: '/' }])[0] as any; + const breadcrumb = useBreadcrumbs([{ text: '', path: '/test' }])[0] as any; const event = { preventDefault: jest.fn() }; breadcrumb.onClick(event); - expect(mockKibanaContext.navigateToUrl).toHaveBeenCalled(); + expect(mockKibanaContext.navigateToUrl).toHaveBeenCalledWith('/app/enterprise_search/test'); expect(mockHistory.createHref).toHaveBeenCalled(); expect(event.preventDefault).toHaveBeenCalled(); }); + it('does not call createHref if shouldNotCreateHref is passed', () => { + const breadcrumb = useBreadcrumbs([ + { text: '', path: '/test', shouldNotCreateHref: true }, + ])[0] as any; + breadcrumb.onClick({ preventDefault: () => null }); + + expect(mockKibanaContext.navigateToUrl).toHaveBeenCalledWith('/test'); + expect(mockHistory.createHref).not.toHaveBeenCalled(); + }); + it('does not prevent default browser behavior on new tab/window clicks', () => { const breadcrumb = useBreadcrumbs([{ text: '', path: '/' }])[0] as any; @@ -95,15 +105,17 @@ describe('useEnterpriseSearchBreadcrumbs', () => { expect(useEnterpriseSearchBreadcrumbs(breadcrumbs)).toEqual([ { text: 'Enterprise Search', + href: '/app/enterprise_search/overview', + onClick: expect.any(Function), }, { text: 'Page 1', - href: '/enterprise_search/page1', + href: '/app/enterprise_search/page1', onClick: expect.any(Function), }, { text: 'Page 2', - href: '/enterprise_search/page2', + href: '/app/enterprise_search/page2', onClick: expect.any(Function), }, ]); @@ -113,6 +125,8 @@ describe('useEnterpriseSearchBreadcrumbs', () => { expect(useEnterpriseSearchBreadcrumbs()).toEqual([ { text: 'Enterprise Search', + href: '/app/enterprise_search/overview', + onClick: expect.any(Function), }, ]); }); @@ -122,7 +136,7 @@ describe('useAppSearchBreadcrumbs', () => { beforeEach(() => { jest.clearAllMocks(); mockHistory.createHref.mockImplementation( - ({ pathname }: any) => `/enterprise_search/app_search${pathname}` + ({ pathname }: any) => `/app/enterprise_search/app_search${pathname}` ); }); @@ -141,20 +155,22 @@ describe('useAppSearchBreadcrumbs', () => { expect(useAppSearchBreadcrumbs(breadcrumbs)).toEqual([ { text: 'Enterprise Search', + href: '/app/enterprise_search/overview', + onClick: expect.any(Function), }, { text: 'App Search', - href: '/enterprise_search/app_search/', + href: '/app/enterprise_search/app_search/', onClick: expect.any(Function), }, { text: 'Page 1', - href: '/enterprise_search/app_search/page1', + href: '/app/enterprise_search/app_search/page1', onClick: expect.any(Function), }, { text: 'Page 2', - href: '/enterprise_search/app_search/page2', + href: '/app/enterprise_search/app_search/page2', onClick: expect.any(Function), }, ]); @@ -164,10 +180,12 @@ describe('useAppSearchBreadcrumbs', () => { expect(useAppSearchBreadcrumbs()).toEqual([ { text: 'Enterprise Search', + href: '/app/enterprise_search/overview', + onClick: expect.any(Function), }, { text: 'App Search', - href: '/enterprise_search/app_search/', + href: '/app/enterprise_search/app_search/', onClick: expect.any(Function), }, ]); @@ -178,7 +196,7 @@ describe('useWorkplaceSearchBreadcrumbs', () => { beforeEach(() => { jest.clearAllMocks(); mockHistory.createHref.mockImplementation( - ({ pathname }: any) => `/enterprise_search/workplace_search${pathname}` + ({ pathname }: any) => `/app/enterprise_search/workplace_search${pathname}` ); }); @@ -197,20 +215,22 @@ describe('useWorkplaceSearchBreadcrumbs', () => { expect(useWorkplaceSearchBreadcrumbs(breadcrumbs)).toEqual([ { text: 'Enterprise Search', + href: '/app/enterprise_search/overview', + onClick: expect.any(Function), }, { text: 'Workplace Search', - href: '/enterprise_search/workplace_search/', + href: '/app/enterprise_search/workplace_search/', onClick: expect.any(Function), }, { text: 'Page 1', - href: '/enterprise_search/workplace_search/page1', + href: '/app/enterprise_search/workplace_search/page1', onClick: expect.any(Function), }, { text: 'Page 2', - href: '/enterprise_search/workplace_search/page2', + href: '/app/enterprise_search/workplace_search/page2', onClick: expect.any(Function), }, ]); @@ -220,10 +240,12 @@ describe('useWorkplaceSearchBreadcrumbs', () => { expect(useWorkplaceSearchBreadcrumbs()).toEqual([ { text: 'Enterprise Search', + href: '/app/enterprise_search/overview', + onClick: expect.any(Function), }, { text: 'Workplace Search', - href: '/enterprise_search/workplace_search/', + href: '/app/enterprise_search/workplace_search/', onClick: expect.any(Function), }, ]); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts index 6eab936719d01..19714608e73e9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts @@ -26,6 +26,9 @@ import { letBrowserHandleEvent } from '../react_router_helpers'; interface IBreadcrumb { text: string; path?: string; + // Used to navigate outside of the React Router basename, + // i.e. if we need to go from App Search to Enterprise Search + shouldNotCreateHref?: boolean; } export type TBreadcrumbs = IBreadcrumb[]; @@ -33,11 +36,11 @@ export const useBreadcrumbs = (breadcrumbs: TBreadcrumbs) => { const history = useHistory(); const { navigateToUrl } = useContext(KibanaContext) as IKibanaContext; - return breadcrumbs.map(({ text, path }) => { + return breadcrumbs.map(({ text, path, shouldNotCreateHref }) => { const breadcrumb = { text } as EuiBreadcrumb; if (path) { - const href = history.createHref({ pathname: path }) as string; + const href = shouldNotCreateHref ? path : (history.createHref({ pathname: path }) as string); breadcrumb.href = href; breadcrumb.onClick = (event) => { @@ -56,7 +59,14 @@ export const useBreadcrumbs = (breadcrumbs: TBreadcrumbs) => { */ export const useEnterpriseSearchBreadcrumbs = (breadcrumbs: TBreadcrumbs = []) => - useBreadcrumbs([{ text: ENTERPRISE_SEARCH_PLUGIN.NAME }, ...breadcrumbs]); + useBreadcrumbs([ + { + text: ENTERPRISE_SEARCH_PLUGIN.NAME, + path: ENTERPRISE_SEARCH_PLUGIN.URL, + shouldNotCreateHref: true, + }, + ...breadcrumbs, + ]); export const useAppSearchBreadcrumbs = (breadcrumbs: TBreadcrumbs = []) => useEnterpriseSearchBreadcrumbs([{ text: APP_SEARCH_PLUGIN.NAME, path: '/' }, ...breadcrumbs]); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.ts index 706baefc00cc2..de5f72de79192 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_title.ts @@ -20,7 +20,7 @@ export type TTitle = string[]; /** * Given an array of page titles, return a final formatted document title * @param pages - e.g., ['Curations', 'some Engine', 'App Search'] - * @returns - e.g., 'Curations | some Engine | App Search' + * @returns - e.g., 'Curations - some Engine - App Search' */ export const generateTitle = (pages: TTitle) => pages.join(' - '); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts index 4468d11ba94c9..02013a03c3395 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts @@ -4,4 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -export { SetAppSearchChrome, SetWorkplaceSearchChrome } from './set_chrome'; +export { + SetEnterpriseSearchChrome, + SetAppSearchChrome, + SetWorkplaceSearchChrome, +} from './set_chrome'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx index bda816c9a5554..61a066bb92216 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx @@ -12,18 +12,24 @@ import React from 'react'; import { mockKibanaContext, mountWithKibanaContext } from '../../__mocks__'; jest.mock('./generate_breadcrumbs', () => ({ + useEnterpriseSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), useAppSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), useWorkplaceSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), })); -import { useAppSearchBreadcrumbs, useWorkplaceSearchBreadcrumbs } from './generate_breadcrumbs'; +import { + useEnterpriseSearchBreadcrumbs, + useAppSearchBreadcrumbs, + useWorkplaceSearchBreadcrumbs, +} from './generate_breadcrumbs'; jest.mock('./generate_title', () => ({ + enterpriseSearchTitle: jest.fn((title: any) => title), appSearchTitle: jest.fn((title: any) => title), workplaceSearchTitle: jest.fn((title: any) => title), })); -import { appSearchTitle, workplaceSearchTitle } from './generate_title'; +import { enterpriseSearchTitle, appSearchTitle, workplaceSearchTitle } from './generate_title'; -import { SetAppSearchChrome, SetWorkplaceSearchChrome } from './'; +import { SetEnterpriseSearchChrome, SetAppSearchChrome, SetWorkplaceSearchChrome } from './'; describe('Set Kibana Chrome helpers', () => { beforeEach(() => { @@ -35,6 +41,27 @@ describe('Set Kibana Chrome helpers', () => { expect(mockKibanaContext.setDocTitle).toHaveBeenCalled(); }); + describe('SetEnterpriseSearchChrome', () => { + it('sets breadcrumbs and document title', () => { + mountWithKibanaContext(); + + expect(enterpriseSearchTitle).toHaveBeenCalledWith(['Hello World']); + expect(useEnterpriseSearchBreadcrumbs).toHaveBeenCalledWith([ + { + text: 'Hello World', + path: '/current-path', + }, + ]); + }); + + it('sets empty breadcrumbs and document title when isRoot is true', () => { + mountWithKibanaContext(); + + expect(enterpriseSearchTitle).toHaveBeenCalledWith([]); + expect(useEnterpriseSearchBreadcrumbs).toHaveBeenCalledWith([]); + }); + }); + describe('SetAppSearchChrome', () => { it('sets breadcrumbs and document title', () => { mountWithKibanaContext(); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx index 43db93c1583d1..5e8d972e1a135 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx @@ -10,11 +10,17 @@ import { EuiBreadcrumb } from '@elastic/eui'; import { KibanaContext, IKibanaContext } from '../../index'; import { + useEnterpriseSearchBreadcrumbs, useAppSearchBreadcrumbs, useWorkplaceSearchBreadcrumbs, TBreadcrumbs, } from './generate_breadcrumbs'; -import { appSearchTitle, workplaceSearchTitle, TTitle } from './generate_title'; +import { + enterpriseSearchTitle, + appSearchTitle, + workplaceSearchTitle, + TTitle, +} from './generate_title'; /** * Helpers for setting Kibana chrome (breadcrumbs, doc titles) on React view mount @@ -33,6 +39,24 @@ interface IRootBreadcrumbsProps { } type TBreadcrumbsProps = IBreadcrumbsProps | IRootBreadcrumbsProps; +export const SetEnterpriseSearchChrome: React.FC = ({ text, isRoot }) => { + const history = useHistory(); + const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; + + const title = isRoot ? [] : [text]; + const docTitle = enterpriseSearchTitle(title as TTitle | []); + + const crumb = isRoot ? [] : [{ text, path: history.location.pathname }]; + const breadcrumbs = useEnterpriseSearchBreadcrumbs(crumb as TBreadcrumbs | []); + + useEffect(() => { + setBreadcrumbs(breadcrumbs); + setDocTitle(docTitle); + }, []); + + return null; +}; + export const SetAppSearchChrome: React.FC = ({ text, isRoot }) => { const history = useHistory(); const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx index 063118f94cd19..0c7bac99085dd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx @@ -45,10 +45,18 @@ describe('EUI & React Router Component Helpers', () => { const link = wrapper.find(EuiLink); expect(link.prop('onClick')).toBeInstanceOf(Function); - expect(link.prop('href')).toEqual('/enterprise_search/foo/bar'); + expect(link.prop('href')).toEqual('/app/enterprise_search/foo/bar'); expect(mockHistory.createHref).toHaveBeenCalled(); }); + it('renders with the correct non-basenamed href when shouldNotCreateHref is passed', () => { + const wrapper = mount(); + const link = wrapper.find(EuiLink); + + expect(link.prop('href')).toEqual('/foo/bar'); + expect(mockHistory.createHref).not.toHaveBeenCalled(); + }); + describe('onClick', () => { it('prevents default navigation and uses React Router history', () => { const wrapper = mount(); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx index 7221a61d0997b..e3b46632ddf9e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx @@ -21,14 +21,22 @@ import { letBrowserHandleEvent } from './link_events'; interface IEuiReactRouterProps { to: string; onClick?(): void; + // Used to navigate outside of the React Router plugin basename but still within Kibana, + // e.g. if we need to go from Enterprise Search to App Search + shouldNotCreateHref?: boolean; } -export const EuiReactRouterHelper: React.FC = ({ to, onClick, children }) => { +export const EuiReactRouterHelper: React.FC = ({ + to, + onClick, + shouldNotCreateHref, + children, +}) => { const history = useHistory(); const { navigateToUrl } = useContext(KibanaContext) as IKibanaContext; // Generate the correct link href (with basename etc. accounted for) - const href = history.createHref({ pathname: to }); + const href = shouldNotCreateHref ? to : history.createHref({ pathname: to }); const reactRouterLinkClick = (event: React.MouseEvent) => { if (onClick) onClick(); // Run any passed click events (e.g. telemetry) @@ -51,9 +59,10 @@ type TEuiReactRouterButtonProps = EuiButtonProps & IEuiReactRouterProps; export const EuiReactRouterLink: React.FC = ({ to, onClick, + shouldNotCreateHref, ...rest }) => ( - + ); @@ -61,9 +70,10 @@ export const EuiReactRouterLink: React.FC = ({ export const EuiReactRouterButton: React.FC = ({ to, onClick, + shouldNotCreateHref, ...rest }) => ( - + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/index.ts index eadf7fa805590..a8b9636c3ff3e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/index.ts @@ -5,5 +5,8 @@ */ export { sendTelemetry } from './send_telemetry'; -export { SendAppSearchTelemetry } from './send_telemetry'; -export { SendWorkplaceSearchTelemetry } from './send_telemetry'; +export { + SendEnterpriseSearchTelemetry, + SendAppSearchTelemetry, + SendWorkplaceSearchTelemetry, +} from './send_telemetry'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx index 3c873dbc25e37..8f7cf090e2d57 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx @@ -10,7 +10,12 @@ import { httpServiceMock } from 'src/core/public/mocks'; import { JSON_HEADER as headers } from '../../../../common/constants'; import { mountWithKibanaContext } from '../../__mocks__'; -import { sendTelemetry, SendAppSearchTelemetry, SendWorkplaceSearchTelemetry } from './'; +import { + sendTelemetry, + SendEnterpriseSearchTelemetry, + SendAppSearchTelemetry, + SendWorkplaceSearchTelemetry, +} from './'; describe('Shared Telemetry Helpers', () => { const httpMock = httpServiceMock.createSetupContract(); @@ -44,6 +49,17 @@ describe('Shared Telemetry Helpers', () => { }); describe('React component helpers', () => { + it('SendEnterpriseSearchTelemetry component', () => { + mountWithKibanaContext(, { + http: httpMock, + }); + + expect(httpMock.put).toHaveBeenCalledWith('/api/enterprise_search/telemetry', { + headers, + body: '{"product":"enterprise_search","action":"viewed","metric":"page"}', + }); + }); + it('SendAppSearchTelemetry component', () => { mountWithKibanaContext(, { http: httpMock, @@ -56,13 +72,13 @@ describe('Shared Telemetry Helpers', () => { }); it('SendWorkplaceSearchTelemetry component', () => { - mountWithKibanaContext(, { + mountWithKibanaContext(, { http: httpMock, }); expect(httpMock.put).toHaveBeenCalledWith('/api/enterprise_search/telemetry', { headers, - body: '{"product":"workplace_search","action":"viewed","metric":"page"}', + body: '{"product":"workplace_search","action":"error","metric":"not_found"}', }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.tsx index 715d61b31512c..4df1428221de6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.tsx @@ -35,9 +35,21 @@ export const sendTelemetry = async ({ http, product, action, metric }: ISendTele /** * React component helpers - useful for on-page-load/views - * TODO: SendEnterpriseSearchTelemetry */ +export const SendEnterpriseSearchTelemetry: React.FC = ({ + action, + metric, +}) => { + const { http } = useContext(KibanaContext) as IKibanaContext; + + useEffect(() => { + sendTelemetry({ http, action, metric, product: 'enterprise_search' }); + }, [action, metric, http]); + + return null; +}; + export const SendAppSearchTelemetry: React.FC = ({ action, metric }) => { const { http } = useContext(KibanaContext) as IKibanaContext; diff --git a/x-pack/plugins/enterprise_search/public/plugin.ts b/x-pack/plugins/enterprise_search/public/plugin.ts index 83598a0dc971d..b735db7c49520 100644 --- a/x-pack/plugins/enterprise_search/public/plugin.ts +++ b/x-pack/plugins/enterprise_search/public/plugin.ts @@ -12,7 +12,6 @@ import { AppMountParameters, HttpSetup, } from 'src/core/public'; -import { i18n } from '@kbn/i18n'; import { FeatureCatalogueCategory, HomePublicPluginSetup, @@ -52,6 +51,25 @@ export class EnterpriseSearchPlugin implements Plugin { } public setup(core: CoreSetup, plugins: PluginsSetup) { + core.application.register({ + id: ENTERPRISE_SEARCH_PLUGIN.ID, + title: ENTERPRISE_SEARCH_PLUGIN.NAV_TITLE, + appRoute: ENTERPRISE_SEARCH_PLUGIN.URL, + category: DEFAULT_APP_CATEGORIES.enterpriseSearch, + mount: async (params: AppMountParameters) => { + const [coreStart] = await core.getStartServices(); + const { chrome } = coreStart; + chrome.docTitle.change(ENTERPRISE_SEARCH_PLUGIN.NAME); + + await this.getInitialData(coreStart.http); + + const { renderApp } = await import('./applications'); + const { EnterpriseSearch } = await import('./applications/enterprise_search'); + + return renderApp(EnterpriseSearch, params, coreStart, plugins, this.config, this.data); + }, + }); + core.application.register({ id: APP_SEARCH_PLUGIN.ID, title: APP_SEARCH_PLUGIN.NAME, @@ -94,22 +112,10 @@ export class EnterpriseSearchPlugin implements Plugin { plugins.home.featureCatalogue.registerSolution({ id: ENTERPRISE_SEARCH_PLUGIN.ID, title: ENTERPRISE_SEARCH_PLUGIN.NAME, - subtitle: i18n.translate('xpack.enterpriseSearch.featureCatalogue.subtitle', { - defaultMessage: 'Search everything', - }), + subtitle: ENTERPRISE_SEARCH_PLUGIN.SUBTITLE, icon: 'logoEnterpriseSearch', - descriptions: [ - i18n.translate('xpack.enterpriseSearch.featureCatalogueDescription1', { - defaultMessage: 'Build a powerful search experience.', - }), - i18n.translate('xpack.enterpriseSearch.featureCatalogueDescription2', { - defaultMessage: 'Connect your users to relevant data.', - }), - i18n.translate('xpack.enterpriseSearch.featureCatalogueDescription3', { - defaultMessage: 'Unify your team content.', - }), - ], - path: APP_SEARCH_PLUGIN.URL, // TODO: Change this to enterprise search overview page once available + descriptions: ENTERPRISE_SEARCH_PLUGIN.DESCRIPTIONS, + path: ENTERPRISE_SEARCH_PLUGIN.URL, }); plugins.home.featureCatalogue.register({ diff --git a/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.test.ts b/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.test.ts new file mode 100644 index 0000000000000..c3e2aff6551c9 --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.test.ts @@ -0,0 +1,85 @@ +/* + * 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 { mockLogger } from '../../__mocks__'; + +import { registerTelemetryUsageCollector } from './telemetry'; + +describe('Enterprise Search Telemetry Usage Collector', () => { + const makeUsageCollectorStub = jest.fn(); + const registerStub = jest.fn(); + const usageCollectionMock = { + makeUsageCollector: makeUsageCollectorStub, + registerCollector: registerStub, + } as any; + + const savedObjectsRepoStub = { + get: () => ({ + attributes: { + 'ui_viewed.overview': 10, + 'ui_clicked.app_search': 2, + 'ui_clicked.workplace_search': 3, + }, + }), + incrementCounter: jest.fn(), + }; + const savedObjectsMock = { + createInternalRepository: jest.fn(() => savedObjectsRepoStub), + } as any; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('registerTelemetryUsageCollector', () => { + it('should make and register the usage collector', () => { + registerTelemetryUsageCollector(usageCollectionMock, savedObjectsMock, mockLogger); + + expect(registerStub).toHaveBeenCalledTimes(1); + expect(makeUsageCollectorStub).toHaveBeenCalledTimes(1); + expect(makeUsageCollectorStub.mock.calls[0][0].type).toBe('enterprise_search'); + expect(makeUsageCollectorStub.mock.calls[0][0].isReady()).toBe(true); + }); + }); + + describe('fetchTelemetryMetrics', () => { + it('should return existing saved objects data', async () => { + registerTelemetryUsageCollector(usageCollectionMock, savedObjectsMock, mockLogger); + const savedObjectsCounts = await makeUsageCollectorStub.mock.calls[0][0].fetch(); + + expect(savedObjectsCounts).toEqual({ + ui_viewed: { + overview: 10, + }, + ui_clicked: { + app_search: 2, + workplace_search: 3, + }, + }); + }); + + it('should return a default telemetry object if no saved data exists', async () => { + const emptySavedObjectsMock = { + createInternalRepository: () => ({ + get: () => ({ attributes: null }), + }), + } as any; + + registerTelemetryUsageCollector(usageCollectionMock, emptySavedObjectsMock, mockLogger); + const savedObjectsCounts = await makeUsageCollectorStub.mock.calls[0][0].fetch(); + + expect(savedObjectsCounts).toEqual({ + ui_viewed: { + overview: 0, + }, + ui_clicked: { + app_search: 0, + workplace_search: 0, + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts new file mode 100644 index 0000000000000..a124a185b9a34 --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts @@ -0,0 +1,87 @@ +/* + * 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 { get } from 'lodash'; +import { SavedObjectsServiceStart, Logger } from 'src/core/server'; +import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; + +import { getSavedObjectAttributesFromRepo } from '../lib/telemetry'; + +interface ITelemetry { + ui_viewed: { + overview: number; + }; + ui_clicked: { + app_search: number; + workplace_search: number; + }; +} + +export const ES_TELEMETRY_NAME = 'enterprise_search_telemetry'; + +/** + * Register the telemetry collector + */ + +export const registerTelemetryUsageCollector = ( + usageCollection: UsageCollectionSetup, + savedObjects: SavedObjectsServiceStart, + log: Logger +) => { + const telemetryUsageCollector = usageCollection.makeUsageCollector({ + type: 'enterprise_search', + fetch: async () => fetchTelemetryMetrics(savedObjects, log), + isReady: () => true, + schema: { + ui_viewed: { + overview: { type: 'long' }, + }, + ui_clicked: { + app_search: { type: 'long' }, + workplace_search: { type: 'long' }, + }, + }, + }); + usageCollection.registerCollector(telemetryUsageCollector); +}; + +/** + * Fetch the aggregated telemetry metrics from our saved objects + */ + +const fetchTelemetryMetrics = async (savedObjects: SavedObjectsServiceStart, log: Logger) => { + const savedObjectsRepository = savedObjects.createInternalRepository(); + const savedObjectAttributes = await getSavedObjectAttributesFromRepo( + ES_TELEMETRY_NAME, + savedObjectsRepository, + log + ); + + const defaultTelemetrySavedObject: ITelemetry = { + ui_viewed: { + overview: 0, + }, + ui_clicked: { + app_search: 0, + workplace_search: 0, + }, + }; + + // If we don't have an existing/saved telemetry object, return the default + if (!savedObjectAttributes) { + return defaultTelemetrySavedObject; + } + + return { + ui_viewed: { + overview: get(savedObjectAttributes, 'ui_viewed.overview', 0), + }, + ui_clicked: { + app_search: get(savedObjectAttributes, 'ui_clicked.app_search', 0), + workplace_search: get(savedObjectAttributes, 'ui_clicked.workplace_search', 0), + }, + } as ITelemetry; +}; diff --git a/x-pack/plugins/enterprise_search/server/collectors/lib/telemetry.test.ts b/x-pack/plugins/enterprise_search/server/collectors/lib/telemetry.test.ts index aae162c23ccb4..6cf0be9fd1f31 100644 --- a/x-pack/plugins/enterprise_search/server/collectors/lib/telemetry.test.ts +++ b/x-pack/plugins/enterprise_search/server/collectors/lib/telemetry.test.ts @@ -15,7 +15,7 @@ import { SavedObjectsErrorHelpers } from '../../../../../../src/core/server'; import { getSavedObjectAttributesFromRepo, incrementUICounter } from './telemetry'; -describe('App Search Telemetry Usage Collector', () => { +describe('Telemetry helpers', () => { beforeEach(() => { jest.clearAllMocks(); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts index 323f79e63bc6f..8e3ae2cfbeb86 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts @@ -38,51 +38,63 @@ describe('callEnterpriseSearchConfigAPI', () => { external_url: 'http://some.vanity.url/', read_only_mode: false, ilm_enabled: true, + is_federated_auth: false, configured_limits: { - max_document_byte_size: 102400, - max_engines_per_meta_engine: 15, + app_search: { + engine: { + document_size_in_bytes: 102400, + source_engines_per_meta_engine: 15, + }, + }, + workplace_search: { + custom_api_source: { + document_size_in_bytes: 102400, + total_fields: 64, + }, + }, + }, + }, + current_user: { + name: 'someuser', + access: { + app_search: true, + workplace_search: false, }, app_search: { - account_id: 'some-id-string', - onboarding_complete: true, + account: { + id: 'some-id-string', + onboarding_complete: true, + }, + role: { + id: 'account_id:somestring|user_oid:somestring', + role_type: 'owner', + ability: { + access_all_engines: true, + destroy: ['session'], + manage: ['account_credentials', 'account_engines'], // etc + edit: ['LocoMoco::Account'], // etc + view: ['Engine'], // etc + credential_types: ['admin', 'private', 'search'], + available_role_types: ['owner', 'admin'], + }, + }, }, workplace_search: { - can_create_invitations: true, - is_federated_auth: false, organization: { name: 'ACME Donuts', default_org_name: 'My Organization', }, - fp_account: { + account: { id: 'some-id-string', groups: ['Default', 'Cats'], is_admin: true, can_create_personal_sources: true, + can_create_invitations: true, is_curated: false, viewed_onboarding_page: true, }, }, }, - current_user: { - name: 'someuser', - access: { - app_search: true, - workplace_search: false, - }, - app_search_role: { - id: 'account_id:somestring|user_oid:somestring', - role_type: 'owner', - ability: { - access_all_engines: true, - destroy: ['session'], - manage: ['account_credentials', 'account_engines'], // etc - edit: ['LocoMoco::Account'], // etc - view: ['Engine'], // etc - credential_types: ['admin', 'private', 'search'], - available_role_types: ['owner', 'admin'], - }, - }, - }, }; beforeEach(() => { @@ -91,7 +103,7 @@ describe('callEnterpriseSearchConfigAPI', () => { it('calls the config API endpoint', async () => { fetchMock.mockImplementationOnce((url: string) => { - expect(url).toEqual('http://localhost:3002/api/ent/v1/internal/client_config'); + expect(url).toEqual('http://localhost:3002/api/ent/v2/internal/client_config'); return Promise.resolve(new Response(JSON.stringify(mockResponse))); }); @@ -116,9 +128,20 @@ describe('callEnterpriseSearchConfigAPI', () => { publicUrl: undefined, readOnlyMode: false, ilmEnabled: false, + isFederatedAuth: false, configuredLimits: { - maxDocumentByteSize: undefined, - maxEnginesPerMetaEngine: undefined, + appSearch: { + engine: { + maxDocumentByteSize: undefined, + maxEnginesPerMetaEngine: undefined, + }, + }, + workplaceSearch: { + customApiSource: { + maxDocumentByteSize: undefined, + totalFields: undefined, + }, + }, }, appSearch: { accountId: undefined, @@ -138,17 +161,16 @@ describe('callEnterpriseSearchConfigAPI', () => { }, }, workplaceSearch: { - canCreateInvitations: false, - isFederatedAuth: false, organization: { name: undefined, defaultOrgName: undefined, }, - fpAccount: { + account: { id: undefined, groups: [], isAdmin: false, canCreatePersonalSources: false, + canCreateInvitations: false, isCurated: false, viewedOnboardingPage: false, }, diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts index c9cbec15169d9..10a75e59cb249 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts @@ -29,7 +29,7 @@ interface IReturn extends IInitialAppData { * useful various settings (e.g. product access, external URL) * needed by the Kibana plugin at the setup stage */ -const ENDPOINT = '/api/ent/v1/internal/client_config'; +const ENDPOINT = '/api/ent/v2/internal/client_config'; export const callEnterpriseSearchConfigAPI = async ({ config, @@ -67,44 +67,60 @@ export const callEnterpriseSearchConfigAPI = async ({ publicUrl: stripTrailingSlash(data?.settings?.external_url), readOnlyMode: !!data?.settings?.read_only_mode, ilmEnabled: !!data?.settings?.ilm_enabled, + isFederatedAuth: !!data?.settings?.is_federated_auth, // i.e., not standard auth configuredLimits: { - maxDocumentByteSize: data?.settings?.configured_limits?.max_document_byte_size, - maxEnginesPerMetaEngine: data?.settings?.configured_limits?.max_engines_per_meta_engine, + appSearch: { + engine: { + maxDocumentByteSize: + data?.settings?.configured_limits?.app_search?.engine?.document_size_in_bytes, + maxEnginesPerMetaEngine: + data?.settings?.configured_limits?.app_search?.engine?.source_engines_per_meta_engine, + }, + }, + workplaceSearch: { + customApiSource: { + maxDocumentByteSize: + data?.settings?.configured_limits?.workplace_search?.custom_api_source + ?.document_size_in_bytes, + totalFields: + data?.settings?.configured_limits?.workplace_search?.custom_api_source?.total_fields, + }, + }, }, appSearch: { - accountId: data?.settings?.app_search?.account_id, - onBoardingComplete: !!data?.settings?.app_search?.onboarding_complete, + accountId: data?.current_user?.app_search?.account?.id, + onBoardingComplete: !!data?.current_user?.app_search?.account?.onboarding_complete, role: { - id: data?.current_user?.app_search_role?.id, - roleType: data?.current_user?.app_search_role?.role_type, + id: data?.current_user?.app_search?.role?.id, + roleType: data?.current_user?.app_search?.role?.role_type, ability: { - accessAllEngines: !!data?.current_user?.app_search_role?.ability?.access_all_engines, - destroy: data?.current_user?.app_search_role?.ability?.destroy || [], - manage: data?.current_user?.app_search_role?.ability?.manage || [], - edit: data?.current_user?.app_search_role?.ability?.edit || [], - view: data?.current_user?.app_search_role?.ability?.view || [], - credentialTypes: data?.current_user?.app_search_role?.ability?.credential_types || [], + accessAllEngines: !!data?.current_user?.app_search?.role?.ability?.access_all_engines, + destroy: data?.current_user?.app_search?.role?.ability?.destroy || [], + manage: data?.current_user?.app_search?.role?.ability?.manage || [], + edit: data?.current_user?.app_search?.role?.ability?.edit || [], + view: data?.current_user?.app_search?.role?.ability?.view || [], + credentialTypes: data?.current_user?.app_search?.role?.ability?.credential_types || [], availableRoleTypes: - data?.current_user?.app_search_role?.ability?.available_role_types || [], + data?.current_user?.app_search?.role?.ability?.available_role_types || [], }, }, }, workplaceSearch: { - canCreateInvitations: !!data?.settings?.workplace_search?.can_create_invitations, - isFederatedAuth: !!data?.settings?.workplace_search?.is_federated_auth, organization: { - name: data?.settings?.workplace_search?.organization?.name, - defaultOrgName: data?.settings?.workplace_search?.organization?.default_org_name, + name: data?.current_user?.workplace_search?.organization?.name, + defaultOrgName: data?.current_user?.workplace_search?.organization?.default_org_name, }, - fpAccount: { - id: data?.settings?.workplace_search?.fp_account.id, - groups: data?.settings?.workplace_search?.fp_account.groups || [], - isAdmin: !!data?.settings?.workplace_search?.fp_account?.is_admin, - canCreatePersonalSources: !!data?.settings?.workplace_search?.fp_account + account: { + id: data?.current_user?.workplace_search?.account?.id, + groups: data?.current_user?.workplace_search?.account?.groups || [], + isAdmin: !!data?.current_user?.workplace_search?.account?.is_admin, + canCreatePersonalSources: !!data?.current_user?.workplace_search?.account ?.can_create_personal_sources, - isCurated: !!data?.settings?.workplace_search?.fp_account.is_curated, - viewedOnboardingPage: !!data?.settings?.workplace_search?.fp_account - .viewed_onboarding_page, + canCreateInvitations: !!data?.current_user?.workplace_search?.account + ?.can_create_invitations, + isCurated: !!data?.current_user?.workplace_search?.account?.is_curated, + viewedOnboardingPage: !!data?.current_user?.workplace_search?.account + ?.viewed_onboarding_page, }, }, }; diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.test.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.test.ts index 3f3f182433144..34f83ef3a3fd2 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.test.ts @@ -5,6 +5,7 @@ */ import { mockConfig, mockLogger } from '../__mocks__'; +import { JSON_HEADER } from '../../common/constants'; import { EnterpriseSearchRequestHandler } from './enterprise_search_request_handler'; @@ -150,18 +151,26 @@ describe('EnterpriseSearchRequestHandler', () => { ); }); - it('returns an error when user authentication to Enterprise Search fails', async () => { - EnterpriseSearchAPI.mockReturn({}, { url: 'http://localhost:3002/login' }); - const requestHandler = enterpriseSearchRequestHandler.createRequest({ - path: '/api/unauthenticated', + describe('user authentication errors', () => { + afterEach(async () => { + const requestHandler = enterpriseSearchRequestHandler.createRequest({ + path: '/api/unauthenticated', + }); + await makeAPICall(requestHandler); + + EnterpriseSearchAPI.shouldHaveBeenCalledWith('http://localhost:3002/api/unauthenticated'); + expect(responseMock.customError).toHaveBeenCalledWith({ + body: 'Error connecting to Enterprise Search: Cannot authenticate Enterprise Search user', + statusCode: 502, + }); }); - await makeAPICall(requestHandler); - EnterpriseSearchAPI.shouldHaveBeenCalledWith('http://localhost:3002/api/unauthenticated'); + it('errors when redirected to /login', async () => { + EnterpriseSearchAPI.mockReturn({}, { url: 'http://localhost:3002/login' }); + }); - expect(responseMock.customError).toHaveBeenCalledWith({ - body: 'Error connecting to Enterprise Search: Cannot authenticate Enterprise Search user', - statusCode: 502, + it('errors when redirected to /ent/select', async () => { + EnterpriseSearchAPI.mockReturn({}, { url: 'http://localhost:3002/ent/select' }); }); }); }); @@ -185,7 +194,7 @@ const makeAPICall = (handler: Function, params = {}) => { const EnterpriseSearchAPI = { shouldHaveBeenCalledWith(expectedUrl: string, expectedParams = {}) { expect(fetchMock).toHaveBeenCalledWith(expectedUrl, { - headers: { Authorization: 'Basic 123' }, + headers: { Authorization: 'Basic 123', ...JSON_HEADER }, method: 'GET', body: undefined, ...expectedParams, diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.ts index 8f31bd9063d4a..18f10c590847c 100644 --- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.ts +++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.ts @@ -14,6 +14,7 @@ import { Logger, } from 'src/core/server'; import { ConfigType } from '../index'; +import { JSON_HEADER } from '../../common/constants'; interface IConstructorDependencies { config: ConfigType; @@ -25,7 +26,7 @@ interface IRequestParams { hasValidData?: (body?: ResponseBody) => boolean; } export interface IEnterpriseSearchRequestHandler { - createRequest(requestParams?: object): RequestHandler, unknown>; + createRequest(requestParams?: object): RequestHandler; } /** @@ -52,12 +53,12 @@ export class EnterpriseSearchRequestHandler { }: IRequestParams) { return async ( _context: RequestHandlerContext, - request: KibanaRequest, unknown>, + request: KibanaRequest, response: KibanaResponseFactory ) => { try { // Set up API URL - const queryParams = { ...request.query, ...params }; + const queryParams = { ...(request.query as object), ...params }; const queryString = !this.isEmptyObj(queryParams) ? `?${querystring.stringify(queryParams)}` : ''; @@ -65,7 +66,7 @@ export class EnterpriseSearchRequestHandler { // Set up API options const { method } = request.route; - const headers = { Authorization: request.headers.authorization as string }; + const headers = { Authorization: request.headers.authorization as string, ...JSON_HEADER }; const body = !this.isEmptyObj(request.body as object) ? JSON.stringify(request.body) : undefined; @@ -73,7 +74,7 @@ export class EnterpriseSearchRequestHandler { // Call the Enterprise Search API and pass back response to the front-end const apiResponse = await fetch(url, { method, headers, body }); - if (apiResponse.url.endsWith('/login')) { + if (apiResponse.url.endsWith('/login') || apiResponse.url.endsWith('/ent/select')) { throw new Error('Cannot authenticate Enterprise Search user'); } diff --git a/x-pack/plugins/enterprise_search/server/plugin.ts b/x-pack/plugins/enterprise_search/server/plugin.ts index 617210a544262..729a03d24065e 100644 --- a/x-pack/plugins/enterprise_search/server/plugin.ts +++ b/x-pack/plugins/enterprise_search/server/plugin.ts @@ -31,8 +31,10 @@ import { IEnterpriseSearchRequestHandler, } from './lib/enterprise_search_request_handler'; -import { registerConfigDataRoute } from './routes/enterprise_search/config_data'; +import { enterpriseSearchTelemetryType } from './saved_objects/enterprise_search/telemetry'; +import { registerTelemetryUsageCollector as registerESTelemetryUsageCollector } from './collectors/enterprise_search/telemetry'; import { registerTelemetryRoute } from './routes/enterprise_search/telemetry'; +import { registerConfigDataRoute } from './routes/enterprise_search/config_data'; import { appSearchTelemetryType } from './saved_objects/app_search/telemetry'; import { registerTelemetryUsageCollector as registerASTelemetryUsageCollector } from './collectors/app_search/telemetry'; @@ -81,8 +83,12 @@ export class EnterpriseSearchPlugin implements Plugin { name: ENTERPRISE_SEARCH_PLUGIN.NAME, order: 0, icon: 'logoEnterpriseSearch', - navLinkId: APP_SEARCH_PLUGIN.ID, // TODO - remove this once functional tests no longer rely on navLinkId - app: ['kibana', APP_SEARCH_PLUGIN.ID, WORKPLACE_SEARCH_PLUGIN.ID], + app: [ + 'kibana', + ENTERPRISE_SEARCH_PLUGIN.ID, + APP_SEARCH_PLUGIN.ID, + WORKPLACE_SEARCH_PLUGIN.ID, + ], catalogue: [ENTERPRISE_SEARCH_PLUGIN.ID, APP_SEARCH_PLUGIN.ID, WORKPLACE_SEARCH_PLUGIN.ID], privileges: null, }); @@ -94,14 +100,16 @@ export class EnterpriseSearchPlugin implements Plugin { const dependencies = { config, security, request, log }; const { hasAppSearchAccess, hasWorkplaceSearchAccess } = await checkAccess(dependencies); + const showEnterpriseSearchOverview = hasAppSearchAccess || hasWorkplaceSearchAccess; return { navLinks: { + enterpriseSearch: showEnterpriseSearchOverview, appSearch: hasAppSearchAccess, workplaceSearch: hasWorkplaceSearchAccess, }, catalogue: { - enterpriseSearch: hasAppSearchAccess || hasWorkplaceSearchAccess, + enterpriseSearch: showEnterpriseSearchOverview, appSearch: hasAppSearchAccess, workplaceSearch: hasWorkplaceSearchAccess, }, @@ -123,6 +131,7 @@ export class EnterpriseSearchPlugin implements Plugin { /** * Bootstrap the routes, saved objects, and collector for telemetry */ + savedObjects.registerType(enterpriseSearchTelemetryType); savedObjects.registerType(appSearchTelemetryType); savedObjects.registerType(workplaceSearchTelemetryType); let savedObjectsStarted: SavedObjectsServiceStart; @@ -131,6 +140,7 @@ export class EnterpriseSearchPlugin implements Plugin { savedObjectsStarted = coreStart.savedObjects; if (usageCollection) { + registerESTelemetryUsageCollector(usageCollection, savedObjectsStarted, this.logger); registerASTelemetryUsageCollector(usageCollection, savedObjectsStarted, this.logger); registerWSTelemetryUsageCollector(usageCollection, savedObjectsStarted, this.logger); } diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.ts index 7ed1d7b17753c..bfc07c8b64ef5 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.ts @@ -9,12 +9,13 @@ import { schema } from '@kbn/config-schema'; import { IRouteDependencies } from '../../plugin'; import { incrementUICounter } from '../../collectors/lib/telemetry'; +import { ES_TELEMETRY_NAME } from '../../collectors/enterprise_search/telemetry'; import { AS_TELEMETRY_NAME } from '../../collectors/app_search/telemetry'; import { WS_TELEMETRY_NAME } from '../../collectors/workplace_search/telemetry'; const productToTelemetryMap = { + enterprise_search: ES_TELEMETRY_NAME, app_search: AS_TELEMETRY_NAME, workplace_search: WS_TELEMETRY_NAME, - enterprise_search: 'TODO', }; export function registerTelemetryRoute({ diff --git a/x-pack/plugins/enterprise_search/server/saved_objects/enterprise_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/saved_objects/enterprise_search/telemetry.ts new file mode 100644 index 0000000000000..54044e67939da --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/saved_objects/enterprise_search/telemetry.ts @@ -0,0 +1,19 @@ +/* + * 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. + */ +/* istanbul ignore file */ + +import { SavedObjectsType } from 'src/core/server'; +import { ES_TELEMETRY_NAME } from '../../collectors/enterprise_search/telemetry'; + +export const enterpriseSearchTelemetryType: SavedObjectsType = { + name: ES_TELEMETRY_NAME, + hidden: false, + namespaceType: 'agnostic', + mappings: { + dynamic: false, + properties: {}, + }, +}; diff --git a/x-pack/plugins/features/server/__snapshots__/oss_features.test.ts.snap b/x-pack/plugins/features/server/__snapshots__/oss_features.test.ts.snap index e4014cf49778c..63a59d59d6d07 100644 --- a/x-pack/plugins/features/server/__snapshots__/oss_features.test.ts.snap +++ b/x-pack/plugins/features/server/__snapshots__/oss_features.test.ts.snap @@ -111,6 +111,7 @@ Array [ "visualization", "timelion-sheet", "canvas-workpad", + "lens", "map", "dashboard", "query", diff --git a/x-pack/plugins/features/server/oss_features.ts b/x-pack/plugins/features/server/oss_features.ts index e37c7491de5dc..4122c590e74b1 100644 --- a/x-pack/plugins/features/server/oss_features.ts +++ b/x-pack/plugins/features/server/oss_features.ts @@ -172,6 +172,7 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS 'visualization', 'timelion-sheet', 'canvas-workpad', + 'lens', 'map', 'dashboard', 'query', diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation.tsx index 6f80afccbff5e..6a22d8716514c 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/node_allocation.tsx @@ -52,7 +52,7 @@ export const NodeAllocation = ({ phaseData, isShowingErrors, }: React.PropsWithChildren>) => { - const { isLoading, data: nodes, error, sendRequest } = useLoadNodes(); + const { isLoading, data: nodes, error, resendRequest } = useLoadNodes(); const [selectedNodeAttrsForDetails, setSelectedNodeAttrsForDetails] = useState( null @@ -84,7 +84,7 @@ export const NodeAllocation = ({

{message} ({statusCode})

- + = ({ close, selectedNodeAttrs }) => { - const { data, isLoading, error, sendRequest } = useLoadNodeDetails(selectedNodeAttrs); + const { data, isLoading, error, resendRequest } = useLoadNodeDetails(selectedNodeAttrs); let content; if (isLoading) { content = ; @@ -47,7 +47,7 @@ export const NodeAttrsDetails: React.FunctionComponent = ({ close, select

{message} ({statusCode})

- + = ({ onChange, getUrlForApp, }) => { - const { error, isLoading, data, sendRequest } = useLoadSnapshotPolicies(); + const { error, isLoading, data, resendRequest } = useLoadSnapshotPolicies(); const policies = data.map((name: string) => ({ label: name, @@ -75,7 +75,7 @@ export const SnapshotPolicies: React.FunctionComponent = ({ { - const { error, isLoading, data: policies, sendRequest } = useLoadPoliciesList(false); + const { error, isLoading, data: policies, resendRequest } = useLoadPoliciesList(false); if (isLoading) { return ( } actions={ - + = navigateToApp, history, }) => { - const { data: policies, isLoading, error, sendRequest } = useLoadPoliciesList(true); + const { data: policies, isLoading, error, resendRequest } = useLoadPoliciesList(true); if (isLoading) { return ( @@ -53,7 +53,7 @@ export const PolicyTable: React.FunctionComponent =

} actions={ - + = policies={policies || []} history={history} navigateToApp={navigateToApp} - updatePolicies={sendRequest} + updatePolicies={resendRequest} /> ); }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx index 8ba7409a9ac57..05f7f53969ded 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx @@ -42,7 +42,7 @@ export const ComponentTemplateList: React.FunctionComponent = ({ } = useGlobalFlyout(); const { api, trackMetric, documentation } = useComponentTemplatesContext(); - const { data, isLoading, error, sendRequest } = api.useLoadComponentTemplates(); + const { data, isLoading, error, resendRequest } = api.useLoadComponentTemplates(); const [componentTemplatesToDelete, setComponentTemplatesToDelete] = useState([]); @@ -170,7 +170,7 @@ export const ComponentTemplateList: React.FunctionComponent = ({ = ({ } else if (data && data.length === 0) { content = ; } else if (error) { - content = ; + content = ; } return ( @@ -194,7 +194,7 @@ export const ComponentTemplateList: React.FunctionComponent = ({ callback={(deleteResponse) => { if (deleteResponse?.hasDeletedComponentTemplates) { // refetch the component templates - sendRequest(); + resendRequest(); // go back to list view (if deleted from details flyout) goToComponentTemplateList(); } diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts index a9f6d2ea03bdf..6882ddea4ad5d 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts @@ -24,7 +24,7 @@ export interface DataTypeDefinition { export interface ParameterDefinition { title?: string; description?: JSX.Element | string; - fieldConfig: FieldConfig; + fieldConfig: FieldConfig; schema?: any; props?: { [key: string]: ParameterDefinition }; documentation?: { diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx index d37576f18e849..4f2a5c4a27b7a 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx @@ -49,7 +49,7 @@ export const DataStreamList: React.FunctionComponent {}; + reload: UseRequestResponse['resendRequest']; history: ScopedHistory; includeStats: boolean; filters?: string; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_table/template_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_table/template_table.tsx index 9203e76fce787..7ec6f1f94a2ab 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_table/template_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_table/template_table.tsx @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiInMemoryTable, EuiButton, EuiLink, EuiBasicTableColumn } from '@elastic/eui'; import { ScopedHistory } from 'kibana/public'; -import { SendRequestResponse, reactRouterNavigate } from '../../../../../../shared_imports'; +import { UseRequestResponse, reactRouterNavigate } from '../../../../../../shared_imports'; import { TemplateListItem } from '../../../../../../../common'; import { UIM_TEMPLATE_SHOW_DETAILS_CLICK } from '../../../../../../../common/constants'; import { TemplateDeleteModal } from '../../../../../components'; @@ -20,7 +20,7 @@ import { TemplateTypeIndicator } from '../../components'; interface Props { templates: TemplateListItem[]; - reload: () => Promise; + reload: UseRequestResponse['resendRequest']; editTemplate: (name: string, isLegacy?: boolean) => void; cloneTemplate: (name: string, isLegacy?: boolean) => void; history: ScopedHistory; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx index 5bacffc4c2404..94891297c857e 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details_content.tsx @@ -31,7 +31,7 @@ import { UIM_TEMPLATE_DETAIL_PANEL_ALIASES_TAB, UIM_TEMPLATE_DETAIL_PANEL_PREVIEW_TAB, } from '../../../../../../common/constants'; -import { SendRequestResponse } from '../../../../../shared_imports'; +import { UseRequestResponse } from '../../../../../shared_imports'; import { TemplateDeleteModal, SectionLoading, SectionError, Error } from '../../../../components'; import { useLoadIndexTemplate } from '../../../../services/api'; import { decodePathFromReactRouter } from '../../../../services/routing'; @@ -92,7 +92,7 @@ export interface Props { onClose: () => void; editTemplate: (name: string, isLegacy?: boolean) => void; cloneTemplate: (name: string, isLegacy?: boolean) => void; - reload: () => Promise; + reload: UseRequestResponse['resendRequest']; } export const TemplateDetailsContent = ({ diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx index f421bc5d87a54..c711f457123fb 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx @@ -59,7 +59,7 @@ export const TemplateList: React.FunctionComponent { const { uiMetricService } = useServices(); - const { error, isLoading, data: allTemplates, sendRequest: reload } = useLoadIndexTemplates(); + const { error, isLoading, data: allTemplates, resendRequest: reload } = useLoadIndexTemplates(); const [filters, setFilters] = useState>({ managed: { diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx index 3dffdcde160f1..c32fd29cf9f92 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx @@ -12,7 +12,7 @@ import { ScopedHistory } from 'kibana/public'; import { TemplateListItem } from '../../../../../../common'; import { UIM_TEMPLATE_SHOW_DETAILS_CLICK } from '../../../../../../common/constants'; -import { SendRequestResponse, reactRouterNavigate } from '../../../../../shared_imports'; +import { UseRequestResponse, reactRouterNavigate } from '../../../../../shared_imports'; import { encodePathForReactRouter } from '../../../../services/routing'; import { useServices } from '../../../../app_context'; import { TemplateDeleteModal } from '../../../../components'; @@ -21,7 +21,7 @@ import { TemplateTypeIndicator } from '../components'; interface Props { templates: TemplateListItem[]; - reload: () => Promise; + reload: UseRequestResponse['resendRequest']; editTemplate: (name: string) => void; cloneTemplate: (name: string) => void; history: ScopedHistory; diff --git a/x-pack/plugins/index_management/public/shared_imports.ts b/x-pack/plugins/index_management/public/shared_imports.ts index f7f992a090501..d58545768732e 100644 --- a/x-pack/plugins/index_management/public/shared_imports.ts +++ b/x-pack/plugins/index_management/public/shared_imports.ts @@ -8,6 +8,7 @@ export { SendRequestConfig, SendRequestResponse, UseRequestConfig, + UseRequestResponse, sendRequest, useRequest, Forms, diff --git a/x-pack/plugins/infra/common/http_api/index.ts b/x-pack/plugins/infra/common/http_api/index.ts index 818009417fb1c..4c729d11ba8c1 100644 --- a/x-pack/plugins/infra/common/http_api/index.ts +++ b/x-pack/plugins/infra/common/http_api/index.ts @@ -10,3 +10,4 @@ export * from './log_entries'; export * from './metrics_explorer'; export * from './metrics_api'; export * from './log_alerts'; +export * from './snapshot_api'; diff --git a/x-pack/plugins/infra/common/http_api/metrics_api.ts b/x-pack/plugins/infra/common/http_api/metrics_api.ts index 7436566f039ca..41657fdce2153 100644 --- a/x-pack/plugins/infra/common/http_api/metrics_api.ts +++ b/x-pack/plugins/infra/common/http_api/metrics_api.ts @@ -33,7 +33,6 @@ export const MetricsAPIRequestRT = rt.intersection([ afterKey: rt.union([rt.null, afterKeyObjectRT]), limit: rt.union([rt.number, rt.null, rt.undefined]), filters: rt.array(rt.object), - forceInterval: rt.boolean, dropLastBucket: rt.boolean, alignDataToEnd: rt.boolean, }), @@ -59,7 +58,10 @@ export const MetricsAPIRowRT = rt.intersection([ rt.type({ timestamp: rt.number, }), - rt.record(rt.string, rt.union([rt.string, rt.number, rt.null, rt.undefined])), + rt.record( + rt.string, + rt.union([rt.string, rt.number, rt.null, rt.undefined, rt.array(rt.object)]) + ), ]); export const MetricsAPISeriesRT = rt.intersection([ diff --git a/x-pack/plugins/infra/common/http_api/metrics_explorer.ts b/x-pack/plugins/infra/common/http_api/metrics_explorer.ts index c5776e0b0ced1..460b2bf9d802e 100644 --- a/x-pack/plugins/infra/common/http_api/metrics_explorer.ts +++ b/x-pack/plugins/infra/common/http_api/metrics_explorer.ts @@ -89,7 +89,10 @@ export const metricsExplorerRowRT = rt.intersection([ rt.type({ timestamp: rt.number, }), - rt.record(rt.string, rt.union([rt.string, rt.number, rt.null, rt.undefined])), + rt.record( + rt.string, + rt.union([rt.string, rt.number, rt.null, rt.undefined, rt.array(rt.object)]) + ), ]); export const metricsExplorerSeriesRT = rt.intersection([ diff --git a/x-pack/plugins/infra/common/http_api/snapshot_api.ts b/x-pack/plugins/infra/common/http_api/snapshot_api.ts index 11cb57238f917..e1b8dfa4770ba 100644 --- a/x-pack/plugins/infra/common/http_api/snapshot_api.ts +++ b/x-pack/plugins/infra/common/http_api/snapshot_api.ts @@ -6,7 +6,7 @@ import * as rt from 'io-ts'; import { SnapshotMetricTypeRT, ItemTypeRT } from '../inventory_models/types'; -import { metricsExplorerSeriesRT } from './metrics_explorer'; +import { MetricsAPISeriesRT } from './metrics_api'; export const SnapshotNodePathRT = rt.intersection([ rt.type({ @@ -22,7 +22,7 @@ const SnapshotNodeMetricOptionalRT = rt.partial({ value: rt.union([rt.number, rt.null]), avg: rt.union([rt.number, rt.null]), max: rt.union([rt.number, rt.null]), - timeseries: metricsExplorerSeriesRT, + timeseries: MetricsAPISeriesRT, }); const SnapshotNodeMetricRequiredRT = rt.type({ @@ -36,6 +36,7 @@ export const SnapshotNodeMetricRT = rt.intersection([ export const SnapshotNodeRT = rt.type({ metrics: rt.array(SnapshotNodeMetricRT), path: rt.array(SnapshotNodePathRT), + name: rt.string, }); export const SnapshotNodeResponseRT = rt.type({ diff --git a/x-pack/plugins/infra/common/inventory_models/types.ts b/x-pack/plugins/infra/common/inventory_models/types.ts index 570220bbc7aa5..851646ef1fa12 100644 --- a/x-pack/plugins/infra/common/inventory_models/types.ts +++ b/x-pack/plugins/infra/common/inventory_models/types.ts @@ -281,6 +281,10 @@ export const ESSumBucketAggRT = rt.type({ }), }); +export const ESTopHitsAggRT = rt.type({ + top_hits: rt.object, +}); + interface SnapshotTermsWithAggregation { terms: { field: string }; aggregations: MetricsUIAggregation; @@ -304,6 +308,7 @@ export const ESAggregationRT = rt.union([ ESSumBucketAggRT, ESTermsWithAggregationRT, ESCaridnalityAggRT, + ESTopHitsAggRT, ]); export const MetricsUIAggregationRT = rt.record(rt.string, ESAggregationRT); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/conditional_tooltip.test.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/conditional_tooltip.test.tsx index d2c30a4f38ee9..e01ca3ab6e844 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/conditional_tooltip.test.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/conditional_tooltip.test.tsx @@ -88,6 +88,7 @@ describe('ConditionalToolTip', () => { mockedUseSnapshot.mockReturnValue({ nodes: [ { + name: 'host-01', path: [{ label: 'host-01', value: 'host-01', ip: '192.168.1.10' }], metrics: [ { name: 'cpu', value: 0.1, avg: 0.4, max: 0.7 }, diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/calculate_bounds_from_nodes.test.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/calculate_bounds_from_nodes.test.ts index fbb6aa933219a..49f4b56532936 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/calculate_bounds_from_nodes.test.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/calculate_bounds_from_nodes.test.ts @@ -7,6 +7,7 @@ import { calculateBoundsFromNodes } from './calculate_bounds_from_nodes'; import { SnapshotNode } from '../../../../../common/http_api/snapshot_api'; const nodes: SnapshotNode[] = [ { + name: 'host-01', path: [{ value: 'host-01', label: 'host-01' }], metrics: [ { @@ -18,6 +19,7 @@ const nodes: SnapshotNode[] = [ ], }, { + name: 'host-02', path: [{ value: 'host-02', label: 'host-02' }], metrics: [ { diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/sort_nodes.test.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/sort_nodes.test.ts index 2a9f8b911c124..f7d9f029f00df 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/sort_nodes.test.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/sort_nodes.test.ts @@ -9,6 +9,7 @@ import { SnapshotNode } from '../../../../../common/http_api/snapshot_api'; const nodes: SnapshotNode[] = [ { + name: 'host-01', path: [{ value: 'host-01', label: 'host-01' }], metrics: [ { @@ -20,6 +21,7 @@ const nodes: SnapshotNode[] = [ ], }, { + name: 'host-02', path: [{ value: 'host-02', label: 'host-02' }], metrics: [ { diff --git a/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts b/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts index 939498305eb98..c5b667fb20538 100644 --- a/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts +++ b/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts @@ -8,12 +8,12 @@ import { timeMilliseconds } from 'd3-time'; import * as runtimeTypes from 'io-ts'; -import { compact, first, get, has } from 'lodash'; +import { compact, first } from 'lodash'; import { pipe } from 'fp-ts/lib/pipeable'; import { map, fold } from 'fp-ts/lib/Either'; import { identity, constant } from 'fp-ts/lib/function'; import { RequestHandlerContext } from 'src/core/server'; -import { JsonObject, JsonValue } from '../../../../common/typed_json'; +import { JsonValue } from '../../../../common/typed_json'; import { LogEntriesAdapter, LogEntriesParams, @@ -31,7 +31,7 @@ const TIMESTAMP_FORMAT = 'epoch_millis'; interface LogItemHit { _index: string; _id: string; - _source: JsonObject; + fields: { [key: string]: [value: unknown] }; sort: [number, number]; } @@ -82,7 +82,8 @@ export class InfraKibanaLogEntriesAdapter implements LogEntriesAdapter { body: { size: typeof size !== 'undefined' ? size : LOG_ENTRIES_PAGE_SIZE, track_total_hits: false, - _source: fields, + _source: false, + fields, query: { bool: { filter: [ @@ -214,6 +215,8 @@ export class InfraKibanaLogEntriesAdapter implements LogEntriesAdapter { values: [id], }, }, + fields: ['*'], + _source: false, }, }; @@ -230,8 +233,8 @@ function mapHitsToLogEntryDocuments(hits: SortedSearchHit[], fields: string[]): return hits.map((hit) => { const logFields = fields.reduce<{ [fieldName: string]: JsonValue }>( (flattenedFields, field) => { - if (has(hit._source, field)) { - flattenedFields[field] = get(hit._source, field); + if (field in hit.fields) { + flattenedFields[field] = hit.fields[field][0]; } return flattenedFields; }, diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts index 2f3593a11f664..d6592719d0723 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts @@ -16,12 +16,11 @@ import { } from '../../adapters/framework/adapter_types'; import { Comparator, InventoryMetricConditions } from './types'; import { AlertServices } from '../../../../../alerts/server'; -import { InfraSnapshot } from '../../snapshot'; -import { parseFilterQuery } from '../../../utils/serialized_query'; import { InventoryItemType, SnapshotMetricType } from '../../../../common/inventory_models/types'; -import { InfraTimerangeInput } from '../../../../common/http_api/snapshot_api'; -import { InfraSourceConfiguration } from '../../sources'; +import { InfraTimerangeInput, SnapshotRequest } from '../../../../common/http_api/snapshot_api'; +import { InfraSource } from '../../sources'; import { UNGROUPED_FACTORY_KEY } from '../common/utils'; +import { getNodes } from '../../../routes/snapshot/lib/get_nodes'; type ConditionResult = InventoryMetricConditions & { shouldFire: boolean[]; @@ -33,7 +32,7 @@ type ConditionResult = InventoryMetricConditions & { export const evaluateCondition = async ( condition: InventoryMetricConditions, nodeType: InventoryItemType, - sourceConfiguration: InfraSourceConfiguration, + source: InfraSource, callCluster: AlertServices['callCluster'], filterQuery?: string, lookbackSize?: number @@ -55,7 +54,7 @@ export const evaluateCondition = async ( nodeType, metric, timerange, - sourceConfiguration, + source, filterQuery, customMetric ); @@ -94,12 +93,11 @@ const getData = async ( nodeType: InventoryItemType, metric: SnapshotMetricType, timerange: InfraTimerangeInput, - sourceConfiguration: InfraSourceConfiguration, + source: InfraSource, filterQuery?: string, customMetric?: SnapshotCustomMetricInput ) => { - const snapshot = new InfraSnapshot(); - const esClient = ( + const client = ( options: CallWithRequestParams ): Promise> => callCluster('search', options); @@ -107,17 +105,17 @@ const getData = async ( metric === 'custom' ? (customMetric as SnapshotCustomMetricInput) : { type: metric }, ]; - const options = { - filterQuery: parseFilterQuery(filterQuery), + const snapshotRequest: SnapshotRequest = { + filterQuery, nodeType, groupBy: [], - sourceConfiguration, + sourceId: 'default', metrics, timerange, includeTimeseries: Boolean(timerange.lookbackSize), }; try { - const { nodes } = await snapshot.getNodes(esClient, options); + const { nodes } = await getNodes(client, snapshotRequest, source); if (!nodes.length) return { [UNGROUPED_FACTORY_KEY]: null }; // No Data state diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts index bdac9dcd1dee8..99904f15b4606 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts @@ -50,9 +50,7 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) = ); const results = await Promise.all( - criteria.map((c) => - evaluateCondition(c, nodeType, source.configuration, services.callCluster, filterQuery) - ) + criteria.map((c) => evaluateCondition(c, nodeType, source, services.callCluster, filterQuery)) ); const inventoryItems = Object.keys(first(results)!); diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/preview_inventory_metric_threshold_alert.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/preview_inventory_metric_threshold_alert.ts index 755c395818f5a..2ab015b6b37a2 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/preview_inventory_metric_threshold_alert.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/preview_inventory_metric_threshold_alert.ts @@ -26,7 +26,7 @@ interface InventoryMetricThresholdParams { interface PreviewInventoryMetricThresholdAlertParams { callCluster: ILegacyScopedClusterClient['callAsCurrentUser']; params: InventoryMetricThresholdParams; - config: InfraSource['configuration']; + source: InfraSource; lookback: Unit; alertInterval: string; } @@ -34,7 +34,7 @@ interface PreviewInventoryMetricThresholdAlertParams { export const previewInventoryMetricThresholdAlert = async ({ callCluster, params, - config, + source, lookback, alertInterval, }: PreviewInventoryMetricThresholdAlertParams) => { @@ -55,7 +55,7 @@ export const previewInventoryMetricThresholdAlert = async ({ try { const results = await Promise.all( criteria.map((c) => - evaluateCondition(c, nodeType, config, callCluster, filterQuery, lookbackSize) + evaluateCondition(c, nodeType, source, callCluster, filterQuery, lookbackSize) ) ); diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/metric_query.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/metric_query.ts index 078ca46d42e60..8696081043ff7 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/metric_query.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/metric_query.ts @@ -8,8 +8,8 @@ import { networkTraffic } from '../../../../../common/inventory_models/shared/me import { MetricExpressionParams, Aggregators } from '../types'; import { getIntervalInSeconds } from '../../../../utils/get_interval_in_seconds'; import { roundTimestamp } from '../../../../utils/round_timestamp'; -import { getDateHistogramOffset } from '../../../snapshot/query_helpers'; import { createPercentileAggregation } from './create_percentile_aggregation'; +import { calculateDateHistogramOffset } from '../../../metrics/lib/calculate_date_histogram_offset'; const MINIMUM_BUCKETS = 5; @@ -46,7 +46,7 @@ export const getElasticsearchMetricQuery = ( timeUnit ); - const offset = getDateHistogramOffset(from, interval); + const offset = calculateDateHistogramOffset({ from, to, interval, field: timefield }); const aggregations = aggType === Aggregators.COUNT diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts index 099e7c3b5038c..7c8560d72ff97 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts @@ -20,6 +20,11 @@ const serializeValue = (value: any): string => { } return `${value}`; }; +export const convertESFieldsToLogItemFields = (fields: { + [field: string]: [value: unknown]; +}): LogEntriesItemField[] => { + return Object.keys(fields).map((field) => ({ field, value: serializeValue(fields[field][0]) })); +}; export const convertDocumentSourceToLogItemFields = ( source: JsonObject, diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts index 9b3e31f4da87a..e211f72b4e076 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts @@ -22,7 +22,7 @@ import { SavedSourceConfigurationFieldColumnRuntimeType, } from '../../sources'; import { getBuiltinRules } from './builtin_rules'; -import { convertDocumentSourceToLogItemFields } from './convert_document_source_to_log_item_fields'; +import { convertESFieldsToLogItemFields } from './convert_document_source_to_log_item_fields'; import { CompiledLogMessageFormattingRule, Fields, @@ -264,7 +264,7 @@ export class InfraLogEntriesDomain { tiebreaker: document.sort[1], }, fields: sortBy( - [...defaultFields, ...convertDocumentSourceToLogItemFields(document._source)], + [...defaultFields, ...convertESFieldsToLogItemFields(document.fields)], 'field' ), }; @@ -313,7 +313,7 @@ export class InfraLogEntriesDomain { interface LogItemHit { _index: string; _id: string; - _source: JsonObject; + fields: { [field: string]: [value: unknown] }; sort: [number, number]; } diff --git a/x-pack/plugins/infra/server/lib/infra_types.ts b/x-pack/plugins/infra/server/lib/infra_types.ts index 9896ad6ac1cd1..084ece52302b0 100644 --- a/x-pack/plugins/infra/server/lib/infra_types.ts +++ b/x-pack/plugins/infra/server/lib/infra_types.ts @@ -8,7 +8,6 @@ import { InfraSourceConfiguration } from '../../common/graphql/types'; import { InfraFieldsDomain } from './domains/fields_domain'; import { InfraLogEntriesDomain } from './domains/log_entries_domain'; import { InfraMetricsDomain } from './domains/metrics_domain'; -import { InfraSnapshot } from './snapshot'; import { InfraSources } from './sources'; import { InfraSourceStatus } from './source_status'; import { InfraConfig } from '../plugin'; @@ -30,7 +29,6 @@ export interface InfraDomainLibs { export interface InfraBackendLibs extends InfraDomainLibs { configuration: InfraConfig; framework: KibanaFramework; - snapshot: InfraSnapshot; sources: InfraSources; sourceStatus: InfraSourceStatus; } diff --git a/x-pack/plugins/infra/server/lib/metrics/lib/__snapshots__/create_aggregations.test.ts.snap b/x-pack/plugins/infra/server/lib/metrics/lib/__snapshots__/create_aggregations.test.ts.snap index d2d90914eced5..2cbbc623aed38 100644 --- a/x-pack/plugins/infra/server/lib/metrics/lib/__snapshots__/create_aggregations.test.ts.snap +++ b/x-pack/plugins/infra/server/lib/metrics/lib/__snapshots__/create_aggregations.test.ts.snap @@ -53,7 +53,6 @@ Object { "groupBy0": Object { "terms": Object { "field": "host.name", - "order": "asc", }, }, }, diff --git a/x-pack/plugins/infra/server/lib/metrics/lib/convert_histogram_buckets_to_timeseries.ts b/x-pack/plugins/infra/server/lib/metrics/lib/convert_histogram_buckets_to_timeseries.ts index 95e6ece215133..90e584368e9ad 100644 --- a/x-pack/plugins/infra/server/lib/metrics/lib/convert_histogram_buckets_to_timeseries.ts +++ b/x-pack/plugins/infra/server/lib/metrics/lib/convert_histogram_buckets_to_timeseries.ts @@ -5,6 +5,7 @@ */ import { get, values, first } from 'lodash'; +import * as rt from 'io-ts'; import { MetricsAPIRequest, MetricsAPISeries, @@ -13,15 +14,20 @@ import { } from '../../../../common/http_api/metrics_api'; import { HistogramBucket, - MetricValueType, BasicMetricValueRT, NormalizedMetricValueRT, PercentilesTypeRT, PercentilesKeyedTypeRT, + TopHitsTypeRT, + MetricValueTypeRT, } from '../types'; + const BASE_COLUMNS = [{ name: 'timestamp', type: 'date' }] as MetricsAPIColumn[]; -const getValue = (valueObject: string | number | MetricValueType) => { +const ValueObjectTypeRT = rt.union([rt.string, rt.number, MetricValueTypeRT]); +type ValueObjectType = rt.TypeOf; + +const getValue = (valueObject: ValueObjectType) => { if (NormalizedMetricValueRT.is(valueObject)) { return valueObject.normalized_value || valueObject.value; } @@ -50,6 +56,10 @@ const getValue = (valueObject: string | number | MetricValueType) => { return valueObject.value; } + if (TopHitsTypeRT.is(valueObject)) { + return valueObject.hits.hits.map((hit) => hit._source); + } + return null; }; @@ -61,8 +71,8 @@ const convertBucketsToRows = ( const ids = options.metrics.map((metric) => metric.id); const metrics = ids.reduce((acc, id) => { const valueObject = get(bucket, [id]); - return { ...acc, [id]: getValue(valueObject) }; - }, {} as Record); + return { ...acc, [id]: ValueObjectTypeRT.is(valueObject) ? getValue(valueObject) : null }; + }, {} as Record); return { timestamp: bucket.key as number, ...metrics }; }); }; diff --git a/x-pack/plugins/infra/server/lib/metrics/lib/create_aggregations.ts b/x-pack/plugins/infra/server/lib/metrics/lib/create_aggregations.ts index 991e5febfc634..63fdbb3d2b30f 100644 --- a/x-pack/plugins/infra/server/lib/metrics/lib/create_aggregations.ts +++ b/x-pack/plugins/infra/server/lib/metrics/lib/create_aggregations.ts @@ -33,7 +33,7 @@ export const createAggregations = (options: MetricsAPIRequest) => { composite: { size: limit, sources: options.groupBy.map((field, index) => ({ - [`groupBy${index}`]: { terms: { field, order: 'asc' } }, + [`groupBy${index}`]: { terms: { field } }, })), }, aggs: histogramAggregation, diff --git a/x-pack/plugins/infra/server/lib/metrics/types.ts b/x-pack/plugins/infra/server/lib/metrics/types.ts index d1866470e0cf9..8746614b559d6 100644 --- a/x-pack/plugins/infra/server/lib/metrics/types.ts +++ b/x-pack/plugins/infra/server/lib/metrics/types.ts @@ -25,17 +25,51 @@ export const PercentilesKeyedTypeRT = rt.type({ values: rt.array(rt.type({ key: rt.string, value: NumberOrNullRT })), }); +export const TopHitsTypeRT = rt.type({ + hits: rt.type({ + total: rt.type({ + value: rt.number, + relation: rt.string, + }), + hits: rt.array( + rt.intersection([ + rt.type({ + _index: rt.string, + _id: rt.string, + _score: NumberOrNullRT, + _source: rt.object, + }), + rt.partial({ + sort: rt.array(rt.union([rt.string, rt.number])), + max_score: NumberOrNullRT, + }), + ]) + ), + }), +}); + export const MetricValueTypeRT = rt.union([ BasicMetricValueRT, NormalizedMetricValueRT, PercentilesTypeRT, PercentilesKeyedTypeRT, + TopHitsTypeRT, ]); export type MetricValueType = rt.TypeOf; +export const TermsWithMetrics = rt.intersection([ + rt.type({ + buckets: rt.array(rt.record(rt.string, rt.union([rt.number, rt.string, MetricValueTypeRT]))), + }), + rt.partial({ + sum_other_doc_count: rt.number, + doc_count_error_upper_bound: rt.number, + }), +]); + export const HistogramBucketRT = rt.record( rt.string, - rt.union([rt.number, rt.string, MetricValueTypeRT]) + rt.union([rt.number, rt.string, MetricValueTypeRT, TermsWithMetrics]) ); export const HistogramResponseRT = rt.type({ diff --git a/x-pack/plugins/infra/server/lib/snapshot/query_helpers.ts b/x-pack/plugins/infra/server/lib/snapshot/query_helpers.ts deleted file mode 100644 index ca63043ba868e..0000000000000 --- a/x-pack/plugins/infra/server/lib/snapshot/query_helpers.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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 { i18n } from '@kbn/i18n'; -import { findInventoryModel, findInventoryFields } from '../../../common/inventory_models/index'; -import { InfraSnapshotRequestOptions } from './types'; -import { getIntervalInSeconds } from '../../utils/get_interval_in_seconds'; -import { - MetricsUIAggregation, - MetricsUIAggregationRT, - InventoryItemType, -} from '../../../common/inventory_models/types'; -import { - SnapshotMetricInput, - SnapshotCustomMetricInputRT, -} from '../../../common/http_api/snapshot_api'; -import { networkTraffic } from '../../../common/inventory_models/shared/metrics/snapshot/network_traffic'; - -interface GroupBySource { - [id: string]: { - terms: { - field: string | null | undefined; - missing_bucket?: boolean; - }; - }; -} - -export const getFieldByNodeType = (options: InfraSnapshotRequestOptions) => { - const inventoryFields = findInventoryFields(options.nodeType, options.sourceConfiguration.fields); - return inventoryFields.id; -}; - -export const getGroupedNodesSources = (options: InfraSnapshotRequestOptions) => { - const fields = findInventoryFields(options.nodeType, options.sourceConfiguration.fields); - const sources: GroupBySource[] = options.groupBy.map((gb) => { - return { [`${gb.field}`]: { terms: { field: gb.field } } }; - }); - sources.push({ - id: { - terms: { field: fields.id }, - }, - }); - sources.push({ - name: { terms: { field: fields.name, missing_bucket: true } }, - }); - return sources; -}; - -export const getMetricsSources = (options: InfraSnapshotRequestOptions) => { - const fields = findInventoryFields(options.nodeType, options.sourceConfiguration.fields); - return [{ id: { terms: { field: fields.id } } }]; -}; - -export const metricToAggregation = ( - nodeType: InventoryItemType, - metric: SnapshotMetricInput, - index: number -) => { - const inventoryModel = findInventoryModel(nodeType); - if (SnapshotCustomMetricInputRT.is(metric)) { - if (metric.aggregation === 'rate') { - return networkTraffic(`custom_${index}`, metric.field); - } - return { - [`custom_${index}`]: { - [metric.aggregation]: { - field: metric.field, - }, - }, - }; - } - return inventoryModel.metrics.snapshot?.[metric.type]; -}; - -export const getMetricsAggregations = ( - options: InfraSnapshotRequestOptions -): MetricsUIAggregation => { - const { metrics } = options; - return metrics.reduce((aggs, metric, index) => { - const aggregation = metricToAggregation(options.nodeType, metric, index); - if (!MetricsUIAggregationRT.is(aggregation)) { - throw new Error( - i18n.translate('xpack.infra.snapshot.missingSnapshotMetricError', { - defaultMessage: 'The aggregation for {metric} for {nodeType} is not available.', - values: { - nodeType: options.nodeType, - metric: metric.type, - }, - }) - ); - } - return { ...aggs, ...aggregation }; - }, {}); -}; - -export const getDateHistogramOffset = (from: number, interval: string): string => { - const fromInSeconds = Math.floor(from / 1000); - const bucketSizeInSeconds = getIntervalInSeconds(interval); - - // negative offset to align buckets with full intervals (e.g. minutes) - const offset = (fromInSeconds % bucketSizeInSeconds) - bucketSizeInSeconds; - return `${offset}s`; -}; diff --git a/x-pack/plugins/infra/server/lib/snapshot/response_helpers.test.ts b/x-pack/plugins/infra/server/lib/snapshot/response_helpers.test.ts deleted file mode 100644 index 74840afc157d2..0000000000000 --- a/x-pack/plugins/infra/server/lib/snapshot/response_helpers.test.ts +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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 { - isIPv4, - getIPFromBucket, - InfraSnapshotNodeGroupByBucket, - getMetricValueFromBucket, - InfraSnapshotMetricsBucket, -} from './response_helpers'; - -describe('InfraOps ResponseHelpers', () => { - describe('isIPv4', () => { - it('should return true for IPv4', () => { - expect(isIPv4('192.168.2.4')).toBe(true); - }); - it('should return false for anything else', () => { - expect(isIPv4('0:0:0:0:0:0:0:1')).toBe(false); - }); - }); - - describe('getIPFromBucket', () => { - it('should return IPv4 address', () => { - const bucket: InfraSnapshotNodeGroupByBucket = { - key: { - id: 'example-01', - name: 'example-01', - }, - ip: { - hits: { - total: { value: 1 }, - hits: [ - { - _index: 'metricbeat-2019-01-01', - _type: '_doc', - _id: '29392939', - _score: null, - sort: [], - _source: { - host: { - ip: ['2001:db8:85a3::8a2e:370:7334', '192.168.1.4'], - }, - }, - }, - ], - }, - }, - }; - expect(getIPFromBucket('host', bucket)).toBe('192.168.1.4'); - }); - it('should NOT return ipv6 address', () => { - const bucket: InfraSnapshotNodeGroupByBucket = { - key: { - id: 'example-01', - name: 'example-01', - }, - ip: { - hits: { - total: { value: 1 }, - hits: [ - { - _index: 'metricbeat-2019-01-01', - _type: '_doc', - _id: '29392939', - _score: null, - sort: [], - _source: { - host: { - ip: ['2001:db8:85a3::8a2e:370:7334'], - }, - }, - }, - ], - }, - }, - }; - expect(getIPFromBucket('host', bucket)).toBe(null); - }); - }); - - describe('getMetricValueFromBucket', () => { - it('should return the value of a bucket with data', () => { - expect(getMetricValueFromBucket('custom', testBucket, 1)).toBe(0.5); - }); - it('should return the normalized value of a bucket with data', () => { - expect(getMetricValueFromBucket('cpu', testNormalizedBucket, 1)).toBe(50); - }); - it('should return null for a bucket with no data', () => { - expect(getMetricValueFromBucket('custom', testEmptyBucket, 1)).toBe(null); - }); - }); -}); - -// Hack to get around TypeScript -const buckets = [ - { - key: 'a', - doc_count: 1, - custom_1: { - value: 0.5, - }, - }, - { - key: 'b', - doc_count: 1, - cpu: { - value: 0.5, - normalized_value: 50, - }, - }, - { - key: 'c', - doc_count: 0, - }, -] as InfraSnapshotMetricsBucket[]; -const [testBucket, testNormalizedBucket, testEmptyBucket] = buckets; diff --git a/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts b/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts deleted file mode 100644 index 2652e362b7eff..0000000000000 --- a/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts +++ /dev/null @@ -1,208 +0,0 @@ -/* - * 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 { isNumber, last, max, sum, get } from 'lodash'; -import moment from 'moment'; - -import { MetricsExplorerSeries } from '../../../common/http_api/metrics_explorer'; -import { getIntervalInSeconds } from '../../utils/get_interval_in_seconds'; -import { InfraSnapshotRequestOptions } from './types'; -import { findInventoryModel } from '../../../common/inventory_models'; -import { InventoryItemType, SnapshotMetricType } from '../../../common/inventory_models/types'; -import { SnapshotNodeMetric, SnapshotNodePath } from '../../../common/http_api/snapshot_api'; - -export interface InfraSnapshotNodeMetricsBucket { - key: { id: string }; - histogram: { - buckets: InfraSnapshotMetricsBucket[]; - }; -} - -// Jumping through TypeScript hoops here: -// We need an interface that has the known members 'key' and 'doc_count' and also -// an unknown number of members with unknown names but known format, containing the -// metrics. -// This union type is the only way I found to express this that TypeScript accepts. -export interface InfraSnapshotBucketWithKey { - key: string | number; - doc_count: number; -} - -export interface InfraSnapshotBucketWithValues { - [name: string]: { value: number; normalized_value?: number }; -} - -export type InfraSnapshotMetricsBucket = InfraSnapshotBucketWithKey & InfraSnapshotBucketWithValues; - -interface InfraSnapshotIpHit { - _index: string; - _type: string; - _id: string; - _score: number | null; - _source: { - host: { - ip: string[] | string; - }; - }; - sort: number[]; -} - -export interface InfraSnapshotNodeGroupByBucket { - key: { - id: string; - name: string; - [groupByField: string]: string; - }; - ip: { - hits: { - total: { value: number }; - hits: InfraSnapshotIpHit[]; - }; - }; -} - -export const isIPv4 = (subject: string) => /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/.test(subject); - -export const getIPFromBucket = ( - nodeType: InventoryItemType, - bucket: InfraSnapshotNodeGroupByBucket -): string | null => { - const inventoryModel = findInventoryModel(nodeType); - if (!inventoryModel.fields.ip) { - return null; - } - const ip = get(bucket, `ip.hits.hits[0]._source.${inventoryModel.fields.ip}`, null) as - | string[] - | null; - if (Array.isArray(ip)) { - return ip.find(isIPv4) || null; - } else if (typeof ip === 'string') { - return ip; - } - - return null; -}; - -export const getNodePath = ( - groupBucket: InfraSnapshotNodeGroupByBucket, - options: InfraSnapshotRequestOptions -): SnapshotNodePath[] => { - const node = groupBucket.key; - const path = options.groupBy.map((gb) => { - return { value: node[`${gb.field}`], label: node[`${gb.field}`] } as SnapshotNodePath; - }); - const ip = getIPFromBucket(options.nodeType, groupBucket); - path.push({ value: node.id, label: node.name || node.id, ip }); - return path; -}; - -interface NodeMetricsForLookup { - [nodeId: string]: InfraSnapshotMetricsBucket[]; -} - -export const getNodeMetricsForLookup = ( - metrics: InfraSnapshotNodeMetricsBucket[] -): NodeMetricsForLookup => { - return metrics.reduce((acc: NodeMetricsForLookup, metric) => { - acc[`${metric.key.id}`] = metric.histogram.buckets; - return acc; - }, {}); -}; - -// In the returned object, -// value contains the value from the last bucket spanning a full interval -// max and avg are calculated from all buckets returned for the timerange -export const getNodeMetrics = ( - nodeBuckets: InfraSnapshotMetricsBucket[], - options: InfraSnapshotRequestOptions -): SnapshotNodeMetric[] => { - if (!nodeBuckets) { - return options.metrics.map((metric) => ({ - name: metric.type, - value: null, - max: null, - avg: null, - })); - } - const lastBucket = findLastFullBucket(nodeBuckets, options); - if (!lastBucket) return []; - return options.metrics.map((metric, index) => { - const metricResult: SnapshotNodeMetric = { - name: metric.type, - value: getMetricValueFromBucket(metric.type, lastBucket, index), - max: calculateMax(nodeBuckets, metric.type, index), - avg: calculateAvg(nodeBuckets, metric.type, index), - }; - if (options.includeTimeseries) { - metricResult.timeseries = getTimeseriesData(nodeBuckets, metric.type, index); - } - return metricResult; - }); -}; - -const findLastFullBucket = ( - buckets: InfraSnapshotMetricsBucket[], - options: InfraSnapshotRequestOptions -) => { - const to = moment.utc(options.timerange.to); - const bucketSize = getIntervalInSeconds(options.timerange.interval); - return buckets.reduce((current, item) => { - const itemKey = isNumber(item.key) ? item.key : parseInt(item.key, 10); - const date = moment.utc(itemKey + bucketSize * 1000); - if (!date.isAfter(to) && item.doc_count > 0) { - return item; - } - return current; - }, last(buckets)); -}; - -export const getMetricValueFromBucket = ( - type: SnapshotMetricType, - bucket: InfraSnapshotMetricsBucket, - index: number -) => { - const key = type === 'custom' ? `custom_${index}` : type; - const metric = bucket[key]; - const value = metric && (metric.normalized_value || metric.value); - return isFinite(value) ? value : null; -}; - -function calculateMax( - buckets: InfraSnapshotMetricsBucket[], - type: SnapshotMetricType, - index: number -) { - return max(buckets.map((bucket) => getMetricValueFromBucket(type, bucket, index))) || 0; -} - -function calculateAvg( - buckets: InfraSnapshotMetricsBucket[], - type: SnapshotMetricType, - index: number -) { - return ( - sum(buckets.map((bucket) => getMetricValueFromBucket(type, bucket, index))) / buckets.length || - 0 - ); -} - -function getTimeseriesData( - buckets: InfraSnapshotMetricsBucket[], - type: SnapshotMetricType, - index: number -): MetricsExplorerSeries { - return { - id: type, - columns: [ - { name: 'timestamp', type: 'date' }, - { name: 'metric_0', type: 'number' }, - ], - rows: buckets.map((bucket) => ({ - timestamp: bucket.key as number, - metric_0: getMetricValueFromBucket(type, bucket, index), - })), - }; -} diff --git a/x-pack/plugins/infra/server/lib/snapshot/snapshot.ts b/x-pack/plugins/infra/server/lib/snapshot/snapshot.ts deleted file mode 100644 index 33d8e738a717e..0000000000000 --- a/x-pack/plugins/infra/server/lib/snapshot/snapshot.ts +++ /dev/null @@ -1,238 +0,0 @@ -/* - * 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 { InfraDatabaseSearchResponse, CallWithRequestParams } from '../adapters/framework'; - -import { JsonObject } from '../../../common/typed_json'; -import { SNAPSHOT_COMPOSITE_REQUEST_SIZE } from './constants'; -import { - getGroupedNodesSources, - getMetricsAggregations, - getMetricsSources, - getDateHistogramOffset, -} from './query_helpers'; -import { - getNodeMetrics, - getNodeMetricsForLookup, - getNodePath, - InfraSnapshotNodeGroupByBucket, - InfraSnapshotNodeMetricsBucket, -} from './response_helpers'; -import { getAllCompositeData } from '../../utils/get_all_composite_data'; -import { createAfterKeyHandler } from '../../utils/create_afterkey_handler'; -import { findInventoryModel } from '../../../common/inventory_models'; -import { InfraSnapshotRequestOptions } from './types'; -import { createTimeRangeWithInterval } from './create_timerange_with_interval'; -import { SnapshotNode } from '../../../common/http_api/snapshot_api'; - -type NamedSnapshotNode = SnapshotNode & { name: string }; - -export type ESSearchClient = ( - options: CallWithRequestParams -) => Promise>; -export class InfraSnapshot { - public async getNodes( - client: ESSearchClient, - options: InfraSnapshotRequestOptions - ): Promise<{ nodes: NamedSnapshotNode[]; interval: string }> { - // Both requestGroupedNodes and requestNodeMetrics may send several requests to elasticsearch - // in order to page through the results of their respective composite aggregations. - // Both chains of requests are supposed to run in parallel, and their results be merged - // when they have both been completed. - const timeRangeWithIntervalApplied = await createTimeRangeWithInterval(client, options); - const optionsWithTimerange = { ...options, timerange: timeRangeWithIntervalApplied }; - - const groupedNodesPromise = requestGroupedNodes(client, optionsWithTimerange); - const nodeMetricsPromise = requestNodeMetrics(client, optionsWithTimerange); - const [groupedNodeBuckets, nodeMetricBuckets] = await Promise.all([ - groupedNodesPromise, - nodeMetricsPromise, - ]); - return { - nodes: mergeNodeBuckets(groupedNodeBuckets, nodeMetricBuckets, options), - interval: timeRangeWithIntervalApplied.interval, - }; - } -} - -const bucketSelector = ( - response: InfraDatabaseSearchResponse<{}, InfraSnapshotAggregationResponse> -) => (response.aggregations && response.aggregations.nodes.buckets) || []; - -const handleAfterKey = createAfterKeyHandler( - 'body.aggregations.nodes.composite.after', - (input) => input?.aggregations?.nodes?.after_key -); - -const callClusterFactory = (search: ESSearchClient) => (opts: any) => - search<{}, InfraSnapshotAggregationResponse>(opts); - -const requestGroupedNodes = async ( - client: ESSearchClient, - options: InfraSnapshotRequestOptions -): Promise => { - const inventoryModel = findInventoryModel(options.nodeType); - const query = { - allowNoIndices: true, - index: `${options.sourceConfiguration.logAlias},${options.sourceConfiguration.metricAlias}`, - ignoreUnavailable: true, - body: { - query: { - bool: { - filter: buildFilters(options), - }, - }, - size: 0, - aggregations: { - nodes: { - composite: { - size: options.overrideCompositeSize || SNAPSHOT_COMPOSITE_REQUEST_SIZE, - sources: getGroupedNodesSources(options), - }, - aggs: { - ip: { - top_hits: { - sort: [{ [options.sourceConfiguration.fields.timestamp]: { order: 'desc' } }], - _source: { - includes: inventoryModel.fields.ip ? [inventoryModel.fields.ip] : [], - }, - size: 1, - }, - }, - }, - }, - }, - }, - }; - return getAllCompositeData( - callClusterFactory(client), - query, - bucketSelector, - handleAfterKey - ); -}; - -const calculateIndexPatterBasedOnMetrics = (options: InfraSnapshotRequestOptions) => { - const { metrics } = options; - if (metrics.every((m) => m.type === 'logRate')) { - return options.sourceConfiguration.logAlias; - } - if (metrics.some((m) => m.type === 'logRate')) { - return `${options.sourceConfiguration.logAlias},${options.sourceConfiguration.metricAlias}`; - } - return options.sourceConfiguration.metricAlias; -}; - -const requestNodeMetrics = async ( - client: ESSearchClient, - options: InfraSnapshotRequestOptions -): Promise => { - const index = calculateIndexPatterBasedOnMetrics(options); - const query = { - allowNoIndices: true, - index, - ignoreUnavailable: true, - body: { - query: { - bool: { - filter: buildFilters(options, false), - }, - }, - size: 0, - aggregations: { - nodes: { - composite: { - size: options.overrideCompositeSize || SNAPSHOT_COMPOSITE_REQUEST_SIZE, - sources: getMetricsSources(options), - }, - aggregations: { - histogram: { - date_histogram: { - field: options.sourceConfiguration.fields.timestamp, - interval: options.timerange.interval || '1m', - offset: getDateHistogramOffset(options.timerange.from, options.timerange.interval), - extended_bounds: { - min: options.timerange.from, - max: options.timerange.to, - }, - }, - aggregations: getMetricsAggregations(options), - }, - }, - }, - }, - }, - }; - return getAllCompositeData( - callClusterFactory(client), - query, - bucketSelector, - handleAfterKey - ); -}; - -// buckets can be InfraSnapshotNodeGroupByBucket[] or InfraSnapshotNodeMetricsBucket[] -// but typing this in a way that makes TypeScript happy is unreadable (if possible at all) -interface InfraSnapshotAggregationResponse { - nodes: { - buckets: any[]; - after_key: { [id: string]: string }; - }; -} - -const mergeNodeBuckets = ( - nodeGroupByBuckets: InfraSnapshotNodeGroupByBucket[], - nodeMetricsBuckets: InfraSnapshotNodeMetricsBucket[], - options: InfraSnapshotRequestOptions -): NamedSnapshotNode[] => { - const nodeMetricsForLookup = getNodeMetricsForLookup(nodeMetricsBuckets); - - return nodeGroupByBuckets.map((node) => { - return { - name: node.key.name || node.key.id, // For type safety; name can be derived from getNodePath but not in a TS-friendly way - path: getNodePath(node, options), - metrics: getNodeMetrics(nodeMetricsForLookup[node.key.id], options), - }; - }); -}; - -const createQueryFilterClauses = (filterQuery: JsonObject | undefined) => - filterQuery ? [filterQuery] : []; - -const buildFilters = (options: InfraSnapshotRequestOptions, withQuery = true) => { - let filters: any = [ - { - range: { - [options.sourceConfiguration.fields.timestamp]: { - gte: options.timerange.from, - lte: options.timerange.to, - format: 'epoch_millis', - }, - }, - }, - ]; - - if (withQuery) { - filters = [...createQueryFilterClauses(options.filterQuery), ...filters]; - } - - if (options.accountId) { - filters.push({ - term: { - 'cloud.account.id': options.accountId, - }, - }); - } - - if (options.region) { - filters.push({ - term: { - 'cloud.region': options.region, - }, - }); - } - - return filters; -}; diff --git a/x-pack/plugins/infra/server/lib/snapshot/types.ts b/x-pack/plugins/infra/server/lib/snapshot/types.ts deleted file mode 100644 index 7e17cb91c6a59..0000000000000 --- a/x-pack/plugins/infra/server/lib/snapshot/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * 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 { JsonObject } from '../../../common/typed_json'; -import { InfraSourceConfiguration } from '../../../common/graphql/types'; -import { SnapshotRequest } from '../../../common/http_api/snapshot_api'; - -export interface InfraSnapshotRequestOptions - extends Omit { - sourceConfiguration: InfraSourceConfiguration; - filterQuery: JsonObject | undefined; -} diff --git a/x-pack/plugins/infra/server/lib/sources/has_data.ts b/x-pack/plugins/infra/server/lib/sources/has_data.ts index 79b1375059dcb..53297640e541d 100644 --- a/x-pack/plugins/infra/server/lib/sources/has_data.ts +++ b/x-pack/plugins/infra/server/lib/sources/has_data.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ESSearchClient } from '../snapshot'; +import { ESSearchClient } from '../metrics/types'; export const hasData = async (index: string, client: ESSearchClient) => { const params = { diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts index 51f91d7189db7..90b73b9a7585a 100644 --- a/x-pack/plugins/infra/server/plugin.ts +++ b/x-pack/plugins/infra/server/plugin.ts @@ -19,7 +19,6 @@ import { InfraElasticsearchSourceStatusAdapter } from './lib/adapters/source_sta import { InfraFieldsDomain } from './lib/domains/fields_domain'; import { InfraLogEntriesDomain } from './lib/domains/log_entries_domain'; import { InfraMetricsDomain } from './lib/domains/metrics_domain'; -import { InfraSnapshot } from './lib/snapshot'; import { InfraSourceStatus } from './lib/source_status'; import { InfraSources } from './lib/sources'; import { InfraServerPluginDeps } from './lib/adapters/framework'; @@ -105,7 +104,6 @@ export class InfraServerPlugin { sources, } ); - const snapshot = new InfraSnapshot(); // register saved object types core.savedObjects.registerType(infraSourceConfigurationSavedObjectType); @@ -129,7 +127,6 @@ export class InfraServerPlugin { this.libs = { configuration: this.config, framework, - snapshot, sources, sourceStatus, ...domainLibs, diff --git a/x-pack/plugins/infra/server/routes/alerting/preview.ts b/x-pack/plugins/infra/server/routes/alerting/preview.ts index 5594323d706de..40d09dadfe050 100644 --- a/x-pack/plugins/infra/server/routes/alerting/preview.ts +++ b/x-pack/plugins/infra/server/routes/alerting/preview.ts @@ -82,7 +82,7 @@ export const initAlertPreviewRoute = ({ framework, sources }: InfraBackendLibs) callCluster, params: { criteria, filterQuery, nodeType }, lookback, - config: source.configuration, + source, alertInterval, }); diff --git a/x-pack/plugins/infra/server/routes/log_entries/entries.ts b/x-pack/plugins/infra/server/routes/log_entries/entries.ts index 2cd889d9c5568..c1f63d9c29577 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/entries.ts +++ b/x-pack/plugins/infra/server/routes/log_entries/entries.ts @@ -4,14 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; - -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { schema } from '@kbn/config-schema'; - -import { throwErrors } from '../../../common/runtime_types'; +import { createValidationFunction } from '../../../common/runtime_types'; import { InfraBackendLibs } from '../../lib/infra_types'; import { @@ -22,22 +15,16 @@ import { import { parseFilterQuery } from '../../utils/serialized_query'; import { LogEntriesParams } from '../../lib/domains/log_entries_domain'; -const escapeHatch = schema.object({}, { unknowns: 'allow' }); - export const initLogEntriesRoute = ({ framework, logEntries }: InfraBackendLibs) => { framework.registerRoute( { method: 'post', path: LOG_ENTRIES_PATH, - validate: { body: escapeHatch }, + validate: { body: createValidationFunction(logEntriesRequestRT) }, }, async (requestContext, request, response) => { try { - const payload = pipe( - logEntriesRequestRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - + const payload = request.body; const { startTimestamp: startTimestamp, endTimestamp: endTimestamp, diff --git a/x-pack/plugins/infra/server/routes/log_entries/item.ts b/x-pack/plugins/infra/server/routes/log_entries/item.ts index 85dba8f598a89..67ca481ff4fcb 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/item.ts +++ b/x-pack/plugins/infra/server/routes/log_entries/item.ts @@ -4,14 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; - -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { schema } from '@kbn/config-schema'; - -import { throwErrors } from '../../../common/runtime_types'; +import { createValidationFunction } from '../../../common/runtime_types'; import { InfraBackendLibs } from '../../lib/infra_types'; import { @@ -20,22 +13,16 @@ import { logEntriesItemResponseRT, } from '../../../common/http_api'; -const escapeHatch = schema.object({}, { unknowns: 'allow' }); - export const initLogEntriesItemRoute = ({ framework, sources, logEntries }: InfraBackendLibs) => { framework.registerRoute( { method: 'post', path: LOG_ENTRIES_ITEM_PATH, - validate: { body: escapeHatch }, + validate: { body: createValidationFunction(logEntriesItemRequestRT) }, }, async (requestContext, request, response) => { try { - const payload = pipe( - logEntriesItemRequestRT.decode(request.body), - fold(throwErrors(Boom.badRequest), identity) - ); - + const payload = request.body; const { id, sourceId } = payload; const sourceConfiguration = ( await sources.getSourceConfiguration(requestContext.core.savedObjects.client, sourceId) diff --git a/x-pack/plugins/infra/server/routes/metrics_explorer/lib/find_interval_for_metrics.ts b/x-pack/plugins/infra/server/routes/metrics_explorer/lib/find_interval_for_metrics.ts index 876bbb4199441..8ab0f4a44c85d 100644 --- a/x-pack/plugins/infra/server/routes/metrics_explorer/lib/find_interval_for_metrics.ts +++ b/x-pack/plugins/infra/server/routes/metrics_explorer/lib/find_interval_for_metrics.ts @@ -7,9 +7,9 @@ import { uniq } from 'lodash'; import LRU from 'lru-cache'; import { MetricsExplorerRequestBody } from '../../../../common/http_api'; -import { ESSearchClient } from '../../../lib/snapshot'; import { getDatasetForField } from './get_dataset_for_field'; import { calculateMetricInterval } from '../../../utils/calculate_metric_interval'; +import { ESSearchClient } from '../../../lib/metrics/types'; const cache = new LRU({ max: 100, diff --git a/x-pack/plugins/infra/server/routes/metrics_explorer/lib/get_dataset_for_field.ts b/x-pack/plugins/infra/server/routes/metrics_explorer/lib/get_dataset_for_field.ts index 94e91d32b14bb..85bb5b106c87c 100644 --- a/x-pack/plugins/infra/server/routes/metrics_explorer/lib/get_dataset_for_field.ts +++ b/x-pack/plugins/infra/server/routes/metrics_explorer/lib/get_dataset_for_field.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ESSearchClient } from '../../../lib/snapshot'; +import { ESSearchClient } from '../../../lib/metrics/types'; interface EventDatasetHit { _source: { diff --git a/x-pack/plugins/infra/server/routes/snapshot/index.ts b/x-pack/plugins/infra/server/routes/snapshot/index.ts index 00bc1e74ea871..3f09ae89bc97e 100644 --- a/x-pack/plugins/infra/server/routes/snapshot/index.ts +++ b/x-pack/plugins/infra/server/routes/snapshot/index.ts @@ -10,10 +10,10 @@ import { fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; import { InfraBackendLibs } from '../../lib/infra_types'; import { UsageCollector } from '../../usage/usage_collector'; -import { parseFilterQuery } from '../../utils/serialized_query'; import { SnapshotRequestRT, SnapshotNodeResponseRT } from '../../../common/http_api/snapshot_api'; import { throwErrors } from '../../../common/runtime_types'; import { createSearchClient } from '../../lib/create_search_client'; +import { getNodes } from './lib/get_nodes'; const escapeHatch = schema.object({}, { unknowns: 'allow' }); @@ -30,43 +30,22 @@ export const initSnapshotRoute = (libs: InfraBackendLibs) => { }, async (requestContext, request, response) => { try { - const { - filterQuery, - nodeType, - groupBy, - sourceId, - metrics, - timerange, - accountId, - region, - includeTimeseries, - overrideCompositeSize, - } = pipe( + const snapshotRequest = pipe( SnapshotRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity) ); + const source = await libs.sources.getSourceConfiguration( requestContext.core.savedObjects.client, - sourceId + snapshotRequest.sourceId ); - UsageCollector.countNode(nodeType); - const options = { - filterQuery: parseFilterQuery(filterQuery), - accountId, - region, - nodeType, - groupBy, - sourceConfiguration: source.configuration, - metrics, - timerange, - includeTimeseries, - overrideCompositeSize, - }; + UsageCollector.countNode(snapshotRequest.nodeType); const client = createSearchClient(requestContext, framework); - const nodesWithInterval = await libs.snapshot.getNodes(client, options); + const snapshotResponse = await getNodes(client, snapshotRequest, source); + return response.ok({ - body: SnapshotNodeResponseRT.encode(nodesWithInterval), + body: SnapshotNodeResponseRT.encode(snapshotResponse), }); } catch (error) { return response.internalError({ diff --git a/x-pack/plugins/infra/server/routes/snapshot/lib/apply_metadata_to_last_path.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/apply_metadata_to_last_path.ts new file mode 100644 index 0000000000000..f41d76bbc156f --- /dev/null +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/apply_metadata_to_last_path.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { get, last, first, isArray } from 'lodash'; +import { findInventoryFields } from '../../../../common/inventory_models'; +import { + SnapshotRequest, + SnapshotNodePath, + SnapshotNode, + MetricsAPISeries, + MetricsAPIRow, +} from '../../../../common/http_api'; +import { META_KEY } from './constants'; +import { InfraSource } from '../../../lib/sources'; + +export const isIPv4 = (subject: string) => /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/.test(subject); + +type RowWithMetadata = MetricsAPIRow & { + [META_KEY]: object[]; +}; + +export const applyMetadataToLastPath = ( + series: MetricsAPISeries, + node: SnapshotNode, + snapshotRequest: SnapshotRequest, + source: InfraSource +): SnapshotNodePath[] => { + // First we need to find a row with metadata + const rowWithMeta = series.rows.find( + (row) => (row[META_KEY] && isArray(row[META_KEY]) && (row[META_KEY] as object[]).length) || 0 + ) as RowWithMetadata | undefined; + + if (rowWithMeta) { + // We need just the first doc, there should only be one + const firstMetaDoc = first(rowWithMeta[META_KEY]); + // We also need the last path to add the metadata to + const lastPath = last(node.path); + if (firstMetaDoc && lastPath) { + // We will need the inventory fields so we can use the field paths to get + // the values from the metadata document + const inventoryFields = findInventoryFields( + snapshotRequest.nodeType, + source.configuration.fields + ); + // Set the label as the name and fallback to the id OR path.value + lastPath.label = get(firstMetaDoc, inventoryFields.name, lastPath.value); + // If the inventory fields contain an ip address, we need to try and set that + // on the path object. IP addersses are typically stored as multiple fields. We will + // use the first IPV4 address we find. + if (inventoryFields.ip) { + const ipAddresses = get(firstMetaDoc, inventoryFields.ip) as string[]; + if (Array.isArray(ipAddresses)) { + lastPath.ip = ipAddresses.find(isIPv4) || null; + } else if (typeof ipAddresses === 'string') { + lastPath.ip = ipAddresses; + } + } + return [...node.path.slice(0, node.path.length - 1), lastPath]; + } + } + return node.path; +}; diff --git a/x-pack/plugins/infra/server/routes/snapshot/lib/calculate_index_pattern_based_on_metrics.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/calculate_index_pattern_based_on_metrics.ts new file mode 100644 index 0000000000000..4218aecfe74a8 --- /dev/null +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/calculate_index_pattern_based_on_metrics.ts @@ -0,0 +1,22 @@ +/* + * 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 { SnapshotRequest } from '../../../../common/http_api'; +import { InfraSource } from '../../../lib/sources'; + +export const calculateIndexPatterBasedOnMetrics = ( + options: SnapshotRequest, + source: InfraSource +) => { + const { metrics } = options; + if (metrics.every((m) => m.type === 'logRate')) { + return source.configuration.logAlias; + } + if (metrics.some((m) => m.type === 'logRate')) { + return `${source.configuration.logAlias},${source.configuration.metricAlias}`; + } + return source.configuration.metricAlias; +}; diff --git a/x-pack/plugins/infra/server/lib/snapshot/index.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/constants.ts similarity index 85% rename from x-pack/plugins/infra/server/lib/snapshot/index.ts rename to x-pack/plugins/infra/server/routes/snapshot/lib/constants.ts index 8db54da803648..563c720224435 100644 --- a/x-pack/plugins/infra/server/lib/snapshot/index.ts +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/constants.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export * from './snapshot'; +export const META_KEY = '__metadata__'; diff --git a/x-pack/plugins/infra/server/routes/snapshot/lib/copy_missing_metrics.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/copy_missing_metrics.ts new file mode 100644 index 0000000000000..36397862e4153 --- /dev/null +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/copy_missing_metrics.ts @@ -0,0 +1,45 @@ +/* + * 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 { memoize, last, first } from 'lodash'; +import { SnapshotNode, SnapshotNodeResponse } from '../../../../common/http_api'; + +const createMissingMetricFinder = (nodes: SnapshotNode[]) => + memoize((id: string) => { + const nodeWithMetrics = nodes.find((node) => { + const lastPath = last(node.path); + const metric = first(node.metrics); + return lastPath && metric && lastPath.value === id && metric.value !== null; + }); + if (nodeWithMetrics) { + return nodeWithMetrics.metrics; + } + }); + +/** + * This function will look for nodes with missing data and try to find a node to copy the data from. + * This functionality exists to suppor the use case where the user requests a group by on "Service type". + * Since that grouping naturally excludeds every metric (except the metric for the service.type), we still + * want to display the node with a value. A good example is viewing hosts by CPU Usage and grouping by service + * Without this every service but `system` would be null. + */ +export const copyMissingMetrics = (response: SnapshotNodeResponse) => { + const { nodes } = response; + const find = createMissingMetricFinder(nodes); + const newNodes = nodes.map((node) => { + const lastPath = last(node.path); + const metric = first(node.metrics); + const allRowsNull = metric?.timeseries?.rows.every((r) => r.metric_0 == null) ?? true; + if (lastPath && metric && metric.value === null && allRowsNull) { + const newMetrics = find(lastPath.value); + if (newMetrics) { + return { ...node, metrics: newMetrics }; + } + } + return node; + }); + return { ...response, nodes: newNodes }; +}; diff --git a/x-pack/plugins/infra/server/lib/snapshot/create_timerange_with_interval.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/create_timerange_with_interval.ts similarity index 80% rename from x-pack/plugins/infra/server/lib/snapshot/create_timerange_with_interval.ts rename to x-pack/plugins/infra/server/routes/snapshot/lib/create_timerange_with_interval.ts index 719ffdb8fa7c4..827e0901c1c01 100644 --- a/x-pack/plugins/infra/server/lib/snapshot/create_timerange_with_interval.ts +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/create_timerange_with_interval.ts @@ -5,14 +5,16 @@ */ import { uniq } from 'lodash'; -import { InfraSnapshotRequestOptions } from './types'; -import { getMetricsAggregations } from './query_helpers'; -import { calculateMetricInterval } from '../../utils/calculate_metric_interval'; -import { MetricsUIAggregation, ESBasicMetricAggRT } from '../../../common/inventory_models/types'; -import { getDatasetForField } from '../../routes/metrics_explorer/lib/get_dataset_for_field'; -import { InfraTimerangeInput } from '../../../common/http_api/snapshot_api'; -import { ESSearchClient } from '.'; -import { getIntervalInSeconds } from '../../utils/get_interval_in_seconds'; +import { InfraTimerangeInput } from '../../../../common/http_api'; +import { ESSearchClient } from '../../../lib/metrics/types'; +import { getIntervalInSeconds } from '../../../utils/get_interval_in_seconds'; +import { calculateMetricInterval } from '../../../utils/calculate_metric_interval'; +import { getMetricsAggregations, InfraSnapshotRequestOptions } from './get_metrics_aggregations'; +import { + MetricsUIAggregation, + ESBasicMetricAggRT, +} from '../../../../common/inventory_models/types'; +import { getDatasetForField } from '../../metrics_explorer/lib/get_dataset_for_field'; const createInterval = async (client: ESSearchClient, options: InfraSnapshotRequestOptions) => { const { timerange } = options; diff --git a/x-pack/plugins/infra/server/routes/snapshot/lib/get_metrics_aggregations.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/get_metrics_aggregations.ts new file mode 100644 index 0000000000000..2421469eb1bdd --- /dev/null +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/get_metrics_aggregations.ts @@ -0,0 +1,69 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { JsonObject } from '../../../../common/typed_json'; +import { + InventoryItemType, + MetricsUIAggregation, + MetricsUIAggregationRT, +} from '../../../../common/inventory_models/types'; +import { + SnapshotMetricInput, + SnapshotCustomMetricInputRT, + SnapshotRequest, +} from '../../../../common/http_api'; +import { findInventoryModel } from '../../../../common/inventory_models'; +import { networkTraffic } from '../../../../common/inventory_models/shared/metrics/snapshot/network_traffic'; +import { InfraSourceConfiguration } from '../../../lib/sources'; + +export interface InfraSnapshotRequestOptions + extends Omit { + sourceConfiguration: InfraSourceConfiguration; + filterQuery: JsonObject | undefined; +} + +export const metricToAggregation = ( + nodeType: InventoryItemType, + metric: SnapshotMetricInput, + index: number +) => { + const inventoryModel = findInventoryModel(nodeType); + if (SnapshotCustomMetricInputRT.is(metric)) { + if (metric.aggregation === 'rate') { + return networkTraffic(`custom_${index}`, metric.field); + } + return { + [`custom_${index}`]: { + [metric.aggregation]: { + field: metric.field, + }, + }, + }; + } + return inventoryModel.metrics.snapshot?.[metric.type]; +}; + +export const getMetricsAggregations = ( + options: InfraSnapshotRequestOptions +): MetricsUIAggregation => { + const { metrics } = options; + return metrics.reduce((aggs, metric, index) => { + const aggregation = metricToAggregation(options.nodeType, metric, index); + if (!MetricsUIAggregationRT.is(aggregation)) { + throw new Error( + i18n.translate('xpack.infra.snapshot.missingSnapshotMetricError', { + defaultMessage: 'The aggregation for {metric} for {nodeType} is not available.', + values: { + nodeType: options.nodeType, + metric: metric.type, + }, + }) + ); + } + return { ...aggs, ...aggregation }; + }, {}); +}; diff --git a/x-pack/plugins/infra/server/routes/snapshot/lib/get_nodes.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/get_nodes.ts new file mode 100644 index 0000000000000..9332d5aee1f52 --- /dev/null +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/get_nodes.ts @@ -0,0 +1,34 @@ +/* + * 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 { SnapshotRequest } from '../../../../common/http_api'; +import { ESSearchClient } from '../../../lib/metrics/types'; +import { InfraSource } from '../../../lib/sources'; +import { transformRequestToMetricsAPIRequest } from './transform_request_to_metrics_api_request'; +import { queryAllData } from './query_all_data'; +import { transformMetricsApiResponseToSnapshotResponse } from './trasform_metrics_ui_response'; +import { copyMissingMetrics } from './copy_missing_metrics'; + +export const getNodes = async ( + client: ESSearchClient, + snapshotRequest: SnapshotRequest, + source: InfraSource +) => { + const metricsApiRequest = await transformRequestToMetricsAPIRequest( + client, + source, + snapshotRequest + ); + const metricsApiResponse = await queryAllData(client, metricsApiRequest); + return copyMissingMetrics( + transformMetricsApiResponseToSnapshotResponse( + metricsApiRequest, + snapshotRequest, + source, + metricsApiResponse + ) + ); +}; diff --git a/x-pack/plugins/infra/server/routes/snapshot/lib/query_all_data.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/query_all_data.ts new file mode 100644 index 0000000000000..a9d2352cf55b7 --- /dev/null +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/query_all_data.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { MetricsAPIRequest, MetricsAPIResponse } from '../../../../common/http_api'; +import { ESSearchClient } from '../../../lib/metrics/types'; +import { query } from '../../../lib/metrics'; + +const handleResponse = ( + client: ESSearchClient, + options: MetricsAPIRequest, + previousResponse?: MetricsAPIResponse +) => async (resp: MetricsAPIResponse): Promise => { + const combinedResponse = previousResponse + ? { + ...previousResponse, + series: [...previousResponse.series, ...resp.series], + info: resp.info, + } + : resp; + if (resp.info.afterKey) { + return query(client, { ...options, afterKey: resp.info.afterKey }).then( + handleResponse(client, options, combinedResponse) + ); + } + return combinedResponse; +}; + +export const queryAllData = (client: ESSearchClient, options: MetricsAPIRequest) => { + return query(client, options).then(handleResponse(client, options)); +}; diff --git a/x-pack/plugins/infra/server/routes/snapshot/lib/transform_request_to_metrics_api_request.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/transform_request_to_metrics_api_request.ts new file mode 100644 index 0000000000000..700f4ef39bb66 --- /dev/null +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/transform_request_to_metrics_api_request.ts @@ -0,0 +1,84 @@ +/* + * 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 { findInventoryFields } from '../../../../common/inventory_models'; +import { MetricsAPIRequest, SnapshotRequest } from '../../../../common/http_api'; +import { ESSearchClient } from '../../../lib/metrics/types'; +import { InfraSource } from '../../../lib/sources'; +import { createTimeRangeWithInterval } from './create_timerange_with_interval'; +import { parseFilterQuery } from '../../../utils/serialized_query'; +import { transformSnapshotMetricsToMetricsAPIMetrics } from './transform_snapshot_metrics_to_metrics_api_metrics'; +import { calculateIndexPatterBasedOnMetrics } from './calculate_index_pattern_based_on_metrics'; +import { META_KEY } from './constants'; + +export const transformRequestToMetricsAPIRequest = async ( + client: ESSearchClient, + source: InfraSource, + snapshotRequest: SnapshotRequest +): Promise => { + const timeRangeWithIntervalApplied = await createTimeRangeWithInterval(client, { + ...snapshotRequest, + filterQuery: parseFilterQuery(snapshotRequest.filterQuery), + sourceConfiguration: source.configuration, + }); + + const metricsApiRequest: MetricsAPIRequest = { + indexPattern: calculateIndexPatterBasedOnMetrics(snapshotRequest, source), + timerange: { + field: source.configuration.fields.timestamp, + from: timeRangeWithIntervalApplied.from, + to: timeRangeWithIntervalApplied.to, + interval: timeRangeWithIntervalApplied.interval, + }, + metrics: transformSnapshotMetricsToMetricsAPIMetrics(snapshotRequest), + limit: snapshotRequest.overrideCompositeSize ? snapshotRequest.overrideCompositeSize : 10, + alignDataToEnd: true, + }; + + const filters = []; + const parsedFilters = parseFilterQuery(snapshotRequest.filterQuery); + if (parsedFilters) { + filters.push(parsedFilters); + } + + if (snapshotRequest.accountId) { + filters.push({ term: { 'cloud.account.id': snapshotRequest.accountId } }); + } + + if (snapshotRequest.region) { + filters.push({ term: { 'cloud.region': snapshotRequest.region } }); + } + + const inventoryFields = findInventoryFields( + snapshotRequest.nodeType, + source.configuration.fields + ); + const groupBy = snapshotRequest.groupBy.map((g) => g.field).filter(Boolean) as string[]; + metricsApiRequest.groupBy = [...groupBy, inventoryFields.id]; + + const metaAggregation = { + id: META_KEY, + aggregations: { + [META_KEY]: { + top_hits: { + size: 1, + _source: [inventoryFields.name], + sort: [{ [source.configuration.fields.timestamp]: 'desc' }], + }, + }, + }, + }; + if (inventoryFields.ip) { + metaAggregation.aggregations[META_KEY].top_hits._source.push(inventoryFields.ip); + } + metricsApiRequest.metrics.push(metaAggregation); + + if (filters.length) { + metricsApiRequest.filters = filters; + } + + return metricsApiRequest; +}; diff --git a/x-pack/plugins/infra/server/routes/snapshot/lib/transform_snapshot_metrics_to_metrics_api_metrics.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/transform_snapshot_metrics_to_metrics_api_metrics.ts new file mode 100644 index 0000000000000..6f7c88eda5d7a --- /dev/null +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/transform_snapshot_metrics_to_metrics_api_metrics.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { networkTraffic } from '../../../../common/inventory_models/shared/metrics/snapshot/network_traffic'; +import { findInventoryModel } from '../../../../common/inventory_models'; +import { + MetricsAPIMetric, + SnapshotRequest, + SnapshotCustomMetricInputRT, +} from '../../../../common/http_api'; + +export const transformSnapshotMetricsToMetricsAPIMetrics = ( + snapshotRequest: SnapshotRequest +): MetricsAPIMetric[] => { + return snapshotRequest.metrics.map((metric, index) => { + const inventoryModel = findInventoryModel(snapshotRequest.nodeType); + if (SnapshotCustomMetricInputRT.is(metric)) { + const customId = `custom_${index}`; + if (metric.aggregation === 'rate') { + return { id: customId, aggregations: networkTraffic(customId, metric.field) }; + } + return { + id: customId, + aggregations: { + [customId]: { + [metric.aggregation]: { + field: metric.field, + }, + }, + }, + }; + } + return { id: metric.type, aggregations: inventoryModel.metrics.snapshot?.[metric.type] }; + }); +}; diff --git a/x-pack/plugins/infra/server/routes/snapshot/lib/trasform_metrics_ui_response.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/trasform_metrics_ui_response.ts new file mode 100644 index 0000000000000..309598d71c361 --- /dev/null +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/trasform_metrics_ui_response.ts @@ -0,0 +1,87 @@ +/* + * 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 { get, max, sum, last, isNumber } from 'lodash'; +import { SnapshotMetricType } from '../../../../common/inventory_models/types'; +import { + MetricsAPIResponse, + SnapshotNodeResponse, + MetricsAPIRequest, + MetricsExplorerColumnType, + MetricsAPIRow, + SnapshotRequest, + SnapshotNodePath, + SnapshotNodeMetric, +} from '../../../../common/http_api'; +import { META_KEY } from './constants'; +import { InfraSource } from '../../../lib/sources'; +import { applyMetadataToLastPath } from './apply_metadata_to_last_path'; + +const getMetricValue = (row: MetricsAPIRow) => { + if (!isNumber(row.metric_0)) return null; + const value = row.metric_0; + return isFinite(value) ? value : null; +}; + +const calculateMax = (rows: MetricsAPIRow[]) => { + return max(rows.map(getMetricValue)) || 0; +}; + +const calculateAvg = (rows: MetricsAPIRow[]): number => { + return sum(rows.map(getMetricValue)) / rows.length || 0; +}; + +const getLastValue = (rows: MetricsAPIRow[]) => { + const row = last(rows); + if (!row) return null; + return getMetricValue(row); +}; + +export const transformMetricsApiResponseToSnapshotResponse = ( + options: MetricsAPIRequest, + snapshotRequest: SnapshotRequest, + source: InfraSource, + metricsApiResponse: MetricsAPIResponse +): SnapshotNodeResponse => { + const nodes = metricsApiResponse.series.map((series) => { + const node = { + metrics: options.metrics + .filter((m) => m.id !== META_KEY) + .map((metric) => { + const name = metric.id as SnapshotMetricType; + const timeseries = { + id: name, + columns: [ + { name: 'timestamp', type: 'date' as MetricsExplorerColumnType }, + { name: 'metric_0', type: 'number' as MetricsExplorerColumnType }, + ], + rows: series.rows.map((row) => { + return { timestamp: row.timestamp, metric_0: get(row, metric.id, null) }; + }), + }; + const maxValue = calculateMax(timeseries.rows); + const avg = calculateAvg(timeseries.rows); + const value = getLastValue(timeseries.rows); + const nodeMetric: SnapshotNodeMetric = { name, max: maxValue, value, avg }; + if (snapshotRequest.includeTimeseries) { + nodeMetric.timeseries = timeseries; + } + return nodeMetric; + }), + path: + series.keys?.map((key) => { + return { value: key, label: key } as SnapshotNodePath; + }) ?? [], + name: '', + }; + + const path = applyMetadataToLastPath(series, node, snapshotRequest, source); + const lastPath = last(path); + const name = (lastPath && lastPath.label) || 'N/A'; + return { ...node, path, name }; + }); + return { nodes, interval: `${metricsApiResponse.info.interval}s` }; +}; diff --git a/x-pack/plugins/infra/server/utils/calculate_metric_interval.ts b/x-pack/plugins/infra/server/utils/calculate_metric_interval.ts index a3d674b324ae8..6d16e045d26d5 100644 --- a/x-pack/plugins/infra/server/utils/calculate_metric_interval.ts +++ b/x-pack/plugins/infra/server/utils/calculate_metric_interval.ts @@ -8,7 +8,7 @@ import { findInventoryModel } from '../../common/inventory_models'; // import { KibanaFramework } from '../lib/adapters/framework/kibana_framework_adapter'; import { InventoryItemType } from '../../common/inventory_models/types'; -import { ESSearchClient } from '../lib/snapshot'; +import { ESSearchClient } from '../lib/metrics/types'; interface Options { indexPattern: string; diff --git a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json index d75a914e080d7..b7856e6d57402 100644 --- a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json +++ b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json @@ -1425,11 +1425,13 @@ }, "icons": [ { - "src": "/package/coredns-1.0.1/img/icon.png", + "path": "/package/coredns-1.0.1/img/icon.png", + "src": "/img/icon.png", "size": "1800x1800" }, { - "src": "/package/coredns-1.0.1/img/icon.svg", + "path": "/package/coredns-1.0.1/img/icon.svg", + "src": "/img/icon.svg", "size": "255x144", "type": "image/svg+xml" } @@ -1704,7 +1706,8 @@ }, "icons": [ { - "src": "/package/endpoint/0.3.0/img/logo-endpoint-64-color.svg", + "path": "/package/endpoint/0.3.0/img/logo-endpoint-64-color.svg", + "src": "/img/logo-endpoint-64-color.svg", "size": "16x16", "type": "image/svg+xml" } @@ -2001,7 +2004,8 @@ "download": "/epr/aws/aws-0.0.3.tar.gz", "icons": [ { - "src": "/package/aws/0.0.3/img/logo_aws.svg", + "path": "/package/aws/0.0.3/img/logo_aws.svg", + "src": "/img/logo_aws.svg", "title": "logo aws", "size": "32x32", "type": "image/svg+xml" @@ -2019,7 +2023,8 @@ "download": "/epr/endpoint/endpoint-0.1.0.tar.gz", "icons": [ { - "src": "/package/endpoint/0.1.0/img/logo-endpoint-64-color.svg", + "path": "/package/endpoint/0.1.0/img/logo-endpoint-64-color.svg", + "src": "/img/logo-endpoint-64-color.svg", "size": "16x16", "type": "image/svg+xml" } @@ -2087,7 +2092,8 @@ "download": "/epr/log/log-0.9.0.tar.gz", "icons": [ { - "src": "/package/log/0.9.0/img/icon.svg", + "path": "/package/log/0.9.0/img/icon.svg", + "src": "/img/icon.svg", "type": "image/svg+xml" } ], @@ -2103,7 +2109,8 @@ "download": "/epr/longdocs/longdocs-1.0.4.tar.gz", "icons": [ { - "src": "/package/longdocs/1.0.4/img/icon.svg", + "path": "/package/longdocs/1.0.4/img/icon.svg", + "src": "/img/icon.svg", "type": "image/svg+xml" } ], @@ -2119,7 +2126,8 @@ "download": "/epr/metricsonly/metricsonly-2.0.1.tar.gz", "icons": [ { - "src": "/package/metricsonly/2.0.1/img/icon.svg", + "path": "/package/metricsonly/2.0.1/img/icon.svg", + "src": "/img/icon.svg", "type": "image/svg+xml" } ], @@ -2135,7 +2143,8 @@ "download": "/epr/multiversion/multiversion-1.1.0.tar.gz", "icons": [ { - "src": "/package/multiversion/1.1.0/img/icon.svg", + "path": "/package/multiversion/1.1.0/img/icon.svg", + "src": "/img/icon.svg", "type": "image/svg+xml" } ], @@ -2151,7 +2160,8 @@ "download": "/epr/mysql/mysql-0.1.0.tar.gz", "icons": [ { - "src": "/package/mysql/0.1.0/img/logo_mysql.svg", + "path": "/package/mysql/0.1.0/img/logo_mysql.svg", + "src": "/img/logo_mysql.svg", "title": "logo mysql", "size": "32x32", "type": "image/svg+xml" @@ -2169,7 +2179,8 @@ "download": "/epr/nginx/nginx-0.1.0.tar.gz", "icons": [ { - "src": "/package/nginx/0.1.0/img/logo_nginx.svg", + "path": "/package/nginx/0.1.0/img/logo_nginx.svg", + "src": "/img/logo_nginx.svg", "title": "logo nginx", "size": "32x32", "type": "image/svg+xml" @@ -2187,7 +2198,8 @@ "download": "/epr/redis/redis-0.1.0.tar.gz", "icons": [ { - "src": "/package/redis/0.1.0/img/logo_redis.svg", + "path": "/package/redis/0.1.0/img/logo_redis.svg", + "src": "/img/logo_redis.svg", "title": "logo redis", "size": "32x32", "type": "image/svg+xml" @@ -2205,7 +2217,8 @@ "download": "/epr/reference/reference-1.0.0.tar.gz", "icons": [ { - "src": "/package/reference/1.0.0/img/icon.svg", + "path": "/package/reference/1.0.0/img/icon.svg", + "src": "/img/icon.svg", "size": "32x32", "type": "image/svg+xml" } @@ -2222,7 +2235,8 @@ "download": "/epr/system/system-0.1.0.tar.gz", "icons": [ { - "src": "/package/system/0.1.0/img/system.svg", + "path": "/package/system/0.1.0/img/system.svg", + "src": "/img/system.svg", "title": "system", "size": "1000x1000", "type": "image/svg+xml" @@ -3913,11 +3927,20 @@ "src": { "type": "string" }, + "path": { + "type": "string" + }, "title": { "type": "string" + }, + "size": { + "type": "string" + }, + "type": { + "type": "string" } }, - "required": ["src"] + "required": ["src", "path"] } }, "icons": { diff --git a/x-pack/plugins/ingest_manager/common/types/models/epm.ts b/x-pack/plugins/ingest_manager/common/types/models/epm.ts index 140a76ac85e61..8bc5d9f7210b2 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/epm.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/epm.ts @@ -19,6 +19,8 @@ export enum InstallStatus { uninstalling = 'uninstalling', } +export type InstallType = 'reinstall' | 'reupdate' | 'rollback' | 'update' | 'install'; + export type EpmPackageInstallStatus = 'installed' | 'installing'; export type DetailViewPanelName = 'overview' | 'usages' | 'settings'; @@ -38,6 +40,7 @@ export enum ElasticsearchAssetType { ingestPipeline = 'ingest_pipeline', indexTemplate = 'index_template', ilmPolicy = 'ilm_policy', + transform = 'transform', } export enum AgentAssetType { @@ -71,10 +74,8 @@ export interface RegistryPackage { } interface RegistryImage { - // https://github.com/elastic/package-registry/blob/master/util/package.go#L74 - // says src is potentially missing but I couldn't find any examples - // it seems like src should be required. How can you have an image with no reference to the content? src: string; + path: string; title?: string; size?: string; type?: string; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_package_icon_type.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_package_icon_type.ts index e5a7191372e9c..690ffdf46f704 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_package_icon_type.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_package_icon_type.ts @@ -42,7 +42,7 @@ export const usePackageIconType = ({ const svgIcons = (paramIcons || iconList)?.filter( (iconDef) => iconDef.type === 'image/svg+xml' ); - const localIconSrc = Array.isArray(svgIcons) && svgIcons[0]?.src; + const localIconSrc = Array.isArray(svgIcons) && (svgIcons[0].path || svgIcons[0].src); if (localIconSrc) { CACHED_ICONS.set(pkgKey, toImage(localIconSrc)); setIconType(CACHED_ICONS.get(pkgKey) || ''); diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx index 9f48be54f866d..ccf9e45ebc4fa 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/step_select_agent_policy.tsx @@ -83,7 +83,7 @@ export const StepSelectAgentPolicy: React.FunctionComponent<{ data: agentPoliciesData, error: agentPoliciesError, isLoading: isAgentPoliciesLoading, - sendRequest: refreshAgentPolicies, + resendRequest: refreshAgentPolicies, } = useGetAgentPolicies({ page: 1, perPage: 1000, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/details_page/hooks/use_agent_status.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/details_page/hooks/use_agent_status.tsx index 71dcd728d5d1b..3483d8dee045a 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/details_page/hooks/use_agent_status.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/details_page/hooks/use_agent_status.tsx @@ -25,7 +25,7 @@ export function useGetAgentStatus(policyId?: string, options?: RequestOptions) { isLoading: agentStatusRequest.isLoading, data: agentStatusRequest.data, error: agentStatusRequest.error, - refreshAgentStatus: () => agentStatusRequest.sendRequest, + refreshAgentStatus: () => agentStatusRequest.resendRequest, }; } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/list_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/list_page/index.tsx index 361b1c33f1a04..fb963dc67ae1c 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/list_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/list_page/index.tsx @@ -108,7 +108,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => { ); // Fetch agent policies - const { isLoading, data: agentPolicyData, sendRequest } = useGetAgentPolicies({ + const { isLoading, data: agentPolicyData, resendRequest } = useGetAgentPolicies({ page: pagination.currentPage, perPage: pagination.pageSize, sortField: sorting?.field, @@ -204,7 +204,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => { render: (agentPolicy: AgentPolicy) => ( sendRequest()} + onCopySuccess={() => resendRequest()} /> ), }, @@ -218,7 +218,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => { } return cols; - }, [getHref, isFleetEnabled, sendRequest]); + }, [getHref, isFleetEnabled, resendRequest]); const createAgentPolicyButton = useMemo( () => ( @@ -270,7 +270,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => { { setIsCreateAgentPolicyFlyoutOpen(false); - sendRequest(); + resendRequest(); }} /> ) : null} @@ -289,7 +289,7 @@ export const AgentPolicyListPage: React.FunctionComponent<{}> = () => { /> - sendRequest()}> + resendRequest()}> = () => { const { pagination, pageSizeOptions } = usePagination(); // Fetch data streams - const { isLoading, data: dataStreamsData, sendRequest } = useGetDataStreams(); + const { isLoading, data: dataStreamsData, resendRequest } = useGetDataStreams(); // Some policies retrieved, set up table props const columns = useMemo(() => { @@ -241,7 +241,7 @@ export const DataStreamListPage: React.FunctionComponent<{}> = () => { key="reloadButton" color="primary" iconType="refresh" - onClick={() => sendRequest()} + onClick={() => resendRequest()} > = { dashboard: 'Dashboard', ilm_policy: 'ILM Policy', ingest_pipeline: 'Ingest Pipeline', + transform: 'Transform', 'index-pattern': 'Index Pattern', index_template: 'Index Template', component_template: 'Component Template', diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/screenshots.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/screenshots.tsx index d8388a71556d6..6326e9072be8e 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/screenshots.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/screenshots.tsx @@ -75,7 +75,7 @@ export function Screenshots(props: ScreenshotProps) { set image to same width. Will need to update if size changes. */} = ({ ag [key: string]: JSX.Element; }>({}); - const { isLoading, data, sendRequest } = useGetOneAgentEvents(agent.id, { + const { isLoading, data, resendRequest } = useGetOneAgentEvents(agent.id, { page: pagination.currentPage, perPage: pagination.pageSize, kuery: search && search.trim() !== '' ? search.trim() : undefined, }); - const refresh = () => sendRequest(); + const refresh = () => resendRequest(); const total = data ? data.total : 0; const list = data ? data.list : []; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx index 219b343eba41b..fe0781f4a240b 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx @@ -51,7 +51,7 @@ export const AgentDetailsPage: React.FunctionComponent = () => { isInitialRequest, error, data: agentData, - sendRequest: sendAgentRequest, + resendRequest: sendAgentRequest, } = useGetOneAgent(agentId, { pollIntervalMs: 5000, }); diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/index.tsx index 9548340df5b30..46f7ffb85b21f 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/index.tsx @@ -344,7 +344,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { return ( agentsRequest.sendRequest()} + refresh={() => agentsRequest.resendRequest()} onReassignClick={() => setAgentToReassignId(agent.id)} /> ); @@ -394,7 +394,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { agent={agentToReassign} onClose={() => { setAgentToReassignId(undefined); - agentsRequest.sendRequest(); + agentsRequest.resendRequest(); }} /> diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/enrollment_token_list_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/enrollment_token_list_page/index.tsx index b3a4938b22310..d85a6e8b5b833 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/enrollment_token_list_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/enrollment_token_list_page/index.tsx @@ -244,7 +244,10 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => { render: (_: any, apiKey: EnrollmentAPIKey) => { return ( apiKey.active && ( - enrollmentAPIKeysRequest.sendRequest()} /> + enrollmentAPIKeysRequest.resendRequest()} + /> ) ); }, @@ -258,7 +261,7 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => { agentPolicies={agentPolicies} onClose={() => { setFlyoutOpen(false); - enrollmentAPIKeysRequest.sendRequest(); + enrollmentAPIKeysRequest.resendRequest(); }} /> )} diff --git a/x-pack/plugins/ingest_manager/server/errors.test.ts b/x-pack/plugins/ingest_manager/server/errors/handlers.test.ts similarity index 73% rename from x-pack/plugins/ingest_manager/server/errors.test.ts rename to x-pack/plugins/ingest_manager/server/errors/handlers.test.ts index 70e3a3b4150ad..361386a86d547 100644 --- a/x-pack/plugins/ingest_manager/server/errors.test.ts +++ b/x-pack/plugins/ingest_manager/server/errors/handlers.test.ts @@ -5,16 +5,19 @@ */ import Boom from 'boom'; +import { errors } from 'elasticsearch'; import { httpServerMock } from 'src/core/server/mocks'; -import { createAppContextStartContractMock } from './mocks'; - +import { createAppContextStartContractMock } from '../mocks'; +import { appContextService } from '../services'; import { IngestManagerError, RegistryError, PackageNotFoundError, defaultIngestErrorHandler, -} from './errors'; -import { appContextService } from './services'; +} from './index'; + +const LegacyESErrors = errors as Record; +type ITestEsErrorsFnParams = [errorCode: string, error: any, expectedMessage: string]; describe('defaultIngestErrorHandler', () => { let mockContract: ReturnType; @@ -29,6 +32,55 @@ describe('defaultIngestErrorHandler', () => { appContextService.stop(); }); + async function testEsErrorsFn(...args: ITestEsErrorsFnParams) { + const [, error, expectedMessage] = args; + jest.clearAllMocks(); + const response = httpServerMock.createResponseFactory(); + await defaultIngestErrorHandler({ error, response }); + + // response + expect(response.ok).toHaveBeenCalledTimes(0); + expect(response.customError).toHaveBeenCalledTimes(1); + expect(response.customError).toHaveBeenCalledWith({ + statusCode: error.status, + body: { message: expectedMessage }, + }); + + // logging + expect(mockContract.logger?.error).toHaveBeenCalledTimes(1); + expect(mockContract.logger?.error).toHaveBeenCalledWith(expectedMessage); + } + + describe('use the HTTP error status code provided by LegacyESErrors', () => { + const statusCodes = Object.keys(LegacyESErrors).filter((key) => /^\d+$/.test(key)); + const errorCodes = statusCodes.filter((key) => parseInt(key, 10) >= 400); + const casesWithPathResponse: ITestEsErrorsFnParams[] = errorCodes.map((errorCode) => [ + errorCode, + new LegacyESErrors[errorCode]('the root message', { + path: '/path/to/call', + response: 'response is here', + }), + 'the root message response from /path/to/call: response is here', + ]); + const casesWithOtherMeta: ITestEsErrorsFnParams[] = errorCodes.map((errorCode) => [ + errorCode, + new LegacyESErrors[errorCode]('the root message', { + other: '/path/to/call', + props: 'response is here', + }), + 'the root message', + ]); + const casesWithoutMeta: ITestEsErrorsFnParams[] = errorCodes.map((errorCode) => [ + errorCode, + new LegacyESErrors[errorCode]('some message'), + 'some message', + ]); + + test.each(casesWithPathResponse)('%d - with path & response', testEsErrorsFn); + test.each(casesWithOtherMeta)('%d - with other metadata', testEsErrorsFn); + test.each(casesWithoutMeta)('%d - without metadata', testEsErrorsFn); + }); + describe('IngestManagerError', () => { it('502: RegistryError', async () => { const error = new RegistryError('xyz'); diff --git a/x-pack/plugins/ingest_manager/server/errors.ts b/x-pack/plugins/ingest_manager/server/errors/handlers.ts similarity index 60% rename from x-pack/plugins/ingest_manager/server/errors.ts rename to x-pack/plugins/ingest_manager/server/errors/handlers.ts index 9829a4de23d7b..9f776565cf262 100644 --- a/x-pack/plugins/ingest_manager/server/errors.ts +++ b/x-pack/plugins/ingest_manager/server/errors/handlers.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable max-classes-per-file */ import Boom, { isBoom } from 'boom'; import { RequestHandlerContext, @@ -12,25 +11,39 @@ import { IKibanaResponse, KibanaResponseFactory, } from 'src/core/server'; -import { appContextService } from './services'; +import { errors as LegacyESErrors } from 'elasticsearch'; +import { appContextService } from '../services'; +import { IngestManagerError, RegistryError, PackageNotFoundError } from './index'; type IngestErrorHandler = ( params: IngestErrorHandlerParams ) => IKibanaResponse | Promise; - interface IngestErrorHandlerParams { error: IngestManagerError | Boom | Error; response: KibanaResponseFactory; request?: KibanaRequest; context?: RequestHandlerContext; } +// unsure if this is correct. would prefer to use something "official" +// this type is based on BadRequest values observed while debugging https://github.com/elastic/kibana/issues/75862 -export class IngestManagerError extends Error { - constructor(message?: string) { - super(message); - this.name = this.constructor.name; // for stack traces - } +interface LegacyESClientError { + message: string; + stack: string; + status: number; + displayName: string; + path?: string; + query?: string | undefined; + body?: { + error: object; + status: number; + }; + statusCode?: number; + response?: string; } +export const isLegacyESClientError = (error: any): error is LegacyESClientError => { + return error instanceof LegacyESErrors._Abstract; +}; const getHTTPResponseCode = (error: IngestManagerError): number => { if (error instanceof RegistryError) { @@ -48,6 +61,22 @@ export const defaultIngestErrorHandler: IngestErrorHandler = async ({ response, }: IngestErrorHandlerParams): Promise => { const logger = appContextService.getLogger(); + if (isLegacyESClientError(error)) { + // there was a problem communicating with ES (e.g. via `callCluster`) + // only log the message + const message = + error?.path && error?.response + ? // if possible, return the failing endpoint and its response + `${error.message} response from ${error.path}: ${error.response}` + : error.message; + + logger.error(message); + + return response.customError({ + statusCode: error?.statusCode || error.status, + body: { message }, + }); + } // our "expected" errors if (error instanceof IngestManagerError) { @@ -76,9 +105,3 @@ export const defaultIngestErrorHandler: IngestErrorHandler = async ({ body: { message: error.message }, }); }; - -export class RegistryError extends IngestManagerError {} -export class RegistryConnectionError extends RegistryError {} -export class RegistryResponseError extends RegistryError {} -export class PackageNotFoundError extends IngestManagerError {} -export class PackageOutdatedError extends IngestManagerError {} diff --git a/x-pack/plugins/ingest_manager/server/errors/index.ts b/x-pack/plugins/ingest_manager/server/errors/index.ts new file mode 100644 index 0000000000000..5e36a2ec9a884 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/errors/index.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +/* eslint-disable max-classes-per-file */ +export { defaultIngestErrorHandler } from './handlers'; + +export class IngestManagerError extends Error { + constructor(message?: string) { + super(message); + this.name = this.constructor.name; // for stack traces + } +} +export class RegistryError extends IngestManagerError {} +export class RegistryConnectionError extends RegistryError {} +export class RegistryResponseError extends RegistryError {} +export class PackageNotFoundError extends IngestManagerError {} +export class PackageOutdatedError extends IngestManagerError {} diff --git a/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts index 6d7252ffec41a..b19960cc90228 100644 --- a/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts +++ b/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts @@ -34,6 +34,7 @@ import { } from '../../services/epm/packages'; import { IngestManagerError, defaultIngestErrorHandler } from '../../errors'; import { splitPkgKey } from '../../services/epm/registry'; +import { getInstallType } from '../../services/epm/packages/install'; export const getCategoriesHandler: RequestHandler< undefined, @@ -138,6 +139,8 @@ export const installPackageHandler: RequestHandler< const callCluster = context.core.elasticsearch.legacy.client.callAsCurrentUser; const { pkgkey } = request.params; const { pkgName, pkgVersion } = splitPkgKey(pkgkey); + const installedPkg = await getInstallationObject({ savedObjectsClient, pkgName }); + const installType = getInstallType({ pkgVersion, installedPkg }); try { const res = await installPackage({ savedObjectsClient, @@ -156,15 +159,25 @@ export const installPackageHandler: RequestHandler< if (e instanceof IngestManagerError) { return defaultResult; } - // if there is an unknown server error, uninstall any package assets + + // if there is an unknown server error, uninstall any package assets or reinstall the previous version if update try { - const installedPkg = await getInstallationObject({ savedObjectsClient, pkgName }); - const isUpdate = installedPkg && installedPkg.attributes.version < pkgVersion ? true : false; - if (!isUpdate) { + if (installType === 'install' || installType === 'reinstall') { + logger.error(`uninstalling ${pkgkey} after error installing`); await removeInstallation({ savedObjectsClient, pkgkey, callCluster }); } + if (installType === 'update') { + // @ts-ignore installType conditions already check for existence of installedPkg + const prevVersion = `${pkgName}-${installedPkg.attributes.version}`; + logger.error(`rolling back to ${prevVersion} after error installing ${pkgkey}`); + await installPackage({ + savedObjectsClient, + pkgkey: prevVersion, + callCluster, + }); + } } catch (error) { - logger.error(`could not remove failed installation ${error}`); + logger.error(`failed to uninstall or rollback package after installation error ${error}`); } return defaultResult; } diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts index 44e4eddfbbe6a..878c6ea8f2804 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts @@ -156,7 +156,12 @@ async function installPipeline({ body: pipeline.contentForInstallation, }; if (pipeline.extension === 'yml') { - callClusterParams.headers = { ['Content-Type']: 'application/yaml' }; + callClusterParams.headers = { + // pipeline is YAML + 'Content-Type': 'application/yaml', + // but we want JSON responses (to extract error messages, status code, or other metadata) + Accept: 'application/json', + }; } // This uses the catch-all endpoint 'transport.request' because we have to explicitly diff --git a/x-pack/plugins/maps/public/routing/bootstrap/get_initial_layers.d.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/common.ts similarity index 56% rename from x-pack/plugins/maps/public/routing/bootstrap/get_initial_layers.d.ts rename to x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/common.ts index a23e715a08295..46f36dba96747 100644 --- a/x-pack/plugins/maps/public/routing/bootstrap/get_initial_layers.d.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/common.ts @@ -4,9 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LayerDescriptor } from '../../../common/descriptor_types'; +import * as Registry from '../../registry'; -export function getInitialLayers( - layerListJSON?: string, - initialLayers?: LayerDescriptor[] -): LayerDescriptor[]; +export const getAsset = (path: string): Buffer => { + return Registry.getAsset(path); +}; diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts new file mode 100644 index 0000000000000..1e58319183c7d --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts @@ -0,0 +1,165 @@ +/* + * 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 { SavedObjectsClientContract } from 'kibana/server'; + +import { saveInstalledEsRefs } from '../../packages/install'; +import * as Registry from '../../registry'; +import { + Dataset, + ElasticsearchAssetType, + EsAssetReference, + RegistryPackage, +} from '../../../../../common/types/models'; +import { CallESAsCurrentUser } from '../../../../types'; +import { getInstallation } from '../../packages'; +import { deleteTransforms, deleteTransformRefs } from './remove'; +import { getAsset } from './common'; + +interface TransformInstallation { + installationName: string; + content: string; +} + +interface TransformPathDataset { + path: string; + dataset: Dataset; +} + +export const installTransformForDataset = async ( + registryPackage: RegistryPackage, + paths: string[], + callCluster: CallESAsCurrentUser, + savedObjectsClient: SavedObjectsClientContract +) => { + const installation = await getInstallation({ savedObjectsClient, pkgName: registryPackage.name }); + let previousInstalledTransformEsAssets: EsAssetReference[] = []; + if (installation) { + previousInstalledTransformEsAssets = installation.installed_es.filter( + ({ type, id }) => type === ElasticsearchAssetType.transform + ); + } + + // delete all previous transform + await deleteTransforms( + callCluster, + previousInstalledTransformEsAssets.map((asset) => asset.id) + ); + // install the latest dataset + const datasets = registryPackage.datasets; + if (!datasets?.length) return []; + const installNameSuffix = `${registryPackage.version}`; + + const transformPaths = paths.filter((path) => isTransform(path)); + let installedTransforms: EsAssetReference[] = []; + if (transformPaths.length > 0) { + const transformPathDatasets = datasets.reduce((acc, dataset) => { + transformPaths.forEach((path) => { + if (isDatasetTransform(path, dataset.path)) { + acc.push({ path, dataset }); + } + }); + return acc; + }, []); + + const transformRefs = transformPathDatasets.reduce( + (acc, transformPathDataset) => { + if (transformPathDataset) { + acc.push({ + id: getTransformNameForInstallation(transformPathDataset, installNameSuffix), + type: ElasticsearchAssetType.transform, + }); + } + return acc; + }, + [] + ); + + // get and save transform refs before installing transforms + await saveInstalledEsRefs(savedObjectsClient, registryPackage.name, transformRefs); + + const transforms: TransformInstallation[] = transformPathDatasets.map( + (transformPathDataset: TransformPathDataset) => { + return { + installationName: getTransformNameForInstallation( + transformPathDataset, + installNameSuffix + ), + content: getAsset(transformPathDataset.path).toString('utf-8'), + }; + } + ); + + const installationPromises = transforms.map(async (transform) => { + return installTransform({ callCluster, transform }); + }); + + installedTransforms = await Promise.all(installationPromises).then((results) => results.flat()); + } + + if (previousInstalledTransformEsAssets.length > 0) { + const currentInstallation = await getInstallation({ + savedObjectsClient, + pkgName: registryPackage.name, + }); + + // remove the saved object reference + await deleteTransformRefs( + savedObjectsClient, + currentInstallation?.installed_es || [], + registryPackage.name, + previousInstalledTransformEsAssets.map((asset) => asset.id), + installedTransforms.map((installed) => installed.id) + ); + } + return installedTransforms; +}; + +const isTransform = (path: string) => { + const pathParts = Registry.pathParts(path); + return pathParts.type === ElasticsearchAssetType.transform; +}; + +const isDatasetTransform = (path: string, datasetName: string) => { + const pathParts = Registry.pathParts(path); + return ( + !path.endsWith('/') && + pathParts.type === ElasticsearchAssetType.transform && + pathParts.dataset !== undefined && + datasetName === pathParts.dataset + ); +}; + +async function installTransform({ + callCluster, + transform, +}: { + callCluster: CallESAsCurrentUser; + transform: TransformInstallation; +}): Promise { + // defer validation on put if the source index is not available + await callCluster('transport.request', { + method: 'PUT', + path: `_transform/${transform.installationName}`, + query: 'defer_validation=true', + body: transform.content, + }); + + await callCluster('transport.request', { + method: 'POST', + path: `_transform/${transform.installationName}/_start`, + }); + + return { id: transform.installationName, type: ElasticsearchAssetType.transform }; +} + +const getTransformNameForInstallation = ( + transformDataset: TransformPathDataset, + suffix: string +) => { + const filename = transformDataset?.path.split('/')?.pop()?.split('.')[0]; + return `${transformDataset.dataset.type}-${transformDataset.dataset.name}-${filename}-${suffix}`; +}; diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.test.ts new file mode 100644 index 0000000000000..3f85ee9b550b2 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.test.ts @@ -0,0 +1,69 @@ +/* + * 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 { SavedObjectsClientContract } from 'kibana/server'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { savedObjectsClientMock } from '../../../../../../../../src/core/server/saved_objects/service/saved_objects_client.mock'; +import { deleteTransformRefs } from './remove'; +import { EsAssetReference } from '../../../../../common/types/models'; + +describe('test transform install', () => { + let savedObjectsClient: jest.Mocked; + beforeEach(() => { + savedObjectsClient = savedObjectsClientMock.create(); + }); + + test('can delete transform ref and handle duplicate when previous version and current version are the same', async () => { + await deleteTransformRefs( + savedObjectsClient, + [ + { id: 'metrics-endpoint.policy-0.16.0-dev.0', type: 'ingest_pipeline' }, + { id: 'metrics-endpoint.metadata-current-default-0.16.0-dev.0', type: 'transform' }, + ] as EsAssetReference[], + 'endpoint', + ['metrics-endpoint.metadata-current-default-0.16.0-dev.0'], + ['metrics-endpoint.metadata-current-default-0.16.0-dev.0'] + ); + expect(savedObjectsClient.update.mock.calls).toEqual([ + [ + 'epm-packages', + 'endpoint', + { + installed_es: [ + { id: 'metrics-endpoint.policy-0.16.0-dev.0', type: 'ingest_pipeline' }, + { id: 'metrics-endpoint.metadata-current-default-0.16.0-dev.0', type: 'transform' }, + ], + }, + ], + ]); + }); + + test('can delete transform ref when previous version and current version are not the same', async () => { + await deleteTransformRefs( + savedObjectsClient, + [ + { id: 'metrics-endpoint.policy-0.16.0-dev.0', type: 'ingest_pipeline' }, + { id: 'metrics-endpoint.metadata-current-default-0.16.0-dev.0', type: 'transform' }, + ] as EsAssetReference[], + 'endpoint', + ['metrics-endpoint.metadata-current-default-0.15.0-dev.0'], + ['metrics-endpoint.metadata-current-default-0.16.0-dev.0'] + ); + + expect(savedObjectsClient.update.mock.calls).toEqual([ + [ + 'epm-packages', + 'endpoint', + { + installed_es: [ + { id: 'metrics-endpoint.policy-0.16.0-dev.0', type: 'ingest_pipeline' }, + { id: 'metrics-endpoint.metadata-current-default-0.16.0-dev.0', type: 'transform' }, + ], + }, + ], + ]); + }); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts new file mode 100644 index 0000000000000..5c9d3e2846200 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SavedObjectsClientContract } from 'kibana/server'; +import { CallESAsCurrentUser, ElasticsearchAssetType, EsAssetReference } from '../../../../types'; +import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../../../common/constants'; + +export const stopTransforms = async (transformIds: string[], callCluster: CallESAsCurrentUser) => { + for (const transformId of transformIds) { + await callCluster('transport.request', { + method: 'POST', + path: `_transform/${transformId}/_stop`, + query: 'force=true', + ignore: [404], + }); + } +}; + +export const deleteTransforms = async ( + callCluster: CallESAsCurrentUser, + transformIds: string[] +) => { + await Promise.all( + transformIds.map(async (transformId) => { + await stopTransforms([transformId], callCluster); + await callCluster('transport.request', { + method: 'DELETE', + query: 'force=true', + path: `_transform/${transformId}`, + ignore: [404], + }); + }) + ); +}; + +export const deleteTransformRefs = async ( + savedObjectsClient: SavedObjectsClientContract, + installedEsAssets: EsAssetReference[], + pkgName: string, + installedEsIdToRemove: string[], + currentInstalledEsTransformIds: string[] +) => { + const seen = new Set(); + const filteredAssets = installedEsAssets.filter(({ type, id }) => { + if (type !== ElasticsearchAssetType.transform) return true; + const add = + (currentInstalledEsTransformIds.includes(id) || !installedEsIdToRemove.includes(id)) && + !seen.has(id); + seen.add(id); + return add; + }); + return savedObjectsClient.update(PACKAGES_SAVED_OBJECT_TYPE, pkgName, { + installed_es: filteredAssets, + }); +}; diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts new file mode 100644 index 0000000000000..0b66077b8699a --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts @@ -0,0 +1,420 @@ +/* + * 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. + */ + +jest.mock('../../packages/get', () => { + return { getInstallation: jest.fn(), getInstallationObject: jest.fn() }; +}); + +jest.mock('./common', () => { + return { + getAsset: jest.fn(), + }; +}); + +import { installTransformForDataset } from './install'; +import { ILegacyScopedClusterClient, SavedObject, SavedObjectsClientContract } from 'kibana/server'; +import { ElasticsearchAssetType, Installation, RegistryPackage } from '../../../../types'; +import { getInstallation, getInstallationObject } from '../../packages'; +import { getAsset } from './common'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { savedObjectsClientMock } from '../../../../../../../../src/core/server/saved_objects/service/saved_objects_client.mock'; + +describe('test transform install', () => { + let legacyScopedClusterClient: jest.Mocked; + let savedObjectsClient: jest.Mocked; + beforeEach(() => { + legacyScopedClusterClient = { + callAsInternalUser: jest.fn(), + callAsCurrentUser: jest.fn(), + }; + (getInstallation as jest.MockedFunction).mockReset(); + (getInstallationObject as jest.MockedFunction).mockReset(); + savedObjectsClient = savedObjectsClientMock.create(); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test('can install new versions and removes older version', async () => { + const previousInstallation: Installation = ({ + installed_es: [ + { + id: 'metrics-endpoint.policy-0.16.0-dev.0', + type: ElasticsearchAssetType.ingestPipeline, + }, + { + id: 'metrics-endpoint.metadata_current-default-0.15.0-dev.0', + type: ElasticsearchAssetType.transform, + }, + ], + } as unknown) as Installation; + + const currentInstallation: Installation = ({ + installed_es: [ + { + id: 'metrics-endpoint.policy-0.16.0-dev.0', + type: ElasticsearchAssetType.ingestPipeline, + }, + { + id: 'metrics-endpoint.metadata_current-default-0.15.0-dev.0', + type: ElasticsearchAssetType.transform, + }, + { + id: 'metrics-endpoint.metadata_current-default-0.16.0-dev.0', + type: ElasticsearchAssetType.transform, + }, + { + id: 'metrics-endpoint.metadata-default-0.16.0-dev.0', + type: ElasticsearchAssetType.transform, + }, + ], + } as unknown) as Installation; + (getAsset as jest.MockedFunction) + .mockReturnValueOnce(Buffer.from('{"content": "data"}', 'utf8')) + .mockReturnValueOnce(Buffer.from('{"content": "data"}', 'utf8')); + + (getInstallation as jest.MockedFunction) + .mockReturnValueOnce(Promise.resolve(previousInstallation)) + .mockReturnValueOnce(Promise.resolve(currentInstallation)); + + (getInstallationObject as jest.MockedFunction< + typeof getInstallationObject + >).mockReturnValueOnce( + Promise.resolve(({ + attributes: { + installed_es: previousInstallation.installed_es, + }, + } as unknown) as SavedObject) + ); + + await installTransformForDataset( + ({ + name: 'endpoint', + version: '0.16.0-dev.0', + datasets: [ + { + type: 'metrics', + name: 'endpoint.metadata', + title: 'Endpoint Metadata', + release: 'experimental', + package: 'endpoint', + ingest_pipeline: 'default', + elasticsearch: { + 'index_template.mappings': { + dynamic: false, + }, + }, + path: 'metadata', + }, + { + type: 'metrics', + name: 'endpoint.metadata_current', + title: 'Endpoint Metadata Current', + release: 'experimental', + package: 'endpoint', + ingest_pipeline: 'default', + elasticsearch: { + 'index_template.mappings': { + dynamic: false, + }, + }, + path: 'metadata_current', + }, + ], + } as unknown) as RegistryPackage, + [ + 'endpoint-0.16.0-dev.0/dataset/policy/elasticsearch/ingest_pipeline/default.json', + 'endpoint-0.16.0-dev.0/dataset/metadata/elasticsearch/transform/default.json', + 'endpoint-0.16.0-dev.0/dataset/metadata_current/elasticsearch/transform/default.json', + ], + legacyScopedClusterClient.callAsCurrentUser, + savedObjectsClient + ); + + expect(legacyScopedClusterClient.callAsCurrentUser.mock.calls).toEqual([ + [ + 'transport.request', + { + method: 'POST', + path: '_transform/metrics-endpoint.metadata_current-default-0.15.0-dev.0/_stop', + query: 'force=true', + ignore: [404], + }, + ], + [ + 'transport.request', + { + method: 'DELETE', + query: 'force=true', + path: '_transform/metrics-endpoint.metadata_current-default-0.15.0-dev.0', + ignore: [404], + }, + ], + [ + 'transport.request', + { + method: 'PUT', + path: '_transform/metrics-endpoint.metadata-default-0.16.0-dev.0', + query: 'defer_validation=true', + body: '{"content": "data"}', + }, + ], + [ + 'transport.request', + { + method: 'PUT', + path: '_transform/metrics-endpoint.metadata_current-default-0.16.0-dev.0', + query: 'defer_validation=true', + body: '{"content": "data"}', + }, + ], + [ + 'transport.request', + { + method: 'POST', + path: '_transform/metrics-endpoint.metadata-default-0.16.0-dev.0/_start', + }, + ], + [ + 'transport.request', + { + method: 'POST', + path: '_transform/metrics-endpoint.metadata_current-default-0.16.0-dev.0/_start', + }, + ], + ]); + + expect(savedObjectsClient.update.mock.calls).toEqual([ + [ + 'epm-packages', + 'endpoint', + { + installed_es: [ + { + id: 'metrics-endpoint.policy-0.16.0-dev.0', + type: 'ingest_pipeline', + }, + { + id: 'metrics-endpoint.metadata_current-default-0.15.0-dev.0', + type: 'transform', + }, + { + id: 'metrics-endpoint.metadata-default-0.16.0-dev.0', + type: 'transform', + }, + { + id: 'metrics-endpoint.metadata_current-default-0.16.0-dev.0', + type: 'transform', + }, + ], + }, + ], + [ + 'epm-packages', + 'endpoint', + { + installed_es: [ + { + id: 'metrics-endpoint.policy-0.16.0-dev.0', + type: 'ingest_pipeline', + }, + { + id: 'metrics-endpoint.metadata_current-default-0.16.0-dev.0', + type: 'transform', + }, + { + id: 'metrics-endpoint.metadata-default-0.16.0-dev.0', + type: 'transform', + }, + ], + }, + ], + ]); + }); + + test('can install new version and when no older version', async () => { + const previousInstallation: Installation = ({ + installed_es: [], + } as unknown) as Installation; + + const currentInstallation: Installation = ({ + installed_es: [ + { + id: 'metrics-endpoint.metadata-current-default-0.16.0-dev.0', + type: ElasticsearchAssetType.transform, + }, + ], + } as unknown) as Installation; + (getAsset as jest.MockedFunction).mockReturnValueOnce( + Buffer.from('{"content": "data"}', 'utf8') + ); + (getInstallation as jest.MockedFunction) + .mockReturnValueOnce(Promise.resolve(previousInstallation)) + .mockReturnValueOnce(Promise.resolve(currentInstallation)); + + (getInstallationObject as jest.MockedFunction< + typeof getInstallationObject + >).mockReturnValueOnce( + Promise.resolve(({ attributes: { installed_es: [] } } as unknown) as SavedObject< + Installation + >) + ); + legacyScopedClusterClient.callAsCurrentUser = jest.fn(); + await installTransformForDataset( + ({ + name: 'endpoint', + version: '0.16.0-dev.0', + datasets: [ + { + type: 'metrics', + name: 'endpoint.metadata_current', + title: 'Endpoint Metadata', + release: 'experimental', + package: 'endpoint', + ingest_pipeline: 'default', + elasticsearch: { + 'index_template.mappings': { + dynamic: false, + }, + }, + path: 'metadata_current', + }, + ], + } as unknown) as RegistryPackage, + ['endpoint-0.16.0-dev.0/dataset/metadata_current/elasticsearch/transform/default.json'], + legacyScopedClusterClient.callAsCurrentUser, + savedObjectsClient + ); + + expect(legacyScopedClusterClient.callAsCurrentUser.mock.calls).toEqual([ + [ + 'transport.request', + { + method: 'PUT', + path: '_transform/metrics-endpoint.metadata_current-default-0.16.0-dev.0', + query: 'defer_validation=true', + body: '{"content": "data"}', + }, + ], + [ + 'transport.request', + { + method: 'POST', + path: '_transform/metrics-endpoint.metadata_current-default-0.16.0-dev.0/_start', + }, + ], + ]); + expect(savedObjectsClient.update.mock.calls).toEqual([ + [ + 'epm-packages', + 'endpoint', + { + installed_es: [ + { id: 'metrics-endpoint.metadata_current-default-0.16.0-dev.0', type: 'transform' }, + ], + }, + ], + ]); + }); + + test('can removes older version when no new install in package', async () => { + const previousInstallation: Installation = ({ + installed_es: [ + { + id: 'metrics-endpoint.metadata-current-default-0.15.0-dev.0', + type: ElasticsearchAssetType.transform, + }, + ], + } as unknown) as Installation; + + const currentInstallation: Installation = ({ + installed_es: [], + } as unknown) as Installation; + + (getInstallation as jest.MockedFunction) + .mockReturnValueOnce(Promise.resolve(previousInstallation)) + .mockReturnValueOnce(Promise.resolve(currentInstallation)); + + (getInstallationObject as jest.MockedFunction< + typeof getInstallationObject + >).mockReturnValueOnce( + Promise.resolve(({ + attributes: { installed_es: currentInstallation.installed_es }, + } as unknown) as SavedObject) + ); + + await installTransformForDataset( + ({ + name: 'endpoint', + version: '0.16.0-dev.0', + datasets: [ + { + type: 'metrics', + name: 'endpoint.metadata', + title: 'Endpoint Metadata', + release: 'experimental', + package: 'endpoint', + ingest_pipeline: 'default', + elasticsearch: { + 'index_template.mappings': { + dynamic: false, + }, + }, + path: 'metadata', + }, + { + type: 'metrics', + name: 'endpoint.metadata_current', + title: 'Endpoint Metadata Current', + release: 'experimental', + package: 'endpoint', + ingest_pipeline: 'default', + elasticsearch: { + 'index_template.mappings': { + dynamic: false, + }, + }, + path: 'metadata_current', + }, + ], + } as unknown) as RegistryPackage, + [], + legacyScopedClusterClient.callAsCurrentUser, + savedObjectsClient + ); + + expect(legacyScopedClusterClient.callAsCurrentUser.mock.calls).toEqual([ + [ + 'transport.request', + { + ignore: [404], + method: 'POST', + path: '_transform/metrics-endpoint.metadata-current-default-0.15.0-dev.0/_stop', + query: 'force=true', + }, + ], + [ + 'transport.request', + { + ignore: [404], + method: 'DELETE', + path: '_transform/metrics-endpoint.metadata-current-default-0.15.0-dev.0', + query: 'force=true', + }, + ], + ]); + expect(savedObjectsClient.update.mock.calls).toEqual([ + [ + 'epm-packages', + 'endpoint', + { + installed_es: [], + }, + ], + ]); + }); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.test.ts new file mode 100644 index 0000000000000..cc26e631a6215 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.test.ts @@ -0,0 +1,77 @@ +/* + * 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 { ElasticsearchAssetType, Installation, KibanaAssetType } from '../../../types'; +import { SavedObject } from 'src/core/server'; +import { getInstallType } from './install'; + +const mockInstallation: SavedObject = { + id: 'test-pkg', + references: [], + type: 'epm-packages', + attributes: { + id: 'test-pkg', + installed_kibana: [{ type: KibanaAssetType.dashboard, id: 'dashboard-1' }], + installed_es: [{ type: ElasticsearchAssetType.ingestPipeline, id: 'pipeline' }], + es_index_patterns: { pattern: 'pattern-name' }, + name: 'test packagek', + version: '1.0.0', + install_status: 'installed', + install_version: '1.0.0', + install_started_at: new Date().toISOString(), + }, +}; +const mockInstallationUpdateFail: SavedObject = { + id: 'test-pkg', + references: [], + type: 'epm-packages', + attributes: { + id: 'test-pkg', + installed_kibana: [{ type: KibanaAssetType.dashboard, id: 'dashboard-1' }], + installed_es: [{ type: ElasticsearchAssetType.ingestPipeline, id: 'pipeline' }], + es_index_patterns: { pattern: 'pattern-name' }, + name: 'test packagek', + version: '1.0.0', + install_status: 'installing', + install_version: '1.0.1', + install_started_at: new Date().toISOString(), + }, +}; +describe('install', () => { + describe('getInstallType', () => { + it('should return correct type when installing and no other version is currently installed', () => {}); + const installTypeInstall = getInstallType({ pkgVersion: '1.0.0', installedPkg: undefined }); + expect(installTypeInstall).toBe('install'); + + it('should return correct type when installing the same version', () => {}); + const installTypeReinstall = getInstallType({ + pkgVersion: '1.0.0', + installedPkg: mockInstallation, + }); + expect(installTypeReinstall).toBe('reinstall'); + + it('should return correct type when moving from one version to another', () => {}); + const installTypeUpdate = getInstallType({ + pkgVersion: '1.0.1', + installedPkg: mockInstallation, + }); + expect(installTypeUpdate).toBe('update'); + + it('should return correct type when update fails and trys again', () => {}); + const installTypeReupdate = getInstallType({ + pkgVersion: '1.0.1', + installedPkg: mockInstallationUpdateFail, + }); + expect(installTypeReupdate).toBe('reupdate'); + + it('should return correct type when attempting to rollback from a failed update', () => {}); + const installTypeRollback = getInstallType({ + pkgVersion: '1.0.0', + installedPkg: mockInstallationUpdateFail, + }); + expect(installTypeRollback).toBe('rollback'); + }); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts index e49dbe8f0b5d4..e6144e0309594 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SavedObjectsClientContract } from 'src/core/server'; +import { SavedObject, SavedObjectsClientContract } from 'src/core/server'; import semver from 'semver'; import { PACKAGES_SAVED_OBJECT_TYPE, MAX_TIME_COMPLETE_INSTALL } from '../../../constants'; import { @@ -16,6 +16,7 @@ import { KibanaAssetReference, EsAssetReference, ElasticsearchAssetType, + InstallType, } from '../../../types'; import { installIndexPatterns } from '../kibana/index_pattern/install'; import * as Registry from '../registry'; @@ -34,6 +35,7 @@ import { updateCurrentWriteIndices } from '../elasticsearch/template/template'; import { deleteKibanaSavedObjectsAssets } from './remove'; import { PackageOutdatedError } from '../../../errors'; import { getPackageSavedObjects } from './get'; +import { installTransformForDataset } from '../elasticsearch/transform/install'; export async function installLatestPackage(options: { savedObjectsClient: SavedObjectsClientContract; @@ -110,11 +112,13 @@ export async function installPackage({ const latestPackage = await Registry.fetchFindLatestPackage(pkgName); // get the currently installed package const installedPkg = await getInstallationObject({ savedObjectsClient, pkgName }); - const reinstall = pkgVersion === installedPkg?.attributes.version; - const reupdate = pkgVersion === installedPkg?.attributes.install_version; - // let the user install if using the force flag or this is a reinstall or reupdate due to intallation interruption - if (semver.lt(pkgVersion, latestPackage.version) && !force && !reinstall && !reupdate) { + const installType = getInstallType({ pkgVersion, installedPkg }); + + // let the user install if using the force flag or needing to reinstall or install a previous version due to failed update + const installOutOfDateVersionOk = + installType === 'reinstall' || installType === 'reupdate' || installType === 'rollback'; + if (semver.lt(pkgVersion, latestPackage.version) && !force && !installOutOfDateVersionOk) { throw new PackageOutdatedError(`${pkgkey} is out-of-date and cannot be installed or updated`); } const paths = await Registry.getArchiveInfo(pkgName, pkgVersion); @@ -188,28 +192,51 @@ export async function installPackage({ // update current backing indices of each data stream await updateCurrentWriteIndices(callCluster, installedTemplates); - // if this is an update, delete the previous version's pipelines - if (installedPkg && !reinstall) { + const installedTransforms = await installTransformForDataset( + registryPackageInfo, + paths, + callCluster, + savedObjectsClient + ); + + // if this is an update or retrying an update, delete the previous version's pipelines + if (installType === 'update' || installType === 'reupdate') { await deletePreviousPipelines( callCluster, savedObjectsClient, pkgName, + // @ts-ignore installType conditions already check for existence of installedPkg installedPkg.attributes.version ); } - + // pipelines from a different version may have installed during a failed update + if (installType === 'rollback') { + await deletePreviousPipelines( + callCluster, + savedObjectsClient, + pkgName, + // @ts-ignore installType conditions already check for existence of installedPkg + installedPkg.attributes.install_version + ); + } const installedTemplateRefs = installedTemplates.map((template) => ({ id: template.templateName, type: ElasticsearchAssetType.indexTemplate, })); await Promise.all([installKibanaAssetsPromise, installIndexPatternPromise]); + // update to newly installed version when all assets are successfully installed if (installedPkg) await updateVersion(savedObjectsClient, pkgName, pkgVersion); await savedObjectsClient.update(PACKAGES_SAVED_OBJECT_TYPE, pkgName, { install_version: pkgVersion, install_status: 'installed', }); - return [...installedKibanaAssetsRefs, ...installedPipelines, ...installedTemplateRefs]; + return [ + ...installedKibanaAssetsRefs, + ...installedPipelines, + ...installedTemplateRefs, + ...installedTransforms, + ]; } const updateVersion = async ( @@ -326,3 +353,23 @@ export async function ensurePackagesCompletedInstall( await Promise.all(installingPromises); return installingPackages; } + +export function getInstallType({ + pkgVersion, + installedPkg, +}: { + pkgVersion: string; + installedPkg: SavedObject | undefined; +}): InstallType { + const isInstalledPkg = !!installedPkg; + const currentPkgVersion = installedPkg?.attributes.version; + const lastStartedInstallVersion = installedPkg?.attributes.install_version; + if (!isInstalledPkg) return 'install'; + if (pkgVersion === currentPkgVersion && pkgVersion !== lastStartedInstallVersion) + return 'rollback'; + if (pkgVersion === currentPkgVersion) return 'reinstall'; + if (pkgVersion === lastStartedInstallVersion && pkgVersion !== currentPkgVersion) + return 'reupdate'; + if (pkgVersion !== lastStartedInstallVersion && pkgVersion !== currentPkgVersion) return 'update'; + throw new Error('unknown install type'); +} diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts index 71eee1ee82c90..2434ebf27aa5d 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts @@ -6,12 +6,17 @@ import { SavedObjectsClientContract } from 'src/core/server'; import Boom from 'boom'; -import { PACKAGES_SAVED_OBJECT_TYPE, PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '../../../constants'; -import { AssetReference, AssetType, ElasticsearchAssetType } from '../../../types'; -import { CallESAsCurrentUser } from '../../../types'; +import { PACKAGE_POLICY_SAVED_OBJECT_TYPE, PACKAGES_SAVED_OBJECT_TYPE } from '../../../constants'; +import { + AssetReference, + AssetType, + CallESAsCurrentUser, + ElasticsearchAssetType, +} from '../../../types'; import { getInstallation, savedObjectTypes } from './index'; import { deletePipeline } from '../elasticsearch/ingest_pipeline/'; import { installIndexPatterns } from '../kibana/index_pattern/install'; +import { deleteTransforms } from '../elasticsearch/transform/remove'; import { packagePolicyService, appContextService } from '../..'; import { splitPkgKey, deletePackageCache, getArchiveInfo } from '../registry'; @@ -72,6 +77,8 @@ async function deleteAssets( return deletePipeline(callCluster, id); } else if (assetType === ElasticsearchAssetType.indexTemplate) { return deleteTemplate(callCluster, id); + } else if (assetType === ElasticsearchAssetType.transform) { + return deleteTransforms(callCluster, [id]); } }); try { diff --git a/x-pack/plugins/ingest_manager/server/types/index.tsx b/x-pack/plugins/ingest_manager/server/types/index.tsx index e01568cfbb3c9..2746dfcd00ce3 100644 --- a/x-pack/plugins/ingest_manager/server/types/index.tsx +++ b/x-pack/plugins/ingest_manager/server/types/index.tsx @@ -63,6 +63,7 @@ export { IndexTemplateMappings, Settings, SettingsSOAttributes, + InstallType, // Agent Request types PostAgentEnrollRequest, PostAgentCheckinRequest, diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/kv.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/kv.tsx index f51bf19ad180a..4104e8f727ab1 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/kv.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/kv.tsx @@ -33,9 +33,15 @@ const fieldsConfig: FieldsConfig = { label: i18n.translate('xpack.ingestPipelines.pipelineEditor.kvForm.fieldSplitFieldLabel', { defaultMessage: 'Field split', }), - helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.kvForm.fieldSplitHelpText', { - defaultMessage: 'Regex pattern for splitting key-value pairs.', - }), + helpText: ( + {'" "'}, + }} + /> + ), validations: [ { validator: emptyField( @@ -52,9 +58,15 @@ const fieldsConfig: FieldsConfig = { label: i18n.translate('xpack.ingestPipelines.pipelineEditor.kvForm.valueSplitFieldLabel', { defaultMessage: 'Value split', }), - helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.kvForm.valueSplitHelpText', { - defaultMessage: 'Regex pattern for splitting the key from the value within a key-value pair.', - }), + helpText: ( + {'"="'}, + }} + /> + ), validations: [ { validator: emptyField( @@ -75,8 +87,7 @@ const fieldsConfig: FieldsConfig = { defaultMessage: 'Include keys', }), helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.kvForm.includeKeysHelpText', { - defaultMessage: - 'List of keys to filter and insert into document. Defaults to including all keys.', + defaultMessage: 'List of extracted keys to include in the output. Defaults to all keys.', }), }, @@ -88,7 +99,7 @@ const fieldsConfig: FieldsConfig = { defaultMessage: 'Exclude keys', }), helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.kvForm.excludeKeysHelpText', { - defaultMessage: 'List of keys to exclude from document.', + defaultMessage: 'List of extracted keys to exclude from the output.', }), }, @@ -99,7 +110,7 @@ const fieldsConfig: FieldsConfig = { defaultMessage: 'Prefix', }), helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.kvForm.prefixHelpText', { - defaultMessage: 'Prefix to be added to extracted keys.', + defaultMessage: 'Prefix to add to extracted keys.', }), }, @@ -136,7 +147,7 @@ const fieldsConfig: FieldsConfig = { helpText: ( {'()'}, angle: <>, @@ -154,7 +165,7 @@ export const Kv: FunctionComponent = () => { <> @@ -166,8 +177,7 @@ export const Kv: FunctionComponent = () => { helpText={i18n.translate( 'xpack.ingestPipelines.pipelineEditor.kvForm.targetFieldHelpText', { - defaultMessage: - 'Field to insert the extracted keys into. Defaults to the root of the document.', + defaultMessage: 'Output field for the extracted fields. Defaults to the document root.', } )} /> diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/lowercase.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/lowercase.tsx index 9db313a05007f..0d8170338ea10 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/lowercase.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/lowercase.tsx @@ -6,8 +6,6 @@ import React, { FunctionComponent } from 'react'; import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiCode } from '@elastic/eui'; import { FieldNameField } from './common_fields/field_name_field'; import { TargetField } from './common_fields/target_field'; @@ -23,17 +21,7 @@ export const Lowercase: FunctionComponent = () => { )} /> - {'field'}, - }} - /> - } - /> + diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/pipeline.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/pipeline.tsx index c785cf935833d..57843e2411359 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/pipeline.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/pipeline.tsx @@ -27,7 +27,7 @@ const fieldsConfig: FieldsConfig = { helpText: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.pipelineForm.pipelineNameFieldHelpText', { - defaultMessage: 'Name of the pipeline to execute.', + defaultMessage: 'Name of the ingest pipeline to run.', } ), validations: [ diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/remove.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/remove.tsx index 3e90ce2b76f7b..3ba1cdb0c802d 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/remove.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/remove.tsx @@ -29,7 +29,7 @@ const fieldsConfig: FieldsConfig = { defaultMessage: 'Fields', }), helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.removeForm.fieldNameHelpText', { - defaultMessage: 'Fields to be removed.', + defaultMessage: 'Fields to remove.', }), validations: [ { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/rename.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/rename.tsx index 8b796d9664586..099e2bd2c80fb 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/rename.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/rename.tsx @@ -21,7 +21,7 @@ export const Rename: FunctionComponent = () => { @@ -31,7 +31,7 @@ export const Rename: FunctionComponent = () => { })} helpText={i18n.translate( 'xpack.ingestPipelines.pipelineEditor.renameForm.targetFieldHelpText', - { defaultMessage: 'Name of the new field.' } + { defaultMessage: 'New field name. This field cannot already exist.' } )} validations={[ { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/script.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/script.tsx index ae0bbbb490ae9..de28f66766603 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/script.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/script.tsx @@ -32,7 +32,7 @@ const fieldsConfig: FieldsConfig = { helpText: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.scriptForm.storedScriptIDFieldHelpText', { - defaultMessage: 'Stored script reference.', + defaultMessage: 'ID of the stored script to run.', } ), validations: [ @@ -55,7 +55,7 @@ const fieldsConfig: FieldsConfig = { helpText: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.scriptForm.sourceFieldHelpText', { - defaultMessage: 'Script to be executed.', + defaultMessage: 'Inline script to run.', } ), validations: [ @@ -98,7 +98,7 @@ const fieldsConfig: FieldsConfig = { helpText: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.scriptForm.paramsFieldHelpText', { - defaultMessage: 'Script parameters.', + defaultMessage: 'Named parameters passed to the script as variables.', } ), validations: [ @@ -128,7 +128,7 @@ export const Script: FormFieldsComponent = ({ initialFieldValues }) => { setShowId((v) => !v)} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx index c282be35e5071..04ea0c44c3513 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx @@ -32,13 +32,13 @@ const fieldsConfig: FieldsConfig = { defaultMessage: 'Value', }), helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.setForm.valueFieldHelpText', { - defaultMessage: 'Value to be set for the field', + defaultMessage: 'Value for the field.', }), validations: [ { validator: emptyField( i18n.translate('xpack.ingestPipelines.pipelineEditor.setForm.valueRequiredError', { - defaultMessage: 'A value is required', + defaultMessage: 'A value is required.', }) ), }, @@ -53,9 +53,15 @@ const fieldsConfig: FieldsConfig = { label: i18n.translate('xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldLabel', { defaultMessage: 'Override', }), - helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldHelpText', { - defaultMessage: 'If disabled, fields containing non-null values will not be updated.', - }), + helpText: ( + {'null'}, + }} + /> + ), }, ignore_empty_value: { type: FIELD_TYPES.TOGGLE, @@ -71,7 +77,8 @@ const fieldsConfig: FieldsConfig = { helpText: ( {'value'}, nullValue: {'null'}, @@ -89,7 +96,7 @@ export const SetProcessor: FunctionComponent = () => { <> diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set_security_user.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set_security_user.tsx index 78128b3d54c75..46bfe8c97ebea 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set_security_user.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set_security_user.tsx @@ -44,7 +44,7 @@ const fieldsConfig: FieldsConfig = { helpText: ( [{helpTextValues}], }} @@ -60,7 +60,7 @@ export const SetSecurityUser: FunctionComponent = () => { helpText={i18n.translate( 'xpack.ingestPipelines.pipelineEditor.setSecurityUserForm.fieldNameField', { - defaultMessage: 'Field to store the user information', + defaultMessage: 'Output field.', } )} /> diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/sort.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/sort.tsx index cdd0ff888accf..c8c0562011fd6 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/sort.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/sort.tsx @@ -24,7 +24,8 @@ const fieldsConfig: FieldsConfig = { defaultMessage: 'Order', }), helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.sortForm.orderFieldHelpText', { - defaultMessage: 'Sort order to use', + defaultMessage: + 'Sort order. Arrays containing a mix of strings and numbers are sorted lexicographically.', }), }, }; @@ -35,7 +36,7 @@ export const Sort: FunctionComponent = () => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/split.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/split.tsx index b48ce74110b39..fa178aaddd314 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/split.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/split.tsx @@ -33,7 +33,7 @@ const fieldsConfig: FieldsConfig = { helpText: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.splitForm.separatorFieldHelpText', { - defaultMessage: 'Regex to match a separator', + defaultMessage: 'Regex pattern used to delimit the field value.', } ), validations: [ @@ -60,7 +60,7 @@ const fieldsConfig: FieldsConfig = { ), helpText: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.splitForm.preserveTrailingFieldHelpText', - { defaultMessage: 'If enabled, preserve any trailing space.' } + { defaultMessage: 'Preserve any trailing whitespace in the split field values.' } ), }, }; @@ -71,7 +71,7 @@ export const Split: FunctionComponent = () => { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx index 59ec64944a3c9..9de371f8d0024 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx @@ -107,7 +107,7 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { defaultMessage: 'CSV', }), description: i18n.translate('xpack.ingestPipelines.processors.description.csv', { - defaultMessage: 'Extracts fields values from CSV data.', + defaultMessage: 'Extracts field values from CSV data.', }), }, date: { @@ -306,7 +306,10 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { FieldsComponent: Kv, docLinkPath: '/kv-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.kv', { - defaultMessage: 'KV', + defaultMessage: 'Key-value (KV)', + }), + description: i18n.translate('xpack.ingestPipelines.processors.description.kv', { + defaultMessage: 'Extracts fields from a string containing key-value pairs.', }), }, lowercase: { @@ -315,6 +318,9 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { label: i18n.translate('xpack.ingestPipelines.processors.label.lowercase', { defaultMessage: 'Lowercase', }), + description: i18n.translate('xpack.ingestPipelines.processors.description.lowercase', { + defaultMessage: 'Converts a string to lowercase.', + }), }, pipeline: { FieldsComponent: Pipeline, @@ -322,6 +328,9 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { label: i18n.translate('xpack.ingestPipelines.processors.label.pipeline', { defaultMessage: 'Pipeline', }), + description: i18n.translate('xpack.ingestPipelines.processors.description.pipeline', { + defaultMessage: 'Runs another ingest node pipeline.', + }), }, remove: { FieldsComponent: Remove, @@ -329,6 +338,9 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { label: i18n.translate('xpack.ingestPipelines.processors.label.remove', { defaultMessage: 'Remove', }), + description: i18n.translate('xpack.ingestPipelines.processors.description.remove', { + defaultMessage: 'Removes one or more fields.', + }), }, rename: { FieldsComponent: Rename, @@ -336,6 +348,9 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { label: i18n.translate('xpack.ingestPipelines.processors.label.rename', { defaultMessage: 'Rename', }), + description: i18n.translate('xpack.ingestPipelines.processors.description.rename', { + defaultMessage: 'Renames an existing field.', + }), }, script: { FieldsComponent: Script, @@ -343,6 +358,9 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { label: i18n.translate('xpack.ingestPipelines.processors.label.script', { defaultMessage: 'Script', }), + description: i18n.translate('xpack.ingestPipelines.processors.description.script', { + defaultMessage: 'Runs a script on incoming documents.', + }), }, set: { FieldsComponent: SetProcessor, @@ -350,6 +368,9 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { label: i18n.translate('xpack.ingestPipelines.processors.label.set', { defaultMessage: 'Set', }), + description: i18n.translate('xpack.ingestPipelines.processors.description.set', { + defaultMessage: 'Sets the value of a field.', + }), }, set_security_user: { FieldsComponent: SetSecurityUser, @@ -357,12 +378,9 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { label: i18n.translate('xpack.ingestPipelines.processors.label.setSecurityUser', { defaultMessage: 'Set security user', }), - }, - split: { - FieldsComponent: Split, - docLinkPath: '/split-processor.html', - label: i18n.translate('xpack.ingestPipelines.processors.label.split', { - defaultMessage: 'Split', + description: i18n.translate('xpack.ingestPipelines.processors.description.setSecurityUser', { + defaultMessage: + 'Adds details about the current user, such user name and email address, to incoming documents. Requires an authenticated user for the indexing request.', }), }, sort: { @@ -371,6 +389,19 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { label: i18n.translate('xpack.ingestPipelines.processors.label.sort', { defaultMessage: 'Sort', }), + description: i18n.translate('xpack.ingestPipelines.processors.description.sort', { + defaultMessage: "Sorts a field's array elements.", + }), + }, + split: { + FieldsComponent: Split, + docLinkPath: '/split-processor.html', + label: i18n.translate('xpack.ingestPipelines.processors.label.split', { + defaultMessage: 'Split', + }), + description: i18n.translate('xpack.ingestPipelines.processors.description.split', { + defaultMessage: 'Splits a field value into an array.', + }), }, trim: { FieldsComponent: undefined, // TODO: Implement diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/main.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/main.tsx index ccb50376dddb7..88148f1bc5746 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/main.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_list/main.tsx @@ -51,7 +51,7 @@ export const PipelinesList: React.FunctionComponent = ({ const [pipelinesToDelete, setPipelinesToDelete] = useState([]); - const { data, isLoading, error, sendRequest } = services.api.useLoadPipelines(); + const { data, isLoading, error, resendRequest } = services.api.useLoadPipelines(); // Track component loaded useEffect(() => { @@ -98,7 +98,7 @@ export const PipelinesList: React.FunctionComponent = ({ } else if (data?.length) { content = ( = ({ defaultMessage="Unable to load pipelines. {reloadLink}" values={{ reloadLink: ( - + = ({ callback={(deleteResponse) => { if (deleteResponse?.hasDeletedPipelines) { // reload pipelines list - sendRequest(); + resendRequest(); setSelectedPipeline(undefined); goHome(); } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx index a0cc5ec352130..cf15c29844053 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx @@ -117,14 +117,7 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) { ); function fetchData() { - if ( - state.isLoading || - (field.type !== 'number' && - field.type !== 'string' && - field.type !== 'date' && - field.type !== 'boolean' && - field.type !== 'ip') - ) { + if (state.isLoading) { return; } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts index 660be9514a92f..19213d4afc9bc 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts @@ -93,6 +93,16 @@ const indexPattern1 = ({ searchable: true, esTypes: ['keyword'], }, + { + name: 'scripted', + displayName: 'Scripted', + type: 'string', + searchable: true, + aggregatable: true, + scripted: true, + lang: 'painless', + script: '1234', + }, documentField, ], } as unknown) as IndexPattern; @@ -156,12 +166,13 @@ const indexPattern2 = ({ aggregatable: true, searchable: true, scripted: true, + lang: 'painless', + script: '1234', aggregationRestrictions: { terms: { agg: 'terms', }, }, - esTypes: ['keyword'], }, documentField, ], diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts index 585a1281cbf51..0ab658b961336 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts @@ -55,15 +55,27 @@ export async function loadIndexPatterns({ !indexPatternsUtils.isNestedField(field) && (!!field.aggregatable || !!field.scripted) ) .map( - (field): IndexPatternField => ({ - name: field.name, - displayName: field.displayName, - type: field.type, - aggregatable: field.aggregatable, - searchable: field.searchable, - scripted: field.scripted, - esTypes: field.esTypes, - }) + (field): IndexPatternField => { + // Convert the getters on the index pattern service into plain JSON + const base = { + name: field.name, + displayName: field.displayName, + type: field.type, + aggregatable: field.aggregatable, + searchable: field.searchable, + esTypes: field.esTypes, + scripted: field.scripted, + }; + + // Simplifies tests by hiding optional properties instead of undefined + return base.scripted + ? { + ...base, + lang: field.lang, + script: field.script, + } + : base; + } ) .concat(documentField); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts b/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts index 31e6240993d36..21ed23321cf57 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts @@ -64,6 +64,16 @@ export const createMockedIndexPattern = (): IndexPattern => ({ searchable: true, esTypes: ['keyword'], }, + { + name: 'scripted', + displayName: 'Scripted', + type: 'string', + searchable: true, + aggregatable: true, + scripted: true, + lang: 'painless', + script: '1234', + }, ], }); @@ -95,6 +105,8 @@ export const createMockedRestrictedIndexPattern = () => ({ searchable: true, scripted: true, esTypes: ['keyword'], + lang: 'painless', + script: '1234', }, ], typeMeta: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/types.ts b/x-pack/plugins/lens/public/indexpattern_datasource/types.ts index c101f1354b703..21ca41234fdf1 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/types.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/types.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { IFieldType } from 'src/plugins/data/common'; import { IndexPatternColumn } from './operations'; import { IndexPatternAggRestrictions } from '../../../../../src/plugins/data/public'; @@ -22,16 +23,10 @@ export interface IndexPattern { hasRestrictions: boolean; } -export interface IndexPatternField { - name: string; +export type IndexPatternField = IFieldType & { displayName: string; - type: string; - esTypes?: string[]; - aggregatable: boolean; - scripted?: boolean; - searchable: boolean; aggregationRestrictions?: Partial; -} +}; export interface IndexPatternLayer { columnOrder: string[]; diff --git a/x-pack/plugins/lens/server/routes/field_stats.ts b/x-pack/plugins/lens/server/routes/field_stats.ts index 20d3e2b4164ca..a7368a12f0e2c 100644 --- a/x-pack/plugins/lens/server/routes/field_stats.ts +++ b/x-pack/plugins/lens/server/routes/field_stats.ts @@ -8,6 +8,7 @@ import Boom from 'boom'; import DateMath from '@elastic/datemath'; import { schema } from '@kbn/config-schema'; import { CoreSetup } from 'src/core/server'; +import { IFieldType } from 'src/plugins/data/common'; import { ESSearchResponse } from '../../../apm/typings/elasticsearch'; import { FieldStatsResponse, BASE_API_URL } from '../../common'; @@ -33,6 +34,9 @@ export async function initFieldsRoute(setup: CoreSetup) { name: schema.string(), type: schema.string(), esTypes: schema.maybe(schema.arrayOf(schema.string())), + scripted: schema.maybe(schema.boolean()), + lang: schema.maybe(schema.string()), + script: schema.maybe(schema.string()), }, { unknowns: 'allow' } ), @@ -83,21 +87,15 @@ export async function initFieldsRoute(setup: CoreSetup) { return res.ok({ body: await getNumberHistogram(search, field), }); - } else if (field.type === 'string') { - return res.ok({ - body: await getStringSamples(search, field), - }); } else if (field.type === 'date') { return res.ok({ body: await getDateHistogram(search, field, { fromDate, toDate }), }); - } else if (field.type === 'boolean') { - return res.ok({ - body: await getStringSamples(search, field), - }); } - return res.ok({}); + return res.ok({ + body: await getStringSamples(search, field), + }); } catch (e) { if (e.status === 404) { return res.notFound(); @@ -119,8 +117,10 @@ export async function initFieldsRoute(setup: CoreSetup) { export async function getNumberHistogram( aggSearchWithBody: (body: unknown) => Promise, - field: { name: string; type: string; esTypes?: string[] } + field: IFieldType ): Promise { + const fieldRef = getFieldRef(field); + const searchBody = { sample: { sampler: { shard_size: SHARD_SIZE }, @@ -131,9 +131,9 @@ export async function getNumberHistogram( max_value: { max: { field: field.name }, }, - sample_count: { value_count: { field: field.name } }, + sample_count: { value_count: { ...fieldRef } }, top_values: { - terms: { field: field.name, size: 10 }, + terms: { ...fieldRef, size: 10 }, }, }, }, @@ -206,15 +206,20 @@ export async function getNumberHistogram( export async function getStringSamples( aggSearchWithBody: (body: unknown) => unknown, - field: { name: string; type: string } + field: IFieldType ): Promise { + const fieldRef = getFieldRef(field); + const topValuesBody = { sample: { sampler: { shard_size: SHARD_SIZE }, aggs: { - sample_count: { value_count: { field: field.name } }, + sample_count: { value_count: { ...fieldRef } }, top_values: { - terms: { field: field.name, size: 10 }, + terms: { + ...fieldRef, + size: 10, + }, }, }, }, @@ -241,7 +246,7 @@ export async function getStringSamples( // This one is not sampled so that it returns the full date range export async function getDateHistogram( aggSearchWithBody: (body: unknown) => unknown, - field: { name: string; type: string }, + field: IFieldType, range: { fromDate: string; toDate: string } ): Promise { const fromDate = DateMath.parse(range.fromDate); @@ -265,7 +270,7 @@ export async function getDateHistogram( const fixedInterval = `${interval}ms`; const histogramBody = { - histo: { date_histogram: { field: field.name, fixed_interval: fixedInterval } }, + histo: { date_histogram: { ...getFieldRef(field), fixed_interval: fixedInterval } }, }; const results = (await aggSearchWithBody(histogramBody)) as ESSearchResponse< unknown, @@ -283,3 +288,14 @@ export async function getDateHistogram( }, }; } + +function getFieldRef(field: IFieldType) { + return field.scripted + ? { + script: { + lang: field.lang as string, + source: field.script as string, + }, + } + : { field: field.name }; +} diff --git a/x-pack/plugins/maps/public/classes/joins/inner_join.js b/x-pack/plugins/maps/public/classes/joins/inner_join.js index 76afe2430b818..75bf59d9d6404 100644 --- a/x-pack/plugins/maps/public/classes/joins/inner_join.js +++ b/x-pack/plugins/maps/public/classes/joins/inner_join.js @@ -94,8 +94,8 @@ export class InnerJoin { return this._descriptor; } - async filterAndFormatPropertiesForTooltip(properties) { - return await this._rightSource.filterAndFormatPropertiesToHtml(properties); + async getTooltipProperties(properties) { + return await this._rightSource.getTooltipProperties(properties); } getIndexPatternIds() { diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js index c49d0044e6ad6..27c344b713a60 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js @@ -949,13 +949,11 @@ export class VectorLayer extends AbstractLayer { async getPropertiesForTooltip(properties) { const vectorSource = this.getSource(); - let allProperties = await vectorSource.filterAndFormatPropertiesToHtml(properties); + let allProperties = await vectorSource.getTooltipProperties(properties); this._addJoinsToSourceTooltips(allProperties); for (let i = 0; i < this.getJoins().length; i++) { - const propsFromJoin = await this.getJoins()[i].filterAndFormatPropertiesForTooltip( - properties - ); + const propsFromJoin = await this.getJoins()[i].getTooltipProperties(properties); allProperties = [...allProperties, ...propsFromJoin]; } return allProperties; diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.test.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.test.tsx index c5d6ced76b5c0..674ee832daab9 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.test.tsx @@ -17,10 +17,10 @@ function makeEMSFileSource(tooltipProperties: string[]) { } describe('EMS file source', () => { - describe('filterAndFormatPropertiesToHtml', () => { + describe('getTooltipProperties', () => { it('should create tooltip-properties with human readable label', async () => { const mockEMSFileSource = makeEMSFileSource(['iso2']); - const out = await mockEMSFileSource.filterAndFormatPropertiesToHtml({ + const out = await mockEMSFileSource.getTooltipProperties({ iso2: 'US', }); @@ -33,7 +33,7 @@ describe('EMS file source', () => { it('should order tooltip-properties', async () => { const tooltipProperties = ['iso3', 'iso2', 'name']; const mockEMSFileSource = makeEMSFileSource(tooltipProperties); - const out = await mockEMSFileSource.filterAndFormatPropertiesToHtml({ + const out = await mockEMSFileSource.getTooltipProperties({ name: 'United States', iso3: 'USA', iso2: 'US', diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.tsx index f55a7434d1217..5f73a9e23431b 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.tsx @@ -23,7 +23,6 @@ import { ITooltipProperty } from '../../tooltips/tooltip_property'; export interface IEmsFileSource extends IVectorSource { getEmsFieldLabel(emsFieldName: string): Promise; - createField({ fieldName }: { fieldName: string }): IField; } export const sourceTitle = i18n.translate('xpack.maps.source.emsFileTitle', { @@ -168,7 +167,7 @@ export class EMSFileSource extends AbstractVectorSource implements IEmsFileSourc return this._tooltipFields.length > 0; } - async filterAndFormatPropertiesToHtml(properties: unknown): Promise { + async getTooltipProperties(properties: unknown): Promise { const promises = this._tooltipFields.map((field) => { // @ts-ignore const value = properties[field.getName()]; diff --git a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.d.ts b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.d.ts deleted file mode 100644 index eb50cd7528c8b..0000000000000 --- a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 { IESSource } from '../es_source'; -import { AbstractESSource } from '../es_source'; -import { AGG_TYPE } from '../../../../common/constants'; -import { IESAggField } from '../../fields/es_agg_field'; -import { AbstractESAggSourceDescriptor } from '../../../../common/descriptor_types'; - -export interface IESAggSource extends IESSource { - getAggKey(aggType: AGG_TYPE, fieldName: string): string; - getAggLabel(aggType: AGG_TYPE, fieldName: string): string; - getMetricFields(): IESAggField[]; - hasMatchingMetricField(fieldName: string): boolean; - getMetricFieldForName(fieldName: string): IESAggField | null; -} - -export class AbstractESAggSource extends AbstractESSource implements IESAggSource { - constructor(sourceDescriptor: AbstractESAggSourceDescriptor, inspectorAdapters: object); - - getAggKey(aggType: AGG_TYPE, fieldName: string): string; - getAggLabel(aggType: AGG_TYPE, fieldName: string): string; - getMetricFields(): IESAggField[]; - hasMatchingMetricField(fieldName: string): boolean; - getMetricFieldForName(fieldName: string): IESAggField | null; -} diff --git a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.js b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts similarity index 56% rename from x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.js rename to x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts index e20c509ccd4a2..a9c886617d3af 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.js +++ b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts @@ -5,19 +5,38 @@ */ import { i18n } from '@kbn/i18n'; +import { Adapters } from 'src/plugins/inspector/public'; +import { GeoJsonProperties } from 'geojson'; +import { IESSource } from '../es_source'; import { AbstractESSource } from '../es_source'; import { esAggFieldsFactory } from '../../fields/es_agg_field'; import { AGG_TYPE, COUNT_PROP_LABEL, FIELD_ORIGIN } from '../../../../common/constants'; +import { IESAggField } from '../../fields/es_agg_field'; import { getSourceAggKey } from '../../../../common/get_agg_key'; +import { AbstractESAggSourceDescriptor, AggDescriptor } from '../../../../common/descriptor_types'; +import { IndexPattern } from '../../../../../../../src/plugins/data/public'; +import { IField } from '../../fields/field'; +import { ITooltipProperty } from '../../tooltips/tooltip_property'; export const DEFAULT_METRIC = { type: AGG_TYPE.COUNT }; +export interface IESAggSource extends IESSource { + getAggKey(aggType: AGG_TYPE, fieldName: string): string; + getAggLabel(aggType: AGG_TYPE, fieldName: string): string; + getMetricFields(): IESAggField[]; + hasMatchingMetricField(fieldName: string): boolean; + getMetricFieldForName(fieldName: string): IESAggField | null; + getValueAggsDsl(indexPattern: IndexPattern): { [key: string]: unknown }; +} + export class AbstractESAggSource extends AbstractESSource { - constructor(descriptor, inspectorAdapters) { + private readonly _metricFields: IESAggField[]; + + constructor(descriptor: AbstractESAggSourceDescriptor, inspectorAdapters: Adapters) { super(descriptor, inspectorAdapters); this._metricFields = []; - if (this._descriptor.metrics) { - this._descriptor.metrics.forEach((aggDescriptor) => { + if (descriptor.metrics) { + descriptor.metrics.forEach((aggDescriptor: AggDescriptor) => { this._metricFields.push( ...esAggFieldsFactory(aggDescriptor, this, this.getOriginForField()) ); @@ -25,30 +44,31 @@ export class AbstractESAggSource extends AbstractESSource { } } - getFieldByName(name) { - return this.getMetricFieldForName(name); + getFieldByName(fieldName: string) { + return this.getMetricFieldForName(fieldName); } - createField() { + createField({ fieldName }: { fieldName: string }): IField { throw new Error('Cannot create a new field from just a fieldname for an es_agg_source.'); } - hasMatchingMetricField(fieldName) { + hasMatchingMetricField(fieldName: string): boolean { const matchingField = this.getMetricFieldForName(fieldName); return !!matchingField; } - getMetricFieldForName(fieldName) { - return this.getMetricFields().find((metricField) => { + getMetricFieldForName(fieldName: string): IESAggField | null { + const targetMetricField = this.getMetricFields().find((metricField: IESAggField) => { return metricField.getName() === fieldName; }); + return targetMetricField ? targetMetricField : null; } getOriginForField() { return FIELD_ORIGIN.SOURCE; } - getMetricFields() { + getMetricFields(): IESAggField[] { const metrics = this._metricFields.filter((esAggField) => esAggField.isValid()); // Handle case where metrics is empty because older saved object state is empty array or there are no valid aggs. return metrics.length === 0 @@ -56,14 +76,14 @@ export class AbstractESAggSource extends AbstractESSource { : metrics; } - getAggKey(aggType, fieldName) { + getAggKey(aggType: AGG_TYPE, fieldName: string): string { return getSourceAggKey({ aggType, aggFieldName: fieldName, }); } - getAggLabel(aggType, fieldName) { + getAggLabel(aggType: AGG_TYPE, fieldName: string): string { switch (aggType) { case AGG_TYPE.COUNT: return COUNT_PROP_LABEL; @@ -81,8 +101,8 @@ export class AbstractESAggSource extends AbstractESSource { return this.getMetricFields(); } - getValueAggsDsl(indexPattern) { - const valueAggsDsl = {}; + getValueAggsDsl(indexPattern: IndexPattern) { + const valueAggsDsl: { [key: string]: unknown } = {}; this.getMetricFields().forEach((esAggMetric) => { const aggDsl = esAggMetric.getValueAggDsl(indexPattern); if (aggDsl) { @@ -92,9 +112,9 @@ export class AbstractESAggSource extends AbstractESSource { return valueAggsDsl; } - async filterAndFormatPropertiesToHtmlForMetricFields(properties) { - const metricFields = this.getMetricFields(); - const tooltipPropertiesPromises = []; + async getTooltipProperties(properties: GeoJsonProperties) { + const metricFields = await this.getFields(); + const promises: Array> = []; metricFields.forEach((metricField) => { let value; for (const key in properties) { @@ -105,9 +125,9 @@ export class AbstractESAggSource extends AbstractESSource { } const tooltipPromise = metricField.createTooltipProperty(value); - tooltipPropertiesPromises.push(tooltipPromise); + promises.push(tooltipPromise); }); - return await Promise.all(tooltipPropertiesPromises); + return await Promise.all(promises); } } diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.d.ts b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.d.ts index 51ee15e7ea5af..2ce4353fca13c 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.d.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.d.ts @@ -7,6 +7,7 @@ import { AbstractESAggSource } from '../es_agg_source'; import { ESGeoGridSourceDescriptor } from '../../../../common/descriptor_types'; import { GRID_RESOLUTION } from '../../../../common/constants'; +import { IField } from '../../fields/field'; export class ESGeoGridSource extends AbstractESAggSource { static createDescriptor({ @@ -21,4 +22,5 @@ export class ESGeoGridSource extends AbstractESAggSource { getFieldNames(): string[]; getGridResolution(): GRID_RESOLUTION; getGeoGridPrecision(zoom: number): number; + createField({ fieldName }: { fieldName: string }): IField; } diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js index a6322ff3ba784..aa167cb577672 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js @@ -321,10 +321,6 @@ export class ESGeoGridSource extends AbstractESAggSource { return true; } - async filterAndFormatPropertiesToHtml(properties) { - return await this.filterAndFormatPropertiesToHtmlForMetricFields(properties); - } - async getSupportedShapeTypes() { if (this._descriptor.requestType === RENDER_AS.GRID) { return [VECTOR_SHAPE_TYPE.POLYGON]; diff --git a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.js b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.js index 92b0c717f6724..9ec54335d4e78 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.js +++ b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.js @@ -223,10 +223,6 @@ export class ESPewPewSource extends AbstractESAggSource { canFormatFeatureProperties() { return true; } - - async filterAndFormatPropertiesToHtml(properties) { - return await this.filterAndFormatPropertiesToHtmlForMetricFields(properties); - } } registerSource({ diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.js index 7ac2738eaeb51..df83bd1cf5e60 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.js @@ -438,7 +438,7 @@ export class ESSearchSource extends AbstractESSource { return properties; } - async filterAndFormatPropertiesToHtml(properties) { + async getTooltipProperties(properties) { const indexPattern = await this.getIndexPattern(); const propertyValues = await this._loadTooltipProperties( properties._id, diff --git a/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.js b/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.js index 8cc8dd5c4a080..b4ad256c1598a 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.js +++ b/x-pack/plugins/maps/public/classes/sources/es_term_source/es_term_source.js @@ -129,10 +129,6 @@ export class ESTermSource extends AbstractESAggSource { return `es_table ${this.getIndexPatternId()}`; } - async filterAndFormatPropertiesToHtml(properties) { - return await this.filterAndFormatPropertiesToHtmlForMetricFields(properties); - } - getFieldNames() { return this.getMetricFields().map((esAggMetricField) => esAggMetricField.getName()); } diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx index 4e9e1e9cd7680..48f7b30261f38 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.test.tsx @@ -45,7 +45,7 @@ describe('canFormatFeatureProperties', () => { }); }); -describe('filterAndFormatPropertiesToHtml', () => { +describe('getTooltipProperties', () => { const descriptorWithFields = { ...descriptor, fields: [ @@ -67,7 +67,7 @@ describe('filterAndFormatPropertiesToHtml', () => { it('should get tooltipproperties', async () => { const source = new MVTSingleLayerVectorSource(descriptorWithFields); - const tooltipProperties = await source.filterAndFormatPropertiesToHtml({ + const tooltipProperties = await source.getTooltipProperties({ foo: 'bar', fooz: 123, }); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 52dc89a6bba58..3e515613b3fd0 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -192,7 +192,7 @@ export class MVTSingleLayerVectorSource return false; } - async filterAndFormatPropertiesToHtml( + async getTooltipProperties( properties: GeoJsonProperties, featureId?: string | number ): Promise { diff --git a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts index fd9c179275444..a481e273bc33e 100644 --- a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts +++ b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.d.ts @@ -36,7 +36,7 @@ export type BoundsFilters = { }; export interface IVectorSource extends ISource { - filterAndFormatPropertiesToHtml(properties: GeoJsonProperties): Promise; + getTooltipProperties(properties: GeoJsonProperties): Promise; getBoundsForFilters( boundsFilters: BoundsFilters, registerCancelCallback: (requestToken: symbol, callback: () => void) => void @@ -58,7 +58,7 @@ export interface IVectorSource extends ISource { } export class AbstractVectorSource extends AbstractSource implements IVectorSource { - filterAndFormatPropertiesToHtml(properties: GeoJsonProperties): Promise; + getTooltipProperties(properties: GeoJsonProperties): Promise; getBoundsForFilters( boundsFilters: BoundsFilters, registerCancelCallback: (requestToken: symbol, callback: () => void) => void diff --git a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.js b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.js index 98ed89a6ff0ad..9569b8626aabf 100644 --- a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.js +++ b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.js @@ -106,7 +106,7 @@ export class AbstractVectorSource extends AbstractSource { } // Allow source to filter and format feature properties before displaying to user - async filterAndFormatPropertiesToHtml(properties) { + async getTooltipProperties(properties) { const tooltipProperties = []; for (const key in properties) { if (key.startsWith('__kbn')) { diff --git a/x-pack/plugins/maps/public/components/_index.scss b/x-pack/plugins/maps/public/components/_index.scss index 76ce9f1bc79e3..726573ce4307d 100644 --- a/x-pack/plugins/maps/public/components/_index.scss +++ b/x-pack/plugins/maps/public/components/_index.scss @@ -1,4 +1,4 @@ @import 'action_select'; -@import 'metric_editors'; +@import 'metrics_editor/metric_editors'; @import './geometry_filter'; @import 'tooltip_selector/tooltip_selector'; diff --git a/x-pack/plugins/maps/public/components/__snapshots__/metrics_editor.test.js.snap b/x-pack/plugins/maps/public/components/metrics_editor/__snapshots__/metrics_editor.test.tsx.snap similarity index 92% rename from x-pack/plugins/maps/public/components/__snapshots__/metrics_editor.test.js.snap rename to x-pack/plugins/maps/public/components/metrics_editor/__snapshots__/metrics_editor.test.tsx.snap index 0d4f1f99e464c..bd58ded41e7f5 100644 --- a/x-pack/plugins/maps/public/components/__snapshots__/metrics_editor.test.js.snap +++ b/x-pack/plugins/maps/public/components/metrics_editor/__snapshots__/metrics_editor.test.tsx.snap @@ -16,8 +16,9 @@ exports[`should add default count metric when metrics is empty array 1`] = ` "type": "count", } } - metricsFilter={[Function]} onChange={[Function]} + onRemove={[Function]} + showRemoveButton={false} /> @@ -59,8 +60,9 @@ exports[`should render metrics editor 1`] = ` "type": "sum", } } - metricsFilter={[Function]} onChange={[Function]} + onRemove={[Function]} + showRemoveButton={false} /> diff --git a/x-pack/plugins/maps/public/components/_metric_editors.scss b/x-pack/plugins/maps/public/components/metrics_editor/_metric_editors.scss similarity index 100% rename from x-pack/plugins/maps/public/components/_metric_editors.scss rename to x-pack/plugins/maps/public/components/metrics_editor/_metric_editors.scss diff --git a/x-pack/plugins/maps/public/components/metrics_editor/index.ts b/x-pack/plugins/maps/public/components/metrics_editor/index.ts new file mode 100644 index 0000000000000..3c105c2d798ff --- /dev/null +++ b/x-pack/plugins/maps/public/components/metrics_editor/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { MetricsEditor } from './metrics_editor'; diff --git a/x-pack/plugins/maps/public/components/metric_editor.js b/x-pack/plugins/maps/public/components/metrics_editor/metric_editor.tsx similarity index 59% rename from x-pack/plugins/maps/public/components/metric_editor.js rename to x-pack/plugins/maps/public/components/metrics_editor/metric_editor.tsx index 96b52d84653b2..543d144efdcc7 100644 --- a/x-pack/plugins/maps/public/components/metric_editor.js +++ b/x-pack/plugins/maps/public/components/metrics_editor/metric_editor.tsx @@ -4,18 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment } from 'react'; -import PropTypes from 'prop-types'; +import React, { ChangeEvent, Fragment } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import { EuiButtonEmpty, EuiComboBoxOptionOption, EuiFieldText, EuiFormRow } from '@elastic/eui'; -import { MetricSelect, METRIC_AGGREGATION_VALUES } from './metric_select'; -import { SingleFieldSelect } from './single_field_select'; -import { AGG_TYPE } from '../../common/constants'; -import { getTermsFields } from '../index_pattern_util'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { MetricSelect } from './metric_select'; +import { SingleFieldSelect } from '../single_field_select'; +import { AggDescriptor } from '../../../common/descriptor_types'; +import { AGG_TYPE } from '../../../common/constants'; +import { getTermsFields } from '../../index_pattern_util'; +import { IFieldType } from '../../../../../../src/plugins/data/public'; -function filterFieldsForAgg(fields, aggType) { +function filterFieldsForAgg(fields: IFieldType[], aggType: AGG_TYPE) { if (!fields) { return []; } @@ -34,8 +36,27 @@ function filterFieldsForAgg(fields, aggType) { }); } -export function MetricEditor({ fields, metricsFilter, metric, onChange, removeButton }) { - const onAggChange = (metricAggregationType) => { +interface Props { + metric: AggDescriptor; + fields: IFieldType[]; + onChange: (metric: AggDescriptor) => void; + onRemove: () => void; + metricsFilter?: (metricOption: EuiComboBoxOptionOption) => boolean; + showRemoveButton: boolean; +} + +export function MetricEditor({ + fields, + metricsFilter, + metric, + onChange, + showRemoveButton, + onRemove, +}: Props) { + const onAggChange = (metricAggregationType?: AGG_TYPE) => { + if (!metricAggregationType) { + return; + } const newMetricProps = { ...metric, type: metricAggregationType, @@ -54,13 +75,16 @@ export function MetricEditor({ fields, metricsFilter, metric, onChange, removeBu onChange(newMetricProps); }; - const onFieldChange = (fieldName) => { + const onFieldChange = (fieldName?: string) => { + if (!fieldName) { + return; + } onChange({ ...metric, field: fieldName, }); }; - const onLabelChange = (e) => { + const onLabelChange = (e: ChangeEvent) => { onChange({ ...metric, label: e.target.value, @@ -80,7 +104,7 @@ export function MetricEditor({ fields, metricsFilter, metric, onChange, removeBu placeholder={i18n.translate('xpack.maps.metricsEditor.selectFieldPlaceholder', { defaultMessage: 'Select field', })} - value={metric.field} + value={metric.field ? metric.field : null} onChange={onFieldChange} fields={filterFieldsForAgg(fields, metric.type)} isClearable={false} @@ -108,6 +132,28 @@ export function MetricEditor({ fields, metricsFilter, metric, onChange, removeBu ); } + let removeButton; + if (showRemoveButton) { + removeButton = ( +
+ + + +
+ ); + } + return ( ); } - -MetricEditor.propTypes = { - metric: PropTypes.shape({ - type: PropTypes.oneOf(METRIC_AGGREGATION_VALUES), - field: PropTypes.string, - label: PropTypes.string, - }), - fields: PropTypes.array, - onChange: PropTypes.func.isRequired, - metricsFilter: PropTypes.func, -}; diff --git a/x-pack/plugins/maps/public/components/metric_select.js b/x-pack/plugins/maps/public/components/metrics_editor/metric_select.tsx similarity index 80% rename from x-pack/plugins/maps/public/components/metric_select.js rename to x-pack/plugins/maps/public/components/metrics_editor/metric_select.tsx index 2ebfcf99dece6..197c5466fe0fd 100644 --- a/x-pack/plugins/maps/public/components/metric_select.js +++ b/x-pack/plugins/maps/public/components/metrics_editor/metric_select.tsx @@ -5,10 +5,9 @@ */ import React from 'react'; -import PropTypes from 'prop-types'; import { i18n } from '@kbn/i18n'; -import { EuiComboBox } from '@elastic/eui'; -import { AGG_TYPE } from '../../common/constants'; +import { EuiComboBox, EuiComboBoxOptionOption, EuiComboBoxProps } from '@elastic/eui'; +import { AGG_TYPE } from '../../../common/constants'; const AGG_OPTIONS = [ { @@ -55,17 +54,19 @@ const AGG_OPTIONS = [ }, ]; -export const METRIC_AGGREGATION_VALUES = AGG_OPTIONS.map(({ value }) => { - return value; -}); +type Props = Omit, 'onChange'> & { + value: AGG_TYPE; + onChange: (aggType: AGG_TYPE) => void; + metricsFilter?: (metricOption: EuiComboBoxOptionOption) => boolean; +}; -export function MetricSelect({ value, onChange, metricsFilter, ...rest }) { - function onAggChange(selectedOptions) { +export function MetricSelect({ value, onChange, metricsFilter, ...rest }: Props) { + function onAggChange(selectedOptions: Array>) { if (selectedOptions.length === 0) { return; } - const aggType = selectedOptions[0].value; + const aggType = selectedOptions[0].value!; onChange(aggType); } @@ -87,9 +88,3 @@ export function MetricSelect({ value, onChange, metricsFilter, ...rest }) { /> ); } - -MetricSelect.propTypes = { - metricsFilter: PropTypes.func, - value: PropTypes.oneOf(METRIC_AGGREGATION_VALUES), - onChange: PropTypes.func.isRequired, -}; diff --git a/x-pack/plugins/maps/public/components/metrics_editor.test.js b/x-pack/plugins/maps/public/components/metrics_editor/metrics_editor.test.tsx similarity index 84% rename from x-pack/plugins/maps/public/components/metrics_editor.test.js rename to x-pack/plugins/maps/public/components/metrics_editor/metrics_editor.test.tsx index bcbeef29875ee..7ce7fbce2b066 100644 --- a/x-pack/plugins/maps/public/components/metrics_editor.test.js +++ b/x-pack/plugins/maps/public/components/metrics_editor/metrics_editor.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { MetricsEditor } from './metrics_editor'; -import { AGG_TYPE } from '../../common/constants'; +import { AGG_TYPE } from '../../../common/constants'; const defaultProps = { metrics: [ @@ -19,15 +19,14 @@ const defaultProps = { fields: [], onChange: () => {}, allowMultipleMetrics: true, - metricsFilter: () => {}, }; -test('should render metrics editor', async () => { +test('should render metrics editor', () => { const component = shallow(); expect(component).toMatchSnapshot(); }); -test('should add default count metric when metrics is empty array', async () => { +test('should add default count metric when metrics is empty array', () => { const component = shallow(); expect(component).toMatchSnapshot(); }); diff --git a/x-pack/plugins/maps/public/components/metrics_editor.js b/x-pack/plugins/maps/public/components/metrics_editor/metrics_editor.tsx similarity index 54% rename from x-pack/plugins/maps/public/components/metrics_editor.js rename to x-pack/plugins/maps/public/components/metrics_editor/metrics_editor.tsx index 7d4d7bf3ec7ab..dae1f51469281 100644 --- a/x-pack/plugins/maps/public/components/metrics_editor.js +++ b/x-pack/plugins/maps/public/components/metrics_editor/metrics_editor.tsx @@ -5,48 +5,42 @@ */ import React, { Fragment } from 'react'; -import PropTypes from 'prop-types'; -import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiButtonEmpty, EuiSpacer, EuiTextAlign } from '@elastic/eui'; +import { EuiButtonEmpty, EuiComboBoxOptionOption, EuiSpacer, EuiTextAlign } from '@elastic/eui'; import { MetricEditor } from './metric_editor'; -import { DEFAULT_METRIC } from '../classes/sources/es_agg_source'; +import { DEFAULT_METRIC } from '../../classes/sources/es_agg_source'; +import { IFieldType } from '../../../../../../src/plugins/data/public'; +import { AggDescriptor } from '../../../common/descriptor_types'; +import { AGG_TYPE } from '../../../common/constants'; -export function MetricsEditor({ fields, metrics, onChange, allowMultipleMetrics, metricsFilter }) { +interface Props { + allowMultipleMetrics: boolean; + metrics: AggDescriptor[]; + fields: IFieldType[]; + onChange: (metrics: AggDescriptor[]) => void; + metricsFilter?: (metricOption: EuiComboBoxOptionOption) => boolean; +} + +export function MetricsEditor({ + fields, + metrics = [DEFAULT_METRIC], + onChange, + allowMultipleMetrics = true, + metricsFilter, +}: Props) { function renderMetrics() { // There was a bug in 7.8 that initialized metrics to []. // This check is needed to handle any saved objects created before the bug was patched. const nonEmptyMetrics = metrics.length === 0 ? [DEFAULT_METRIC] : metrics; return nonEmptyMetrics.map((metric, index) => { - const onMetricChange = (metric) => { - onChange([...metrics.slice(0, index), metric, ...metrics.slice(index + 1)]); + const onMetricChange = (updatedMetric: AggDescriptor) => { + onChange([...metrics.slice(0, index), updatedMetric, ...metrics.slice(index + 1)]); }; const onRemove = () => { onChange([...metrics.slice(0, index), ...metrics.slice(index + 1)]); }; - let removeButton; - if (index > 0) { - removeButton = ( -
- - - -
- ); - } return (
0} + onRemove={onRemove} />
); @@ -62,7 +57,7 @@ export function MetricsEditor({ fields, metrics, onChange, allowMultipleMetrics, } function addMetric() { - onChange([...metrics, {}]); + onChange([...metrics, { type: AGG_TYPE.AVG }]); } function renderAddMetricButton() { @@ -71,7 +66,7 @@ export function MetricsEditor({ fields, metrics, onChange, allowMultipleMetrics, } return ( - <> + @@ -81,7 +76,7 @@ export function MetricsEditor({ fields, metrics, onChange, allowMultipleMetrics, /> - + ); } @@ -93,16 +88,3 @@ export function MetricsEditor({ fields, metrics, onChange, allowMultipleMetrics,
); } - -MetricsEditor.propTypes = { - metrics: PropTypes.array, - fields: PropTypes.array, - onChange: PropTypes.func.isRequired, - allowMultipleMetrics: PropTypes.bool, - metricsFilter: PropTypes.func, -}; - -MetricsEditor.defaultProps = { - metrics: [DEFAULT_METRIC], - allowMultipleMetrics: true, -}; diff --git a/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js index 3cd8a3c42879a..e0e1556ecde06 100644 --- a/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js @@ -4,12 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -jest.mock('../../../../components/metric_editor', () => ({ - MetricsEditor: () => { - return
mockMetricsEditor
; - }, -})); - import React from 'react'; import { shallow } from 'enzyme'; import { MetricsExpression } from './metrics_expression'; diff --git a/x-pack/plugins/maps/public/lazy_load_bundle/index.ts b/x-pack/plugins/maps/public/lazy_load_bundle/index.ts index 5f2a640aa9d0f..03752a1c3e11e 100644 --- a/x-pack/plugins/maps/public/lazy_load_bundle/index.ts +++ b/x-pack/plugins/maps/public/lazy_load_bundle/index.ts @@ -7,7 +7,7 @@ import { AnyAction } from 'redux'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { IndexPatternsContract } from 'src/plugins/data/public/index_patterns'; -import { ReactElement } from 'react'; +import { AppMountContext, AppMountParameters } from 'kibana/public'; import { IndexPattern } from 'src/plugins/data/public'; import { Embeddable, IContainer } from '../../../../../src/plugins/embeddable/public'; import { LayerDescriptor } from '../../common/descriptor_types'; @@ -40,7 +40,7 @@ interface LazyLoadedMapModules { initialLayers?: LayerDescriptor[] ) => LayerDescriptor[]; mergeInputWithSavedMap: any; - renderApp: (context: unknown, params: unknown) => ReactElement; + renderApp: (context: AppMountContext, params: AppMountParameters) => Promise<() => void>; createSecurityLayerDescriptors: ( indexPatternId: string, indexPatternTitle: string @@ -57,7 +57,6 @@ export async function lazyLoadMapModules(): Promise { loadModulesPromise = new Promise(async (resolve) => { const { - // @ts-expect-error getMapsSavedObjectLoader, getQueryableUniqueIndexPatternIds, MapEmbeddable, @@ -68,7 +67,6 @@ export async function lazyLoadMapModules(): Promise { addLayerWithoutDataSync, getInitialLayers, mergeInputWithSavedMap, - // @ts-expect-error renderApp, createSecurityLayerDescriptors, registerLayerWizard, diff --git a/x-pack/plugins/maps/public/lazy_load_bundle/lazy/index.ts b/x-pack/plugins/maps/public/lazy_load_bundle/lazy/index.ts index e55160383a8f3..28f5acdc17656 100644 --- a/x-pack/plugins/maps/public/lazy_load_bundle/lazy/index.ts +++ b/x-pack/plugins/maps/public/lazy_load_bundle/lazy/index.ts @@ -7,7 +7,6 @@ // These are map-dependencies of the embeddable. // By lazy-loading these, the Maps-app can register the embeddable when the plugin mounts, without actually pulling all the code. -// @ts-expect-error export * from '../../routing/bootstrap/services/gis_map_saved_object_loader'; export * from '../../embeddable/map_embeddable'; export * from '../../kibana_services'; @@ -16,7 +15,6 @@ export * from '../../actions'; export * from '../../selectors/map_selectors'; export * from '../../routing/bootstrap/get_initial_layers'; export * from '../../embeddable/merge_input_with_saved_map'; -// @ts-expect-error export * from '../../routing/maps_router'; export * from '../../classes/layers/solution_layers/security'; export { registerLayerWizard } from '../../classes/layers/layer_wizard_registry'; diff --git a/x-pack/plugins/maps/public/plugin.ts b/x-pack/plugins/maps/public/plugin.ts index b08135b4e486c..00ee7f376efc6 100644 --- a/x-pack/plugins/maps/public/plugin.ts +++ b/x-pack/plugins/maps/public/plugin.ts @@ -123,7 +123,6 @@ export class MapsPlugin icon: `plugins/${APP_ID}/icon.svg`, euiIconType: APP_ICON, category: DEFAULT_APP_CATEGORIES.kibana, - // @ts-expect-error async mount(context, params) { const { renderApp } = await lazyLoadMapModules(); return renderApp(context, params); diff --git a/x-pack/plugins/maps/public/routing/bootstrap/get_initial_layers.js b/x-pack/plugins/maps/public/routing/bootstrap/get_initial_layers.ts similarity index 87% rename from x-pack/plugins/maps/public/routing/bootstrap/get_initial_layers.js rename to x-pack/plugins/maps/public/routing/bootstrap/get_initial_layers.ts index b47f83d5a6664..e828dc88409cb 100644 --- a/x-pack/plugins/maps/public/routing/bootstrap/get_initial_layers.js +++ b/x-pack/plugins/maps/public/routing/bootstrap/get_initial_layers.ts @@ -15,15 +15,19 @@ import '../../classes/sources/es_pew_pew_source'; import '../../classes/sources/kibana_regionmap_source'; import '../../classes/sources/es_geo_grid_source'; import '../../classes/sources/xyz_tms_source'; +import { LayerDescriptor } from '../../../common/descriptor_types'; +// @ts-expect-error import { KibanaTilemapSource } from '../../classes/sources/kibana_tilemap_source'; import { TileLayer } from '../../classes/layers/tile_layer/tile_layer'; +// @ts-expect-error import { EMSTMSSource } from '../../classes/sources/ems_tms_source'; +// @ts-expect-error import { VectorTileLayer } from '../../classes/layers/vector_tile_layer/vector_tile_layer'; import { getIsEmsEnabled, getToasts } from '../../kibana_services'; import { INITIAL_LAYERS_KEY } from '../../../common/constants'; import { getKibanaTileMap } from '../../meta'; -export function getInitialLayers(layerListJSON, initialLayers = []) { +export function getInitialLayers(layerListJSON?: string, initialLayers: LayerDescriptor[] = []) { if (layerListJSON) { return JSON.parse(layerListJSON); } @@ -58,9 +62,10 @@ export function getInitialLayersFromUrlParam() { try { let mapInitLayers = mapAppParams.get(INITIAL_LAYERS_KEY); - if (mapInitLayers[mapInitLayers.length - 1] === '#') { - mapInitLayers = mapInitLayers.substr(0, mapInitLayers.length - 1); + if (mapInitLayers![mapInitLayers!.length - 1] === '#') { + mapInitLayers = mapInitLayers!.substr(0, mapInitLayers!.length - 1); } + // @ts-ignore return rison.decode_array(mapInitLayers); } catch (e) { getToasts().addWarning({ diff --git a/x-pack/plugins/maps/public/routing/bootstrap/get_initial_query.js b/x-pack/plugins/maps/public/routing/bootstrap/get_initial_query.ts similarity index 73% rename from x-pack/plugins/maps/public/routing/bootstrap/get_initial_query.js rename to x-pack/plugins/maps/public/routing/bootstrap/get_initial_query.ts index 1f2cf27077623..43293d152dbff 100644 --- a/x-pack/plugins/maps/public/routing/bootstrap/get_initial_query.js +++ b/x-pack/plugins/maps/public/routing/bootstrap/get_initial_query.ts @@ -5,8 +5,15 @@ */ import { getData } from '../../kibana_services'; +import { MapsAppState } from '../state_syncing/app_state_manager'; -export function getInitialQuery({ mapStateJSON, appState = {} }) { +export function getInitialQuery({ + mapStateJSON, + appState = {}, +}: { + mapStateJSON?: string; + appState: MapsAppState; +}) { if (appState.query) { return appState.query; } diff --git a/x-pack/plugins/maps/public/routing/bootstrap/get_initial_refresh_config.js b/x-pack/plugins/maps/public/routing/bootstrap/get_initial_refresh_config.ts similarity index 81% rename from x-pack/plugins/maps/public/routing/bootstrap/get_initial_refresh_config.js rename to x-pack/plugins/maps/public/routing/bootstrap/get_initial_refresh_config.ts index d7b3bbf5b4ab2..7d759cb25052f 100644 --- a/x-pack/plugins/maps/public/routing/bootstrap/get_initial_refresh_config.js +++ b/x-pack/plugins/maps/public/routing/bootstrap/get_initial_refresh_config.ts @@ -4,10 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ +import { QueryState } from 'src/plugins/data/public'; import { getUiSettings } from '../../kibana_services'; import { UI_SETTINGS } from '../../../../../../src/plugins/data/public'; -export function getInitialRefreshConfig({ mapStateJSON, globalState = {} }) { +export function getInitialRefreshConfig({ + mapStateJSON, + globalState = {}, +}: { + mapStateJSON?: string; + globalState: QueryState; +}) { const uiSettings = getUiSettings(); if (mapStateJSON) { diff --git a/x-pack/plugins/maps/public/routing/bootstrap/get_initial_time_filters.js b/x-pack/plugins/maps/public/routing/bootstrap/get_initial_time_filters.ts similarity index 75% rename from x-pack/plugins/maps/public/routing/bootstrap/get_initial_time_filters.js rename to x-pack/plugins/maps/public/routing/bootstrap/get_initial_time_filters.ts index 9c11dabe03923..549cc154fe487 100644 --- a/x-pack/plugins/maps/public/routing/bootstrap/get_initial_time_filters.js +++ b/x-pack/plugins/maps/public/routing/bootstrap/get_initial_time_filters.ts @@ -4,9 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ +import { QueryState } from 'src/plugins/data/public'; import { getUiSettings } from '../../kibana_services'; -export function getInitialTimeFilters({ mapStateJSON, globalState }) { +export function getInitialTimeFilters({ + mapStateJSON, + globalState, +}: { + mapStateJSON?: string; + globalState: QueryState; +}) { if (mapStateJSON) { const mapState = JSON.parse(mapStateJSON); if (mapState.timeFilters) { diff --git a/x-pack/plugins/maps/public/routing/bootstrap/services/gis_map_saved_object_loader.js b/x-pack/plugins/maps/public/routing/bootstrap/services/gis_map_saved_object_loader.ts similarity index 100% rename from x-pack/plugins/maps/public/routing/bootstrap/services/gis_map_saved_object_loader.js rename to x-pack/plugins/maps/public/routing/bootstrap/services/gis_map_saved_object_loader.ts diff --git a/x-pack/plugins/maps/public/routing/bootstrap/services/saved_gis_map.ts b/x-pack/plugins/maps/public/routing/bootstrap/services/saved_gis_map.ts index 6f8e7777f671b..511f015b0ff80 100644 --- a/x-pack/plugins/maps/public/routing/bootstrap/services/saved_gis_map.ts +++ b/x-pack/plugins/maps/public/routing/bootstrap/services/saved_gis_map.ts @@ -27,7 +27,6 @@ import { copyPersistentState } from '../../../reducers/util'; // @ts-expect-error import { extractReferences, injectReferences } from '../../../../common/migrations/references'; import { getExistingMapPath, MAP_SAVED_OBJECT_TYPE } from '../../../../common/constants'; -// @ts-expect-error import { getStore } from '../../store_operations'; import { MapStoreState } from '../../../reducers/store'; import { LayerDescriptor } from '../../../../common/descriptor_types'; diff --git a/x-pack/plugins/maps/public/routing/maps_router.js b/x-pack/plugins/maps/public/routing/maps_router.tsx similarity index 80% rename from x-pack/plugins/maps/public/routing/maps_router.js rename to x-pack/plugins/maps/public/routing/maps_router.tsx index f0f5234e3f989..5291d9c361161 100644 --- a/x-pack/plugins/maps/public/routing/maps_router.js +++ b/x-pack/plugins/maps/public/routing/maps_router.tsx @@ -6,8 +6,10 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; -import { Router, Switch, Route, Redirect } from 'react-router-dom'; +import { Router, Switch, Route, Redirect, RouteComponentProps } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; +import { Provider } from 'react-redux'; +import { AppMountContext, AppMountParameters } from 'kibana/public'; import { getCoreChrome, getCoreI18n, @@ -18,16 +20,19 @@ import { import { createKbnUrlStateStorage, withNotifyOnErrors, + IKbnUrlStateStorage, } from '../../../../../src/plugins/kibana_utils/public'; import { getStore } from './store_operations'; -import { Provider } from 'react-redux'; import { LoadListAndRender } from './routes/list/load_list_and_render'; import { LoadMapAndRender } from './routes/maps_app/load_map_and_render'; -export let goToSpecifiedPath; -export let kbnUrlStateStorage; +export let goToSpecifiedPath: (path: string) => void; +export let kbnUrlStateStorage: IKbnUrlStateStorage; -export async function renderApp(context, { appBasePath, element, history, onAppLeave }) { +export async function renderApp( + context: AppMountContext, + { appBasePath, element, history, onAppLeave }: AppMountParameters +) { goToSpecifiedPath = (path) => history.push(path); kbnUrlStateStorage = createKbnUrlStateStorage({ useHash: false, @@ -42,11 +47,19 @@ export async function renderApp(context, { appBasePath, element, history, onAppL }; } -const App = ({ history, appBasePath, onAppLeave }) => { +interface Props { + history: AppMountParameters['history'] | RouteComponentProps['history']; + appBasePath: AppMountParameters['appBasePath']; + onAppLeave: AppMountParameters['onAppLeave']; +} + +const App: React.FC = ({ history, appBasePath, onAppLeave }) => { const store = getStore(); const I18nContext = getCoreI18n().Context; - const stateTransfer = getEmbeddableService()?.getStateTransfer(history); + const stateTransfer = getEmbeddableService()?.getStateTransfer( + history as AppMountParameters['history'] + ); const { originatingApp } = stateTransfer?.getIncomingEditorState({ keysToRemoveAfterFetch: ['originatingApp'] }) || {}; @@ -66,7 +79,7 @@ const App = ({ history, appBasePath, onAppLeave }) => { return ( - + getMapsSavedObjectLoader().find(search, this.state.listingLimit); + _find = (search: string) => getMapsSavedObjectLoader().find(search, this.state.listingLimit); - _delete = (ids) => getMapsSavedObjectLoader().delete(ids); + _delete = (ids: string[]) => getMapsSavedObjectLoader().delete(ids); debouncedFetch = _.debounce(async (filter) => { const response = await this._find(filter); @@ -135,10 +163,10 @@ export class MapsListView extends React.Component { this.setState({ showDeleteModal: true }); }; - onTableChange = ({ page, sort = {} }) => { + onTableChange = ({ page, sort }: CriteriaWithPagination) => { const { index: pageIndex, size: pageSize } = page; - let { field: sortField, direction: sortDirection } = sort; + let { field: sortField, direction: sortDirection } = sort || {}; // 3rd sorting state that is not captured by sort - native order (no sort) // when switching from desc to asc for the same field - use native order @@ -147,8 +175,8 @@ export class MapsListView extends React.Component { this.state.sortDirection === 'desc' && sortDirection === 'asc' ) { - sortField = null; - sortDirection = null; + sortField = undefined; + sortDirection = undefined; } this.setState({ @@ -165,8 +193,8 @@ export class MapsListView extends React.Component { if (this.state.sortField) { itemsCopy.sort((a, b) => { - const fieldA = _.get(a, this.state.sortField, ''); - const fieldB = _.get(b, this.state.sortField, ''); + const fieldA = _.get(a, this.state.sortField!, ''); + const fieldB = _.get(b, this.state.sortField!, ''); let order = 1; if (this.state.sortDirection === 'desc') { order = -1; @@ -320,7 +348,7 @@ export class MapsListView extends React.Component { } renderTable() { - const tableColumns = [ + const tableColumns: Array> = [ { field: 'title', name: i18n.translate('xpack.maps.mapListing.titleFieldTitle', { @@ -329,7 +357,7 @@ export class MapsListView extends React.Component { sortable: true, render: (field, record) => ( { + onClick={(e: MouseEvent) => { e.preventDefault(); goToSpecifiedPath(`/map/${record.id}`); }} @@ -355,12 +383,12 @@ export class MapsListView extends React.Component { pageSizeOptions: [10, 20, 50], }; - let selection = false; + let selection; if (!this.state.readOnly) { selection = { - onSelectionChange: (selection) => { + onSelectionChange: (s: SelectionItem[]) => { this.setState({ - selectedIds: selection.map((item) => { + selectedIds: s.map((item) => { return item.id; }), }); @@ -368,11 +396,11 @@ export class MapsListView extends React.Component { }; } - const sorting = {}; + const sorting: EuiTableSortingType = {}; if (this.state.sortField) { sorting.sort = { field: this.state.sortField, - direction: this.state.sortDirection, + direction: this.state.sortDirection!, }; } const items = this.state.items.length === 0 ? [] : this.getPageOfItems(); diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.tsx b/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.tsx index 1ccf890597edc..149c04b414c18 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.tsx +++ b/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.tsx @@ -6,7 +6,6 @@ import { i18n } from '@kbn/i18n'; import { getNavigateToApp } from '../../../kibana_services'; -// @ts-expect-error import { goToSpecifiedPath } from '../../maps_router'; export const unsavedChangesWarning = i18n.translate( @@ -25,7 +24,7 @@ export function getBreadcrumbs({ title: string; getHasUnsavedChanges: () => boolean; originatingApp?: string; - getAppNameFromId?: (id: string) => string; + getAppNameFromId?: (id: string) => string | undefined; }) { const breadcrumbs = []; if (originatingApp && getAppNameFromId) { diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/index.js b/x-pack/plugins/maps/public/routing/routes/maps_app/index.ts similarity index 62% rename from x-pack/plugins/maps/public/routing/routes/maps_app/index.js rename to x-pack/plugins/maps/public/routing/routes/maps_app/index.ts index 326db7289e60d..812d7fcf30981 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/index.js +++ b/x-pack/plugins/maps/public/routing/routes/maps_app/index.ts @@ -5,6 +5,9 @@ */ import { connect } from 'react-redux'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; +import { Filter, Query, TimeRange } from 'src/plugins/data/public'; import { MapsAppView } from './maps_app_view'; import { getFlyoutDisplay, getIsFullScreen } from '../../../selectors/ui_selectors'; import { @@ -33,8 +36,15 @@ import { import { FLYOUT_STATE } from '../../../reducers/ui'; import { getMapsCapabilities } from '../../../kibana_services'; import { getInspectorAdapters } from '../../../reducers/non_serializable_instances'; +import { MapStoreState } from '../../../reducers/store'; +import { + MapRefreshConfig, + MapCenterAndZoom, + LayerDescriptor, +} from '../../../../common/descriptor_types'; +import { MapSettings } from '../../../reducers/map'; -function mapStateToProps(state = {}) { +function mapStateToProps(state: MapStoreState) { return { isFullScreen: getIsFullScreen(state), isOpenSettingsDisabled: getFlyoutDisplay(state) !== FLYOUT_STATE.NONE, @@ -50,9 +60,19 @@ function mapStateToProps(state = {}) { }; } -function mapDispatchToProps(dispatch) { +function mapDispatchToProps(dispatch: ThunkDispatch) { return { - dispatchSetQuery: ({ forceRefresh, filters, query, timeFilters }) => { + dispatchSetQuery: ({ + forceRefresh, + filters, + query, + timeFilters, + }: { + filters?: Filter[]; + query?: Query; + timeFilters?: TimeRange; + forceRefresh?: boolean; + }) => { dispatch( setQuery({ filters, @@ -62,12 +82,13 @@ function mapDispatchToProps(dispatch) { }) ); }, - setRefreshConfig: (refreshConfig) => dispatch(setRefreshConfig(refreshConfig)), - replaceLayerList: (layerList) => dispatch(replaceLayerList(layerList)), - setGotoWithCenter: (latLonZoom) => dispatch(setGotoWithCenter(latLonZoom)), - setMapSettings: (mapSettings) => dispatch(setMapSettings(mapSettings)), - setIsLayerTOCOpen: (isLayerTOCOpen) => dispatch(setIsLayerTOCOpen(isLayerTOCOpen)), - setOpenTOCDetails: (openTOCDetails) => dispatch(setOpenTOCDetails(openTOCDetails)), + setRefreshConfig: (refreshConfig: MapRefreshConfig) => + dispatch(setRefreshConfig(refreshConfig)), + replaceLayerList: (layerList: LayerDescriptor[]) => dispatch(replaceLayerList(layerList)), + setGotoWithCenter: (latLonZoom: MapCenterAndZoom) => dispatch(setGotoWithCenter(latLonZoom)), + setMapSettings: (mapSettings: MapSettings) => dispatch(setMapSettings(mapSettings)), + setIsLayerTOCOpen: (isLayerTOCOpen: boolean) => dispatch(setIsLayerTOCOpen(isLayerTOCOpen)), + setOpenTOCDetails: (openTOCDetails: string[]) => dispatch(setOpenTOCDetails(openTOCDetails)), clearUi: () => { dispatch(setSelectedLayer(null)); dispatch(updateFlyout(FLYOUT_STATE.NONE)); diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/load_map_and_render.js b/x-pack/plugins/maps/public/routing/routes/maps_app/load_map_and_render.tsx similarity index 75% rename from x-pack/plugins/maps/public/routing/routes/maps_app/load_map_and_render.js rename to x-pack/plugins/maps/public/routing/routes/maps_app/load_map_and_render.tsx index eebbb17582821..7ab138300dc4c 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/load_map_and_render.js +++ b/x-pack/plugins/maps/public/routing/routes/maps_app/load_map_and_render.tsx @@ -5,15 +5,31 @@ */ import React from 'react'; -import { MapsAppView } from '.'; -import { getMapsSavedObjectLoader } from '../../bootstrap/services/gis_map_saved_object_loader'; -import { getCoreChrome, getToasts } from '../../../kibana_services'; import { i18n } from '@kbn/i18n'; import { Redirect } from 'react-router-dom'; +import { AppMountParameters } from 'kibana/public'; +import { EmbeddableStateTransfer } from 'src/plugins/embeddable/public'; +import { getCoreChrome, getToasts } from '../../../kibana_services'; +import { getMapsSavedObjectLoader } from '../../bootstrap/services/gis_map_saved_object_loader'; +import { MapsAppView } from '.'; +import { ISavedGisMap } from '../../bootstrap/services/saved_gis_map'; + +interface Props { + savedMapId?: string; + onAppLeave: AppMountParameters['onAppLeave']; + stateTransfer: EmbeddableStateTransfer; + originatingApp?: string; +} + +interface State { + savedMap?: ISavedGisMap; + failedToLoad: boolean; +} -export const LoadMapAndRender = class extends React.Component { - state = { - savedMap: null, +export const LoadMapAndRender = class extends React.Component { + _isMounted: boolean = false; + state: State = { + savedMap: undefined, failedToLoad: false, }; diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js b/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.tsx similarity index 73% rename from x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js rename to x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.tsx index 485b0ed7682fa..b3377547b2dd1 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js +++ b/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.tsx @@ -7,6 +7,9 @@ import React from 'react'; import 'mapbox-gl/dist/mapbox-gl.css'; import _ from 'lodash'; +import { AppLeaveAction, AppMountParameters } from 'kibana/public'; +import { EmbeddableStateTransfer, Adapters } from 'src/plugins/embeddable/public'; +import { Subscription } from 'rxjs'; import { DEFAULT_IS_LAYER_TOC_OPEN } from '../../../reducers/ui'; import { getData, @@ -23,29 +26,91 @@ import { getGlobalState, updateGlobalState, startGlobalStateSyncing, + MapsGlobalState, } from '../../state_syncing/global_sync'; import { AppStateManager } from '../../state_syncing/app_state_manager'; import { startAppStateSyncing } from '../../state_syncing/app_sync'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { + esFilters, + Filter, + Query, + TimeRange, + IndexPattern, + SavedQuery, + QueryStateChange, + QueryState, +} from '../../../../../../../src/plugins/data/public'; import { MapContainer } from '../../../connected_components/map_container'; import { getIndexPatternsFromIds } from '../../../index_pattern_util'; import { getTopNavConfig } from './top_nav_config'; import { getBreadcrumbs, unsavedChangesWarning } from './get_breadcrumbs'; +import { + LayerDescriptor, + MapRefreshConfig, + MapCenterAndZoom, + MapQuery, +} from '../../../../common/descriptor_types'; +import { MapSettings } from '../../../reducers/map'; +import { ISavedGisMap } from '../../bootstrap/services/saved_gis_map'; + +interface Props { + savedMap: ISavedGisMap; + onAppLeave: AppMountParameters['onAppLeave']; + stateTransfer: EmbeddableStateTransfer; + originatingApp?: string; + layerListConfigOnly: LayerDescriptor[]; + replaceLayerList: (layerList: LayerDescriptor[]) => void; + filters: Filter[]; + isFullScreen: boolean; + isOpenSettingsDisabled: boolean; + enableFullScreen: () => void; + openMapSettings: () => void; + inspectorAdapters: Adapters; + nextIndexPatternIds: string[]; + dispatchSetQuery: ({ + forceRefresh, + filters, + query, + timeFilters, + }: { + filters?: Filter[]; + query?: Query; + timeFilters?: TimeRange; + forceRefresh?: boolean; + }) => void; + timeFilters: TimeRange; + refreshConfig: MapRefreshConfig; + setRefreshConfig: (refreshConfig: MapRefreshConfig) => void; + isSaveDisabled: boolean; + clearUi: () => void; + setGotoWithCenter: (latLonZoom: MapCenterAndZoom) => void; + setMapSettings: (mapSettings: MapSettings) => void; + setIsLayerTOCOpen: (isLayerTOCOpen: boolean) => void; + setOpenTOCDetails: (openTOCDetails: string[]) => void; + query: MapQuery | undefined; +} -export class MapsAppView extends React.Component { - _globalSyncUnsubscribe = null; - _globalSyncChangeMonitorSubscription = null; - _appSyncUnsubscribe = null; +interface State { + initialized: boolean; + initialLayerListConfig?: LayerDescriptor[]; + indexPatterns: IndexPattern[]; + savedQuery?: SavedQuery; + originatingApp?: string; +} + +export class MapsAppView extends React.Component { + _globalSyncUnsubscribe: (() => void) | null = null; + _globalSyncChangeMonitorSubscription: Subscription | null = null; + _appSyncUnsubscribe: (() => void) | null = null; _appStateManager = new AppStateManager(); - _prevIndexPatternIds = null; + _prevIndexPatternIds: string[] | null = null; + _isMounted: boolean = false; - constructor(props) { + constructor(props: Props) { super(props); this.state = { indexPatterns: [], initialized: false, - savedQuery: '', - initialLayerListConfig: null, // tracking originatingApp in state so the connection can be broken by users originatingApp: props.originatingApp, }; @@ -60,10 +125,11 @@ export class MapsAppView extends React.Component { this._updateFromGlobalState ); - const initialSavedQuery = this._appStateManager.getAppState().savedQuery; - if (initialSavedQuery) { - this._updateStateFromSavedQuery(initialSavedQuery); - } + // savedQuery must be fetched from savedQueryId + // const initialSavedQuery = this._appStateManager.getAppState().savedQuery; + // if (initialSavedQuery) { + // this._updateStateFromSavedQuery(initialSavedQuery as SavedQuery); + // } this._initMap(); @@ -72,10 +138,10 @@ export class MapsAppView extends React.Component { this.props.onAppLeave((actions) => { if (this._hasUnsavedChanges()) { if (!window.confirm(unsavedChangesWarning)) { - return; + return {} as AppLeaveAction; } } - return actions.default(); + return actions.default() as AppLeaveAction; }); } @@ -121,7 +187,13 @@ export class MapsAppView extends React.Component { getCoreChrome().setBreadcrumbs(breadcrumbs); }; - _updateFromGlobalState = ({ changes, state: globalState }) => { + _updateFromGlobalState = ({ + changes, + state: globalState, + }: { + changes: QueryStateChange; + state: QueryState; + }) => { if (!this.state.initialized || !changes || !globalState) { return; } @@ -144,7 +216,17 @@ export class MapsAppView extends React.Component { } } - _onQueryChange = ({ filters, query, time, forceRefresh = false }) => { + _onQueryChange = ({ + filters, + query, + time, + forceRefresh = false, + }: { + filters?: Filter[]; + query?: Query; + time?: TimeRange; + forceRefresh?: boolean; + }) => { const { filterManager } = getData().query; if (filters) { @@ -165,7 +247,9 @@ export class MapsAppView extends React.Component { }); // sync globalState - const updatedGlobalState = { filters: filterManager.getGlobalFilters() }; + const updatedGlobalState: MapsGlobalState = { + filters: filterManager.getGlobalFilters(), + }; if (time) { updatedGlobalState.time = time; } @@ -173,7 +257,7 @@ export class MapsAppView extends React.Component { }; _initMapAndLayerSettings() { - const globalState = getGlobalState(); + const globalState: MapsGlobalState = getGlobalState(); const mapStateJSON = this.props.savedMap.mapStateJSON; let savedObjectFilters = []; @@ -219,14 +303,14 @@ export class MapsAppView extends React.Component { }); } - _onFiltersChange = (filters) => { + _onFiltersChange = (filters: Filter[]) => { this._onQueryChange({ filters, }); }; // mapRefreshConfig: MapRefreshConfig - _onRefreshConfigChange(mapRefreshConfig) { + _onRefreshConfigChange(mapRefreshConfig: MapRefreshConfig) { this.props.setRefreshConfig(mapRefreshConfig); updateGlobalState( { @@ -239,9 +323,9 @@ export class MapsAppView extends React.Component { ); } - _updateStateFromSavedQuery = (savedQuery) => { + _updateStateFromSavedQuery = (savedQuery: SavedQuery) => { this.setState({ savedQuery: { ...savedQuery } }); - this._appStateManager.setQueryAndFilters({ savedQuery }); + this._appStateManager.setQueryAndFilters({ savedQueryId: savedQuery.id }); const { filterManager } = getData().query; const savedQueryFilters = savedQuery.attributes.filters || []; @@ -328,7 +412,13 @@ export class MapsAppView extends React.Component { dateRangeTo={this.props.timeFilters.to} isRefreshPaused={this.props.refreshConfig.isPaused} refreshInterval={this.props.refreshConfig.interval} - onRefreshChange={({ isPaused, refreshInterval }) => { + onRefreshChange={({ + isPaused, + refreshInterval, + }: { + isPaused: boolean; + refreshInterval: number; + }) => { this._onRefreshConfigChange({ isPaused, interval: refreshInterval, @@ -337,14 +427,14 @@ export class MapsAppView extends React.Component { showSearchBar={true} showFilterBar={true} showDatePicker={true} - showSaveQuery={getMapsCapabilities().saveQuery} + showSaveQuery={!!getMapsCapabilities().saveQuery} savedQuery={this.state.savedQuery} onSaved={this._updateStateFromSavedQuery} onSavedQueryUpdated={this._updateStateFromSavedQuery} onClearSavedQuery={() => { const { filterManager, queryString } = getData().query; - this.setState({ savedQuery: '' }); - this._appStateManager.setQueryAndFilters({ savedQuery: '' }); + this.setState({ savedQuery: undefined }); + this._appStateManager.setQueryAndFilters({ savedQueryId: '' }); this._onQueryChange({ filters: filterManager.getGlobalFilters(), query: queryString.getDefaultQuery(), @@ -354,7 +444,7 @@ export class MapsAppView extends React.Component { ); } - _addFilter = (newFilters) => { + _addFilter = async (newFilters: Filter[]) => { newFilters.forEach((filter) => { filter.$state = { store: esFilters.FilterStateStore.APP_STATE }; }); diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx b/x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx index 497c87ad533a6..47f41f2b76f3e 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx +++ b/x-pack/plugins/maps/public/routing/routes/maps_app/top_nav_config.tsx @@ -21,7 +21,6 @@ import { showSaveModal, } from '../../../../../../../src/plugins/saved_objects/public'; import { MAP_SAVED_OBJECT_TYPE } from '../../../../common/constants'; -// @ts-expect-error import { goToSpecifiedPath } from '../../maps_router'; import { ISavedGisMap } from '../../bootstrap/services/saved_gis_map'; import { EmbeddableStateTransfer } from '../../../../../../../src/plugins/embeddable/public'; diff --git a/x-pack/plugins/maps/public/routing/state_syncing/app_state_manager.js b/x-pack/plugins/maps/public/routing/state_syncing/app_state_manager.ts similarity index 58% rename from x-pack/plugins/maps/public/routing/state_syncing/app_state_manager.js rename to x-pack/plugins/maps/public/routing/state_syncing/app_state_manager.ts index 4cdba13bd85d2..122b50f823a95 100644 --- a/x-pack/plugins/maps/public/routing/state_syncing/app_state_manager.js +++ b/x-pack/plugins/maps/public/routing/state_syncing/app_state_manager.ts @@ -5,20 +5,27 @@ */ import { Subject } from 'rxjs'; +import { Filter, Query } from 'src/plugins/data/public'; + +export interface MapsAppState { + query?: Query | null; + savedQueryId?: string; + filters?: Filter[]; +} export class AppStateManager { - _query = ''; - _savedQuery = ''; - _filters = []; + _query: Query | null = null; + _savedQueryId: string = ''; + _filters: Filter[] = []; _updated$ = new Subject(); - setQueryAndFilters({ query, savedQuery, filters }) { + setQueryAndFilters({ query, savedQueryId, filters }: MapsAppState) { if (query && this._query !== query) { this._query = query; } - if (savedQuery && this._savedQuery !== savedQuery) { - this._savedQuery = savedQuery; + if (savedQueryId && this._savedQueryId !== savedQueryId) { + this._savedQueryId = savedQueryId; } if (filters && this._filters !== filters) { this._filters = filters; @@ -34,10 +41,10 @@ export class AppStateManager { return this._filters; } - getAppState() { + getAppState(): MapsAppState { return { query: this._query, - savedQuery: this._savedQuery, + savedQueryId: this._savedQueryId, filters: this._filters, }; } diff --git a/x-pack/plugins/maps/public/routing/state_syncing/app_sync.js b/x-pack/plugins/maps/public/routing/state_syncing/app_sync.ts similarity index 88% rename from x-pack/plugins/maps/public/routing/state_syncing/app_sync.js rename to x-pack/plugins/maps/public/routing/state_syncing/app_sync.ts index 60e8dc9cd574c..b346822913bec 100644 --- a/x-pack/plugins/maps/public/routing/state_syncing/app_sync.js +++ b/x-pack/plugins/maps/public/routing/state_syncing/app_sync.ts @@ -4,13 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { connectToQueryState, esFilters } from '../../../../../../src/plugins/data/public'; -import { syncState } from '../../../../../../src/plugins/kibana_utils/public'; import { map } from 'rxjs/operators'; +import { connectToQueryState, esFilters } from '../../../../../../src/plugins/data/public'; +import { syncState, BaseStateContainer } from '../../../../../../src/plugins/kibana_utils/public'; import { getData } from '../../kibana_services'; import { kbnUrlStateStorage } from '../maps_router'; +import { AppStateManager } from './app_state_manager'; -export function startAppStateSyncing(appStateManager) { +export function startAppStateSyncing(appStateManager: AppStateManager) { // get appStateContainer // sync app filters with app state container from data.query to state container const { query } = getData(); @@ -19,7 +20,7 @@ export function startAppStateSyncing(appStateManager) { // clear app state filters to prevent application filters from other applications being transfered to maps query.filterManager.setAppFilters([]); - const stateContainer = { + const stateContainer: BaseStateContainer = { get: () => ({ query: appStateManager.getQuery(), filters: appStateManager.getFilters(), @@ -48,6 +49,7 @@ export function startAppStateSyncing(appStateManager) { // merge initial state from app state container and current state in url const initialAppState = { ...stateContainer.get(), + // @ts-ignore ...kbnUrlStateStorage.get('_a'), }; // trigger state update. actually needed in case some data was in url diff --git a/x-pack/plugins/maps/public/routing/state_syncing/global_sync.ts b/x-pack/plugins/maps/public/routing/state_syncing/global_sync.ts index 4e17241752f53..1e779831c5e0c 100644 --- a/x-pack/plugins/maps/public/routing/state_syncing/global_sync.ts +++ b/x-pack/plugins/maps/public/routing/state_syncing/global_sync.ts @@ -3,27 +3,30 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import { TimeRange, RefreshInterval, Filter } from 'src/plugins/data/public'; import { syncQueryStateWithUrl } from '../../../../../../src/plugins/data/public'; import { getData } from '../../kibana_services'; -// @ts-ignore import { kbnUrlStateStorage } from '../maps_router'; +export interface MapsGlobalState { + time?: TimeRange; + refreshInterval?: RefreshInterval; + filters?: Filter[]; +} + export function startGlobalStateSyncing() { const { stop } = syncQueryStateWithUrl(getData().query, kbnUrlStateStorage); return stop; } -export function getGlobalState() { - return kbnUrlStateStorage.get('_g'); +export function getGlobalState(): MapsGlobalState { + return kbnUrlStateStorage.get('_g') as MapsGlobalState; } -export function updateGlobalState(newState: unknown, flushUrlState = false) { +export function updateGlobalState(newState: MapsGlobalState, flushUrlState = false) { const globalState = getGlobalState(); kbnUrlStateStorage.set('_g', { - // @ts-ignore ...globalState, - // @ts-ignore ...newState, }); if (flushUrlState) { diff --git a/x-pack/plugins/maps/public/routing/store_operations.js b/x-pack/plugins/maps/public/routing/store_operations.ts similarity index 100% rename from x-pack/plugins/maps/public/routing/store_operations.js rename to x-pack/plugins/maps/public/routing/store_operations.ts diff --git a/x-pack/plugins/ml/common/constants/data_frame_analytics.ts b/x-pack/plugins/ml/common/constants/data_frame_analytics.ts new file mode 100644 index 0000000000000..830537cbadbc8 --- /dev/null +++ b/x-pack/plugins/ml/common/constants/data_frame_analytics.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export const DEFAULT_RESULTS_FIELD = 'ml'; diff --git a/x-pack/plugins/ml/common/types/__mocks__/job_config_farequote.json b/x-pack/plugins/ml/common/types/__mocks__/job_config_farequote.json index 18a49bb3841b3..6bc0e55b5aadd 100644 --- a/x-pack/plugins/ml/common/types/__mocks__/job_config_farequote.json +++ b/x-pack/plugins/ml/common/types/__mocks__/job_config_farequote.json @@ -69,9 +69,7 @@ "datafeed_id": "datafeed-farequote", "job_id": "farequote", "query_delay": "115823ms", - "indices": [ - "farequote" - ], + "indices": ["farequote"], "query": { "bool": { "must": [ @@ -103,7 +101,7 @@ "buckets": { "date_histogram": { "field": "@timestamp", - "interval": 900000, + "fixed_interval": "15m", "offset": 0, "order": { "_key": "asc" diff --git a/x-pack/plugins/ml/common/types/data_frame_analytics.ts b/x-pack/plugins/ml/common/types/data_frame_analytics.ts index f0aac75047585..60d2ca63dda59 100644 --- a/x-pack/plugins/ml/common/types/data_frame_analytics.ts +++ b/x-pack/plugins/ml/common/types/data_frame_analytics.ts @@ -79,3 +79,9 @@ export interface DataFrameAnalyticsConfig { version: string; allow_lazy_start?: boolean; } + +export enum ANALYSIS_CONFIG_TYPE { + OUTLIER_DETECTION = 'outlier_detection', + REGRESSION = 'regression', + CLASSIFICATION = 'classification', +} diff --git a/x-pack/plugins/ml/common/types/feature_importance.ts b/x-pack/plugins/ml/common/types/feature_importance.ts new file mode 100644 index 0000000000000..d2ab9f6c58608 --- /dev/null +++ b/x-pack/plugins/ml/common/types/feature_importance.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +export interface ClassFeatureImportance { + class_name: string | boolean; + importance: number; +} +export interface FeatureImportance { + feature_name: string; + importance?: number; + classes?: ClassFeatureImportance[]; +} + +export interface TopClass { + class_name: string; + class_probability: number; + class_score: number; +} + +export type TopClasses = TopClass[]; diff --git a/x-pack/plugins/ml/common/types/file_datavisualizer.ts b/x-pack/plugins/ml/common/types/file_datavisualizer.ts index c997a4e24f868..a8b775c8d5f60 100644 --- a/x-pack/plugins/ml/common/types/file_datavisualizer.ts +++ b/x-pack/plugins/ml/common/types/file_datavisualizer.ts @@ -84,7 +84,12 @@ export interface Settings { } export interface Mappings { - [key: string]: any; + _meta?: { + created_by: string; + }; + properties: { + [key: string]: any; + }; } export interface IngestPipelineWrapper { diff --git a/x-pack/plugins/ml/common/util/analytics_utils.ts b/x-pack/plugins/ml/common/util/analytics_utils.ts new file mode 100644 index 0000000000000..d725984a47d66 --- /dev/null +++ b/x-pack/plugins/ml/common/util/analytics_utils.ts @@ -0,0 +1,79 @@ +/* + * 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 { + AnalysisConfig, + ClassificationAnalysis, + OutlierAnalysis, + RegressionAnalysis, + ANALYSIS_CONFIG_TYPE, +} from '../types/data_frame_analytics'; + +export const isOutlierAnalysis = (arg: any): arg is OutlierAnalysis => { + const keys = Object.keys(arg); + return keys.length === 1 && keys[0] === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION; +}; + +export const isRegressionAnalysis = (arg: any): arg is RegressionAnalysis => { + const keys = Object.keys(arg); + return keys.length === 1 && keys[0] === ANALYSIS_CONFIG_TYPE.REGRESSION; +}; + +export const isClassificationAnalysis = (arg: any): arg is ClassificationAnalysis => { + const keys = Object.keys(arg); + return keys.length === 1 && keys[0] === ANALYSIS_CONFIG_TYPE.CLASSIFICATION; +}; + +export const getDependentVar = ( + analysis: AnalysisConfig +): + | RegressionAnalysis['regression']['dependent_variable'] + | ClassificationAnalysis['classification']['dependent_variable'] => { + let depVar = ''; + + if (isRegressionAnalysis(analysis)) { + depVar = analysis.regression.dependent_variable; + } + + if (isClassificationAnalysis(analysis)) { + depVar = analysis.classification.dependent_variable; + } + return depVar; +}; + +export const getPredictionFieldName = ( + analysis: AnalysisConfig +): + | RegressionAnalysis['regression']['prediction_field_name'] + | ClassificationAnalysis['classification']['prediction_field_name'] => { + // If undefined will be defaulted to dependent_variable when config is created + let predictionFieldName; + if (isRegressionAnalysis(analysis) && analysis.regression.prediction_field_name !== undefined) { + predictionFieldName = analysis.regression.prediction_field_name; + } else if ( + isClassificationAnalysis(analysis) && + analysis.classification.prediction_field_name !== undefined + ) { + predictionFieldName = analysis.classification.prediction_field_name; + } + return predictionFieldName; +}; + +export const getDefaultPredictionFieldName = (analysis: AnalysisConfig) => { + return `${getDependentVar(analysis)}_prediction`; +}; +export const getPredictedFieldName = ( + resultsField: string, + analysis: AnalysisConfig, + forSort?: boolean +) => { + // default is 'ml' + const predictionFieldName = getPredictionFieldName(analysis); + const predictedField = `${resultsField}.${ + predictionFieldName ? predictionFieldName : getDefaultPredictionFieldName(analysis) + }`; + return predictedField; +}; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/common.ts b/x-pack/plugins/ml/public/application/components/data_grid/common.ts index 1f0fcb63f019d..f252729cc20cd 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/common.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/common.ts @@ -119,13 +119,14 @@ export const getDataGridSchemasFromFieldTypes = (fieldTypes: FieldTypes, results schema = 'numeric'; } - if ( - field.includes(`${resultsField}.${FEATURE_IMPORTANCE}`) || - field.includes(`${resultsField}.${TOP_CLASSES}`) - ) { + if (field.includes(`${resultsField}.${TOP_CLASSES}`)) { schema = 'json'; } + if (field.includes(`${resultsField}.${FEATURE_IMPORTANCE}`)) { + schema = 'featureImportance'; + } + return { id: field, schema, isSortable }; }); }; @@ -250,10 +251,6 @@ export const useRenderCellValue = ( return cellValue ? 'true' : 'false'; } - if (typeof cellValue === 'object' && cellValue !== null) { - return JSON.stringify(cellValue); - } - return cellValue; }; }, [indexPattern?.fields, pagination.pageIndex, pagination.pageSize, tableItems]); diff --git a/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx b/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx index d4be2eab13d26..22815fe593d57 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx +++ b/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx @@ -5,8 +5,7 @@ */ import { isEqual } from 'lodash'; -import React, { memo, useEffect, FC } from 'react'; - +import React, { memo, useEffect, FC, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { @@ -24,13 +23,16 @@ import { } from '@elastic/eui'; import { CoreSetup } from 'src/core/public'; - import { DEFAULT_SAMPLER_SHARD_SIZE } from '../../../../common/constants/field_histograms'; -import { INDEX_STATUS } from '../../data_frame_analytics/common'; +import { ANALYSIS_CONFIG_TYPE, INDEX_STATUS } from '../../data_frame_analytics/common'; import { euiDataGridStyle, euiDataGridToolbarSettings } from './common'; import { UseIndexDataReturnType } from './types'; +import { DecisionPathPopover } from './feature_importance/decision_path_popover'; +import { TopClasses } from '../../../../common/types/feature_importance'; +import { DEFAULT_RESULTS_FIELD } from '../../../../common/constants/data_frame_analytics'; + // TODO Fix row hovering + bar highlighting // import { hoveredRow$ } from './column_chart'; @@ -41,6 +43,9 @@ export const DataGridTitle: FC<{ title: string }> = ({ title }) => ( ); interface PropsWithoutHeader extends UseIndexDataReturnType { + baseline?: number; + analysisType?: ANALYSIS_CONFIG_TYPE; + resultsField?: string; dataTestSubj: string; toastNotifications: CoreSetup['notifications']['toasts']; } @@ -60,6 +65,7 @@ type Props = PropsWithHeader | PropsWithoutHeader; export const DataGrid: FC = memo( (props) => { const { + baseline, chartsVisible, chartsButtonVisible, columnsWithCharts, @@ -80,8 +86,10 @@ export const DataGrid: FC = memo( toastNotifications, toggleChartVisibility, visibleColumns, + predictionFieldName, + resultsField, + analysisType, } = props; - // TODO Fix row hovering + bar highlighting // const getRowProps = (item: any) => { // return { @@ -90,6 +98,45 @@ export const DataGrid: FC = memo( // }; // }; + const popOverContent = useMemo(() => { + return analysisType === ANALYSIS_CONFIG_TYPE.REGRESSION || + analysisType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION + ? { + featureImportance: ({ children }: { cellContentsElement: any; children: any }) => { + const rowIndex = children?.props?.visibleRowIndex; + const row = data[rowIndex]; + if (!row) return
; + // if resultsField for some reason is not available then use ml + const mlResultsField = resultsField ?? DEFAULT_RESULTS_FIELD; + const parsedFIArray = row[mlResultsField].feature_importance; + let predictedValue: string | number | undefined; + let topClasses: TopClasses = []; + if ( + predictionFieldName !== undefined && + row && + row[mlResultsField][predictionFieldName] !== undefined + ) { + predictedValue = row[mlResultsField][predictionFieldName]; + topClasses = row[mlResultsField].top_classes; + } + + return ( + + ); + }, + } + : undefined; + }, [baseline, data]); + useEffect(() => { if (invalidSortingColumnns.length > 0) { invalidSortingColumnns.forEach((columnId) => { @@ -225,6 +272,7 @@ export const DataGrid: FC = memo( } : {}), }} + popoverContents={popOverContent} pagination={{ ...pagination, pageSizeOptions: [5, 10, 25], diff --git a/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_chart.tsx b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_chart.tsx new file mode 100644 index 0000000000000..b546ac1db57dd --- /dev/null +++ b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_chart.tsx @@ -0,0 +1,166 @@ +/* + * 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 { + AnnotationDomainTypes, + Axis, + AxisStyle, + Chart, + LineAnnotation, + LineAnnotationStyle, + LineAnnotationDatum, + LineSeries, + PartialTheme, + Position, + RecursivePartial, + ScaleType, + Settings, +} from '@elastic/charts'; +import { EuiIcon } from '@elastic/eui'; + +import React, { useCallback, useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import euiVars from '@elastic/eui/dist/eui_theme_light.json'; +import { DecisionPathPlotData } from './use_classification_path_data'; + +const { euiColorFullShade, euiColorMediumShade } = euiVars; +const axisColor = euiColorMediumShade; + +const baselineStyle: LineAnnotationStyle = { + line: { + strokeWidth: 1, + stroke: euiColorFullShade, + opacity: 0.75, + }, + details: { + fontFamily: 'Arial', + fontSize: 10, + fontStyle: 'bold', + fill: euiColorMediumShade, + padding: 0, + }, +}; + +const axes: RecursivePartial = { + axisLine: { + stroke: axisColor, + }, + tickLabel: { + fontSize: 10, + fill: axisColor, + }, + tickLine: { + stroke: axisColor, + }, + gridLine: { + horizontal: { + dash: [1, 2], + }, + vertical: { + strokeWidth: 0, + }, + }, +}; +const theme: PartialTheme = { + axes, +}; + +interface DecisionPathChartProps { + decisionPathData: DecisionPathPlotData; + predictionFieldName?: string; + baseline?: number; + minDomain: number | undefined; + maxDomain: number | undefined; +} + +const DECISION_PATH_MARGIN = 125; +const DECISION_PATH_ROW_HEIGHT = 10; +const NUM_PRECISION = 3; +const AnnotationBaselineMarker = ; + +export const DecisionPathChart = ({ + decisionPathData, + predictionFieldName, + minDomain, + maxDomain, + baseline, +}: DecisionPathChartProps) => { + // adjust the height so it's compact for items with more features + const baselineData: LineAnnotationDatum[] = useMemo( + () => [ + { + dataValue: baseline, + header: baseline ? baseline.toPrecision(NUM_PRECISION) : '', + details: i18n.translate( + 'xpack.ml.dataframe.analytics.explorationResults.decisionPathBaselineText', + { + defaultMessage: + 'baseline (average of predictions for all data points in the training data set)', + } + ), + }, + ], + [baseline] + ); + // guarantee up to num_precision significant digits + // without having it in scientific notation + const tickFormatter = useCallback((d) => Number(d.toPrecision(NUM_PRECISION)).toString(), []); + + return ( + + + {baseline && ( + + )} + + + + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_classification.tsx b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_classification.tsx new file mode 100644 index 0000000000000..bd001fa81a582 --- /dev/null +++ b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_classification.tsx @@ -0,0 +1,105 @@ +/* + * 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 React, { FC, useMemo, useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiHealth, EuiSpacer, EuiSuperSelect, EuiTitle } from '@elastic/eui'; +import d3 from 'd3'; +import { + isDecisionPathData, + useDecisionPathData, + getStringBasedClassName, +} from './use_classification_path_data'; +import { FeatureImportance, TopClasses } from '../../../../../common/types/feature_importance'; +import { DecisionPathChart } from './decision_path_chart'; +import { MissingDecisionPathCallout } from './missing_decision_path_callout'; + +interface ClassificationDecisionPathProps { + predictedValue: string | boolean; + predictionFieldName?: string; + featureImportance: FeatureImportance[]; + topClasses: TopClasses; +} + +export const ClassificationDecisionPath: FC = ({ + featureImportance, + predictedValue, + topClasses, + predictionFieldName, +}) => { + const [currentClass, setCurrentClass] = useState( + getStringBasedClassName(topClasses[0].class_name) + ); + const { decisionPathData } = useDecisionPathData({ + featureImportance, + predictedValue: currentClass, + }); + const options = useMemo(() => { + const predictionValueStr = getStringBasedClassName(predictedValue); + + return Array.isArray(topClasses) + ? topClasses.map((c) => { + const className = getStringBasedClassName(c.class_name); + return { + value: className, + inputDisplay: + className === predictionValueStr ? ( + + {className} + + ) : ( + className + ), + }; + }) + : undefined; + }, [topClasses, predictedValue]); + + const domain = useMemo(() => { + let maxDomain; + let minDomain; + // if decisionPathData has calculated cumulative path + if (decisionPathData && isDecisionPathData(decisionPathData)) { + const [min, max] = d3.extent(decisionPathData, (d: [string, number, number]) => d[2]); + const buffer = Math.abs(max - min) * 0.1; + maxDomain = max + buffer; + minDomain = min - buffer; + } + return { maxDomain, minDomain }; + }, [decisionPathData]); + + if (!decisionPathData) return ; + + return ( + <> + + + + {i18n.translate( + 'xpack.ml.dataframe.analytics.explorationResults.classificationDecisionPathClassNameTitle', + { + defaultMessage: 'Class name', + } + )} + + + {options !== undefined && ( + + )} + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_json_viewer.tsx b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_json_viewer.tsx new file mode 100644 index 0000000000000..343324b27f9b5 --- /dev/null +++ b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_json_viewer.tsx @@ -0,0 +1,16 @@ +/* + * 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 React, { FC } from 'react'; +import { EuiCodeBlock } from '@elastic/eui'; +import { FeatureImportance } from '../../../../../common/types/feature_importance'; + +interface DecisionPathJSONViewerProps { + featureImportance: FeatureImportance[]; +} +export const DecisionPathJSONViewer: FC = ({ featureImportance }) => { + return {JSON.stringify(featureImportance)}; +}; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_popover.tsx b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_popover.tsx new file mode 100644 index 0000000000000..263337f93e9a8 --- /dev/null +++ b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_popover.tsx @@ -0,0 +1,134 @@ +/* + * 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 React, { FC, useState } from 'react'; +import { EuiLink, EuiTab, EuiTabs, EuiText } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { RegressionDecisionPath } from './decision_path_regression'; +import { DecisionPathJSONViewer } from './decision_path_json_viewer'; +import { FeatureImportance, TopClasses } from '../../../../../common/types/feature_importance'; +import { ANALYSIS_CONFIG_TYPE } from '../../../data_frame_analytics/common'; +import { ClassificationDecisionPath } from './decision_path_classification'; +import { useMlKibana } from '../../../contexts/kibana'; + +interface DecisionPathPopoverProps { + featureImportance: FeatureImportance[]; + analysisType: ANALYSIS_CONFIG_TYPE; + predictionFieldName?: string; + baseline?: number; + predictedValue?: number | string | undefined; + topClasses?: TopClasses; +} + +enum DECISION_PATH_TABS { + CHART = 'decision_path_chart', + JSON = 'decision_path_json', +} + +export interface ExtendedFeatureImportance extends FeatureImportance { + absImportance?: number; +} + +export const DecisionPathPopover: FC = ({ + baseline, + featureImportance, + predictedValue, + topClasses, + analysisType, + predictionFieldName, +}) => { + const [selectedTabId, setSelectedTabId] = useState(DECISION_PATH_TABS.CHART); + const { + services: { docLinks }, + } = useMlKibana(); + const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = docLinks; + + if (featureImportance.length < 2) { + return ; + } + + const tabs = [ + { + id: DECISION_PATH_TABS.CHART, + name: ( + + ), + }, + { + id: DECISION_PATH_TABS.JSON, + name: ( + + ), + }, + ]; + + return ( + <> +
+ + {tabs.map((tab) => ( + setSelectedTabId(tab.id)} + key={tab.id} + > + {tab.name} + + ))} + +
+ {selectedTabId === DECISION_PATH_TABS.CHART && ( + <> + + + + + ), + }} + /> + + {analysisType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION && ( + + )} + {analysisType === ANALYSIS_CONFIG_TYPE.REGRESSION && ( + + )} + + )} + {selectedTabId === DECISION_PATH_TABS.JSON && ( + + )} + + ); +}; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_regression.tsx b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_regression.tsx new file mode 100644 index 0000000000000..345269a944f02 --- /dev/null +++ b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/decision_path_regression.tsx @@ -0,0 +1,79 @@ +/* + * 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 React, { FC, useMemo } from 'react'; +import { EuiCallOut } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import d3 from 'd3'; +import { FeatureImportance, TopClasses } from '../../../../../common/types/feature_importance'; +import { useDecisionPathData, isDecisionPathData } from './use_classification_path_data'; +import { DecisionPathChart } from './decision_path_chart'; +import { MissingDecisionPathCallout } from './missing_decision_path_callout'; + +interface RegressionDecisionPathProps { + predictionFieldName?: string; + baseline?: number; + predictedValue?: number | undefined; + featureImportance: FeatureImportance[]; + topClasses?: TopClasses; +} + +export const RegressionDecisionPath: FC = ({ + baseline, + featureImportance, + predictedValue, + predictionFieldName, +}) => { + const { decisionPathData } = useDecisionPathData({ + baseline, + featureImportance, + predictedValue, + }); + const domain = useMemo(() => { + let maxDomain; + let minDomain; + // if decisionPathData has calculated cumulative path + if (decisionPathData && isDecisionPathData(decisionPathData)) { + const [min, max] = d3.extent(decisionPathData, (d: [string, number, number]) => d[2]); + maxDomain = max; + minDomain = min; + const buffer = Math.abs(maxDomain - minDomain) * 0.1; + maxDomain = + (typeof baseline === 'number' ? Math.max(maxDomain, baseline) : maxDomain) + buffer; + minDomain = + (typeof baseline === 'number' ? Math.min(minDomain, baseline) : minDomain) - buffer; + } + return { maxDomain, minDomain }; + }, [decisionPathData, baseline]); + + if (!decisionPathData) return ; + + return ( + <> + {baseline === undefined && ( + + } + color="warning" + iconType="alert" + /> + )} + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/missing_decision_path_callout.tsx b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/missing_decision_path_callout.tsx new file mode 100644 index 0000000000000..66eb2047b1314 --- /dev/null +++ b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/missing_decision_path_callout.tsx @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { EuiCallOut } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; + +export const MissingDecisionPathCallout = () => { + return ( + + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/use_classification_path_data.tsx b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/use_classification_path_data.tsx new file mode 100644 index 0000000000000..90216c4a58ffc --- /dev/null +++ b/x-pack/plugins/ml/public/application/components/data_grid/feature_importance/use_classification_path_data.tsx @@ -0,0 +1,173 @@ +/* + * 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 { useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FeatureImportance, TopClasses } from '../../../../../common/types/feature_importance'; +import { ExtendedFeatureImportance } from './decision_path_popover'; + +export type DecisionPathPlotData = Array<[string, number, number]>; + +interface UseDecisionPathDataParams { + featureImportance: FeatureImportance[]; + baseline?: number; + predictedValue?: string | number | undefined; + topClasses?: TopClasses; +} + +interface RegressionDecisionPathProps { + baseline?: number; + predictedValue?: number | undefined; + featureImportance: FeatureImportance[]; + topClasses?: TopClasses; +} +const FEATURE_NAME = 'feature_name'; +const FEATURE_IMPORTANCE = 'importance'; + +export const isDecisionPathData = (decisionPathData: any): boolean => { + return ( + Array.isArray(decisionPathData) && + decisionPathData.length > 0 && + decisionPathData[0].length === 3 + ); +}; + +// cast to 'True' | 'False' | value to match Eui display +export const getStringBasedClassName = (v: string | boolean | undefined | number): string => { + if (v === undefined) { + return ''; + } + if (typeof v === 'boolean') { + return v ? 'True' : 'False'; + } + if (typeof v === 'number') { + return v.toString(); + } + return v; +}; + +export const useDecisionPathData = ({ + baseline, + featureImportance, + predictedValue, +}: UseDecisionPathDataParams): { decisionPathData: DecisionPathPlotData | undefined } => { + const decisionPathData = useMemo(() => { + return baseline + ? buildRegressionDecisionPathData({ + baseline, + featureImportance, + predictedValue: predictedValue as number | undefined, + }) + : buildClassificationDecisionPathData({ + featureImportance, + currentClass: predictedValue as string | undefined, + }); + }, [baseline, featureImportance, predictedValue]); + + return { decisionPathData }; +}; + +export const buildDecisionPathData = (featureImportance: ExtendedFeatureImportance[]) => { + const finalResult: DecisionPathPlotData = featureImportance + // sort so absolute importance so it goes from bottom (baseline) to top + .sort( + (a: ExtendedFeatureImportance, b: ExtendedFeatureImportance) => + b.absImportance! - a.absImportance! + ) + .map((d) => [d[FEATURE_NAME] as string, d[FEATURE_IMPORTANCE] as number, NaN]); + + // start at the baseline and end at predicted value + // for regression, cumulativeSum should add up to baseline + let cumulativeSum = 0; + for (let i = featureImportance.length - 1; i >= 0; i--) { + cumulativeSum += finalResult[i][1]; + finalResult[i][2] = cumulativeSum; + } + return finalResult; +}; +export const buildRegressionDecisionPathData = ({ + baseline, + featureImportance, + predictedValue, +}: RegressionDecisionPathProps): DecisionPathPlotData | undefined => { + let mappedFeatureImportance: ExtendedFeatureImportance[] = featureImportance; + mappedFeatureImportance = mappedFeatureImportance.map((d) => ({ + ...d, + absImportance: Math.abs(d[FEATURE_IMPORTANCE] as number), + })); + + if (baseline && predictedValue !== undefined && Number.isFinite(predictedValue)) { + // get the adjusted importance needed for when # of fields included in c++ analysis != max allowed + // if num fields included = num features allowed exactly, adjustedImportance should be 0 + const adjustedImportance = + predictedValue - + mappedFeatureImportance.reduce( + (accumulator, currentValue) => accumulator + currentValue.importance!, + 0 + ) - + baseline; + + mappedFeatureImportance.push({ + [FEATURE_NAME]: i18n.translate( + 'xpack.ml.dataframe.analytics.decisionPathFeatureBaselineTitle', + { + defaultMessage: 'baseline', + } + ), + [FEATURE_IMPORTANCE]: baseline, + absImportance: -1, + }); + + // if the difference is small enough then no need to plot the residual feature importance + if (Math.abs(adjustedImportance) > 1e-5) { + mappedFeatureImportance.push({ + [FEATURE_NAME]: i18n.translate( + 'xpack.ml.dataframe.analytics.decisionPathFeatureOtherTitle', + { + defaultMessage: 'other', + } + ), + [FEATURE_IMPORTANCE]: adjustedImportance, + absImportance: 0, // arbitrary importance so this will be of higher importance than baseline + }); + } + } + const filteredFeatureImportance = mappedFeatureImportance.filter( + (f) => f !== undefined + ) as ExtendedFeatureImportance[]; + + return buildDecisionPathData(filteredFeatureImportance); +}; + +export const buildClassificationDecisionPathData = ({ + featureImportance, + currentClass, +}: { + featureImportance: FeatureImportance[]; + currentClass: string | undefined; +}): DecisionPathPlotData | undefined => { + if (currentClass === undefined) return []; + const mappedFeatureImportance: Array< + ExtendedFeatureImportance | undefined + > = featureImportance.map((feature) => { + const classFeatureImportance = Array.isArray(feature.classes) + ? feature.classes.find((c) => getStringBasedClassName(c.class_name) === currentClass) + : feature; + if (classFeatureImportance && typeof classFeatureImportance[FEATURE_IMPORTANCE] === 'number') { + return { + [FEATURE_NAME]: feature[FEATURE_NAME], + [FEATURE_IMPORTANCE]: classFeatureImportance[FEATURE_IMPORTANCE], + absImportance: Math.abs(classFeatureImportance[FEATURE_IMPORTANCE] as number), + }; + } + return undefined; + }); + const filteredFeatureImportance = mappedFeatureImportance.filter( + (f) => f !== undefined + ) as ExtendedFeatureImportance[]; + + return buildDecisionPathData(filteredFeatureImportance); +}; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/types.ts b/x-pack/plugins/ml/public/application/components/data_grid/types.ts index 756f74c8f9302..f9ee8c37fabf7 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/types.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/types.ts @@ -74,6 +74,9 @@ export interface UseIndexDataReturnType | 'tableItems' | 'toggleChartVisibility' | 'visibleColumns' + | 'baseline' + | 'predictionFieldName' + | 'resultsField' > { renderCellValue: RenderCellValue; } @@ -105,4 +108,7 @@ export interface UseDataGridReturnType { tableItems: DataGridItem[]; toggleChartVisibility: () => void; visibleColumns: ColumnId[]; + baseline?: number; + predictionFieldName?: string; + resultsField?: string; } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts index 8ad861e616b7a..97098ea9e75c6 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts @@ -15,18 +15,19 @@ import { SavedSearchQuery } from '../../contexts/ml'; import { AnalysisConfig, ClassificationAnalysis, - OutlierAnalysis, RegressionAnalysis, + ANALYSIS_CONFIG_TYPE, } from '../../../../common/types/data_frame_analytics'; - +import { + isOutlierAnalysis, + isRegressionAnalysis, + isClassificationAnalysis, + getPredictionFieldName, + getDependentVar, + getPredictedFieldName, +} from '../../../../common/util/analytics_utils'; export type IndexPattern = string; -export enum ANALYSIS_CONFIG_TYPE { - OUTLIER_DETECTION = 'outlier_detection', - REGRESSION = 'regression', - CLASSIFICATION = 'classification', -} - export enum ANALYSIS_ADVANCED_FIELDS { ETA = 'eta', FEATURE_BAG_FRACTION = 'feature_bag_fraction', @@ -156,23 +157,6 @@ export const getAnalysisType = (analysis: AnalysisConfig): string => { return 'unknown'; }; -export const getDependentVar = ( - analysis: AnalysisConfig -): - | RegressionAnalysis['regression']['dependent_variable'] - | ClassificationAnalysis['classification']['dependent_variable'] => { - let depVar = ''; - - if (isRegressionAnalysis(analysis)) { - depVar = analysis.regression.dependent_variable; - } - - if (isClassificationAnalysis(analysis)) { - depVar = analysis.classification.dependent_variable; - } - return depVar; -}; - export const getTrainingPercent = ( analysis: AnalysisConfig ): @@ -190,24 +174,6 @@ export const getTrainingPercent = ( return trainingPercent; }; -export const getPredictionFieldName = ( - analysis: AnalysisConfig -): - | RegressionAnalysis['regression']['prediction_field_name'] - | ClassificationAnalysis['classification']['prediction_field_name'] => { - // If undefined will be defaulted to dependent_variable when config is created - let predictionFieldName; - if (isRegressionAnalysis(analysis) && analysis.regression.prediction_field_name !== undefined) { - predictionFieldName = analysis.regression.prediction_field_name; - } else if ( - isClassificationAnalysis(analysis) && - analysis.classification.prediction_field_name !== undefined - ) { - predictionFieldName = analysis.classification.prediction_field_name; - } - return predictionFieldName; -}; - export const getNumTopClasses = ( analysis: AnalysisConfig ): ClassificationAnalysis['classification']['num_top_classes'] => { @@ -238,35 +204,6 @@ export const getNumTopFeatureImportanceValues = ( return numTopFeatureImportanceValues; }; -export const getPredictedFieldName = ( - resultsField: string, - analysis: AnalysisConfig, - forSort?: boolean -) => { - // default is 'ml' - const predictionFieldName = getPredictionFieldName(analysis); - const defaultPredictionField = `${getDependentVar(analysis)}_prediction`; - const predictedField = `${resultsField}.${ - predictionFieldName ? predictionFieldName : defaultPredictionField - }`; - return predictedField; -}; - -export const isOutlierAnalysis = (arg: any): arg is OutlierAnalysis => { - const keys = Object.keys(arg); - return keys.length === 1 && keys[0] === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION; -}; - -export const isRegressionAnalysis = (arg: any): arg is RegressionAnalysis => { - const keys = Object.keys(arg); - return keys.length === 1 && keys[0] === ANALYSIS_CONFIG_TYPE.REGRESSION; -}; - -export const isClassificationAnalysis = (arg: any): arg is ClassificationAnalysis => { - const keys = Object.keys(arg); - return keys.length === 1 && keys[0] === ANALYSIS_CONFIG_TYPE.CLASSIFICATION; -}; - export const isResultsSearchBoolQuery = (arg: any): arg is ResultsSearchBoolQuery => { if (arg === undefined) return false; const keys = Object.keys(arg); @@ -607,3 +544,13 @@ export const loadDocsCount = async ({ }; } }; + +export { + isOutlierAnalysis, + isRegressionAnalysis, + isClassificationAnalysis, + getPredictionFieldName, + ANALYSIS_CONFIG_TYPE, + getDependentVar, + getPredictedFieldName, +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts index 2f14dfdfdfca3..c2295a92af89c 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts @@ -3,8 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - -export const DEFAULT_RESULTS_FIELD = 'ml'; export const FEATURE_IMPORTANCE = 'feature_importance'; export const FEATURE_INFLUENCE = 'feature_influence'; export const TOP_CLASSES = 'top_classes'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts index 847aefefbc6c8..f9c9bf26a9d16 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts @@ -4,17 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ +import { getNumTopClasses, getNumTopFeatureImportanceValues } from './analytics'; +import { Field } from '../../../../common/types/fields'; import { - getNumTopClasses, - getNumTopFeatureImportanceValues, getPredictedFieldName, getDependentVar, getPredictionFieldName, isClassificationAnalysis, isOutlierAnalysis, isRegressionAnalysis, -} from './analytics'; -import { Field } from '../../../../common/types/fields'; +} from '../../../../common/util/analytics_utils'; import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../../../../src/plugins/data/public'; import { newJobCapsService } from '../../services/new_job_capabilities_service'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/classification_exploration.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/classification_exploration.tsx index ccac9a697210b..2e3a5d89367ce 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/classification_exploration.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/classification_exploration.tsx @@ -9,7 +9,6 @@ import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; import { ExplorationPageWrapper } from '../exploration_page_wrapper'; - import { EvaluatePanel } from './evaluate_panel'; interface Props { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_page_wrapper/exploration_page_wrapper.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_page_wrapper/exploration_page_wrapper.tsx index 34ff36c59fa6c..84b44ef0d349f 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_page_wrapper/exploration_page_wrapper.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_page_wrapper/exploration_page_wrapper.tsx @@ -51,7 +51,6 @@ export const ExplorationPageWrapper: FC = ({ jobId, title, EvaluatePanel /> ); } - return ( <> {isLoadingJobConfig === true && jobConfig === undefined && } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx index 8395a11bd6fda..eea579ef1d064 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx @@ -28,6 +28,8 @@ import { INDEX_STATUS, SEARCH_SIZE, defaultSearchQuery, + getAnalysisType, + ANALYSIS_CONFIG_TYPE, } from '../../../../common'; import { getTaskStateBadge } from '../../../analytics_management/components/analytics_list/use_columns'; import { DATA_FRAME_TASK_STATE } from '../../../analytics_management/components/analytics_list/common'; @@ -36,6 +38,7 @@ import { ExplorationQueryBar } from '../exploration_query_bar'; import { IndexPatternPrompt } from '../index_pattern_prompt'; import { useExplorationResults } from './use_exploration_results'; +import { useMlKibana } from '../../../../../contexts/kibana'; const showingDocs = i18n.translate( 'xpack.ml.dataframe.analytics.explorationResults.documentsShownHelpText', @@ -70,18 +73,27 @@ export const ExplorationResultsTable: FC = React.memo( setEvaluateSearchQuery, title, }) => { + const { + services: { + mlServices: { mlApiServices }, + }, + } = useMlKibana(); const [searchQuery, setSearchQuery] = useState(defaultSearchQuery); useEffect(() => { setEvaluateSearchQuery(searchQuery); }, [JSON.stringify(searchQuery)]); + const analysisType = getAnalysisType(jobConfig.analysis); + const classificationData = useExplorationResults( indexPattern, jobConfig, searchQuery, - getToastNotifications() + getToastNotifications(), + mlApiServices ); + const docFieldsCount = classificationData.columnsWithCharts.length; const { columnsWithCharts, @@ -94,7 +106,6 @@ export const ExplorationResultsTable: FC = React.memo( if (jobConfig === undefined || classificationData === undefined) { return null; } - // if it's a searchBar syntax error leave the table visible so they can try again if (status === INDEX_STATUS.ERROR && !errorMessage.includes('failed to create query')) { return ( @@ -184,6 +195,7 @@ export const ExplorationResultsTable: FC = React.memo( {...classificationData} dataTestSubj="mlExplorationDataGrid" toastNotifications={getToastNotifications()} + analysisType={(analysisType as unknown) as ANALYSIS_CONFIG_TYPE} /> diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts index 8d53214d23d47..a56345017258e 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts @@ -4,12 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useEffect, useMemo } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { EuiDataGridColumn } from '@elastic/eui'; import { CoreSetup } from 'src/core/public'; +import { i18n } from '@kbn/i18n'; +import { MlApiServices } from '../../../../../services/ml_api_service'; import { IndexPattern } from '../../../../../../../../../../src/plugins/data/public'; import { DataLoader } from '../../../../../datavisualizer/index_based/data_loader'; @@ -23,21 +25,26 @@ import { UseIndexDataReturnType, } from '../../../../../components/data_grid'; import { SavedSearchQuery } from '../../../../../contexts/ml'; - import { getIndexData, getIndexFields, DataFrameAnalyticsConfig } from '../../../../common'; import { - DEFAULT_RESULTS_FIELD, - FEATURE_IMPORTANCE, - TOP_CLASSES, -} from '../../../../common/constants'; + getPredictionFieldName, + getDefaultPredictionFieldName, +} from '../../../../../../../common/util/analytics_utils'; +import { FEATURE_IMPORTANCE, TOP_CLASSES } from '../../../../common/constants'; +import { DEFAULT_RESULTS_FIELD } from '../../../../../../../common/constants/data_frame_analytics'; import { sortExplorationResultsFields, ML__ID_COPY } from '../../../../common/fields'; +import { isRegressionAnalysis } from '../../../../common/analytics'; +import { extractErrorMessage } from '../../../../../../../common/util/errors'; export const useExplorationResults = ( indexPattern: IndexPattern | undefined, jobConfig: DataFrameAnalyticsConfig | undefined, searchQuery: SavedSearchQuery, - toastNotifications: CoreSetup['notifications']['toasts'] + toastNotifications: CoreSetup['notifications']['toasts'], + mlApiServices: MlApiServices ): UseIndexDataReturnType => { + const [baseline, setBaseLine] = useState(); + const needsDestIndexFields = indexPattern !== undefined && indexPattern.title === jobConfig?.source.index[0]; @@ -52,7 +59,6 @@ export const useExplorationResults = ( ) ); } - const dataGrid = useDataGrid( columns, 25, @@ -107,16 +113,60 @@ export const useExplorationResults = ( jobConfig?.dest.index, JSON.stringify([searchQuery, dataGrid.visibleColumns]), ]); + const predictionFieldName = useMemo(() => { + if (jobConfig) { + return ( + getPredictionFieldName(jobConfig.analysis) ?? + getDefaultPredictionFieldName(jobConfig.analysis) + ); + } + return undefined; + }, [jobConfig]); + + const getAnalyticsBaseline = useCallback(async () => { + try { + if ( + jobConfig !== undefined && + jobConfig.analysis !== undefined && + isRegressionAnalysis(jobConfig.analysis) + ) { + const result = await mlApiServices.dataFrameAnalytics.getAnalyticsBaseline(jobConfig.id); + if (result?.baseline) { + setBaseLine(result.baseline); + } + } + } catch (e) { + const error = extractErrorMessage(e); + + toastNotifications.addDanger({ + title: i18n.translate( + 'xpack.ml.dataframe.analytics.explorationResults.baselineErrorMessageToast', + { + defaultMessage: 'An error occurred getting feature importance baseline', + } + ), + text: error, + }); + } + }, [mlApiServices, jobConfig]); + + useEffect(() => { + getAnalyticsBaseline(); + }, [jobConfig]); + const resultsField = jobConfig?.dest.results_field ?? DEFAULT_RESULTS_FIELD; const renderCellValue = useRenderCellValue( indexPattern, dataGrid.pagination, dataGrid.tableItems, - jobConfig?.dest.results_field ?? DEFAULT_RESULTS_FIELD + resultsField ); return { ...dataGrid, renderCellValue, + baseline, + predictionFieldName, + resultsField, }; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts index 24649ae5f1e71..151e5ea4e6feb 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts @@ -29,7 +29,8 @@ import { SavedSearchQuery } from '../../../../../contexts/ml'; import { getToastNotifications } from '../../../../../util/dependency_cache'; import { getIndexData, getIndexFields, DataFrameAnalyticsConfig } from '../../../../common'; -import { DEFAULT_RESULTS_FIELD, FEATURE_INFLUENCE } from '../../../../common/constants'; +import { FEATURE_INFLUENCE } from '../../../../common/constants'; +import { DEFAULT_RESULTS_FIELD } from '../../../../../../../common/constants/data_frame_analytics'; import { sortExplorationResultsFields, ML__ID_COPY } from '../../../../common/fields'; import { getFeatureCount, getOutlierScoreFieldName } from './common'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx index 60c699ba0d370..ce24892c9de45 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx @@ -12,7 +12,7 @@ import { IIndexPattern } from 'src/plugins/data/common'; import { DeepReadonly } from '../../../../../../../common/types/common'; import { DataFrameAnalyticsConfig, isOutlierAnalysis } from '../../../../common'; import { isClassificationAnalysis, isRegressionAnalysis } from '../../../../common/analytics'; -import { DEFAULT_RESULTS_FIELD } from '../../../../common/constants'; +import { DEFAULT_RESULTS_FIELD } from '../../../../../../../common/constants/data_frame_analytics'; import { useMlKibana, useNavigateToPath } from '../../../../../contexts/kibana'; import { DEFAULT_NUM_TOP_FEATURE_IMPORTANCE_VALUES } from '../../hooks/use_create_analytics_form'; import { State } from '../../hooks/use_create_analytics_form/state'; diff --git a/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts b/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts index 34f86ffa18788..b36eccdde2798 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts +++ b/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts @@ -80,7 +80,7 @@ export class DataLoader { earliest: number | undefined, latest: number | undefined, fields: FieldRequestConfig[], - interval?: string + interval?: number ): Promise { const stats = await ml.getVisualizerFieldStats({ indexPatternTitle: this._indexPatternTitle, diff --git a/x-pack/plugins/ml/public/application/datavisualizer/index_based/page.tsx b/x-pack/plugins/ml/public/application/datavisualizer/index_based/page.tsx index 26ed3152058dd..bad1488166e23 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/index_based/page.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/index_based/page.tsx @@ -348,7 +348,7 @@ export const Page: FC = () => { earliest, latest, existMetricFields, - aggInterval.expression + aggInterval.asMilliseconds() ); // Add the metric stats to the existing stats in the corresponding config. diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js index 712b64af2db80..a6fda86f27a7c 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js @@ -111,7 +111,7 @@ export const anomalyDataChange = function ( // Query 1 - load the raw metric data. function getMetricData(config, range) { - const { jobId, detectorIndex, entityFields, interval } = config; + const { jobId, detectorIndex, entityFields, bucketSpanSeconds } = config; const job = mlJobService.getJob(jobId); @@ -122,14 +122,14 @@ export const anomalyDataChange = function ( return mlResultsService .getMetricData( config.datafeedConfig.indices, - config.entityFields, + entityFields, datafeedQuery, config.metricFunction, config.metricFieldName, config.timeField, range.min, range.max, - config.interval + bucketSpanSeconds * 1000 ) .toPromise(); } else { @@ -175,7 +175,14 @@ export const anomalyDataChange = function ( }; return mlResultsService - .getModelPlotOutput(jobId, detectorIndex, criteriaFields, range.min, range.max, interval) + .getModelPlotOutput( + jobId, + detectorIndex, + criteriaFields, + range.min, + range.max, + bucketSpanSeconds * 1000 + ) .toPromise() .then((resp) => { // Return data in format required by the explorer charts. @@ -218,7 +225,7 @@ export const anomalyDataChange = function ( [config.jobId], range.min, range.max, - config.interval, + config.bucketSpanSeconds * 1000, 1, MAX_SCHEDULED_EVENTS ) @@ -252,7 +259,7 @@ export const anomalyDataChange = function ( config.timeField, range.min, range.max, - config.interval + config.bucketSpanSeconds * 1000 ); } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/results_loader.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/results_loader.ts index 2b250b9622286..af31df863ab76 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/results_loader.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/results_loader.ts @@ -161,7 +161,7 @@ export class ResultsLoader { [], this._lastModelTimeStamp, this._jobCreator.end, - `${this._chartInterval.getInterval().asMilliseconds()}ms`, + this._chartInterval.getInterval().asMilliseconds(), agg.mlModelPlotAgg ) .toPromise(); @@ -211,7 +211,7 @@ export class ResultsLoader { [this._jobCreator.jobId], this._jobCreator.start, this._jobCreator.end, - `${this._chartInterval.getInterval().asMilliseconds()}ms`, + this._chartInterval.getInterval().asMilliseconds(), 1 ); @@ -233,7 +233,7 @@ export class ResultsLoader { this._jobCreator.jobId, this._jobCreator.start, this._jobCreator.end, - `${this._chartInterval.getInterval().asMilliseconds()}ms`, + this._chartInterval.getInterval().asMilliseconds(), this._detectorSplitFieldFilters ); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/searches.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/searches.ts index 51c396518c851..02a6f47bed6c9 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/searches.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/searches.ts @@ -32,7 +32,7 @@ export function getScoresByRecord( jobId: string, earliestMs: number, latestMs: number, - interval: string, + intervalMs: number, firstSplitField: SplitFieldWithValue | null ): Promise { return new Promise((resolve, reject) => { @@ -104,7 +104,7 @@ export function getScoresByRecord( byTime: { date_histogram: { field: 'timestamp', - interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: 1, extended_bounds: { min: earliestMs, diff --git a/x-pack/plugins/ml/public/application/services/anomaly_timeline_service.ts b/x-pack/plugins/ml/public/application/services/anomaly_timeline_service.ts index 2bdb758be874c..3ee50a4759006 100644 --- a/x-pack/plugins/ml/public/application/services/anomaly_timeline_service.ts +++ b/x-pack/plugins/ml/public/application/services/anomaly_timeline_service.ts @@ -180,7 +180,7 @@ export class AnomalyTimelineService { // Pass the interval in seconds as the swim lane relies on a fixed number of seconds between buckets // which wouldn't be the case if e.g. '1M' was used. - const interval = `${swimlaneBucketInterval.asSeconds()}s`; + const intervalMs = swimlaneBucketInterval.asMilliseconds(); let response; if (viewBySwimlaneFieldName === VIEW_BY_JOB_LABEL) { @@ -190,7 +190,7 @@ export class AnomalyTimelineService { jobIds, searchBounds.min.valueOf(), searchBounds.max.valueOf(), - interval, + intervalMs, perPage, fromPage ); @@ -201,7 +201,7 @@ export class AnomalyTimelineService { fieldValues, searchBounds.min.valueOf(), searchBounds.max.valueOf(), - interval, + intervalMs, swimlaneLimit, perPage, fromPage, @@ -269,7 +269,7 @@ export class AnomalyTimelineService { selectedJobIds, earliestMs, latestMs, - this.getSwimlaneBucketInterval(selectedJobs, swimlaneContainerWidth).asSeconds() + 's', + this.getSwimlaneBucketInterval(selectedJobs, swimlaneContainerWidth).asMilliseconds(), swimlaneLimit ); return Object.keys(resp.results); diff --git a/x-pack/plugins/ml/public/application/services/forecast_service.d.ts b/x-pack/plugins/ml/public/application/services/forecast_service.d.ts index 9eff86c753da9..e30790c57966b 100644 --- a/x-pack/plugins/ml/public/application/services/forecast_service.d.ts +++ b/x-pack/plugins/ml/public/application/services/forecast_service.d.ts @@ -25,7 +25,7 @@ export const mlForecastService: { entityFields: any[], earliestMs: number, latestMs: number, - interval: string, + intervalMs: number, aggType: any ) => Observable; diff --git a/x-pack/plugins/ml/public/application/services/forecast_service.js b/x-pack/plugins/ml/public/application/services/forecast_service.js index 57e50387a03ab..c13e265b4655c 100644 --- a/x-pack/plugins/ml/public/application/services/forecast_service.js +++ b/x-pack/plugins/ml/public/application/services/forecast_service.js @@ -153,7 +153,7 @@ function getForecastData( entityFields, earliestMs, latestMs, - interval, + intervalMs, aggType ) { // Extract the partition, by, over fields on which to filter. @@ -257,7 +257,7 @@ function getForecastData( times: { date_histogram: { field: 'timestamp', - interval: interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: 1, }, aggs: { diff --git a/x-pack/plugins/ml/public/application/services/ml_api_service/data_frame_analytics.ts b/x-pack/plugins/ml/public/application/services/ml_api_service/data_frame_analytics.ts index 7de39d91047ef..434200d0383f5 100644 --- a/x-pack/plugins/ml/public/application/services/ml_api_service/data_frame_analytics.ts +++ b/x-pack/plugins/ml/public/application/services/ml_api_service/data_frame_analytics.ts @@ -135,4 +135,10 @@ export const dataFrameAnalytics = { method: 'GET', }); }, + getAnalyticsBaseline(analyticsId: string) { + return http({ + path: `${basePath()}/data_frame/analytics/${analyticsId}/baseline`, + method: 'POST', + }); + }, }; diff --git a/x-pack/plugins/ml/public/application/services/ml_api_service/index.ts b/x-pack/plugins/ml/public/application/services/ml_api_service/index.ts index 184039729f9ef..9d7ce4f3df59b 100644 --- a/x-pack/plugins/ml/public/application/services/ml_api_service/index.ts +++ b/x-pack/plugins/ml/public/application/services/ml_api_service/index.ts @@ -485,7 +485,7 @@ export function mlApiServicesProvider(httpService: HttpService) { earliest?: number; latest?: number; samplerShardSize?: number; - interval?: string; + interval?: number; fields?: FieldRequestConfig[]; maxExamples?: number; }) { diff --git a/x-pack/plugins/ml/public/application/services/results_service/result_service_rx.ts b/x-pack/plugins/ml/public/application/services/results_service/result_service_rx.ts index 898ca8894cbda..22f878a337f51 100644 --- a/x-pack/plugins/ml/public/application/services/results_service/result_service_rx.ts +++ b/x-pack/plugins/ml/public/application/services/results_service/result_service_rx.ts @@ -70,7 +70,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { timeFieldName: string, earliestMs: number, latestMs: number, - interval: string + intervalMs: number ): Observable { // Build the criteria to use in the bool filter part of the request. // Add criteria for the time range, entity fields, @@ -136,7 +136,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { byTime: { date_histogram: { field: timeFieldName, - interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: 0, }, }, @@ -202,7 +202,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { criteriaFields: any[], earliestMs: number, latestMs: number, - interval: string, + intervalMs: number, aggType?: { min: any; max: any } ): Observable { const obj: ModelPlotOutput = { @@ -291,7 +291,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { times: { date_histogram: { field: 'timestamp', - interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: 0, }, aggs: { @@ -446,7 +446,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { jobIds: string[] | undefined, earliestMs: number, latestMs: number, - interval: string, + intervalMs: number, maxJobs: number, maxEvents: number ): Observable { @@ -518,7 +518,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { times: { date_histogram: { field: 'timestamp', - interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: 1, }, aggs: { diff --git a/x-pack/plugins/ml/public/application/services/results_service/results_service.d.ts b/x-pack/plugins/ml/public/application/services/results_service/results_service.d.ts index b26528b76037b..aae0cb51aa81d 100644 --- a/x-pack/plugins/ml/public/application/services/results_service/results_service.d.ts +++ b/x-pack/plugins/ml/public/application/services/results_service/results_service.d.ts @@ -13,7 +13,7 @@ export function resultsServiceProvider( jobIds: string[], earliestMs: number, latestMs: number, - interval: string | number, + intervalMs: number, perPage?: number, fromPage?: number ): Promise; @@ -41,7 +41,7 @@ export function resultsServiceProvider( influencerFieldValues: string[], earliestMs: number, latestMs: number, - interval: string, + intervalMs: number, maxResults: number, perPage: number, fromPage: number, @@ -57,8 +57,25 @@ export function resultsServiceProvider( timeFieldName: string, earliestMs: number, latestMs: number, - interval: string | number + intervalMs: number + ): Promise; + getEventDistributionData( + index: string, + splitField: string, + filterField: string, + query: any, + metricFunction: string, // ES aggregation name + metricFieldName: string, + timeFieldName: string, + earliestMs: number, + latestMs: number, + intervalMs: number + ): Promise; + getRecordMaxScoreByTime( + jobId: string, + criteriaFields: any[], + earliestMs: number, + latestMs: number, + intervalMs: number ): Promise; - getEventDistributionData(): Promise; - getRecordMaxScoreByTime(): Promise; }; diff --git a/x-pack/plugins/ml/public/application/services/results_service/results_service.js b/x-pack/plugins/ml/public/application/services/results_service/results_service.js index ef00c9025763e..fd48845494dfd 100644 --- a/x-pack/plugins/ml/public/application/services/results_service/results_service.js +++ b/x-pack/plugins/ml/public/application/services/results_service/results_service.js @@ -28,7 +28,7 @@ export function resultsServiceProvider(mlApiServices) { // Pass an empty array or ['*'] to search over all job IDs. // Returned response contains a results property, with a key for job // which has results for the specified time range. - getScoresByBucket(jobIds, earliestMs, latestMs, interval, perPage = 10, fromPage = 1) { + getScoresByBucket(jobIds, earliestMs, latestMs, intervalMs, perPage = 10, fromPage = 1) { return new Promise((resolve, reject) => { const obj = { success: true, @@ -116,7 +116,7 @@ export function resultsServiceProvider(mlApiServices) { byTime: { date_histogram: { field: 'timestamp', - interval: interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: 1, extended_bounds: { min: earliestMs, @@ -492,7 +492,7 @@ export function resultsServiceProvider(mlApiServices) { influencerFieldValues, earliestMs, latestMs, - interval, + intervalMs, maxResults = ANOMALY_SWIM_LANE_HARD_LIMIT, perPage = SWIM_LANE_DEFAULT_PAGE_SIZE, fromPage = 1, @@ -615,7 +615,7 @@ export function resultsServiceProvider(mlApiServices) { byTime: { date_histogram: { field: 'timestamp', - interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: 1, }, aggs: { @@ -1033,7 +1033,7 @@ export function resultsServiceProvider(mlApiServices) { // Extra query object can be supplied, or pass null if no additional query. // Returned response contains a results property, which is an object // of document counts against time (epoch millis). - getEventRateData(index, query, timeFieldName, earliestMs, latestMs, interval) { + getEventRateData(index, query, timeFieldName, earliestMs, latestMs, intervalMs) { return new Promise((resolve, reject) => { const obj = { success: true, results: {} }; @@ -1074,7 +1074,7 @@ export function resultsServiceProvider(mlApiServices) { eventRate: { date_histogram: { field: timeFieldName, - interval: interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: 0, extended_bounds: { min: earliestMs, @@ -1118,7 +1118,7 @@ export function resultsServiceProvider(mlApiServices) { timeFieldName, earliestMs, latestMs, - interval + intervalMs ) { return new Promise((resolve, reject) => { if (splitField === undefined) { @@ -1187,7 +1187,7 @@ export function resultsServiceProvider(mlApiServices) { byTime: { date_histogram: { field: timeFieldName, - interval: interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: AGGREGATION_MIN_DOC_COUNT, }, aggs: { @@ -1277,7 +1277,7 @@ export function resultsServiceProvider(mlApiServices) { // criteria, time range, and aggregation interval. // criteriaFields parameter must be an array, with each object in the array having 'fieldName' // 'fieldValue' properties. - getRecordMaxScoreByTime(jobId, criteriaFields, earliestMs, latestMs, interval) { + getRecordMaxScoreByTime(jobId, criteriaFields, earliestMs, latestMs, intervalMs) { return new Promise((resolve, reject) => { const obj = { success: true, @@ -1331,7 +1331,7 @@ export function resultsServiceProvider(mlApiServices) { times: { date_histogram: { field: 'timestamp', - interval: interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: 1, }, aggs: { diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseries_search_service.ts b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseries_search_service.ts index d1e959b33e5dc..5149fecb0ec26 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseries_search_service.ts +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseries_search_service.ts @@ -29,7 +29,7 @@ function getMetricData( entityFields: EntityField[], earliestMs: number, latestMs: number, - interval: string + intervalMs: number ): Observable { if ( isModelPlotChartableForDetector(job, detectorIndex) && @@ -76,7 +76,7 @@ function getMetricData( criteriaFields, earliestMs, latestMs, - interval + intervalMs ); } else { const obj: ModelPlotOutput = { @@ -96,7 +96,7 @@ function getMetricData( chartConfig.timeField, earliestMs, latestMs, - interval + intervalMs ) .pipe( map((resp) => { diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js index 0e99d64cf202f..7d173e161a1cb 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js @@ -629,7 +629,7 @@ export class TimeSeriesExplorer extends React.Component { nonBlankEntities, searchBounds.min.valueOf(), searchBounds.max.valueOf(), - stateUpdate.contextAggregationInterval.expression + stateUpdate.contextAggregationInterval.asMilliseconds() ) .toPromise() .then((resp) => { @@ -652,7 +652,7 @@ export class TimeSeriesExplorer extends React.Component { this.getCriteriaFields(detectorIndex, entityControls), searchBounds.min.valueOf(), searchBounds.max.valueOf(), - stateUpdate.contextAggregationInterval.expression + stateUpdate.contextAggregationInterval.asMilliseconds() ) .then((resp) => { const fullRangeRecordScoreData = processRecordScoreResults(resp.results); @@ -703,7 +703,7 @@ export class TimeSeriesExplorer extends React.Component { nonBlankEntities, searchBounds.min.valueOf(), searchBounds.max.valueOf(), - stateUpdate.contextAggregationInterval.expression, + stateUpdate.contextAggregationInterval.asMilliseconds(), aggType ) .toPromise() diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/get_focus_data.ts b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/get_focus_data.ts index 23d1e3f7cc904..ce0d7b0abc3e0 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/get_focus_data.ts +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/get_focus_data.ts @@ -61,7 +61,7 @@ export function getFocusData( nonBlankEntities, searchBounds.min.valueOf(), searchBounds.max.valueOf(), - focusAggregationInterval.expression + focusAggregationInterval.asMilliseconds() ), // Query 2 - load all the records across selected time range for the chart anomaly markers. mlResultsService.getRecordsForCriteria( @@ -77,7 +77,7 @@ export function getFocusData( [selectedJob.job_id], searchBounds.min.valueOf(), searchBounds.max.valueOf(), - focusAggregationInterval.expression, + focusAggregationInterval.asMilliseconds(), 1, MAX_SCHEDULED_EVENTS ), @@ -123,7 +123,7 @@ export function getFocusData( nonBlankEntities, searchBounds.min.valueOf(), searchBounds.max.valueOf(), - focusAggregationInterval.expression, + focusAggregationInterval.asMilliseconds(), aggType ); })() diff --git a/x-pack/plugins/ml/server/models/bucket_span_estimator/polled_data_checker.js b/x-pack/plugins/ml/server/models/bucket_span_estimator/polled_data_checker.js index fd0cab7c0625d..981ffe9618d9f 100644 --- a/x-pack/plugins/ml/server/models/bucket_span_estimator/polled_data_checker.js +++ b/x-pack/plugins/ml/server/models/bucket_span_estimator/polled_data_checker.js @@ -56,7 +56,7 @@ export function polledDataCheckerFactory({ asCurrentUser }) { date_histogram: { min_doc_count: 1, field: this.timeField, - interval: `${intervalMs}ms`, + fixed_interval: `${intervalMs}ms`, }, }, }, diff --git a/x-pack/plugins/ml/server/models/bucket_span_estimator/single_series_checker.js b/x-pack/plugins/ml/server/models/bucket_span_estimator/single_series_checker.js index 750f0cfc0b4a8..5dd0a5ff563d6 100644 --- a/x-pack/plugins/ml/server/models/bucket_span_estimator/single_series_checker.js +++ b/x-pack/plugins/ml/server/models/bucket_span_estimator/single_series_checker.js @@ -166,7 +166,7 @@ export function singleSeriesCheckerFactory({ asCurrentUser }) { non_empty_buckets: { date_histogram: { field: this.timeField, - interval: `${intervalMs}ms`, + fixed_interval: `${intervalMs}ms`, }, }, }, diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/feature_importance.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/feature_importance.ts new file mode 100644 index 0000000000000..94f54a5654873 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/feature_importance.ts @@ -0,0 +1,69 @@ +/* + * 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 { IScopedClusterClient } from 'kibana/server'; +import { + getDefaultPredictionFieldName, + getPredictionFieldName, + isRegressionAnalysis, +} from '../../../common/util/analytics_utils'; +import { DEFAULT_RESULTS_FIELD } from '../../../common/constants/data_frame_analytics'; +// Obtains data for the data frame analytics feature importance functionalities +// such as baseline, decision paths, or importance summary. +export function analyticsFeatureImportanceProvider({ + asInternalUser, + asCurrentUser, +}: IScopedClusterClient) { + async function getRegressionAnalyticsBaseline(analyticsId: string): Promise { + const { body } = await asInternalUser.ml.getDataFrameAnalytics({ + id: analyticsId, + }); + const jobConfig = body.data_frame_analytics[0]; + if (!isRegressionAnalysis) return undefined; + const destinationIndex = jobConfig.dest.index; + const predictionFieldName = getPredictionFieldName(jobConfig.analysis); + const mlResultsField = jobConfig.dest?.results_field ?? DEFAULT_RESULTS_FIELD; + const predictedField = `${mlResultsField}.${ + predictionFieldName ? predictionFieldName : getDefaultPredictionFieldName(jobConfig.analysis) + }`; + const isTrainingField = `${mlResultsField}.is_training`; + + const params = { + index: destinationIndex, + size: 0, + body: { + query: { + bool: { + filter: [ + { + term: { + [isTrainingField]: true, + }, + }, + ], + }, + }, + aggs: { + featureImportanceBaseline: { + avg: { + field: predictedField, + }, + }, + }, + }, + }; + let baseline; + const { body: aggregationResult } = await asCurrentUser.search(params); + if (aggregationResult) { + baseline = aggregationResult.aggregations.featureImportanceBaseline.value; + } + return baseline; + } + + return { + getRegressionAnalyticsBaseline, + }; +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_low_request_rate.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_low_request_rate.json index a9865183320d5..084aa08455405 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_low_request_rate.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_low_request_rate.json @@ -10,7 +10,7 @@ "buckets": { "date_histogram": { "field": "timestamp", - "interval": 3600000 + "fixed_interval": "1h" }, "aggregations": { "timestamp": { diff --git a/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts b/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts index dbfa4b5656e5f..95c4e79150059 100644 --- a/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts +++ b/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts @@ -468,7 +468,7 @@ export class DataVisualizer { timeFieldName: string, earliestMs: number, latestMs: number, - interval: number, + intervalMs: number, maxExamples: number ): Promise { // Batch up fields by type, getting stats for multiple fields at a time. @@ -526,7 +526,7 @@ export class DataVisualizer { timeFieldName, earliestMs, latestMs, - interval + intervalMs ); batchStats.push(stats); } @@ -710,7 +710,7 @@ export class DataVisualizer { timeFieldName: string, earliestMs: number, latestMs: number, - interval: number + intervalMs: number ): Promise { const index = indexPatternTitle; const size = 0; @@ -718,11 +718,12 @@ export class DataVisualizer { // Don't use the sampler aggregation as this can lead to some potentially // confusing date histogram results depending on the date range of data amongst shards. + const aggs = { eventRate: { date_histogram: { field: timeFieldName, - interval, + fixed_interval: `${intervalMs}ms`, min_doc_count: 1, }, }, @@ -756,7 +757,7 @@ export class DataVisualizer { return { documentCounts: { - interval, + interval: intervalMs, buckets, }, }; diff --git a/x-pack/plugins/ml/server/models/file_data_visualizer/import_data.ts b/x-pack/plugins/ml/server/models/file_data_visualizer/import_data.ts index 6108454c08aa7..26dba7c2f00c1 100644 --- a/x-pack/plugins/ml/server/models/file_data_visualizer/import_data.ts +++ b/x-pack/plugins/ml/server/models/file_data_visualizer/import_data.ts @@ -94,7 +94,7 @@ export function importDataProvider({ asCurrentUser }: IScopedClusterClient) { _meta: { created_by: INDEX_META_DATA_CREATED_BY, }, - properties: mappings, + properties: mappings.properties, }, }; diff --git a/x-pack/plugins/ml/server/models/job_service/jobs.ts b/x-pack/plugins/ml/server/models/job_service/jobs.ts index e047d31ba6eb7..f4378e29ef826 100644 --- a/x-pack/plugins/ml/server/models/job_service/jobs.ts +++ b/x-pack/plugins/ml/server/models/job_service/jobs.ts @@ -407,28 +407,21 @@ export function jobsProvider(client: IScopedClusterClient) { // Job IDs in supplied array may contain wildcard '*' characters // e.g. *_low_request_rate_ecs async function jobsExist(jobIds: string[] = []) { - // Get the list of job IDs. - const { body } = await asInternalUser.ml.getJobs({ - job_id: jobIds.join(), - }); - const results: { [id: string]: boolean } = {}; - if (body.count > 0) { - const allJobIds = body.jobs.map((job) => job.job_id); - - // Check if each of the supplied IDs match existing jobs. - jobIds.forEach((jobId) => { - // Create a Regex for each supplied ID as wildcard * is allowed. - const regexp = new RegExp(`^${jobId.replace(/\*+/g, '.*')}$`); - const exists = allJobIds.some((existsJobId) => regexp.test(existsJobId)); - results[jobId] = exists; - }); - } else { - jobIds.forEach((jobId) => { + for (const jobId of jobIds) { + try { + const { body } = await asInternalUser.ml.getJobs({ + job_id: jobId, + }); + results[jobId] = body.count > 0; + } catch (e) { + // if a non-wildcarded job id is supplied, the get jobs endpoint will 404 + if (e.body?.status !== 404) { + throw e; + } results[jobId] = false; - }); + } } - return results; } diff --git a/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts b/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts index 9eea1ea2a28ae..128b28a223445 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts @@ -114,7 +114,7 @@ function getSearchJsonFromConfig( times: { date_histogram: { field: timeField, - interval: intervalMs, + fixed_interval: `${intervalMs}ms`, min_doc_count: 0, extended_bounds: { min: start, diff --git a/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts b/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts index 567afec809405..71e81158d8885 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts @@ -142,7 +142,7 @@ function getPopulationSearchJsonFromConfig( times: { date_histogram: { field: timeField, - interval: intervalMs, + fixed_interval: `${intervalMs}ms`, min_doc_count: 0, extended_bounds: { min: start, diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/kibana_saved_objects.json b/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/kibana_saved_objects.json index ca356b2bede22..9e2af76264231 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/kibana_saved_objects.json +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/kibana_saved_objects.json @@ -20,7 +20,7 @@ "type": "index-pattern", "id": "be14ceb0-66b1-11e9-91c9-ffa52374d341", "attributes": { - "typeMeta": "{\"params\":{\"rollup_index\":\"cloud_roll_index\"},\"aggs\":{\"histogram\":{\"NetworkOut\":{\"agg\":\"histogram\",\"interval\":5},\"CPUUtilization\":{\"agg\":\"histogram\",\"interval\":5},\"NetworkIn\":{\"agg\":\"histogram\",\"interval\":5}},\"avg\":{\"NetworkOut\":{\"agg\":\"avg\"},\"CPUUtilization\":{\"agg\":\"avg\"},\"NetworkIn\":{\"agg\":\"avg\"},\"DiskReadBytes\":{\"agg\":\"avg\"}},\"min\":{\"NetworkOut\":{\"agg\":\"min\"},\"NetworkIn\":{\"agg\":\"min\"}},\"value_count\":{\"NetworkOut\":{\"agg\":\"value_count\"},\"DiskReadBytes\":{\"agg\":\"value_count\"},\"CPUUtilization\":{\"agg\":\"value_count\"},\"NetworkIn\":{\"agg\":\"value_count\"}},\"max\":{\"CPUUtilization\":{\"agg\":\"max\"},\"DiskReadBytes\":{\"agg\":\"max\"}},\"date_histogram\":{\"@timestamp\":{\"agg\":\"date_histogram\",\"delay\":\"1d\",\"interval\":\"5m\",\"time_zone\":\"UTC\"}},\"terms\":{\"instance\":{\"agg\":\"terms\"},\"sourcetype.keyword\":{\"agg\":\"terms\"},\"region\":{\"agg\":\"terms\"}},\"sum\":{\"DiskReadBytes\":{\"agg\":\"sum\"},\"NetworkOut\":{\"agg\":\"sum\"}}}}", + "typeMeta": "{\"params\":{\"rollup_index\":\"cloud_roll_index\"},\"aggs\":{\"histogram\":{\"NetworkOut\":{\"agg\":\"histogram\",\"interval\":5},\"CPUUtilization\":{\"agg\":\"histogram\",\"interval\":5},\"NetworkIn\":{\"agg\":\"histogram\",\"interval\":5}},\"avg\":{\"NetworkOut\":{\"agg\":\"avg\"},\"CPUUtilization\":{\"agg\":\"avg\"},\"NetworkIn\":{\"agg\":\"avg\"},\"DiskReadBytes\":{\"agg\":\"avg\"}},\"min\":{\"NetworkOut\":{\"agg\":\"min\"},\"NetworkIn\":{\"agg\":\"min\"}},\"value_count\":{\"NetworkOut\":{\"agg\":\"value_count\"},\"DiskReadBytes\":{\"agg\":\"value_count\"},\"CPUUtilization\":{\"agg\":\"value_count\"},\"NetworkIn\":{\"agg\":\"value_count\"}},\"max\":{\"CPUUtilization\":{\"agg\":\"max\"},\"DiskReadBytes\":{\"agg\":\"max\"}},\"date_histogram\":{\"@timestamp\":{\"agg\":\"date_histogram\",\"delay\":\"1d\",\"fixed_interval\":\"5m\",\"time_zone\":\"UTC\"}},\"terms\":{\"instance\":{\"agg\":\"terms\"},\"sourcetype.keyword\":{\"agg\":\"terms\"},\"region\":{\"agg\":\"terms\"}},\"sum\":{\"DiskReadBytes\":{\"agg\":\"sum\"},\"NetworkOut\":{\"agg\":\"sum\"}}}}", "title": "cloud_roll_index", "type": "rollup" }, diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/rollup_caps.json b/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/rollup_caps.json index 2b2f8576d6769..b62bce700413a 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/rollup_caps.json +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/__mocks__/responses/rollup_caps.json @@ -37,7 +37,7 @@ { "agg": "date_histogram", "delay": "1d", - "interval": "5m", + "fixed_interval": "5m", "time_zone": "UTC" } ], @@ -123,7 +123,7 @@ { "agg": "date_histogram", "delay": "1d", - "interval": "5m", + "fixed_interval": "5m", "time_zone": "UTC" } ], @@ -174,7 +174,7 @@ { "agg": "date_histogram", "delay": "1d", - "interval": "5m", + "fixed_interval": "5m", "time_zone": "UTC" } ] diff --git a/x-pack/plugins/ml/server/routes/apidoc.json b/x-pack/plugins/ml/server/routes/apidoc.json index 86a62b28abb5e..dab00a03b5468 100644 --- a/x-pack/plugins/ml/server/routes/apidoc.json +++ b/x-pack/plugins/ml/server/routes/apidoc.json @@ -20,6 +20,7 @@ "DataVisualizer", "GetOverallStats", "GetStatsForFields", + "GetHistogramsForFields", "AnomalyDetectors", "CreateAnomalyDetectors", diff --git a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts index dea4803e8275e..7606420eacefc 100644 --- a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts +++ b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts @@ -20,6 +20,7 @@ import { import { IndexPatternHandler } from '../models/data_frame_analytics/index_patterns'; import { DeleteDataFrameAnalyticsWithIndexStatus } from '../../common/types/data_frame_analytics'; import { getAuthorizationHeader } from '../lib/request_authorization'; +import { analyticsFeatureImportanceProvider } from '../models/data_frame_analytics/feature_importance'; function getIndexPatternId(context: RequestHandlerContext, patternName: string) { const iph = new IndexPatternHandler(context.core.savedObjects.client); @@ -545,4 +546,38 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat } }) ); + + /** + * @apiGroup DataFrameAnalytics + * + * @api {get} /api/ml/data_frame/analytics/baseline Get analytics's feature importance baseline + * @apiName GetDataFrameAnalyticsBaseline + * @apiDescription Returns the baseline for data frame analytics job. + * + * @apiSchema (params) analyticsIdSchema + */ + router.post( + { + path: '/api/ml/data_frame/analytics/{analyticsId}/baseline', + validate: { + params: analyticsIdSchema, + }, + options: { + tags: ['access:ml:canGetDataFrameAnalytics'], + }, + }, + mlLicense.fullLicenseAPIGuard(async ({ client, request, response }) => { + try { + const { analyticsId } = request.params; + const { getRegressionAnalyticsBaseline } = analyticsFeatureImportanceProvider(client); + const baseline = await getRegressionAnalyticsBaseline(analyticsId); + + return response.ok({ + body: { baseline }, + }); + } catch (e) { + return response.customError(wrapError(e)); + } + }) + ); } diff --git a/x-pack/plugins/ml/server/routes/data_visualizer.ts b/x-pack/plugins/ml/server/routes/data_visualizer.ts index a697fe017f192..50d9be1be4230 100644 --- a/x-pack/plugins/ml/server/routes/data_visualizer.ts +++ b/x-pack/plugins/ml/server/routes/data_visualizer.ts @@ -84,7 +84,7 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization) /** * @apiGroup DataVisualizer * - * @api {post} /api/ml/data_visualizer/get_field_stats/:indexPatternTitle Get histograms for fields + * @api {post} /api/ml/data_visualizer/get_field_histograms/:indexPatternTitle Get histograms for fields * @apiName GetHistogramsForFields * @apiDescription Returns the histograms on a list fields in the specified index pattern. * diff --git a/x-pack/plugins/ml/server/routes/schemas/data_visualizer_schema.ts b/x-pack/plugins/ml/server/routes/schemas/data_visualizer_schema.ts index 24e45514e1efc..57bc5578e92c5 100644 --- a/x-pack/plugins/ml/server/routes/schemas/data_visualizer_schema.ts +++ b/x-pack/plugins/ml/server/routes/schemas/data_visualizer_schema.ts @@ -32,8 +32,8 @@ export const dataVisualizerFieldStatsSchema = schema.object({ earliest: schema.maybe(schema.number()), /** Latest timestamp for search, as epoch ms (optional). */ latest: schema.maybe(schema.number()), - /** Aggregation interval to use for obtaining document counts over time (optional). */ - interval: schema.maybe(schema.string()), + /** Aggregation interval, in milliseconds, to use for obtaining document counts over time (optional). */ + interval: schema.maybe(schema.number()), /** Maximum number of examples to return for text type fields. */ maxExamples: schema.number(), }); diff --git a/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx b/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx index 56cba83813a63..c9f82eb521433 100644 --- a/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx +++ b/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx @@ -23,6 +23,6 @@ export function createCpuUsageAlertType(): AlertTypeModel { ), validate, defaultActionMessage: '{{context.internalFullMessage}}', - requiresAppContext: false, + requiresAppContext: true, }; } diff --git a/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx b/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx index 58b37e43085ff..f6223d41ab30e 100644 --- a/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx +++ b/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx @@ -33,7 +33,7 @@ export function createLegacyAlertTypes(): AlertTypeModel[] { ), defaultActionMessage: '{{context.internalFullMessage}}', validate: () => ({ errors: {} }), - requiresAppContext: false, + requiresAppContext: true, }; }); } diff --git a/x-pack/plugins/reporting/common/constants.ts b/x-pack/plugins/reporting/common/constants.ts index c461c2de4e2ad..e5bca43cef562 100644 --- a/x-pack/plugins/reporting/common/constants.ts +++ b/x-pack/plugins/reporting/common/constants.ts @@ -16,6 +16,7 @@ export const API_BASE_URL_V1 = '/api/reporting/v1'; // export const API_BASE_GENERATE_V1 = `${API_BASE_URL_V1}/generate`; export const API_LIST_URL = '/api/reporting/jobs'; export const API_GENERATE_IMMEDIATE = `${API_BASE_URL_V1}/generate/immediate/csv/saved-object`; +export const API_DIAGNOSE_URL = `${API_BASE_URL}/diagnose`; export const CONTENT_TYPE_CSV = 'text/csv'; export const CSV_REPORTING_ACTION = 'downloadCsvReport'; diff --git a/x-pack/plugins/reporting/public/components/report_diagnostic.tsx b/x-pack/plugins/reporting/public/components/report_diagnostic.tsx new file mode 100644 index 0000000000000..b5b055207ddbb --- /dev/null +++ b/x-pack/plugins/reporting/public/components/report_diagnostic.tsx @@ -0,0 +1,281 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import React, { useState, Fragment } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { + EuiButton, + EuiButtonEmpty, + EuiCallOut, + EuiCodeBlock, + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiSpacer, + EuiSteps, + EuiText, + EuiTitle, +} from '@elastic/eui'; +import { ReportingAPIClient, DiagnoseResponse } from '../lib/reporting_api_client'; + +interface Props { + apiClient: ReportingAPIClient; +} + +type ResultStatus = 'danger' | 'incomplete' | 'complete'; + +enum statuses { + configStatus = 'configStatus', + chromeStatus = 'chromeStatus', + screenshotStatus = 'screenshotStatus', +} + +interface State { + isFlyoutVisible: boolean; + configStatus: ResultStatus; + chromeStatus: ResultStatus; + screenshotStatus: ResultStatus; + help: string[]; + logs: string; + isBusy: boolean; + success: boolean; +} + +const initialState: State = { + [statuses.configStatus]: 'incomplete', + [statuses.chromeStatus]: 'incomplete', + [statuses.screenshotStatus]: 'incomplete', + isFlyoutVisible: false, + help: [], + logs: '', + isBusy: false, + success: true, +}; + +export const ReportDiagnostic = ({ apiClient }: Props) => { + const [state, setStateBase] = useState(initialState); + const setState = (s: Partial) => + setStateBase({ + ...state, + ...s, + }); + const { + configStatus, + isBusy, + screenshotStatus, + chromeStatus, + isFlyoutVisible, + help, + logs, + success, + } = state; + + const closeFlyout = () => setState({ ...initialState, isFlyoutVisible: false }); + const showFlyout = () => setState({ isFlyoutVisible: true }); + const apiWrapper = (apiMethod: () => Promise, statusProp: statuses) => () => { + setState({ isBusy: true, [statusProp]: 'incomplete' }); + apiMethod() + .then((response) => { + setState({ + isBusy: false, + help: response.help, + logs: response.logs, + success: response.success, + [statusProp]: response.success ? 'complete' : 'danger', + }); + }) + .catch((error) => { + setState({ + isBusy: false, + help: [ + i18n.translate('xpack.reporting.listing.diagnosticApiCallFailure', { + defaultMessage: `There was a problem running the diagnostic: {error}`, + values: { error }, + }), + ], + logs: `${error.message}`, + success: false, + [statusProp]: 'danger', + }); + }); + }; + + const steps = [ + { + title: i18n.translate('xpack.reporting.listing.diagnosticConfigTitle', { + defaultMessage: 'Verify Kibana Configuration', + }), + children: ( + + + + + + + + ), + status: !success && configStatus !== 'complete' ? 'danger' : configStatus, + }, + ]; + + if (configStatus === 'complete') { + steps.push({ + title: i18n.translate('xpack.reporting.listing.diagnosticBrowserTitle', { + defaultMessage: 'Check Browser', + }), + children: ( + + + + + + + + ), + status: !success && chromeStatus !== 'complete' ? 'danger' : chromeStatus, + }); + } + + if (chromeStatus === 'complete') { + steps.push({ + title: i18n.translate('xpack.reporting.listing.diagnosticScreenshotTitle', { + defaultMessage: 'Check Screen Capture Capabilities', + }), + children: ( + + + + + + + + ), + status: !success && screenshotStatus !== 'complete' ? 'danger' : screenshotStatus, + }); + } + + if (screenshotStatus === 'complete') { + steps.push({ + title: i18n.translate('xpack.reporting.listing.diagnosticSuccessTitle', { + defaultMessage: 'All set!', + }), + children: ( + + + + ), + status: !success ? 'danger' : screenshotStatus, + }); + } + + if (!success) { + steps.push({ + title: i18n.translate('xpack.reporting.listing.diagnosticFailureTitle', { + defaultMessage: "Whoops! Looks like something isn't working properly.", + }), + children: ( + + {help.length ? ( + + +

{help.join('\n')}

+
+
+ ) : null} + {logs.length ? ( + + + + + {logs} + + ) : null} +
+ ), + status: 'danger', + }); + } + + let flyout; + if (isFlyoutVisible) { + flyout = ( + + + +

+ +

+
+ + + + +
+ + + +
+ ); + } + return ( +
+ {flyout} + + + +
+ ); +}; diff --git a/x-pack/plugins/reporting/public/components/report_listing.tsx b/x-pack/plugins/reporting/public/components/report_listing.tsx index afcae93a8db16..65db13f22788b 100644 --- a/x-pack/plugins/reporting/public/components/report_listing.tsx +++ b/x-pack/plugins/reporting/public/components/report_listing.tsx @@ -6,6 +6,8 @@ import { EuiBasicTable, + EuiFlexItem, + EuiFlexGroup, EuiPageContent, EuiSpacer, EuiText, @@ -31,6 +33,7 @@ import { ReportErrorButton, ReportInfoButton, } from './buttons'; +import { ReportDiagnostic } from './report_diagnostic'; export interface Job { id: string; @@ -134,23 +137,38 @@ class ReportListingUi extends Component { public render() { return ( - - -

- -

-
- -

- -

-
- - {this.renderTable()} -
+
+ + + + +

+ +

+
+ +

+ +

+
+
+
+ + {this.renderTable()} +
+ + + + + + +
); } diff --git a/x-pack/plugins/reporting/public/lib/reporting_api_client.ts b/x-pack/plugins/reporting/public/lib/reporting_api_client.ts index 54bdc99532320..2f813bd811c6c 100644 --- a/x-pack/plugins/reporting/public/lib/reporting_api_client.ts +++ b/x-pack/plugins/reporting/public/lib/reporting_api_client.ts @@ -8,7 +8,12 @@ import { stringify } from 'query-string'; import rison from 'rison-node'; import { HttpSetup } from 'src/core/public'; import { JobId, SourceJob } from '../../common/types'; -import { API_BASE_GENERATE, API_LIST_URL, REPORTING_MANAGEMENT_HOME } from '../../constants'; +import { + API_BASE_URL, + API_BASE_GENERATE, + API_LIST_URL, + REPORTING_MANAGEMENT_HOME, +} from '../../constants'; import { add } from './job_completion_notifications'; export interface JobQueueEntry { @@ -59,6 +64,12 @@ interface JobParams { [paramName: string]: any; } +export interface DiagnoseResponse { + help: string[]; + success: boolean; + logs: string; +} + export class ReportingAPIClient { private http: HttpSetup; @@ -157,4 +168,28 @@ export class ReportingAPIClient { * provides the raw server basePath to allow it to be stripped out from relativeUrls in job params */ public getServerBasePath = () => this.http.basePath.serverBasePath; + + /* + * Diagnostic-related API calls + */ + public verifyConfig = (): Promise => + this.http.post(`${API_BASE_URL}/diagnose/config`, { + asSystemRequest: true, + }); + + /* + * Diagnostic-related API calls + */ + public verifyBrowser = (): Promise => + this.http.post(`${API_BASE_URL}/diagnose/browser`, { + asSystemRequest: true, + }); + + /* + * Diagnostic-related API calls + */ + public verifyScreenCapture = (): Promise => + this.http.post(`${API_BASE_URL}/diagnose/screenshot`, { + asSystemRequest: true, + }); } diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts index 809bfb57dd4fa..88be86d1ecc30 100644 --- a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts @@ -59,28 +59,6 @@ export class HeadlessChromiumDriverFactory { type = BROWSER_TYPE; - test(logger: LevelLogger) { - const chromiumArgs = args({ - userDataDir: this.userDataDir, - viewport: { width: 800, height: 600 }, - disableSandbox: this.browserConfig.disableSandbox, - proxy: this.browserConfig.proxy, - }); - - return puppeteerLaunch({ - userDataDir: this.userDataDir, - executablePath: this.binaryPath, - ignoreHTTPSErrors: true, - args: chromiumArgs, - } as LaunchOptions).catch((error: Error) => { - logger.error( - `The Reporting plugin encountered issues launching Chromium in a self-test. You may have trouble generating reports.` - ); - logger.error(error); - return null; - }); - } - /* * Return an observable to objects which will drive screenshot capture for a page */ diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts new file mode 100644 index 0000000000000..8eafbd8e0ddbe --- /dev/null +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts @@ -0,0 +1,133 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { spawn } from 'child_process'; +import del from 'del'; +import { mkdtempSync } from 'fs'; +import { uniq } from 'lodash'; +import { tmpdir } from 'os'; +import { join } from 'path'; +import { createInterface } from 'readline'; +import { fromEvent, timer, merge, of } from 'rxjs'; +import { takeUntil, map, reduce, tap, catchError } from 'rxjs/operators'; +import { ReportingCore } from '../../..'; +import { LevelLogger } from '../../../lib'; +import { getBinaryPath } from '../../install'; +import { args } from './args'; + +const browserLaunchTimeToWait = 5 * 1000; + +// Default args used by pptr +// https://github.com/puppeteer/puppeteer/blob/13ea347/src/node/Launcher.ts#L168 +const defaultArgs = [ + '--disable-background-networking', + '--enable-features=NetworkService,NetworkServiceInProcess', + '--disable-background-timer-throttling', + '--disable-backgrounding-occluded-windows', + '--disable-breakpad', + '--disable-client-side-phishing-detection', + '--disable-component-extensions-with-background-pages', + '--disable-default-apps', + '--disable-dev-shm-usage', + '--disable-extensions', + '--disable-features=TranslateUI', + '--disable-hang-monitor', + '--disable-ipc-flooding-protection', + '--disable-popup-blocking', + '--disable-prompt-on-repost', + '--disable-renderer-backgrounding', + '--disable-sync', + '--force-color-profile=srgb', + '--metrics-recording-only', + '--no-first-run', + '--enable-automation', + '--password-store=basic', + '--use-mock-keychain', + '--remote-debugging-port=0', + '--headless', +]; + +export const browserStartLogs = ( + core: ReportingCore, + logger: LevelLogger, + overrideFlags: string[] = [] +) => { + const config = core.getConfig(); + const proxy = config.get('capture', 'browser', 'chromium', 'proxy'); + const disableSandbox = config.get('capture', 'browser', 'chromium', 'disableSandbox'); + const userDataDir = mkdtempSync(join(tmpdir(), 'chromium-')); + const binaryPath = getBinaryPath(); + const kbnArgs = args({ + userDataDir, + viewport: { width: 800, height: 600 }, + disableSandbox, + proxy, + }); + const finalArgs = uniq([...defaultArgs, ...kbnArgs, ...overrideFlags]); + + // On non-windows platforms, `detached: true` makes child process a + // leader of a new process group, making it possible to kill child + // process tree with `.kill(-pid)` command. @see + // https://nodejs.org/api/child_process.html#child_process_options_detached + const browserProcess = spawn(binaryPath, finalArgs, { + detached: process.platform !== 'win32', + }); + + const rl = createInterface({ input: browserProcess.stderr }); + + const exit$ = fromEvent(browserProcess, 'exit').pipe( + map((code) => { + logger.error(`Browser exited abnormally, received code: ${code}`); + return i18n.translate('xpack.reporting.diagnostic.browserCrashed', { + defaultMessage: `Browser exited abnormally during startup`, + }); + }) + ); + + const error$ = fromEvent(browserProcess, 'error').pipe( + map(() => { + logger.error(`Browser process threw an error on startup`); + return i18n.translate('xpack.reporting.diagnostic.browserErrored', { + defaultMessage: `Browser process threw an error on startup`, + }); + }) + ); + + const browserProcessLogger = logger.clone(['chromium-stderr']); + const log$ = fromEvent(rl, 'line').pipe( + tap((message: unknown) => { + if (typeof message === 'string') { + browserProcessLogger.info(message); + } + }) + ); + + // Collect all events (exit, error and on log-lines), but let chromium keep spitting out + // logs as sometimes it's "bind" successfully for remote connections, but later emit + // a log indicative of an issue (for example, no default font found). + return merge(exit$, error$, log$).pipe( + takeUntil(timer(browserLaunchTimeToWait)), + reduce((acc, curr) => `${acc}${curr}\n`, ''), + tap(() => { + if (browserProcess && browserProcess.pid && !browserProcess.killed) { + browserProcess.kill('SIGKILL'); + logger.info(`Successfully sent 'SIGKILL' to browser process (PID: ${browserProcess.pid})`); + } + browserProcess.removeAllListeners(); + rl.removeAllListeners(); + rl.close(); + del(userDataDir, { force: true }).catch((error) => { + logger.error(`Error deleting user data directory at [${userDataDir}]!`); + logger.error(error); + }); + }), + catchError((error) => { + logger.error(error); + return of(error); + }) + ); +}; diff --git a/x-pack/plugins/reporting/server/browsers/install.ts b/x-pack/plugins/reporting/server/browsers/install.ts index 9eddbe5ef0498..35cc5b6d8b7c2 100644 --- a/x-pack/plugins/reporting/server/browsers/install.ts +++ b/x-pack/plugins/reporting/server/browsers/install.ts @@ -4,24 +4,43 @@ * you may not use this file except in compliance with the Elastic License. */ +import del from 'del'; import os from 'os'; import path from 'path'; -import del from 'del'; - import * as Rx from 'rxjs'; import { LevelLogger } from '../lib'; +import { paths } from './chromium/paths'; import { ensureBrowserDownloaded } from './download'; // @ts-ignore import { md5 } from './download/checksum'; // @ts-ignore import { extract } from './extract'; -import { paths } from './chromium/paths'; interface Package { platforms: string[]; architecture: string; } +/** + * Small helper util to resolve where chromium is installed + */ +export const getBinaryPath = ( + chromiumPath: string = path.resolve(__dirname, '../../chromium'), + platform: string = process.platform, + architecture: string = os.arch() +) => { + const pkg = paths.packages.find((p: Package) => { + return p.platforms.includes(platform) && p.architecture === architecture; + }); + + if (!pkg) { + // TODO: validate this + throw new Error(`Unsupported platform: ${platform}-${architecture}`); + } + + return path.join(chromiumPath, pkg.binaryRelativePath); +}; + /** * "install" a browser by type into installs path by extracting the downloaded * archive. If there is an error extracting the archive an `ExtractError` is thrown @@ -43,7 +62,7 @@ export function installBrowser( throw new Error(`Unsupported platform: ${platform}-${architecture}`); } - const binaryPath = path.join(chromiumPath, pkg.binaryRelativePath); + const binaryPath = getBinaryPath(chromiumPath, platform, architecture); const binaryChecksum = await md5(binaryPath).catch(() => ''); if (binaryChecksum !== pkg.binaryChecksum) { diff --git a/x-pack/plugins/reporting/server/export_types/png/lib/generate_png.ts b/x-pack/plugins/reporting/server/export_types/png/lib/generate_png.ts index c3d5b2cc60051..096d0bd428214 100644 --- a/x-pack/plugins/reporting/server/export_types/png/lib/generate_png.ts +++ b/x-pack/plugins/reporting/server/export_types/png/lib/generate_png.ts @@ -28,7 +28,7 @@ export async function generatePngObservableFactory(reporting: ReportingCore) { if (!layoutParams || !layoutParams.dimensions) { throw new Error(`LayoutParams.Dimensions is undefined.`); } - const layout = new PreserveLayout(layoutParams.dimensions); + const layout = new PreserveLayout(layoutParams.dimensions, layoutParams.selectors); if (apmLayout) apmLayout.end(); const apmScreenshots = apmTrans?.startSpan('screenshots_pipeline', 'setup'); diff --git a/x-pack/plugins/reporting/server/lib/index.ts b/x-pack/plugins/reporting/server/lib/index.ts index f3a09cffbb104..9e5a3ca76126d 100644 --- a/x-pack/plugins/reporting/server/lib/index.ts +++ b/x-pack/plugins/reporting/server/lib/index.ts @@ -13,4 +13,3 @@ export { LevelLogger } from './level_logger'; export { statuses } from './statuses'; export { ReportingStore } from './store'; export { startTrace } from './trace'; -export { runValidations } from './validate'; diff --git a/x-pack/plugins/reporting/server/lib/layouts/index.ts b/x-pack/plugins/reporting/server/lib/layouts/index.ts index d46f088475222..507b7614072ea 100644 --- a/x-pack/plugins/reporting/server/lib/layouts/index.ts +++ b/x-pack/plugins/reporting/server/lib/layouts/index.ts @@ -54,6 +54,7 @@ export interface Size { export interface LayoutParams { id: string; dimensions: Size; + selectors?: LayoutSelectorDictionary; } interface LayoutSelectors { diff --git a/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.ts b/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.ts index 9041055ddce2d..e8d182dac0b1d 100644 --- a/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.ts +++ b/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.ts @@ -25,12 +25,16 @@ export class PreserveLayout extends Layout { private readonly scaledHeight: number; private readonly scaledWidth: number; - constructor(size: Size) { + constructor(size: Size, layoutSelectors?: LayoutSelectorDictionary) { super(LayoutTypes.PRESERVE_LAYOUT); this.height = size.height; this.width = size.width; this.scaledHeight = size.height * ZOOM; this.scaledWidth = size.width * ZOOM; + + if (layoutSelectors) { + this.selectors = layoutSelectors; + } } public getCssOverridesPath() { diff --git a/x-pack/plugins/reporting/server/lib/store/store.test.ts b/x-pack/plugins/reporting/server/lib/store/store.test.ts index e6c4eb7346460..b87466ca289cf 100644 --- a/x-pack/plugins/reporting/server/lib/store/store.test.ts +++ b/x-pack/plugins/reporting/server/lib/store/store.test.ts @@ -7,8 +7,7 @@ import sinon from 'sinon'; import { ElasticsearchServiceSetup } from 'src/core/server'; import { ReportingConfig, ReportingCore } from '../..'; -import { createMockReportingCore } from '../../test_helpers'; -import { createMockLevelLogger } from '../../test_helpers/create_mock_levellogger'; +import { createMockReportingCore, createMockLevelLogger } from '../../test_helpers'; import { Report } from './report'; import { ReportingStore } from './store'; diff --git a/x-pack/plugins/reporting/server/lib/validate/index.ts b/x-pack/plugins/reporting/server/lib/validate/index.ts deleted file mode 100644 index d20df6b7315be..0000000000000 --- a/x-pack/plugins/reporting/server/lib/validate/index.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 { i18n } from '@kbn/i18n'; -import { ElasticsearchServiceSetup } from 'kibana/server'; -import { ReportingConfig } from '../../'; -import { HeadlessChromiumDriverFactory } from '../../browsers/chromium/driver_factory'; -import { LevelLogger } from '../'; -import { validateBrowser } from './validate_browser'; -import { validateMaxContentLength } from './validate_max_content_length'; - -export async function runValidations( - config: ReportingConfig, - elasticsearch: ElasticsearchServiceSetup, - browserFactory: HeadlessChromiumDriverFactory, - parentLogger: LevelLogger -) { - const logger = parentLogger.clone(['validations']); - try { - await Promise.all([ - validateBrowser(browserFactory, logger), - validateMaxContentLength(config, elasticsearch, logger), - ]); - logger.debug( - i18n.translate('xpack.reporting.selfCheck.ok', { - defaultMessage: `Reporting plugin self-check ok!`, - }) - ); - } catch (err) { - logger.error(err); - logger.warning( - i18n.translate('xpack.reporting.selfCheck.warning', { - defaultMessage: `Reporting plugin self-check generated a warning: {err}`, - values: { - err, - }, - }) - ); - } -} diff --git a/x-pack/plugins/reporting/server/lib/validate/validate_browser.ts b/x-pack/plugins/reporting/server/lib/validate/validate_browser.ts deleted file mode 100644 index d29aa522dad90..0000000000000 --- a/x-pack/plugins/reporting/server/lib/validate/validate_browser.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 { Browser } from 'puppeteer'; -import { BROWSER_TYPE } from '../../../common/constants'; -import { HeadlessChromiumDriverFactory } from '../../browsers/chromium/driver_factory'; -import { LevelLogger } from '../'; - -/* - * Validate the Reporting headless browser can launch, and that it can connect - * to the locally running Kibana instance. - */ -export const validateBrowser = async ( - browserFactory: HeadlessChromiumDriverFactory, - logger: LevelLogger -) => { - if (browserFactory.type === BROWSER_TYPE) { - return browserFactory.test(logger).then((browser: Browser | null) => { - if (browser && browser.close) { - browser.close(); - } else { - throw new Error('Could not close browser client handle!'); - } - }); - } -}; diff --git a/x-pack/plugins/reporting/server/lib/validate/validate_max_content_length.test.js b/x-pack/plugins/reporting/server/lib/validate/validate_max_content_length.test.js deleted file mode 100644 index f358021560cff..0000000000000 --- a/x-pack/plugins/reporting/server/lib/validate/validate_max_content_length.test.js +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 sinon from 'sinon'; -import { validateMaxContentLength } from './validate_max_content_length'; - -const FIVE_HUNDRED_MEGABYTES = 524288000; -const ONE_HUNDRED_MEGABYTES = 104857600; - -describe('Reporting: Validate Max Content Length', () => { - const elasticsearch = { - legacy: { - client: { - callAsInternalUser: () => ({ - defaults: { - http: { - max_content_length: '100mb', - }, - }, - }), - }, - }, - }; - - const logger = { - warning: sinon.spy(), - }; - - beforeEach(() => { - logger.warning.resetHistory(); - }); - - it('should log warning messages when reporting has a higher max-size than elasticsearch', async () => { - const config = { get: sinon.stub().returns(FIVE_HUNDRED_MEGABYTES) }; - const elasticsearch = { - legacy: { - client: { - callAsInternalUser: () => ({ - defaults: { - http: { - max_content_length: '100mb', - }, - }, - }), - }, - }, - }; - - await validateMaxContentLength(config, elasticsearch, logger); - - sinon.assert.calledWithMatch( - logger.warning, - `xpack.reporting.csv.maxSizeBytes (524288000) is higher` - ); - sinon.assert.calledWithMatch( - logger.warning, - `than ElasticSearch's http.max_content_length (104857600)` - ); - sinon.assert.calledWithMatch( - logger.warning, - 'Please set http.max_content_length in ElasticSearch to match' - ); - sinon.assert.calledWithMatch( - logger.warning, - 'or lower your xpack.reporting.csv.maxSizeBytes in Kibana' - ); - }); - - it('should do nothing when reporting has the same max-size as elasticsearch', async () => { - const config = { get: sinon.stub().returns(ONE_HUNDRED_MEGABYTES) }; - - expect( - async () => await validateMaxContentLength(config, elasticsearch, logger.warning) - ).not.toThrow(); - sinon.assert.notCalled(logger.warning); - }); -}); diff --git a/x-pack/plugins/reporting/server/lib/validate/validate_max_content_length.ts b/x-pack/plugins/reporting/server/lib/validate/validate_max_content_length.ts deleted file mode 100644 index c38c6e5297854..0000000000000 --- a/x-pack/plugins/reporting/server/lib/validate/validate_max_content_length.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 numeral from '@elastic/numeral'; -import { ElasticsearchServiceSetup } from 'kibana/server'; -import { defaults, get } from 'lodash'; -import { ReportingConfig } from '../../'; -import { LevelLogger } from '../'; - -const KIBANA_MAX_SIZE_BYTES_PATH = 'csv.maxSizeBytes'; -const ES_MAX_SIZE_BYTES_PATH = 'http.max_content_length'; - -export async function validateMaxContentLength( - config: ReportingConfig, - elasticsearch: ElasticsearchServiceSetup, - logger: LevelLogger -) { - const { callAsInternalUser } = elasticsearch.legacy.client; - - const elasticClusterSettingsResponse = await callAsInternalUser('cluster.getSettings', { - includeDefaults: true, - }); - const { persistent, transient, defaults: defaultSettings } = elasticClusterSettingsResponse; - const elasticClusterSettings = defaults({}, persistent, transient, defaultSettings); - - const elasticSearchMaxContent = get(elasticClusterSettings, 'http.max_content_length', '100mb'); - const elasticSearchMaxContentBytes = numeral().unformat(elasticSearchMaxContent.toUpperCase()); - const kibanaMaxContentBytes = config.get('csv', 'maxSizeBytes'); - - if (kibanaMaxContentBytes > elasticSearchMaxContentBytes) { - // TODO this should simply throw an error and let the handler conver it to a warning mesasge. See validateServerHost. - logger.warning( - `xpack.reporting.${KIBANA_MAX_SIZE_BYTES_PATH} (${kibanaMaxContentBytes}) is higher than ElasticSearch's ${ES_MAX_SIZE_BYTES_PATH} (${elasticSearchMaxContentBytes}). ` + - `Please set ${ES_MAX_SIZE_BYTES_PATH} in ElasticSearch to match, or lower your xpack.reporting.${KIBANA_MAX_SIZE_BYTES_PATH} in Kibana to avoid this warning.` - ); - } -} diff --git a/x-pack/plugins/reporting/server/plugin.ts b/x-pack/plugins/reporting/server/plugin.ts index 8c0e352aa06c5..af1ccfd592b96 100644 --- a/x-pack/plugins/reporting/server/plugin.ts +++ b/x-pack/plugins/reporting/server/plugin.ts @@ -11,7 +11,7 @@ import { PLUGIN_ID, UI_SETTINGS_CUSTOM_PDF_LOGO } from '../common/constants'; import { ReportingCore } from './'; import { initializeBrowserDriverFactory } from './browsers'; import { buildConfig, ReportingConfigType } from './config'; -import { createQueueFactory, LevelLogger, ReportingStore, runValidations } from './lib'; +import { createQueueFactory, LevelLogger, ReportingStore } from './lib'; import { registerRoutes } from './routes'; import { setFieldFormats } from './services'; import { ReportingSetup, ReportingSetupDeps, ReportingStart, ReportingStartDeps } from './types'; @@ -105,7 +105,6 @@ export class ReportingPlugin setFieldFormats(plugins.data.fieldFormats); const { logger, reportingCore } = this; - const { elasticsearch } = reportingCore.getPluginSetupDeps(); // async background start (async () => { @@ -124,9 +123,6 @@ export class ReportingPlugin store, }); - // run self-check validations - runValidations(config, elasticsearch, browserDriverFactory, this.logger); - this.logger.debug('Start complete'); })().catch((e) => { this.logger.error(`Error in Reporting start, reporting may not function properly`); diff --git a/x-pack/plugins/reporting/server/routes/diagnostic/browser.test.ts b/x-pack/plugins/reporting/server/routes/diagnostic/browser.test.ts new file mode 100644 index 0000000000000..f92fbfc7013cf --- /dev/null +++ b/x-pack/plugins/reporting/server/routes/diagnostic/browser.test.ts @@ -0,0 +1,250 @@ +/* + * 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 { UnwrapPromise } from '@kbn/utility-types'; +import { spawn } from 'child_process'; +import { createInterface } from 'readline'; +import { setupServer } from 'src/core/server/test_utils'; +import supertest from 'supertest'; +import { ReportingCore } from '../..'; +import { createMockLevelLogger, createMockReportingCore } from '../../test_helpers'; +import { registerDiagnoseBrowser } from './browser'; + +jest.mock('child_process'); +jest.mock('readline'); + +type SetupServerReturn = UnwrapPromise>; + +const devtoolMessage = 'DevTools listening on (ws://localhost:4000)'; +const fontNotFoundMessage = 'Could not find the default font'; + +describe('POST /diagnose/browser', () => { + jest.setTimeout(6000); + const reportingSymbol = Symbol('reporting'); + const mockLogger = createMockLevelLogger(); + + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let core: ReportingCore; + const mockedSpawn: any = spawn; + const mockedCreateInterface: any = createInterface; + + const config = { + get: jest.fn().mockImplementation(() => ({})), + kbnConfig: { get: jest.fn() }, + }; + + beforeEach(async () => { + ({ server, httpSetup } = await setupServer(reportingSymbol)); + httpSetup.registerRouteHandlerContext(reportingSymbol, 'reporting', () => ({})); + + const mockSetupDeps = ({ + elasticsearch: { + legacy: { client: { callAsInternalUser: jest.fn() } }, + }, + router: httpSetup.createRouter(''), + } as unknown) as any; + + core = await createMockReportingCore(config, mockSetupDeps); + + mockedSpawn.mockImplementation(() => ({ + removeAllListeners: jest.fn(), + kill: jest.fn(), + pid: 123, + stderr: 'stderr', + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + })); + + mockedCreateInterface.mockImplementation(() => ({ + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + removeAllListeners: jest.fn(), + close: jest.fn(), + })); + }); + + afterEach(async () => { + await server.stop(); + }); + + it('returns a 200 when successful', async () => { + registerDiagnoseBrowser(core, mockLogger); + + await server.start(); + + mockedCreateInterface.mockImplementation(() => ({ + addEventListener: (e: string, cb: any) => setTimeout(() => cb(devtoolMessage), 0), + removeEventListener: jest.fn(), + removeAllListeners: jest.fn(), + close: jest.fn(), + })); + + return supertest(httpSetup.server.listener) + .post('/api/reporting/diagnose/browser') + .expect(200) + .then(({ body }) => { + expect(body.success).toEqual(true); + expect(body.help).toEqual([]); + }); + }); + + it('returns logs when browser crashes + helpful links', async () => { + const logs = `Could not find the default font`; + registerDiagnoseBrowser(core, mockLogger); + + await server.start(); + + mockedCreateInterface.mockImplementation(() => ({ + addEventListener: (e: string, cb: any) => setTimeout(() => cb(logs), 0), + removeEventListener: jest.fn(), + removeAllListeners: jest.fn(), + close: jest.fn(), + })); + + mockedSpawn.mockImplementation(() => ({ + removeAllListeners: jest.fn(), + kill: jest.fn(), + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + })); + + return supertest(httpSetup.server.listener) + .post('/api/reporting/diagnose/browser') + .expect(200) + .then(({ body }) => { + expect(body).toMatchInlineSnapshot(` + Object { + "help": Array [ + "The browser couldn't locate a default font. Please see https://www.elastic.co/guide/en/kibana/current/reporting-troubleshooting.html#reporting-troubleshooting-system-dependencies to fix this issue.", + ], + "logs": "Could not find the default font + ", + "success": false, + } + `); + }); + }); + + it('logs a message when the browser starts, but then has problems later', async () => { + registerDiagnoseBrowser(core, mockLogger); + + await server.start(); + + mockedCreateInterface.mockImplementation(() => ({ + addEventListener: (e: string, cb: any) => { + setTimeout(() => cb(devtoolMessage), 0); + setTimeout(() => cb(fontNotFoundMessage), 0); + }, + removeEventListener: jest.fn(), + removeAllListeners: jest.fn(), + close: jest.fn(), + })); + + mockedSpawn.mockImplementation(() => ({ + removeAllListeners: jest.fn(), + kill: jest.fn(), + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + })); + + return supertest(httpSetup.server.listener) + .post('/api/reporting/diagnose/browser') + .expect(200) + .then(({ body }) => { + expect(body).toMatchInlineSnapshot(` + Object { + "help": Array [ + "The browser couldn't locate a default font. Please see https://www.elastic.co/guide/en/kibana/current/reporting-troubleshooting.html#reporting-troubleshooting-system-dependencies to fix this issue.", + ], + "logs": "DevTools listening on (ws://localhost:4000) + Could not find the default font + ", + "success": false, + } + `); + }); + }); + + it('logs a message when the browser starts, but then crashes', async () => { + registerDiagnoseBrowser(core, mockLogger); + + await server.start(); + + mockedCreateInterface.mockImplementation(() => ({ + addEventListener: (e: string, cb: any) => { + setTimeout(() => cb(fontNotFoundMessage), 0); + }, + removeEventListener: jest.fn(), + removeAllListeners: jest.fn(), + close: jest.fn(), + })); + + mockedSpawn.mockImplementation(() => ({ + removeAllListeners: jest.fn(), + kill: jest.fn(), + addEventListener: (e: string, cb: any) => { + if (e === 'exit') { + setTimeout(() => cb(), 5); + } + }, + removeEventListener: jest.fn(), + })); + + return supertest(httpSetup.server.listener) + .post('/api/reporting/diagnose/browser') + .expect(200) + .then(({ body }) => { + expect(body).toMatchInlineSnapshot(` + Object { + "help": Array [ + "The browser couldn't locate a default font. Please see https://www.elastic.co/guide/en/kibana/current/reporting-troubleshooting.html#reporting-troubleshooting-system-dependencies to fix this issue.", + ], + "logs": "Could not find the default font + Browser exited abnormally during startup + ", + "success": false, + } + `); + }); + }); + + it('cleans up process and subscribers', async () => { + registerDiagnoseBrowser(core, mockLogger); + + await server.start(); + const killMock = jest.fn(); + const spawnListenersMock = jest.fn(); + const createInterfaceListenersMock = jest.fn(); + const createInterfaceCloseMock = jest.fn(); + + mockedSpawn.mockImplementation(() => ({ + removeAllListeners: spawnListenersMock, + kill: killMock, + pid: 123, + stderr: 'stderr', + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + })); + + mockedCreateInterface.mockImplementation(() => ({ + addEventListener: (e: string, cb: any) => setTimeout(() => cb(devtoolMessage), 0), + removeEventListener: jest.fn(), + removeAllListeners: createInterfaceListenersMock, + close: createInterfaceCloseMock, + })); + + return supertest(httpSetup.server.listener) + .post('/api/reporting/diagnose/browser') + .expect(200) + .then(() => { + expect(killMock.mock.calls.length).toBe(1); + expect(spawnListenersMock.mock.calls.length).toBe(1); + expect(createInterfaceListenersMock.mock.calls.length).toBe(1); + expect(createInterfaceCloseMock.mock.calls.length).toBe(1); + }); + }); +}); diff --git a/x-pack/plugins/reporting/server/routes/diagnostic/browser.ts b/x-pack/plugins/reporting/server/routes/diagnostic/browser.ts new file mode 100644 index 0000000000000..24b85220defb4 --- /dev/null +++ b/x-pack/plugins/reporting/server/routes/diagnostic/browser.ts @@ -0,0 +1,78 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { ReportingCore } from '../..'; +import { API_DIAGNOSE_URL } from '../../../common/constants'; +import { browserStartLogs } from '../../browsers/chromium/driver_factory/start_logs'; +import { LevelLogger as Logger } from '../../lib'; +import { DiagnosticResponse } from '../../types'; +import { authorizedUserPreRoutingFactory } from '../lib/authorized_user_pre_routing'; + +const logsToHelpMap = { + 'error while loading shared libraries': i18n.translate( + 'xpack.reporting.diagnostic.browserMissingDependency', + { + defaultMessage: `The browser couldn't start properly due to missing system dependencies. Please see {url}`, + values: { + url: + 'https://www.elastic.co/guide/en/kibana/current/reporting-troubleshooting.html#reporting-troubleshooting-system-dependencies', + }, + } + ), + + 'Could not find the default font': i18n.translate( + 'xpack.reporting.diagnostic.browserMissingFonts', + { + defaultMessage: `The browser couldn't locate a default font. Please see {url} to fix this issue.`, + values: { + url: + 'https://www.elastic.co/guide/en/kibana/current/reporting-troubleshooting.html#reporting-troubleshooting-system-dependencies', + }, + } + ), + + 'No usable sandbox': i18n.translate('xpack.reporting.diagnostic.noUsableSandbox', { + defaultMessage: `Unable to use Chromium sandbox. This can be disabled at your own risk with 'xpack.reporting.capture.browser.chromium.disableSandbox'. Please see {url}`, + values: { + url: + 'https://www.elastic.co/guide/en/kibana/current/reporting-troubleshooting.html#reporting-troubleshooting-sandbox-dependency', + }, + }), +}; + +export const registerDiagnoseBrowser = (reporting: ReportingCore, logger: Logger) => { + const { router } = reporting.getPluginSetupDeps(); + const userHandler = authorizedUserPreRoutingFactory(reporting); + + router.post( + { + path: `${API_DIAGNOSE_URL}/browser`, + validate: {}, + }, + userHandler(async (user, context, req, res) => { + const logs = await browserStartLogs(reporting, logger).toPromise(); + const knownIssues = Object.keys(logsToHelpMap) as Array; + + const boundSuccessfully = logs.includes(`DevTools listening on`); + const help = knownIssues.reduce((helpTexts: string[], knownIssue) => { + const helpText = logsToHelpMap[knownIssue]; + if (logs.includes(knownIssue)) { + helpTexts.push(helpText); + } + return helpTexts; + }, []); + + const response: DiagnosticResponse = { + success: boundSuccessfully && !help.length, + help, + logs, + }; + + return res.ok({ body: response }); + }) + ); +}; diff --git a/x-pack/plugins/reporting/server/routes/diagnostic/config.test.ts b/x-pack/plugins/reporting/server/routes/diagnostic/config.test.ts new file mode 100644 index 0000000000000..624397246656d --- /dev/null +++ b/x-pack/plugins/reporting/server/routes/diagnostic/config.test.ts @@ -0,0 +1,107 @@ +/* + * 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 { UnwrapPromise } from '@kbn/utility-types'; +import { setupServer } from 'src/core/server/test_utils'; +import supertest from 'supertest'; +import { ReportingCore } from '../..'; +import { createMockReportingCore, createMockLevelLogger } from '../../test_helpers'; +import { registerDiagnoseConfig } from './config'; + +type SetupServerReturn = UnwrapPromise>; + +describe('POST /diagnose/config', () => { + const reportingSymbol = Symbol('reporting'); + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let core: ReportingCore; + let mockSetupDeps: any; + let config: any; + + const mockLogger = createMockLevelLogger(); + + beforeEach(async () => { + ({ server, httpSetup } = await setupServer(reportingSymbol)); + httpSetup.registerRouteHandlerContext(reportingSymbol, 'reporting', () => ({})); + + mockSetupDeps = ({ + elasticsearch: { + legacy: { client: { callAsInternalUser: jest.fn() } }, + }, + router: httpSetup.createRouter(''), + } as unknown) as any; + + config = { + get: jest.fn(), + kbnConfig: { get: jest.fn() }, + }; + + core = await createMockReportingCore(config, mockSetupDeps); + }); + + afterEach(async () => { + await server.stop(); + }); + + it('returns a 200 by default when configured properly', async () => { + mockSetupDeps.elasticsearch.legacy.client.callAsInternalUser.mockImplementation(() => + Promise.resolve({ + defaults: { + http: { + max_content_length: '100mb', + }, + }, + }) + ); + registerDiagnoseConfig(core, mockLogger); + + await server.start(); + + await supertest(httpSetup.server.listener) + .post('/api/reporting/diagnose/config') + .expect(200) + .then(({ body }) => { + expect(body).toMatchInlineSnapshot(` + Object { + "help": Array [], + "logs": "", + "success": true, + } + `); + }); + }); + + it('returns a 200 with help text when not configured properly', async () => { + config.get.mockImplementation(() => 10485760); + mockSetupDeps.elasticsearch.legacy.client.callAsInternalUser.mockImplementation(() => + Promise.resolve({ + defaults: { + http: { + max_content_length: '5mb', + }, + }, + }) + ); + registerDiagnoseConfig(core, mockLogger); + + await server.start(); + + await supertest(httpSetup.server.listener) + .post('/api/reporting/diagnose/config') + .expect(200) + .then(({ body }) => { + expect(body).toMatchInlineSnapshot(` + Object { + "help": Array [ + "xpack.reporting.csv.maxSizeBytes (10485760) is higher than ElasticSearch's http.max_content_length (5242880). Please set http.max_content_length in ElasticSearch to match, or lower your xpack.reporting.csv.maxSizeBytes in Kibana.", + ], + "logs": "xpack.reporting.csv.maxSizeBytes (10485760) is higher than ElasticSearch's http.max_content_length (5242880). Please set http.max_content_length in ElasticSearch to match, or lower your xpack.reporting.csv.maxSizeBytes in Kibana.", + "success": false, + } + `); + }); + }); +}); diff --git a/x-pack/plugins/reporting/server/routes/diagnostic/config.ts b/x-pack/plugins/reporting/server/routes/diagnostic/config.ts new file mode 100644 index 0000000000000..198ba63e2614d --- /dev/null +++ b/x-pack/plugins/reporting/server/routes/diagnostic/config.ts @@ -0,0 +1,81 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import numeral from '@elastic/numeral'; +import { defaults, get } from 'lodash'; +import { ReportingCore } from '../..'; +import { API_DIAGNOSE_URL } from '../../../common/constants'; +import { LevelLogger as Logger } from '../../lib'; +import { DiagnosticResponse } from '../../types'; +import { authorizedUserPreRoutingFactory } from '../lib/authorized_user_pre_routing'; + +const KIBANA_MAX_SIZE_BYTES_PATH = 'csv.maxSizeBytes'; +const ES_MAX_SIZE_BYTES_PATH = 'http.max_content_length'; + +export const registerDiagnoseConfig = (reporting: ReportingCore, logger: Logger) => { + const setupDeps = reporting.getPluginSetupDeps(); + const userHandler = authorizedUserPreRoutingFactory(reporting); + const { router, elasticsearch } = setupDeps; + + router.post( + { + path: `${API_DIAGNOSE_URL}/config`, + validate: {}, + }, + userHandler(async (user, context, req, res) => { + const warnings = []; + const { callAsInternalUser } = elasticsearch.legacy.client; + const config = reporting.getConfig(); + + const elasticClusterSettingsResponse = await callAsInternalUser('cluster.getSettings', { + includeDefaults: true, + }); + const { persistent, transient, defaults: defaultSettings } = elasticClusterSettingsResponse; + const elasticClusterSettings = defaults({}, persistent, transient, defaultSettings); + + const elasticSearchMaxContent = get( + elasticClusterSettings, + 'http.max_content_length', + '100mb' + ); + const elasticSearchMaxContentBytes = numeral().unformat( + elasticSearchMaxContent.toUpperCase() + ); + const kibanaMaxContentBytes = config.get('csv', 'maxSizeBytes'); + + if (kibanaMaxContentBytes > elasticSearchMaxContentBytes) { + const maxContentSizeWarning = i18n.translate( + 'xpack.reporting.diagnostic.configSizeMismatch', + { + defaultMessage: + `xpack.reporting.{KIBANA_MAX_SIZE_BYTES_PATH} ({kibanaMaxContentBytes}) is higher than ElasticSearch's {ES_MAX_SIZE_BYTES_PATH} ({elasticSearchMaxContentBytes}). ` + + `Please set {ES_MAX_SIZE_BYTES_PATH} in ElasticSearch to match, or lower your xpack.reporting.{KIBANA_MAX_SIZE_BYTES_PATH} in Kibana.`, + values: { + kibanaMaxContentBytes, + elasticSearchMaxContentBytes, + KIBANA_MAX_SIZE_BYTES_PATH, + ES_MAX_SIZE_BYTES_PATH, + }, + } + ); + warnings.push(maxContentSizeWarning); + } + + if (warnings.length) { + warnings.forEach((warn) => logger.warn(warn)); + } + + const body: DiagnosticResponse = { + help: warnings, + success: !warnings.length, + logs: warnings.join('\n'), + }; + + return res.ok({ body }); + }) + ); +}; diff --git a/x-pack/plugins/reporting/server/routes/diagnostic/index.ts b/x-pack/plugins/reporting/server/routes/diagnostic/index.ts new file mode 100644 index 0000000000000..895dee32614f1 --- /dev/null +++ b/x-pack/plugins/reporting/server/routes/diagnostic/index.ts @@ -0,0 +1,17 @@ +/* + * 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 { registerDiagnoseBrowser } from './browser'; +import { registerDiagnoseConfig } from './config'; +import { registerDiagnoseScreenshot } from './screenshot'; +import { LevelLogger as Logger } from '../../lib'; +import { ReportingCore } from '../../core'; + +export const registerDiagnosticRoutes = (reporting: ReportingCore, logger: Logger) => { + registerDiagnoseBrowser(reporting, logger); + registerDiagnoseConfig(reporting, logger); + registerDiagnoseScreenshot(reporting, logger); +}; diff --git a/x-pack/plugins/reporting/server/routes/diagnostic/screenshot.test.ts b/x-pack/plugins/reporting/server/routes/diagnostic/screenshot.test.ts new file mode 100644 index 0000000000000..ec4ab0446ae5f --- /dev/null +++ b/x-pack/plugins/reporting/server/routes/diagnostic/screenshot.test.ts @@ -0,0 +1,112 @@ +/* + * 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 { UnwrapPromise } from '@kbn/utility-types'; +import { setupServer } from 'src/core/server/test_utils'; +import supertest from 'supertest'; +import { ReportingCore } from '../..'; +import { createMockReportingCore, createMockLevelLogger } from '../../test_helpers'; +import { registerDiagnoseScreenshot } from './screenshot'; + +jest.mock('../../export_types/png/lib/generate_png'); + +import { generatePngObservableFactory } from '../../export_types/png/lib/generate_png'; + +type SetupServerReturn = UnwrapPromise>; + +describe('POST /diagnose/screenshot', () => { + const reportingSymbol = Symbol('reporting'); + let server: SetupServerReturn['server']; + let httpSetup: SetupServerReturn['httpSetup']; + let core: ReportingCore; + + const setScreenshotResponse = (resp: object | Error) => { + const generateMock = Promise.resolve(() => ({ + pipe: () => ({ + toPromise: () => (resp instanceof Error ? Promise.reject(resp) : Promise.resolve(resp)), + }), + })); + (generatePngObservableFactory as any).mockResolvedValue(generateMock); + }; + + const config = { + get: jest.fn(), + kbnConfig: { get: jest.fn() }, + }; + const mockLogger = createMockLevelLogger(); + + beforeEach(async () => { + ({ server, httpSetup } = await setupServer(reportingSymbol)); + httpSetup.registerRouteHandlerContext(reportingSymbol, 'reporting', () => ({})); + + const mockSetupDeps = ({ + elasticsearch: { + legacy: { client: { callAsInternalUser: jest.fn() } }, + }, + router: httpSetup.createRouter(''), + } as unknown) as any; + + core = await createMockReportingCore(config, mockSetupDeps); + }); + + afterEach(async () => { + await server.stop(); + }); + + it('returns a 200 by default', async () => { + registerDiagnoseScreenshot(core, mockLogger); + setScreenshotResponse({ warnings: [] }); + await server.start(); + + await supertest(httpSetup.server.listener) + .post('/api/reporting/diagnose/screenshot') + .expect(200) + .then(({ body }) => { + expect(body).toMatchInlineSnapshot(` + Object { + "help": Array [], + "logs": "", + "success": true, + } + `); + }); + }); + + it('returns a 200 when it fails and sets success to false', async () => { + registerDiagnoseScreenshot(core, mockLogger); + setScreenshotResponse({ warnings: [`Timeout waiting for .dank to load`] }); + await server.start(); + + await supertest(httpSetup.server.listener) + .post('/api/reporting/diagnose/screenshot') + .expect(200) + .then(({ body }) => { + expect(body).toMatchInlineSnapshot(` + Object { + "help": Array [], + "logs": Array [ + "Timeout waiting for .dank to load", + ], + "success": false, + } + `); + }); + }); + + it('catches errors and returns a well formed response', async () => { + registerDiagnoseScreenshot(core, mockLogger); + setScreenshotResponse(new Error('Failure to start chromium!')); + await server.start(); + + await supertest(httpSetup.server.listener) + .post('/api/reporting/diagnose/screenshot') + .expect(200) + .then(({ body }) => { + expect(body.help).toContain(`We couldn't screenshot your Kibana install.`); + expect(body.logs).toContain(`Failure to start chromium!`); + }); + }); +}); diff --git a/x-pack/plugins/reporting/server/routes/diagnostic/screenshot.ts b/x-pack/plugins/reporting/server/routes/diagnostic/screenshot.ts new file mode 100644 index 0000000000000..7e07779b5fd37 --- /dev/null +++ b/x-pack/plugins/reporting/server/routes/diagnostic/screenshot.ts @@ -0,0 +1,116 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { ReportingCore } from '../..'; +import { API_DIAGNOSE_URL } from '../../../common/constants'; +import { omitBlacklistedHeaders } from '../../export_types/common'; +import { getAbsoluteUrlFactory } from '../../export_types/common/get_absolute_url'; +import { generatePngObservableFactory } from '../../export_types/png/lib/generate_png'; +import { LevelLogger as Logger } from '../../lib'; +import { DiagnosticResponse } from '../../types'; +import { authorizedUserPreRoutingFactory } from '../lib/authorized_user_pre_routing'; + +export const registerDiagnoseScreenshot = (reporting: ReportingCore, logger: Logger) => { + const setupDeps = reporting.getPluginSetupDeps(); + const userHandler = authorizedUserPreRoutingFactory(reporting); + const { router } = setupDeps; + + router.post( + { + path: `${API_DIAGNOSE_URL}/screenshot`, + validate: {}, + }, + userHandler(async (user, context, req, res) => { + const generatePngObservable = await generatePngObservableFactory(reporting); + const config = reporting.getConfig(); + const decryptedHeaders = req.headers as Record; + const [basePath, protocol, hostname, port] = [ + config.kbnConfig.get('server', 'basePath'), + config.get('kibanaServer', 'protocol'), + config.get('kibanaServer', 'hostname'), + config.get('kibanaServer', 'port'), + ] as string[]; + + const getAbsoluteUrl = getAbsoluteUrlFactory({ + defaultBasePath: basePath, + protocol, + hostname, + port, + }); + + const hashUrl = getAbsoluteUrl({ + basePath, + path: '/', + hash: '', + search: '', + }); + + // Hack the layout to make the base/login page work + const layout = { + id: 'png', + dimensions: { + width: 1440, + height: 2024, + }, + selectors: { + screenshot: '.application', + renderComplete: '.application', + itemsCountAttribute: 'data-test-subj="kibanaChrome"', + timefilterDurationAttribute: 'data-test-subj="kibanaChrome"', + }, + }; + + const headers = { + headers: omitBlacklistedHeaders({ + job: null, + decryptedHeaders, + }), + conditions: { + hostname, + port: +port, + basePath, + protocol, + }, + }; + + return generatePngObservable(logger, hashUrl, 'America/Los_Angeles', headers, layout) + .pipe() + .toPromise() + .then((screenshot) => { + if (screenshot.warnings.length) { + return res.ok({ + body: { + success: false, + help: [], + logs: screenshot.warnings, + }, + }); + } + return res.ok({ + body: { + success: true, + help: [], + logs: '', + } as DiagnosticResponse, + }); + }) + .catch((error) => + res.ok({ + body: { + success: false, + help: [ + i18n.translate('xpack.reporting.diagnostic.screenshotFailureMessage', { + defaultMessage: `We couldn't screenshot your Kibana install.`, + }), + ], + logs: error.message, + } as DiagnosticResponse, + }) + ); + }) + ); +}; diff --git a/x-pack/plugins/reporting/server/routes/generation.test.ts b/x-pack/plugins/reporting/server/routes/generation.test.ts index 0db0073149e57..dd905223a81d5 100644 --- a/x-pack/plugins/reporting/server/routes/generation.test.ts +++ b/x-pack/plugins/reporting/server/routes/generation.test.ts @@ -11,8 +11,7 @@ import { setupServer } from 'src/core/server/test_utils'; import supertest from 'supertest'; import { ReportingCore } from '..'; import { ExportTypesRegistry } from '../lib/export_types_registry'; -import { createMockReportingCore } from '../test_helpers'; -import { createMockLevelLogger } from '../test_helpers/create_mock_levellogger'; +import { createMockReportingCore, createMockLevelLogger } from '../test_helpers'; import { registerJobGenerationRoutes } from './generation'; type SetupServerReturn = UnwrapPromise>; diff --git a/x-pack/plugins/reporting/server/routes/index.ts b/x-pack/plugins/reporting/server/routes/index.ts index 005d82086665c..11ad4cc9d4eb8 100644 --- a/x-pack/plugins/reporting/server/routes/index.ts +++ b/x-pack/plugins/reporting/server/routes/index.ts @@ -8,8 +8,10 @@ import { LevelLogger as Logger } from '../lib'; import { registerJobGenerationRoutes } from './generation'; import { registerJobInfoRoutes } from './jobs'; import { ReportingCore } from '../core'; +import { registerDiagnosticRoutes } from './diagnostic'; export function registerRoutes(reporting: ReportingCore, logger: Logger) { registerJobGenerationRoutes(reporting, logger); registerJobInfoRoutes(reporting); + registerDiagnosticRoutes(reporting, logger); } diff --git a/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts b/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts index c508ee6974ca0..d1ebb4d59e631 100644 --- a/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts +++ b/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts @@ -8,7 +8,6 @@ jest.mock('../routes'); jest.mock('../usage'); jest.mock('../browsers'); jest.mock('../lib/create_queue'); -jest.mock('../lib/validate'); import * as Rx from 'rxjs'; import { ReportingConfig, ReportingCore } from '../'; diff --git a/x-pack/plugins/reporting/server/test_helpers/index.ts b/x-pack/plugins/reporting/server/test_helpers/index.ts index b37b447dc05a9..2d5ef9fdd768d 100644 --- a/x-pack/plugins/reporting/server/test_helpers/index.ts +++ b/x-pack/plugins/reporting/server/test_helpers/index.ts @@ -8,3 +8,4 @@ export { createMockServer } from './create_mock_server'; export { createMockReportingCore, createMockConfigSchema } from './create_mock_reportingplugin'; export { createMockBrowserDriverFactory } from './create_mock_browserdriverfactory'; export { createMockLayoutInstance } from './create_mock_layoutinstance'; +export { createMockLevelLogger } from './create_mock_levellogger'; diff --git a/x-pack/plugins/reporting/server/types.ts b/x-pack/plugins/reporting/server/types.ts index 10519842d9dec..bb2d5368cd181 100644 --- a/x-pack/plugins/reporting/server/types.ts +++ b/x-pack/plugins/reporting/server/types.ts @@ -160,3 +160,9 @@ export interface ExportTypeDefinition< runTaskFnFactory: RunTaskFnFactory; validLicenses: string[]; } + +export interface DiagnosticResponse { + help: string[]; + success: boolean; + logs: string; +} diff --git a/x-pack/plugins/security/common/licensing/index.mock.ts b/x-pack/plugins/security/common/licensing/index.mock.ts index 06a7057abb87c..87225f479ceed 100644 --- a/x-pack/plugins/security/common/licensing/index.mock.ts +++ b/x-pack/plugins/security/common/licensing/index.mock.ts @@ -9,6 +9,7 @@ import { SecurityLicense } from '.'; export const licenseMock = { create: (): jest.Mocked => ({ + isLicenseAvailable: jest.fn(), isEnabled: jest.fn().mockReturnValue(true), getFeatures: jest.fn(), features$: of(), diff --git a/x-pack/plugins/security/common/licensing/license_service.test.ts b/x-pack/plugins/security/common/licensing/license_service.test.ts index 564b71a2e0fac..94aad8d3ac539 100644 --- a/x-pack/plugins/security/common/licensing/license_service.test.ts +++ b/x-pack/plugins/security/common/licensing/license_service.test.ts @@ -13,6 +13,7 @@ describe('license features', function () { const serviceSetup = new SecurityLicenseService().setup({ license$: of(undefined as any), }); + expect(serviceSetup.license.isLicenseAvailable()).toEqual(false); expect(serviceSetup.license.getFeatures()).toEqual({ showLogin: true, allowLogin: false, @@ -34,6 +35,7 @@ describe('license features', function () { const serviceSetup = new SecurityLicenseService().setup({ license$: of(rawLicenseMock), }); + expect(serviceSetup.license.isLicenseAvailable()).toEqual(false); expect(serviceSetup.license.getFeatures()).toEqual({ showLogin: true, allowLogin: false, @@ -60,6 +62,7 @@ describe('license features', function () { const subscriptionHandler = jest.fn(); const subscription = serviceSetup.license.features$.subscribe(subscriptionHandler); try { + expect(serviceSetup.license.isLicenseAvailable()).toEqual(false); expect(subscriptionHandler).toHaveBeenCalledTimes(1); expect(subscriptionHandler.mock.calls[0]).toMatchInlineSnapshot(` Array [ @@ -80,6 +83,7 @@ describe('license features', function () { `); rawLicense$.next(licenseMock.createLicenseMock()); + expect(serviceSetup.license.isLicenseAvailable()).toEqual(true); expect(subscriptionHandler).toHaveBeenCalledTimes(2); expect(subscriptionHandler.mock.calls[1]).toMatchInlineSnapshot(` Array [ @@ -112,6 +116,7 @@ describe('license features', function () { const serviceSetup = new SecurityLicenseService().setup({ license$: of(mockRawLicense), }); + expect(serviceSetup.license.isLicenseAvailable()).toEqual(true); expect(serviceSetup.license.getFeatures()).toEqual({ showLogin: true, allowLogin: true, @@ -136,6 +141,7 @@ describe('license features', function () { const serviceSetup = new SecurityLicenseService().setup({ license$: of(mockRawLicense), }); + expect(serviceSetup.license.isLicenseAvailable()).toEqual(true); expect(serviceSetup.license.getFeatures()).toEqual({ showLogin: false, allowLogin: false, @@ -159,6 +165,7 @@ describe('license features', function () { const serviceSetup = new SecurityLicenseService().setup({ license$: of(mockRawLicense), }); + expect(serviceSetup.license.isLicenseAvailable()).toEqual(true); expect(serviceSetup.license.getFeatures()).toEqual({ showLogin: true, allowLogin: true, @@ -182,6 +189,7 @@ describe('license features', function () { const serviceSetup = new SecurityLicenseService().setup({ license$: of(mockRawLicense), }); + expect(serviceSetup.license.isLicenseAvailable()).toEqual(true); expect(serviceSetup.license.getFeatures()).toEqual({ showLogin: true, allowLogin: true, @@ -205,6 +213,7 @@ describe('license features', function () { const serviceSetup = new SecurityLicenseService().setup({ license$: of(mockRawLicense), }); + expect(serviceSetup.license.isLicenseAvailable()).toEqual(true); expect(serviceSetup.license.getFeatures()).toEqual({ showLogin: true, allowLogin: true, diff --git a/x-pack/plugins/security/common/licensing/license_service.ts b/x-pack/plugins/security/common/licensing/license_service.ts index 75c7670f28a67..09b6ae95c282c 100644 --- a/x-pack/plugins/security/common/licensing/license_service.ts +++ b/x-pack/plugins/security/common/licensing/license_service.ts @@ -10,6 +10,7 @@ import { ILicense } from '../../../licensing/common/types'; import { SecurityLicenseFeatures } from './license_features'; export interface SecurityLicense { + isLicenseAvailable(): boolean; isEnabled(): boolean; getFeatures(): SecurityLicenseFeatures; features$: Observable; @@ -31,6 +32,8 @@ export class SecurityLicenseService { return { license: Object.freeze({ + isLicenseAvailable: () => rawLicense?.isAvailable ?? false, + isEnabled: () => this.isSecurityEnabledFromRawLicense(rawLicense), getFeatures: () => this.calculateFeaturesFromRawLicense(rawLicense), diff --git a/x-pack/plugins/security/kibana.json b/x-pack/plugins/security/kibana.json index 6a09e9e55a01b..40d7e293eaf66 100644 --- a/x-pack/plugins/security/kibana.json +++ b/x-pack/plugins/security/kibana.json @@ -4,7 +4,7 @@ "kibanaVersion": "kibana", "configPath": ["xpack", "security"], "requiredPlugins": ["data", "features", "licensing", "taskManager"], - "optionalPlugins": ["home", "management"], + "optionalPlugins": ["home", "management", "usageCollection"], "server": true, "ui": true, "requiredBundles": [ diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/__snapshots__/elasticsearch_privileges.test.tsx.snap b/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/__snapshots__/elasticsearch_privileges.test.tsx.snap index 1c020685c246d..a2e46af19bf34 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/__snapshots__/elasticsearch_privileges.test.tsx.snap +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/es/__snapshots__/elasticsearch_privileges.test.tsx.snap @@ -184,6 +184,7 @@ exports[`it renders without crashing 1`] = ` }, "getFeatures": [MockFunction], "isEnabled": [MockFunction], + "isLicenseAvailable": [MockFunction], } } onChange={[MockFunction]} diff --git a/x-pack/plugins/security/public/plugin.test.tsx b/x-pack/plugins/security/public/plugin.test.tsx index 8cec4fbc2f5a2..8fe7d2805e18e 100644 --- a/x-pack/plugins/security/public/plugin.test.tsx +++ b/x-pack/plugins/security/public/plugin.test.tsx @@ -41,6 +41,7 @@ describe('Security Plugin', () => { __legacyCompat: { logoutUrl: '/some-base-path/logout', tenant: '/some-base-path' }, authc: { getCurrentUser: expect.any(Function), areAPIKeysEnabled: expect.any(Function) }, license: { + isLicenseAvailable: expect.any(Function), isEnabled: expect.any(Function), getFeatures: expect.any(Function), features$: expect.any(Observable), @@ -67,6 +68,7 @@ describe('Security Plugin', () => { expect(setupManagementServiceMock).toHaveBeenCalledWith({ authc: { getCurrentUser: expect.any(Function), areAPIKeysEnabled: expect.any(Function) }, license: { + isLicenseAvailable: expect.any(Function), isEnabled: expect.any(Function), getFeatures: expect.any(Function), features$: expect.any(Observable), diff --git a/x-pack/plugins/security/server/config.test.ts b/x-pack/plugins/security/server/config.test.ts index 520081ae30d8d..093a7643fbf64 100644 --- a/x-pack/plugins/security/server/config.test.ts +++ b/x-pack/plugins/security/server/config.test.ts @@ -904,11 +904,13 @@ describe('createConfig()', () => { }, "sortedProviders": Array [ Object { + "hasAccessAgreement": false, "name": "saml", "order": 0, "type": "saml", }, Object { + "hasAccessAgreement": false, "name": "basic", "order": 1, "type": "basic", @@ -982,6 +984,63 @@ describe('createConfig()', () => { ).toBe(true); }); + it('indicates which providers have the access agreement enabled', () => { + expect( + createConfig( + ConfigSchema.validate({ + authc: { + providers: { + basic: { basic1: { order: 3 } }, + saml: { + saml1: { order: 2, realm: 'saml1', accessAgreement: { message: 'foo' } }, + saml2: { order: 1, realm: 'saml2' }, + }, + oidc: { + oidc1: { order: 0, realm: 'oidc1', accessAgreement: { message: 'foo' } }, + oidc2: { order: 4, realm: 'oidc2' }, + }, + }, + }, + }), + loggingSystemMock.create().get(), + { isTLSEnabled: true } + ).authc.sortedProviders + ).toMatchInlineSnapshot(` + Array [ + Object { + "hasAccessAgreement": true, + "name": "oidc1", + "order": 0, + "type": "oidc", + }, + Object { + "hasAccessAgreement": false, + "name": "saml2", + "order": 1, + "type": "saml", + }, + Object { + "hasAccessAgreement": true, + "name": "saml1", + "order": 2, + "type": "saml", + }, + Object { + "hasAccessAgreement": false, + "name": "basic1", + "order": 3, + "type": "basic", + }, + Object { + "hasAccessAgreement": false, + "name": "oidc2", + "order": 4, + "type": "oidc", + }, + ] + `); + }); + it('correctly sorts providers based on the `order`', () => { expect( createConfig( @@ -1000,26 +1059,31 @@ describe('createConfig()', () => { ).toMatchInlineSnapshot(` Array [ Object { + "hasAccessAgreement": false, "name": "oidc1", "order": 0, "type": "oidc", }, Object { + "hasAccessAgreement": false, "name": "saml2", "order": 1, "type": "saml", }, Object { + "hasAccessAgreement": false, "name": "saml1", "order": 2, "type": "saml", }, Object { + "hasAccessAgreement": false, "name": "basic1", "order": 3, "type": "basic", }, Object { + "hasAccessAgreement": false, "name": "oidc2", "order": 4, "type": "oidc", diff --git a/x-pack/plugins/security/server/config.ts b/x-pack/plugins/security/server/config.ts index dcfe4825fb035..9ccbdac5e09f4 100644 --- a/x-pack/plugins/security/server/config.ts +++ b/x-pack/plugins/security/server/config.ts @@ -255,13 +255,19 @@ export function createConfig( type: keyof ProvidersConfigType; name: string; order: number; + hasAccessAgreement: boolean; }> = []; for (const [type, providerGroup] of Object.entries(providers)) { - for (const [name, { enabled, order }] of Object.entries(providerGroup ?? {})) { + for (const [name, { enabled, order, accessAgreement }] of Object.entries(providerGroup ?? {})) { if (!enabled) { delete providerGroup![name]; } else { - sortedProviders.push({ type: type as any, name, order }); + sortedProviders.push({ + type: type as any, + name, + order, + hasAccessAgreement: !!accessAgreement?.message, + }); } } } diff --git a/x-pack/plugins/security/server/plugin.test.ts b/x-pack/plugins/security/server/plugin.test.ts index 8d13f81075714..9825e77b164c8 100644 --- a/x-pack/plugins/security/server/plugin.test.ts +++ b/x-pack/plugins/security/server/plugin.test.ts @@ -108,6 +108,7 @@ describe('Security Plugin', () => { }, "getFeatures": [Function], "isEnabled": [Function], + "isLicenseAvailable": [Function], }, "registerSpacesService": [Function], } diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index 7d94e03916fa1..1eb406dd2061b 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -7,6 +7,7 @@ import { combineLatest } from 'rxjs'; import { first, map } from 'rxjs/operators'; import { TypeOf } from '@kbn/config-schema'; +import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { deepFreeze, CoreSetup, @@ -32,6 +33,7 @@ import { AuditService, SecurityAuditLogger, AuditServiceSetup } from './audit'; import { SecurityFeatureUsageService, SecurityFeatureUsageServiceStart } from './feature_usage'; import { ElasticsearchService } from './elasticsearch'; import { SessionManagementService } from './session_management'; +import { registerSecurityUsageCollector } from './usage_collector'; export type SpacesService = Pick< SpacesPluginSetup['spacesService'], @@ -74,6 +76,7 @@ export interface PluginSetupDependencies { features: FeaturesPluginSetup; licensing: LicensingPluginSetup; taskManager: TaskManagerSetupContract; + usageCollection?: UsageCollectionSetup; } export interface PluginStartDependencies { @@ -123,7 +126,7 @@ export class Plugin { public async setup( core: CoreSetup, - { features, licensing, taskManager }: PluginSetupDependencies + { features, licensing, taskManager, usageCollection }: PluginSetupDependencies ) { const [config, legacyConfig] = await combineLatest([ this.initializerContext.config.create>().pipe( @@ -151,6 +154,8 @@ export class Plugin { this.featureUsageService.setup({ featureUsage: licensing.featureUsage }); + registerSecurityUsageCollector({ usageCollection, config, license }); + const audit = this.auditService.setup({ license, config: config.audit }); const auditLogger = new SecurityAuditLogger(audit.getLogger()); diff --git a/x-pack/plugins/security/server/usage_collector/index.ts b/x-pack/plugins/security/server/usage_collector/index.ts new file mode 100644 index 0000000000000..dd405ebac4241 --- /dev/null +++ b/x-pack/plugins/security/server/usage_collector/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { registerSecurityUsageCollector } from './security_usage_collector'; diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts new file mode 100644 index 0000000000000..6c3dcddcdb418 --- /dev/null +++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.test.ts @@ -0,0 +1,465 @@ +/* + * 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 { createConfig, ConfigSchema } from '../config'; +import { loggingSystemMock } from 'src/core/server/mocks'; +import { TypeOf } from '@kbn/config-schema'; +import { usageCollectionPluginMock } from 'src/plugins/usage_collection/server/mocks'; +import { registerSecurityUsageCollector } from './security_usage_collector'; +import { elasticsearchServiceMock } from 'src/core/server/mocks'; +import { licenseMock } from '../../common/licensing/index.mock'; +import { SecurityLicenseFeatures } from '../../common/licensing'; + +describe('Security UsageCollector', () => { + const createSecurityConfig = (config: TypeOf) => { + return createConfig(config, loggingSystemMock.createLogger(), { isTLSEnabled: true }); + }; + + const createSecurityLicense = ({ + allowAccessAgreement = true, + allowAuditLogging = true, + allowRbac = true, + isLicenseAvailable, + }: Partial & { isLicenseAvailable: boolean }) => { + const license = licenseMock.create(); + license.isLicenseAvailable.mockReturnValue(isLicenseAvailable); + license.getFeatures.mockReturnValue({ + allowAccessAgreement, + allowAuditLogging, + allowRbac, + } as SecurityLicenseFeatures); + return license; + }; + + const clusterClient = elasticsearchServiceMock.createLegacyClusterClient(); + + describe('initialization', () => { + it('handles an undefined usage collector', () => { + const config = createSecurityConfig(ConfigSchema.validate({})); + const usageCollection = undefined; + const license = createSecurityLicense({ allowRbac: false, isLicenseAvailable: false }); + registerSecurityUsageCollector({ usageCollection, config, license }); + }); + + it('registers itself and waits for the license to become available before reporting itself as ready', async () => { + const config = createSecurityConfig(ConfigSchema.validate({})); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ allowRbac: false, isLicenseAvailable: false }); + + registerSecurityUsageCollector({ usageCollection, config, license }); + + expect(usageCollection.getCollectorByType('security')?.isReady()).toBe(false); + + license.isLicenseAvailable.mockReturnValue(true); + license.getFeatures.mockReturnValue({ allowRbac: true } as SecurityLicenseFeatures); + + expect(usageCollection.getCollectorByType('security')?.isReady()).toBe(true); + }); + }); + + it('reports correctly for a default configuration', async () => { + const config = createSecurityConfig(ConfigSchema.validate({})); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 1, + enabledAuthProviders: ['basic'], + loginSelectorEnabled: false, + httpAuthSchemes: ['apikey'], + }); + }); + + it('reports correctly when security is disabled in Elasticsearch', async () => { + const config = createSecurityConfig(ConfigSchema.validate({})); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ allowRbac: false, isLicenseAvailable: true }); + + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 0, + enabledAuthProviders: [], + loginSelectorEnabled: false, + httpAuthSchemes: [], + }); + }); + + describe('auth providers', () => { + it('does not report disabled auth providers', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + authc: { + providers: { + basic: { + basic: { + order: 0, + }, + disabledBasic: { + enabled: false, + order: 1, + }, + }, + saml: { + disabledSaml: { + enabled: false, + realm: 'foo', + order: 2, + }, + }, + }, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 1, + enabledAuthProviders: ['basic'], + loginSelectorEnabled: false, + httpAuthSchemes: ['apikey'], + }); + }); + + it('reports the types and count of enabled auth providers', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + authc: { + providers: { + basic: { + basic: { + order: 0, + enabled: false, + }, + }, + saml: { + saml1: { + realm: 'foo', + order: 1, + }, + saml2: { + realm: 'bar', + order: 2, + }, + }, + pki: { + pki1: { + enabled: true, + order: 3, + }, + }, + }, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 3, + enabledAuthProviders: ['saml', 'pki'], + loginSelectorEnabled: true, + httpAuthSchemes: ['apikey'], + }); + }); + }); + + describe('access agreement', () => { + it('reports if the access agreement message is configured for any provider', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + authc: { + providers: { + saml: { + saml1: { + realm: 'foo', + order: 1, + accessAgreement: { + message: 'foo message', + }, + }, + }, + }, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: true, + authProviderCount: 1, + enabledAuthProviders: ['saml'], + loginSelectorEnabled: false, + httpAuthSchemes: ['apikey'], + }); + }); + it('does not report the access agreement if the license does not permit it', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + authc: { + providers: { + saml: { + saml1: { + realm: 'foo', + order: 1, + accessAgreement: { + message: 'foo message', + }, + }, + }, + }, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ + isLicenseAvailable: true, + allowAccessAgreement: false, + }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 1, + enabledAuthProviders: ['saml'], + loginSelectorEnabled: false, + httpAuthSchemes: ['apikey'], + }); + }); + + it('does not report the access agreement for disabled providers', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + authc: { + providers: { + saml: { + saml1: { + enabled: false, + realm: 'foo', + order: 1, + accessAgreement: { + message: 'foo message', + }, + }, + saml2: { + realm: 'foo', + order: 2, + }, + }, + }, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 1, + enabledAuthProviders: ['saml'], + loginSelectorEnabled: false, + httpAuthSchemes: ['apikey'], + }); + }); + }); + + describe('login selector', () => { + it('reports when the login selector is enabled', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + authc: { + selector: { + enabled: true, + }, + providers: { + saml: { + saml1: { + realm: 'foo', + order: 1, + showInSelector: true, + }, + }, + }, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 1, + enabledAuthProviders: ['saml'], + loginSelectorEnabled: true, + httpAuthSchemes: ['apikey'], + }); + }); + }); + + describe('audit logging', () => { + it('reports when audit logging is enabled', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + audit: { + enabled: true, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true, allowAuditLogging: true }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: true, + accessAgreementEnabled: false, + authProviderCount: 1, + enabledAuthProviders: ['basic'], + loginSelectorEnabled: false, + httpAuthSchemes: ['apikey'], + }); + }); + + it('does not report audit logging when the license does not permit it', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + audit: { + enabled: true, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true, allowAuditLogging: false }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 1, + enabledAuthProviders: ['basic'], + loginSelectorEnabled: false, + httpAuthSchemes: ['apikey'], + }); + }); + }); + + describe('http auth schemes', () => { + it('reports customized http auth schemes', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + authc: { + http: { + schemes: ['basic', 'Negotiate'], + }, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true, allowAuditLogging: false }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 1, + enabledAuthProviders: ['basic'], + loginSelectorEnabled: false, + httpAuthSchemes: ['basic', 'Negotiate'], + }); + }); + + it('does not report auth schemes that are not "well known"', async () => { + const config = createSecurityConfig( + ConfigSchema.validate({ + authc: { + http: { + schemes: ['basic', 'Negotiate', 'customScheme'], + }, + }, + }) + ); + const usageCollection = usageCollectionPluginMock.createSetupContract(); + const license = createSecurityLicense({ isLicenseAvailable: true, allowAuditLogging: false }); + registerSecurityUsageCollector({ usageCollection, config, license }); + + const usage = await usageCollection + .getCollectorByType('security') + ?.fetch(clusterClient.asScoped().callAsCurrentUser); + + expect(usage).toEqual({ + auditLoggingEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 1, + enabledAuthProviders: ['basic'], + loginSelectorEnabled: false, + httpAuthSchemes: ['basic', 'Negotiate'], + }); + }); + }); +}); diff --git a/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts new file mode 100644 index 0000000000000..11e58f7f95fc2 --- /dev/null +++ b/x-pack/plugins/security/server/usage_collector/security_usage_collector.ts @@ -0,0 +1,116 @@ +/* + * 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 { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { ConfigType } from '../config'; +import { SecurityLicense } from '../../common/licensing'; + +interface Usage { + auditLoggingEnabled: boolean; + loginSelectorEnabled: boolean; + accessAgreementEnabled: boolean; + authProviderCount: number; + enabledAuthProviders: string[]; + httpAuthSchemes: string[]; +} + +interface Deps { + usageCollection?: UsageCollectionSetup; + config: ConfigType; + license: SecurityLicense; +} + +// List of auth schemes collected from https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml +const WELL_KNOWN_AUTH_SCHEMES = [ + 'basic', + 'bearer', + 'digest', + 'hoba', + 'mutual', + 'negotiate', + 'oauth', + 'scram-sha-1', + 'scram-sha-256', + 'vapid', + 'apikey', // not part of the spec, but used by the Elastic Stack for API Key authentication +]; + +export function registerSecurityUsageCollector({ usageCollection, config, license }: Deps): void { + // usageCollection is an optional dependency, so make sure to return if it is not registered. + if (!usageCollection) { + return; + } + + // create usage collector + const securityCollector = usageCollection.makeUsageCollector({ + type: 'security', + isReady: () => license.isLicenseAvailable(), + schema: { + auditLoggingEnabled: { + type: 'boolean', + }, + loginSelectorEnabled: { + type: 'boolean', + }, + accessAgreementEnabled: { + type: 'boolean', + }, + authProviderCount: { + type: 'number', + }, + enabledAuthProviders: { + type: 'keyword', + }, + httpAuthSchemes: { + type: 'keyword', + }, + }, + fetch: () => { + const { allowRbac, allowAccessAgreement, allowAuditLogging } = license.getFeatures(); + if (!allowRbac) { + return { + auditLoggingEnabled: false, + loginSelectorEnabled: false, + accessAgreementEnabled: false, + authProviderCount: 0, + enabledAuthProviders: [], + httpAuthSchemes: [], + }; + } + + const auditLoggingEnabled = allowAuditLogging && config.audit.enabled; + const loginSelectorEnabled = config.authc.selector.enabled; + const authProviderCount = config.authc.sortedProviders.length; + const enabledAuthProviders = [ + ...new Set( + config.authc.sortedProviders.reduce( + (acc, provider) => [...acc, provider.type], + [] as string[] + ) + ), + ]; + const accessAgreementEnabled = + allowAccessAgreement && + config.authc.sortedProviders.some((provider) => provider.hasAccessAgreement); + + const httpAuthSchemes = config.authc.http.schemes.filter((scheme) => + WELL_KNOWN_AUTH_SCHEMES.includes(scheme.toLowerCase()) + ); + + return { + auditLoggingEnabled, + loginSelectorEnabled, + accessAgreementEnabled, + authProviderCount, + enabledAuthProviders, + httpAuthSchemes, + }; + }, + }); + + // register usage collector + usageCollection.registerCollector(securityCollector); +} diff --git a/x-pack/plugins/security_solution/common/endpoint/constants.ts b/x-pack/plugins/security_solution/common/endpoint/constants.ts index 366bf7a1df1f2..a6018837fa4fe 100644 --- a/x-pack/plugins/security_solution/common/endpoint/constants.ts +++ b/x-pack/plugins/security_solution/common/endpoint/constants.ts @@ -7,6 +7,7 @@ export const eventsIndexPattern = 'logs-endpoint.events.*'; export const alertsIndexPattern = 'logs-endpoint.alerts-*'; export const metadataIndexPattern = 'metrics-endpoint.metadata-*'; +export const metadataCurrentIndexPattern = 'metrics-endpoint.metadata_current-*'; export const policyIndexPattern = 'metrics-endpoint.policy-*'; export const telemetryIndexPattern = 'metrics-endpoint.telemetry-*'; export const LIMITED_CONCURRENCY_ENDPOINT_ROUTE_TAG = 'endpoint:limited-concurrency'; diff --git a/x-pack/plugins/security_solution/common/endpoint/generate_data.ts b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts index 11f37d01aca96..7f31c71fe712b 100644 --- a/x-pack/plugins/security_solution/common/endpoint/generate_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts @@ -1153,7 +1153,8 @@ export class EndpointDocGenerator { path: '/package/endpoint/0.5.0', icons: [ { - src: '/package/endpoint/0.5.0/img/logo-endpoint-64-color.svg', + path: '/package/endpoint/0.5.0/img/logo-endpoint-64-color.svg', + src: '/img/logo-endpoint-64-color.svg', size: '16x16', type: 'image/svg+xml', }, diff --git a/x-pack/plugins/security_solution/common/endpoint/types/index.ts b/x-pack/plugins/security_solution/common/endpoint/types/index.ts index 89ea27aa10b3d..cc40225ec1a10 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/index.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/index.ts @@ -509,6 +509,13 @@ export type HostInfo = Immutable<{ host_status: HostStatus; }>; +export type HostMetadataDetails = Immutable<{ + agent: { + id: string; + }; + HostDetails: HostMetadata; +}>; + export type HostMetadata = Immutable<{ '@timestamp': number; event: { diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/index.ts index b7d905d22e839..35fcc3b07fd05 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/index.ts @@ -23,6 +23,8 @@ import { } from './hosts'; import { NetworkQueries, + NetworkDetailsStrategyResponse, + NetworkDetailsRequestOptions, NetworkDnsStrategyResponse, NetworkDnsRequestOptions, NetworkTlsStrategyResponse, @@ -35,6 +37,8 @@ import { NetworkTopCountriesRequestOptions, NetworkTopNFlowStrategyResponse, NetworkTopNFlowRequestOptions, + NetworkUsersStrategyResponse, + NetworkUsersRequestOptions, } from './network'; import { MatrixHistogramQuery, @@ -87,6 +91,8 @@ export type StrategyResponseType = T extends HostsQ ? HostFirstLastSeenStrategyResponse : T extends HostsQueries.uncommonProcesses ? HostUncommonProcessesStrategyResponse + : T extends NetworkQueries.details + ? NetworkDetailsStrategyResponse : T extends NetworkQueries.dns ? NetworkDnsStrategyResponse : T extends NetworkQueries.http @@ -99,6 +105,8 @@ export type StrategyResponseType = T extends HostsQ ? NetworkTopCountriesStrategyResponse : T extends NetworkQueries.topNFlow ? NetworkTopNFlowStrategyResponse + : T extends NetworkQueries.users + ? NetworkUsersStrategyResponse : T extends typeof MatrixHistogramQuery ? MatrixHistogramStrategyResponse : never; @@ -115,6 +123,8 @@ export type StrategyRequestType = T extends HostsQu ? HostFirstLastSeenRequestOptions : T extends HostsQueries.uncommonProcesses ? HostUncommonProcessesRequestOptions + : T extends NetworkQueries.details + ? NetworkDetailsRequestOptions : T extends NetworkQueries.dns ? NetworkDnsRequestOptions : T extends NetworkQueries.http @@ -127,6 +137,8 @@ export type StrategyRequestType = T extends HostsQu ? NetworkTopCountriesRequestOptions : T extends NetworkQueries.topNFlow ? NetworkTopNFlowRequestOptions + : T extends NetworkQueries.users + ? NetworkUsersRequestOptions : T extends typeof MatrixHistogramQuery ? MatrixHistogramRequestOptions : never; diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/common/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/common/index.ts index 66676569b3c9e..19521741c5f66 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/common/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/common/index.ts @@ -15,6 +15,13 @@ export enum NetworkTopTablesFields { source_ips = 'source_ips', } +export enum FlowTarget { + client = 'client', + destination = 'destination', + server = 'server', + source = 'source', +} + export enum FlowTargetSourceDest { destination = 'destination', source = 'source', diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/details/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/details/index.ts new file mode 100644 index 0000000000000..920d7cf8c5eaf --- /dev/null +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/details/index.ts @@ -0,0 +1,109 @@ +/* + * 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 { IEsSearchResponse } from '../../../../../../../../src/plugins/data/common'; +import { HostEcs } from '../../../../ecs/host'; +import { GeoEcs } from '../../../../ecs/geo'; +import { Inspect, Maybe, TotalValue, Hit, ShardsResponse } from '../../../common'; +import { RequestBasicOptions } from '../..'; + +export interface NetworkDetailsRequestOptions extends Omit { + ip: string; +} + +export interface NetworkDetailsStrategyResponse extends IEsSearchResponse { + networkDetails: { + client?: Maybe; + destination?: Maybe; + host?: HostEcs; + server?: Maybe; + source?: Maybe; + }; + inspect?: Maybe; +} + +export interface NetworkDetails { + firstSeen?: Maybe; + lastSeen?: Maybe; + autonomousSystem: AutonomousSystem; + geo: GeoEcs; +} + +export interface AutonomousSystem { + number?: Maybe; + organization?: Maybe; +} + +export interface AutonomousSystemOrganization { + name?: Maybe; +} + +interface ResultHit { + doc_count: number; + results: { + hits: { + total: TotalValue | number; + max_score: number | null; + hits: Array<{ + _source: T; + sort?: [number]; + _index?: string; + _type?: string; + _id?: string; + _score?: number | null; + }>; + }; + }; +} + +export interface NetworkHit { + took?: number; + timed_out?: boolean; + _scroll_id?: string; + _shards?: ShardsResponse; + timeout?: number; + hits?: { + total: number; + hits: Hit[]; + }; + doc_count: number; + geo: ResultHit; + autonomousSystem: ResultHit; + firstSeen: { + value: number; + value_as_string: string; + }; + lastSeen: { + value: number; + value_as_string: string; + }; +} + +export type NetworkDetailsHostHit = ResultHit; + +export interface NetworkDetailsHit { + aggregations: { + destination?: NetworkHit; + source?: NetworkHit; + host: ResultHit; + }; + _shards: { + total: number; + successful: number; + skipped: number; + failed: number; + }; + hits: { + total: { + value: number; + relation: string; + }; + max_score: number | null; + hits: []; + }; + took: number; + timeout: number; +} diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/http/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/http/index.ts index ad58442b16994..cd661cd9b9e9f 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/http/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/http/index.ts @@ -8,6 +8,16 @@ import { IEsSearchResponse } from '../../../../../../../../src/plugins/data/comm import { Maybe, CursorType, Inspect, PageInfoPaginated, GenericBuckets } from '../../../common'; import { RequestOptionsPaginated } from '../..'; +export enum NetworkHttpFields { + domains = 'domains', + lastHost = 'lastHost', + lastSourceIp = 'lastSourceIp', + methods = 'methods', + path = 'path', + requestCount = 'requestCount', + statuses = 'statuses', +} + export interface NetworkHttpRequestOptions extends RequestOptionsPaginated { ip?: string; defaultIndex: string[]; diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/index.ts index d61acbe62ffb0..4e73fe11ef430 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/index.ts @@ -5,18 +5,22 @@ */ export * from './common'; +export * from './details'; export * from './dns'; export * from './http'; export * from './overview'; export * from './tls'; export * from './top_countries'; export * from './top_n_flow'; +export * from './users'; export enum NetworkQueries { + details = 'networkDetails', dns = 'dns', http = 'http', overview = 'overviewNetwork', tls = 'tls', topCountries = 'topCountries', topNFlow = 'topNFlow', + users = 'users', } diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/tls/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/tls/index.ts index dffc994fcf4cb..5e1c9459aaac3 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/tls/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/tls/index.ts @@ -9,7 +9,7 @@ import { CursorType, Inspect, Maybe, PageInfoPaginated } from '../../../common'; import { RequestOptionsPaginated } from '../..'; import { FlowTargetSourceDest } from '../common'; -export interface TlsBuckets { +export interface NetworkTlsBuckets { key: string; timestamp?: { value: number; @@ -29,7 +29,7 @@ export interface TlsBuckets { }; } -export interface TlsNode { +export interface NetworkTlsNode { _id?: Maybe; timestamp?: Maybe; notAfter?: Maybe; @@ -38,23 +38,23 @@ export interface TlsNode { issuers?: Maybe; } -export enum TlsFields { +export enum NetworkTlsFields { _id = '_id', } -export interface TlsEdges { - node: TlsNode; +export interface NetworkTlsEdges { + node: NetworkTlsNode; cursor: CursorType; } -export interface NetworkTlsRequestOptions extends RequestOptionsPaginated { +export interface NetworkTlsRequestOptions extends RequestOptionsPaginated { ip: string; flowTarget: FlowTargetSourceDest; defaultIndex: string[]; } export interface NetworkTlsStrategyResponse extends IEsSearchResponse { - edges: TlsEdges[]; + edges: NetworkTlsEdges[]; totalCount: number; pageInfo: PageInfoPaginated; inspect?: Maybe; diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/top_countries/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/top_countries/index.ts index a28388a2c6f8f..2c89bbf048e62 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/top_countries/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/top_countries/index.ts @@ -14,13 +14,6 @@ import { TopNetworkTablesEcsField, } from '../common'; -export enum FlowTarget { - client = 'client', - destination = 'destination', - server = 'server', - source = 'source', -} - export interface TopCountriesItemSource { country?: Maybe; destination_ips?: Maybe; diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/users/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/users/index.ts new file mode 100644 index 0000000000000..196317e7587bf --- /dev/null +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/users/index.ts @@ -0,0 +1,73 @@ +/* + * 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 { IEsSearchResponse } from '../../../../../../../../src/plugins/data/common'; +import { CursorType, Inspect, Maybe, PageInfoPaginated, SortField } from '../../../common'; +import { FlowTarget } from '../common'; +import { RequestOptionsPaginated } from '../..'; + +export enum NetworkUsersFields { + name = 'name', + count = 'count', +} + +export interface NetworkUsersRequestOptions extends RequestOptionsPaginated { + ip: string; + sort: SortField; + flowTarget: FlowTarget; +} + +export interface NetworkUsersStrategyResponse extends IEsSearchResponse { + edges: NetworkUsersEdges[]; + totalCount: number; + pageInfo: PageInfoPaginated; + inspect?: Maybe; +} + +export interface NetworkUsersEdges { + node: NetworkUsersNode; + cursor: CursorType; +} + +export interface NetworkUsersNode { + _id?: Maybe; + timestamp?: Maybe; + user?: Maybe; +} + +export interface NetworkUsersItem { + name?: Maybe; + id?: Maybe; + groupId?: Maybe; + groupName?: Maybe; + count?: Maybe; +} + +export interface NetworkUsersBucketsItem { + key: string; + doc_count: number; + groupName?: NetworkUsersGroupName; + groupId?: NetworkUsersGroupId; + id?: Id; +} + +export interface NetworkUsersGroupName { + doc_count_error_upper_bound: number; + sum_other_doc_count: number; + buckets: NetworkUsersBucketsItem[]; +} + +export interface NetworkUsersGroupId { + doc_count_error_upper_bound: number; + sum_other_doc_count: number; + buckets: NetworkUsersBucketsItem[]; +} + +interface Id { + doc_count_error_upper_bound: number; + sum_other_doc_count: number; + buckets: NetworkUsersBucketsItem[]; +} diff --git a/x-pack/plugins/security_solution/cypress/integration/url_compatibility.spec.ts b/x-pack/plugins/security_solution/cypress/integration/url_compatibility.spec.ts index d55a8faae021d..5b42897b065e3 100644 --- a/x-pack/plugins/security_solution/cypress/integration/url_compatibility.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/url_compatibility.spec.ts @@ -18,8 +18,7 @@ const ABSOLUTE_DATE = { startTime: '2019-08-01T20:03:29.186Z', }; -// FLAKY: https://github.com/elastic/kibana/issues/75697 -describe.skip('URL compatibility', () => { +describe('URL compatibility', () => { it('Redirects to Detection alerts from old Detections URL', () => { loginAndWaitForPage(DETECTIONS); diff --git a/x-pack/plugins/security_solution/public/common/components/link_to/__mocks__/index.ts b/x-pack/plugins/security_solution/public/common/components/link_to/__mocks__/index.ts index 6c9620e27fabf..07855c3477106 100644 --- a/x-pack/plugins/security_solution/public/common/components/link_to/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/public/common/components/link_to/__mocks__/index.ts @@ -9,7 +9,7 @@ import { SecurityPageName } from '../../../../app/types'; export { getDetectionEngineUrl } from '../redirect_to_detection_engine'; export { getAppOverviewUrl } from '../redirect_to_overview'; export { getHostDetailsUrl, getHostsUrl } from '../redirect_to_hosts'; -export { getNetworkUrl, getIPDetailsUrl } from '../redirect_to_network'; +export { getNetworkUrl, getNetworkDetailsUrl } from '../redirect_to_network'; export { getTimelinesUrl, getTimelineTabsUrl } from '../redirect_to_timelines'; export { getCaseDetailsUrl, diff --git a/x-pack/plugins/security_solution/public/common/components/link_to/index.ts b/x-pack/plugins/security_solution/public/common/components/link_to/index.ts index c6e58d4206958..403c8d838fa44 100644 --- a/x-pack/plugins/security_solution/public/common/components/link_to/index.ts +++ b/x-pack/plugins/security_solution/public/common/components/link_to/index.ts @@ -15,7 +15,7 @@ import { useKibana } from '../../lib/kibana'; export { getDetectionEngineUrl } from './redirect_to_detection_engine'; export { getAppOverviewUrl } from './redirect_to_overview'; export { getHostDetailsUrl, getHostsUrl } from './redirect_to_hosts'; -export { getNetworkUrl, getIPDetailsUrl } from './redirect_to_network'; +export { getNetworkUrl, getNetworkDetailsUrl } from './redirect_to_network'; export { getTimelinesUrl, getTimelineTabsUrl } from './redirect_to_timelines'; export { getCaseDetailsUrl, diff --git a/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_network.tsx b/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_network.tsx index 100c5e46141a2..c042c8e1470b4 100644 --- a/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_network.tsx +++ b/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_network.tsx @@ -13,7 +13,7 @@ import { appendSearch } from './helpers'; export const getNetworkUrl = (search?: string) => `${appendSearch(search)}`; -export const getIPDetailsUrl = ( +export const getNetworkDetailsUrl = ( detailName: string, flowTarget?: FlowTarget | FlowTargetSourceDest, search?: string diff --git a/x-pack/plugins/security_solution/public/common/components/links/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/links/index.test.tsx index b6817c4cab1f2..e6d34b5e432ac 100644 --- a/x-pack/plugins/security_solution/public/common/components/links/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/links/index.test.tsx @@ -14,7 +14,7 @@ import { useUiSetting$ } from '../../lib/kibana'; import { GoogleLink, HostDetailsLink, - IPDetailsLink, + NetworkDetailsLink, ReputationLink, WhoIsLink, CertificateFingerprintLink, @@ -61,9 +61,9 @@ describe('Custom Links', () => { }); }); - describe('IPDetailsLink', () => { + describe('NetworkDetailsLink', () => { test('should render valid link to IP Details with ipv4 as the display text', () => { - const wrapper = mount(); + const wrapper = mount(); expect(wrapper.find('EuiLink').prop('href')).toEqual( `/ip/${encodeURIComponent(ipv4)}/source` ); @@ -71,7 +71,7 @@ describe('Custom Links', () => { }); test('should render valid link to IP Details with child text as the display text', () => { - const wrapper = mount({hostName}); + const wrapper = mount({hostName}); expect(wrapper.find('EuiLink').prop('href')).toEqual( `/ip/${encodeURIComponent(ipv4)}/source` ); @@ -79,7 +79,7 @@ describe('Custom Links', () => { }); test('should render valid link to IP Details with ipv6 as the display text', () => { - const wrapper = mount(); + const wrapper = mount(); expect(wrapper.find('EuiLink').prop('href')).toEqual( `/ip/${encodeURIComponent(ipv6Encoded)}/source` ); diff --git a/x-pack/plugins/security_solution/public/common/components/links/index.tsx b/x-pack/plugins/security_solution/public/common/components/links/index.tsx index 943f2d8336ca7..d6cbd31e86ddb 100644 --- a/x-pack/plugins/security_solution/public/common/components/links/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/links/index.tsx @@ -28,7 +28,7 @@ import { encodeIpv6 } from '../../lib/helpers'; import { getCaseDetailsUrl, getHostDetailsUrl, - getIPDetailsUrl, + getNetworkDetailsUrl, getCreateCaseUrl, useFormatUrl, } from '../link_to'; @@ -114,7 +114,7 @@ export const ExternalLink = React.memo<{ ExternalLink.displayName = 'ExternalLink'; -const IPDetailsLinkComponent: React.FC<{ +const NetworkDetailsLinkComponent: React.FC<{ children?: React.ReactNode; ip: string; flowTarget?: FlowTarget | FlowTargetSourceDest; @@ -125,7 +125,7 @@ const IPDetailsLinkComponent: React.FC<{ (ev) => { ev.preventDefault(); navigateToApp(`${APP_ID}:${SecurityPageName.network}`, { - path: getIPDetailsUrl(encodeURIComponent(encodeIpv6(ip)), flowTarget, search), + path: getNetworkDetailsUrl(encodeURIComponent(encodeIpv6(ip)), flowTarget, search), }); }, [flowTarget, ip, navigateToApp, search] @@ -134,14 +134,14 @@ const IPDetailsLinkComponent: React.FC<{ return ( {children ? children : ip} ); }; -export const IPDetailsLink = React.memo(IPDetailsLinkComponent); +export const NetworkDetailsLink = React.memo(NetworkDetailsLinkComponent); const CaseDetailsLinkComponent: React.FC<{ children?: React.ReactNode; diff --git a/x-pack/plugins/security_solution/public/common/components/links/translations.ts b/x-pack/plugins/security_solution/public/common/components/links/translations.ts index cf7db8bfa8161..014acdf3fd557 100644 --- a/x-pack/plugins/security_solution/public/common/components/links/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/links/translations.ts @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; -export * from '../../../network/components/ip_overview/translations'; +export * from '../../../network/components/details/translations'; export const CASE_DETAILS_LINK_ARIA = (detailName: string) => i18n.translate('xpack.securitySolution.case.caseTable.caseDetailsLinkAria', { diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.tsx index 52b26a20a8f64..3dd408e5aa822 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.tsx @@ -14,7 +14,7 @@ import { Anomaly, AnomaliesByNetwork } from '../types'; import { getRowItemDraggable } from '../../tables/helpers'; import { EntityDraggable } from '../entity_draggable'; import { createCompoundNetworkKey } from './create_compound_key'; -import { IPDetailsLink } from '../../links'; +import { NetworkDetailsLink } from '../../links'; import * as i18n from './translations'; import { getEntries } from '../get_entries'; @@ -46,7 +46,7 @@ export const getAnomaliesNetworkTableColumns = ( rowItem: ip, attrName: anomaliesByNetwork.type, idPrefix: `anomalies-network-table-ip-${createCompoundNetworkKey(anomaliesByNetwork)}`, - render: (item) => , + render: (item) => , }), }, { diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts index a10e4cf568dd1..2964572cb7cf3 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts @@ -10,7 +10,7 @@ import { ChromeBreadcrumb } from '../../../../../../../../src/core/public'; import { APP_NAME } from '../../../../../common/constants'; import { StartServices } from '../../../../types'; import { getBreadcrumbs as getHostDetailsBreadcrumbs } from '../../../../hosts/pages/details/utils'; -import { getBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../../network/pages/ip_details'; +import { getBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../../network/pages/details'; import { getBreadcrumbs as getCaseDetailsBreadcrumbs } from '../../../../cases/pages/utils'; import { getBreadcrumbs as getDetectionRulesBreadcrumbs } from '../../../../detections/pages/detection_engine/rules/utils'; import { getBreadcrumbs as getTimelinesBreadcrumbs } from '../../../../timelines/pages'; diff --git a/x-pack/plugins/security_solution/public/common/components/paginated_table/index.tsx b/x-pack/plugins/security_solution/public/common/components/paginated_table/index.tsx index 448fa58443407..f7b69c4fc8ed3 100644 --- a/x-pack/plugins/security_solution/public/common/components/paginated_table/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/paginated_table/index.tsx @@ -16,12 +16,12 @@ import { EuiLoadingContent, EuiPagination, EuiPopover, - Direction, } from '@elastic/eui'; import { noop } from 'lodash/fp'; import React, { FC, memo, useState, useEffect, ComponentType } from 'react'; import styled from 'styled-components'; +import { Direction } from '../../../../common/search_strategy'; import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../../common/constants'; import { AuthTableColumns } from '../../../hosts/components/authentications_table'; import { HostsTableColumns } from '../../../hosts/components/hosts_table'; @@ -29,11 +29,11 @@ import { NetworkDnsColumns } from '../../../network/components/network_dns_table import { NetworkHttpColumns } from '../../../network/components/network_http_table/columns'; import { NetworkTopNFlowColumns, - NetworkTopNFlowColumnsIpDetails, + NetworkTopNFlowColumnsNetworkDetails, } from '../../../network/components/network_top_n_flow_table/columns'; import { NetworkTopCountriesColumns, - NetworkTopCountriesColumnsIpDetails, + NetworkTopCountriesColumnsNetworkDetails, } from '../../../network/components/network_top_countries_table/columns'; import { TlsColumns } from '../../../network/components/tls_table/columns'; import { UncommonProcessTableColumns } from '../../../hosts/components/uncommon_process_table'; @@ -78,9 +78,9 @@ declare type BasicTableColumns = | NetworkDnsColumns | NetworkHttpColumns | NetworkTopCountriesColumns - | NetworkTopCountriesColumnsIpDetails + | NetworkTopCountriesColumnsNetworkDetails | NetworkTopNFlowColumns - | NetworkTopNFlowColumnsIpDetails + | NetworkTopNFlowColumnsNetworkDetails | TlsColumns | UncommonProcessTableColumns | UsersColumns; diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts index 833f85712b5fa..9e6982ea20301 100644 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts +++ b/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts @@ -4,14 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ServiceNowConnectorConfiguration } from '../../../../../triggers_actions_ui/public/common'; -import { connector as jiraConnectorConfig } from './jira/config'; +/* eslint-disable @kbn/eslint/no-restricted-paths */ + +import { + ServiceNowConnectorConfiguration, + JiraConnectorConfiguration, +} from '../../../../../triggers_actions_ui/public/common'; import { connector as resilientConnectorConfig } from './resilient/config'; import { ConnectorConfiguration } from './types'; export const connectorsConfiguration: Record = { '.servicenow': ServiceNowConnectorConfiguration as ConnectorConfiguration, - '.jira': jiraConnectorConfig, + '.jira': JiraConnectorConfiguration as ConnectorConfiguration, '.resilient': resilientConnectorConfig, }; diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/index.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/index.ts index f32e1e0df184e..33afa82c84f34 100644 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/index.ts +++ b/x-pack/plugins/security_solution/public/common/lib/connectors/index.ts @@ -4,5 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { getActionType as jiraActionType } from './jira'; export { getActionType as resilientActionType } from './resilient'; diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/flyout.tsx b/x-pack/plugins/security_solution/public/common/lib/connectors/jira/flyout.tsx deleted file mode 100644 index 0737db3cd08eb..0000000000000 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/flyout.tsx +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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 React from 'react'; -import { - EuiFieldText, - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, - EuiFieldPassword, - EuiSpacer, -} from '@elastic/eui'; - -import * as i18n from './translations'; -import { ConnectorFlyoutFormProps } from '../types'; -import { JiraActionConnector } from './types'; -import { withConnectorFlyout } from '../components/connector_flyout'; - -const JiraConnectorForm: React.FC> = ({ - errors, - action, - onChangeSecret, - onBlurSecret, - onChangeConfig, - onBlurConfig, -}) => { - const { projectKey } = action.config; - const { email, apiToken } = action.secrets; - const isProjectKeyInvalid: boolean = errors.projectKey.length > 0 && projectKey != null; - const isEmailInvalid: boolean = errors.email.length > 0 && email != null; - const isApiTokenInvalid: boolean = errors.apiToken.length > 0 && apiToken != null; - - return ( - <> - - - - onChangeConfig('projectKey', evt.target.value)} - onBlur={() => onBlurConfig('projectKey')} - /> - - - - - - - - onChangeSecret('email', evt.target.value)} - onBlur={() => onBlurSecret('email')} - /> - - - - - - - - onChangeSecret('apiToken', evt.target.value)} - onBlur={() => onBlurSecret('apiToken')} - /> - - - - - ); -}; - -export const JiraConnectorFlyout = withConnectorFlyout({ - ConnectorFormComponent: JiraConnectorForm, - secretKeys: ['email', 'apiToken'], - configKeys: ['projectKey'], - connectorActionTypeId: '.jira', -}); - -// eslint-disable-next-line import/no-default-export -export { JiraConnectorFlyout as default }; diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/index.tsx b/x-pack/plugins/security_solution/public/common/lib/connectors/jira/index.tsx deleted file mode 100644 index cead392010dc7..0000000000000 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/index.tsx +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 { lazy } from 'react'; -import { - ValidationResult, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../triggers_actions_ui/public/types'; - -import { connector } from './config'; -import { createActionType } from '../utils'; -import logo from './logo.svg'; -import { JiraActionConnector } from './types'; -import * as i18n from './translations'; - -interface Errors { - projectKey: string[]; - email: string[]; - apiToken: string[]; -} - -const validateConnector = (action: JiraActionConnector): ValidationResult => { - const errors: Errors = { - projectKey: [], - email: [], - apiToken: [], - }; - - if (!action.config.projectKey) { - errors.projectKey = [...errors.projectKey, i18n.JIRA_PROJECT_KEY_REQUIRED]; - } - - if (!action.secrets.email) { - errors.email = [...errors.email, i18n.JIRA_EMAIL_REQUIRED]; - } - - if (!action.secrets.apiToken) { - errors.apiToken = [...errors.apiToken, i18n.JIRA_API_TOKEN_REQUIRED]; - } - - return { errors }; -}; - -export const getActionType = createActionType({ - id: connector.id, - iconClass: logo, - selectMessage: i18n.JIRA_DESC, - actionTypeTitle: connector.name, - validateConnector, - actionConnectorFields: lazy(() => import('./flyout')), -}); diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/translations.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/jira/translations.ts deleted file mode 100644 index d7abf77a58d4c..0000000000000 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/translations.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 { i18n } from '@kbn/i18n'; - -export * from '../translations'; - -export const JIRA_DESC = i18n.translate( - 'xpack.securitySolution.case.connectors.jira.selectMessageText', - { - defaultMessage: 'Push or update Security case data to a new issue in Jira', - } -); - -export const JIRA_TITLE = i18n.translate( - 'xpack.securitySolution.case.connectors.jira.actionTypeTitle', - { - defaultMessage: 'Jira', - } -); - -export const JIRA_PROJECT_KEY_LABEL = i18n.translate( - 'xpack.securitySolution.case.connectors.jira.projectKey', - { - defaultMessage: 'Project key', - } -); - -export const JIRA_PROJECT_KEY_REQUIRED = i18n.translate( - 'xpack.securitySolution.case.connectors.jira.requiredProjectKeyTextField', - { - defaultMessage: 'Project key is required', - } -); - -export const JIRA_EMAIL_LABEL = i18n.translate( - 'xpack.securitySolution.case.connectors.jira.emailTextFieldLabel', - { - defaultMessage: 'Email or Username', - } -); - -export const JIRA_EMAIL_REQUIRED = i18n.translate( - 'xpack.securitySolution.case.connectors.jira.requiredEmailTextField', - { - defaultMessage: 'Email or Username is required', - } -); - -export const JIRA_API_TOKEN_LABEL = i18n.translate( - 'xpack.securitySolution.case.connectors.jira.apiTokenTextFieldLabel', - { - defaultMessage: 'API token or Password', - } -); - -export const JIRA_API_TOKEN_REQUIRED = i18n.translate( - 'xpack.securitySolution.case.connectors.jira.requiredApiTokenTextField', - { - defaultMessage: 'API token or Password is required', - } -); - -export const MAPPING_FIELD_SUMMARY = i18n.translate( - 'xpack.securitySolution.case.configureCases.mappingFieldSummary', - { - defaultMessage: 'Summary', - } -); diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/types.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/jira/types.ts deleted file mode 100644 index fafb4a0d41fb3..0000000000000 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/types.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - */ - -/* eslint-disable no-restricted-imports */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ - -import { - JiraPublicConfigurationType, - JiraSecretConfigurationType, -} from '../../../../../../actions/server/builtin_action_types/jira/types'; - -export { JiraFieldsType } from '../../../../../../case/common/api/connectors'; - -export * from '../types'; - -export interface JiraActionConnector { - config: JiraPublicConfigurationType; - secrets: JiraSecretConfigurationType; -} diff --git a/x-pack/plugins/security_solution/public/common/mock/global_state.ts b/x-pack/plugins/security_solution/public/common/mock/global_state.ts index 2849e8ffabd36..a74c9a6d2009d 100644 --- a/x-pack/plugins/security_solution/public/common/mock/global_state.ts +++ b/x-pack/plugins/security_solution/public/common/mock/global_state.ts @@ -11,9 +11,9 @@ import { HostsFields, NetworkDnsFields, NetworkTopTablesFields, - TlsFields, - UsersFields, -} from '../../graphql/types'; + NetworkTlsFields, + NetworkUsersFields, +} from '../../../common/search_strategy'; import { State } from '../store'; import { defaultHeaders } from './header'; @@ -100,7 +100,7 @@ export const mockGlobalState: State = { [networkModel.NetworkTableType.tls]: { activePage: 0, limit: 10, - sort: { field: TlsFields._id, direction: Direction.desc }, + sort: { field: NetworkTlsFields._id, direction: Direction.desc }, }, [networkModel.NetworkTableType.http]: { activePage: 0, @@ -116,37 +116,37 @@ export const mockGlobalState: State = { details: { flowTarget: FlowTarget.source, queries: { - [networkModel.IpDetailsTableType.topCountriesDestination]: { + [networkModel.NetworkDetailsTableType.topCountriesDestination]: { activePage: 0, limit: 10, sort: { field: NetworkTopTablesFields.bytes_out, direction: Direction.desc }, }, - [networkModel.IpDetailsTableType.topCountriesSource]: { + [networkModel.NetworkDetailsTableType.topCountriesSource]: { activePage: 0, limit: 10, sort: { field: NetworkTopTablesFields.bytes_out, direction: Direction.desc }, }, - [networkModel.IpDetailsTableType.topNFlowSource]: { + [networkModel.NetworkDetailsTableType.topNFlowSource]: { activePage: 0, limit: 10, sort: { field: NetworkTopTablesFields.bytes_out, direction: Direction.desc }, }, - [networkModel.IpDetailsTableType.topNFlowDestination]: { + [networkModel.NetworkDetailsTableType.topNFlowDestination]: { activePage: 0, limit: 10, sort: { field: NetworkTopTablesFields.bytes_out, direction: Direction.desc }, }, - [networkModel.IpDetailsTableType.tls]: { + [networkModel.NetworkDetailsTableType.tls]: { activePage: 0, limit: 10, - sort: { field: TlsFields._id, direction: Direction.desc }, + sort: { field: NetworkTlsFields._id, direction: Direction.desc }, }, - [networkModel.IpDetailsTableType.users]: { + [networkModel.NetworkDetailsTableType.users]: { activePage: 0, limit: 10, - sort: { field: UsersFields.name, direction: Direction.asc }, + sort: { field: NetworkUsersFields.name, direction: Direction.asc }, }, - [networkModel.IpDetailsTableType.http]: { + [networkModel.NetworkDetailsTableType.http]: { activePage: 0, limit: 10, sort: { direction: Direction.desc }, diff --git a/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx b/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx index c7810af13eb74..5a4eaad72ac32 100644 --- a/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx @@ -95,6 +95,7 @@ export const useFormFieldMock = (options?: Partial): FieldHook => { clearErrors: jest.fn(), validate: jest.fn(), reset: jest.fn(), + __isIncludedInOutput: true, __serializeValue: jest.fn(), ...options, }; diff --git a/x-pack/plugins/security_solution/public/common/store/actions.ts b/x-pack/plugins/security_solution/public/common/store/actions.ts index cd8836e38bfef..6b446ab6692d9 100644 --- a/x-pack/plugins/security_solution/public/common/store/actions.ts +++ b/x-pack/plugins/security_solution/public/common/store/actions.ts @@ -7,10 +7,16 @@ import { EndpointAction } from '../../management/pages/endpoint_hosts/store/action'; import { PolicyListAction } from '../../management/pages/policy/store/policy_list'; import { PolicyDetailsAction } from '../../management/pages/policy/store/policy_details'; +import { TrustedAppsPageAction } from '../../management/pages/trusted_apps/store/action'; export { appActions } from './app'; export { dragAndDropActions } from './drag_and_drop'; export { inputsActions } from './inputs'; import { RoutingAction } from './routing'; -export type AppAction = EndpointAction | RoutingAction | PolicyListAction | PolicyDetailsAction; +export type AppAction = + | EndpointAction + | RoutingAction + | PolicyListAction + | PolicyDetailsAction + | TrustedAppsPageAction; diff --git a/x-pack/plugins/security_solution/public/common/store/routing/action.ts b/x-pack/plugins/security_solution/public/common/store/routing/action.ts index ae5e4eb32d476..d0cc38970ca21 100644 --- a/x-pack/plugins/security_solution/public/common/store/routing/action.ts +++ b/x-pack/plugins/security_solution/public/common/store/routing/action.ts @@ -6,7 +6,7 @@ import { AppLocation, Immutable } from '../../../../common/endpoint/types'; -interface UserChangedUrl { +export interface UserChangedUrl { readonly type: 'userChangedUrl'; readonly payload: Immutable; } diff --git a/x-pack/plugins/security_solution/public/helpers.test.ts b/x-pack/plugins/security_solution/public/helpers.test.ts new file mode 100644 index 0000000000000..9244452a23e6d --- /dev/null +++ b/x-pack/plugins/security_solution/public/helpers.test.ts @@ -0,0 +1,55 @@ +/* + * 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 { parseRoute } from './helpers'; + +describe('public helpers parseRoute', () => { + it('should properly parse hash route', () => { + const hashSearch = + '?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))'; + const hashLocation = { + hash: `#/detections/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${hashSearch}`, + pathname: '/app/siem', + search: '', + }; + + expect(parseRoute(hashLocation)).toEqual({ + pageName: 'detections', + path: `/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${hashSearch}`, + search: hashSearch, + }); + }); + + it('should properly parse non-hash route', () => { + const nonHashLocation = { + hash: '', + pathname: '/app/security/detections/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit', + search: + '?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))', + }; + + expect(parseRoute(nonHashLocation)).toEqual({ + pageName: 'detections', + path: `/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${nonHashLocation.search}`, + search: nonHashLocation.search, + }); + }); + + it('should properly parse non-hash subplugin route', () => { + const nonHashLocation = { + hash: '', + pathname: '/app/security/detections', + search: + '?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))', + }; + + expect(parseRoute(nonHashLocation)).toEqual({ + pageName: 'detections', + path: `${nonHashLocation.search}`, + search: nonHashLocation.search, + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/helpers.ts b/x-pack/plugins/security_solution/public/helpers.ts index 63c3f3ea81d98..92f3d23907559 100644 --- a/x-pack/plugins/security_solution/public/helpers.ts +++ b/x-pack/plugins/security_solution/public/helpers.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { isEmpty } from 'lodash/fp'; + import { CoreStart } from '../../../../src/core/public'; import { APP_ID } from '../common/constants'; import { @@ -13,13 +15,37 @@ import { import { SecurityPageName } from './app/types'; import { InspectResponse } from './types'; +export const parseRoute = (location: Pick) => { + if (!isEmpty(location.hash)) { + const hashPath = location.hash.split('?'); + const search = hashPath.length >= 1 ? `?${hashPath[1]}` : ''; + const pageRoute = hashPath.length > 0 ? hashPath[0].split('/') : []; + const pageName = pageRoute.length >= 1 ? pageRoute[1] : ''; + const path = `/${pageRoute.slice(2).join('/') ?? ''}${search}`; + + return { + pageName, + path, + search, + }; + } + + const search = location.search; + const pageRoute = location.pathname.split('/'); + const pageName = pageRoute[3]; + const subpluginPath = pageRoute.length > 4 ? `/${pageRoute.slice(4).join('/')}` : ''; + const path = `${subpluginPath}${search}`; + + return { + pageName, + path, + search, + }; +}; + export const manageOldSiemRoutes = async (coreStart: CoreStart) => { const { application } = coreStart; - const hashPath = window.location.hash.split('?'); - const search = hashPath.length >= 1 ? hashPath[1] : ''; - const pageRoute = hashPath.length > 0 ? hashPath[0].split('/') : []; - const pageName = pageRoute.length >= 1 ? pageRoute[1] : ''; - const path = `/${pageRoute.slice(2).join('/') ?? ''}?${search}`; + const { pageName, path, search } = parseRoute(window.location); switch (pageName) { case SecurityPageName.overview: @@ -73,7 +99,7 @@ export const manageOldSiemRoutes = async (coreStart: CoreStart) => { default: application.navigateToApp(`${APP_ID}:${SecurityPageName.overview}`, { replace: true, - path: `?${search}`, + path: `${search}`, }); break; } diff --git a/x-pack/plugins/security_solution/public/hosts/components/authentications_table/index.tsx b/x-pack/plugins/security_solution/public/hosts/components/authentications_table/index.tsx index 8e2b47769adf3..3d291d9bf7b28 100644 --- a/x-pack/plugins/security_solution/public/hosts/components/authentications_table/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/components/authentications_table/index.tsx @@ -20,7 +20,7 @@ import { import { escapeDataProviderId } from '../../../common/components/drag_and_drop/helpers'; import { getEmptyTagValue } from '../../../common/components/empty_value'; import { FormattedRelativePreferenceDate } from '../../../common/components/formatted_date'; -import { HostDetailsLink, IPDetailsLink } from '../../../common/components/links'; +import { HostDetailsLink, NetworkDetailsLink } from '../../../common/components/links'; import { Columns, ItemsPerRow, PaginatedTable } from '../../../common/components/paginated_table'; import { IS_OPERATOR } from '../../../timelines/components/timeline/data_providers/data_provider'; import { Provider } from '../../../timelines/components/timeline/data_providers/provider'; @@ -264,7 +264,7 @@ const getAuthenticationColumns = (): AuthTableColumns => [ : null, attrName: 'source.ip', idPrefix: `authentications-table-${node._id}-lastSuccessSource`, - render: (item) => , + render: (item) => , }), }, { @@ -309,7 +309,7 @@ const getAuthenticationColumns = (): AuthTableColumns => [ : null, attrName: 'source.ip', idPrefix: `authentications-table-${node._id}-lastFailureSource`, - render: (item) => , + render: (item) => , }), }, { diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx index 49b63a5f76a14..d8cd59f119d52 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx @@ -9,6 +9,7 @@ import { noop } from 'lodash/fp'; import React, { useEffect, useCallback, useMemo } from 'react'; import { connect, ConnectedProps } from 'react-redux'; +import { HostItem } from '../../../../common/search_strategy'; import { SecurityPageName } from '../../../app/types'; import { UpdateDateRange } from '../../../common/components/charts/common'; import { FiltersGlobal } from '../../../common/components/filters_global'; @@ -137,7 +138,7 @@ const HostDetailsComponent = React.memo( inspect={inspect} refetch={refetch} setQuery={setQuery} - data={hostOverview} + data={hostOverview as HostItem} anomaliesData={anomaliesData} isLoadingAnomaliesData={isLoadingAnomaliesData} loading={loading} diff --git a/x-pack/plugins/security_solution/public/management/common/constants.ts b/x-pack/plugins/security_solution/public/management/common/constants.ts index 06f0f09bcf54d..cd4ce743bb701 100644 --- a/x-pack/plugins/security_solution/public/management/common/constants.ts +++ b/x-pack/plugins/security_solution/public/management/common/constants.ts @@ -24,6 +24,12 @@ export const MANAGEMENT_STORE_POLICY_LIST_NAMESPACE = 'policyList'; export const MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE = 'policyDetails'; /** Namespace within the Management state where endpoint-host state is maintained */ export const MANAGEMENT_STORE_ENDPOINTS_NAMESPACE = 'endpoints'; +/** Namespace within the Management state where trusted apps page state is maintained */ +export const MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE = 'trustedApps'; + +export const MANAGEMENT_PAGE_SIZE_OPTIONS: readonly number[] = [10, 20, 50]; +export const MANAGEMENT_DEFAULT_PAGE = 0; +export const MANAGEMENT_DEFAULT_PAGE_SIZE = 10; // --[ DEFAULTS ]--------------------------------------------------------------------------- /** The default polling interval to start all polling pages */ diff --git a/x-pack/plugins/security_solution/public/management/common/routing.test.ts b/x-pack/plugins/security_solution/public/management/common/routing.test.ts new file mode 100644 index 0000000000000..7a36654dcffc3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/common/routing.test.ts @@ -0,0 +1,111 @@ +/* + * 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 { extractListPaginationParams, getTrustedAppsListPath } from './routing'; +import { MANAGEMENT_DEFAULT_PAGE, MANAGEMENT_DEFAULT_PAGE_SIZE } from './constants'; + +describe('routing', () => { + describe('extractListPaginationParams()', () => { + it('extracts default page index when not provided', () => { + expect(extractListPaginationParams({}).page_index).toBe(MANAGEMENT_DEFAULT_PAGE); + }); + + it('extracts default page index when too small value provided', () => { + expect(extractListPaginationParams({ page_index: '-1' }).page_index).toBe( + MANAGEMENT_DEFAULT_PAGE + ); + }); + + it('extracts default page index when not a number provided', () => { + expect(extractListPaginationParams({ page_index: 'a' }).page_index).toBe( + MANAGEMENT_DEFAULT_PAGE + ); + }); + + it('extracts only last page index when multiple values provided', () => { + expect(extractListPaginationParams({ page_index: ['1', '2'] }).page_index).toBe(2); + }); + + it('extracts proper page index when single valid value provided', () => { + expect(extractListPaginationParams({ page_index: '2' }).page_index).toBe(2); + }); + + it('extracts default page size when not provided', () => { + expect(extractListPaginationParams({}).page_size).toBe(MANAGEMENT_DEFAULT_PAGE_SIZE); + }); + + it('extracts default page size when invalid option provided', () => { + expect(extractListPaginationParams({ page_size: '25' }).page_size).toBe( + MANAGEMENT_DEFAULT_PAGE_SIZE + ); + }); + + it('extracts default page size when not a number provided', () => { + expect(extractListPaginationParams({ page_size: 'a' }).page_size).toBe( + MANAGEMENT_DEFAULT_PAGE_SIZE + ); + }); + + it('extracts only last page size when multiple values provided', () => { + expect(extractListPaginationParams({ page_size: ['10', '20'] }).page_size).toBe(20); + }); + + it('extracts proper page size when single valid value provided', () => { + expect(extractListPaginationParams({ page_size: '20' }).page_size).toBe(20); + }); + }); + + describe('getTrustedAppsListPath()', () => { + it('builds proper path when no parameters provided', () => { + expect(getTrustedAppsListPath()).toEqual('/trusted_apps'); + }); + + it('builds proper path when empty parameters provided', () => { + expect(getTrustedAppsListPath({})).toEqual('/trusted_apps'); + }); + + it('builds proper path when no page index provided', () => { + expect(getTrustedAppsListPath({ page_size: 20 })).toEqual('/trusted_apps?page_size=20'); + }); + + it('builds proper path when no page size provided', () => { + expect(getTrustedAppsListPath({ page_index: 2 })).toEqual('/trusted_apps?page_index=2'); + }); + + it('builds proper path when both page index and size provided', () => { + expect(getTrustedAppsListPath({ page_index: 2, page_size: 20 })).toEqual( + '/trusted_apps?page_index=2&page_size=20' + ); + }); + + it('builds proper path when page index is equal to default', () => { + const path = getTrustedAppsListPath({ + page_index: MANAGEMENT_DEFAULT_PAGE, + page_size: 20, + }); + + expect(path).toEqual('/trusted_apps?page_size=20'); + }); + + it('builds proper path when page size is equal to default', () => { + const path = getTrustedAppsListPath({ + page_index: 2, + page_size: MANAGEMENT_DEFAULT_PAGE_SIZE, + }); + + expect(path).toEqual('/trusted_apps?page_index=2'); + }); + + it('builds proper path when both page index and size are equal to default', () => { + const path = getTrustedAppsListPath({ + page_index: MANAGEMENT_DEFAULT_PAGE, + page_size: MANAGEMENT_DEFAULT_PAGE_SIZE, + }); + + expect(path).toEqual('/trusted_apps'); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/common/routing.ts b/x-pack/plugins/security_solution/public/management/common/routing.ts index c5ced6f3bcf55..62f360df90192 100644 --- a/x-pack/plugins/security_solution/public/management/common/routing.ts +++ b/x-pack/plugins/security_solution/public/management/common/routing.ts @@ -10,6 +10,9 @@ import { generatePath } from 'react-router-dom'; import querystring from 'querystring'; import { + MANAGEMENT_DEFAULT_PAGE, + MANAGEMENT_DEFAULT_PAGE_SIZE, + MANAGEMENT_PAGE_SIZE_OPTIONS, MANAGEMENT_ROUTING_ENDPOINTS_PATH, MANAGEMENT_ROUTING_POLICIES_PATH, MANAGEMENT_ROUTING_POLICY_DETAILS_PATH, @@ -86,8 +89,61 @@ export const getPolicyDetailPath = (policyId: string, search?: string) => { })}${appendSearch(search)}`; }; -export const getTrustedAppsListPath = (search?: string) => { - return `${generatePath(MANAGEMENT_ROUTING_TRUSTED_APPS_PATH, { +interface ListPaginationParams { + page_index: number; + page_size: number; +} + +const isDefaultOrMissing = (value: number | undefined, defaultValue: number) => { + return value === undefined || value === defaultValue; +}; + +const normalizeListPaginationParams = ( + params?: Partial +): Partial => { + if (params) { + return { + ...(!isDefaultOrMissing(params.page_index, MANAGEMENT_DEFAULT_PAGE) + ? { page_index: params.page_index } + : {}), + ...(!isDefaultOrMissing(params.page_size, MANAGEMENT_DEFAULT_PAGE_SIZE) + ? { page_size: params.page_size } + : {}), + }; + } else { + return {}; + } +}; + +const extractFirstParamValue = (query: querystring.ParsedUrlQuery, key: string): string => { + const value = query[key]; + + return Array.isArray(value) ? value[value.length - 1] : value; +}; + +const extractPageIndex = (query: querystring.ParsedUrlQuery): number => { + const pageIndex = Number(extractFirstParamValue(query, 'page_index')); + + return !Number.isFinite(pageIndex) || pageIndex < 0 ? MANAGEMENT_DEFAULT_PAGE : pageIndex; +}; + +const extractPageSize = (query: querystring.ParsedUrlQuery): number => { + const pageSize = Number(extractFirstParamValue(query, 'page_size')); + + return MANAGEMENT_PAGE_SIZE_OPTIONS.includes(pageSize) ? pageSize : MANAGEMENT_DEFAULT_PAGE_SIZE; +}; + +export const extractListPaginationParams = ( + query: querystring.ParsedUrlQuery +): ListPaginationParams => ({ + page_index: extractPageIndex(query), + page_size: extractPageSize(query), +}); + +export const getTrustedAppsListPath = (params?: Partial): string => { + const path = generatePath(MANAGEMENT_ROUTING_TRUSTED_APPS_PATH, { tabName: AdministrationSubTab.trustedApps, - })}${appendSearch(search)}`; + }); + + return `${path}${appendSearch(querystring.stringify(normalizeListPaginationParams(params)))}`; }; diff --git a/x-pack/plugins/security_solution/public/management/index.ts b/x-pack/plugins/security_solution/public/management/index.ts index 902ed085bd369..4bd9ac495ada9 100644 --- a/x-pack/plugins/security_solution/public/management/index.ts +++ b/x-pack/plugins/security_solution/public/management/index.ts @@ -47,9 +47,7 @@ export class Management { * Cast the ImmutableReducer to a regular reducer for compatibility with * the subplugin architecture (which expects plain redux reducers.) */ - reducer: { - management: managementReducer, - } as ManagementPluginReducer, + reducer: { management: managementReducer } as ManagementPluginReducer, middleware: managementMiddlewareFactory(core, plugins), }, }; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts index 68ba71b7bbc94..e8abe37cf0a88 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/selectors.ts @@ -15,9 +15,12 @@ import { HostPolicyResponseActionStatus, } from '../../../../../common/endpoint/types'; import { EndpointState, EndpointIndexUIQueryParams } from '../types'; -import { MANAGEMENT_ROUTING_ENDPOINTS_PATH } from '../../../common/constants'; - -const PAGE_SIZES = Object.freeze([10, 20, 50]); +import { extractListPaginationParams } from '../../../common/routing'; +import { + MANAGEMENT_DEFAULT_PAGE, + MANAGEMENT_DEFAULT_PAGE_SIZE, + MANAGEMENT_ROUTING_ENDPOINTS_PATH, +} from '../../../common/constants'; export const listData = (state: Immutable) => state.hosts; @@ -129,17 +132,17 @@ export const uiQueryParams: ( ) => Immutable = createSelector( (state: Immutable) => state.location, (location: Immutable['location']) => { - const data: EndpointIndexUIQueryParams = { page_index: '0', page_size: '10' }; + const data: EndpointIndexUIQueryParams = { + page_index: String(MANAGEMENT_DEFAULT_PAGE), + page_size: String(MANAGEMENT_DEFAULT_PAGE_SIZE), + }; + if (location) { // Removes the `?` from the beginning of query string if it exists const query = querystring.parse(location.search.slice(1)); + const paginationParams = extractListPaginationParams(query); - const keys: Array = [ - 'selected_endpoint', - 'page_size', - 'page_index', - 'show', - ]; + const keys: Array = ['selected_endpoint', 'show']; for (const key of keys) { const value: string | undefined = @@ -160,17 +163,10 @@ export const uiQueryParams: ( } } - // Check if page size is an expected size, otherwise default to 10 - if (!PAGE_SIZES.includes(Number(data.page_size))) { - data.page_size = '10'; - } - - // Check if page index is a valid positive integer, otherwise default to 0 - const pageIndexAsNumber = Number(data.page_index); - if (!Number.isFinite(pageIndexAsNumber) || pageIndexAsNumber < 0) { - data.page_index = '0'; - } + data.page_size = String(paginationParams.page_size); + data.page_index = String(paginationParams.page_index); } + return data; } ); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx index 8d08ac4e59a87..a569c4f02604b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx @@ -33,7 +33,7 @@ import { import { useNavigateByRouterEventHandler } from '../../../../common/hooks/endpoint/use_navigate_by_router_event_handler'; import { CreateStructuredSelector } from '../../../../common/store'; import { Immutable, HostInfo } from '../../../../../common/endpoint/types'; -import { DEFAULT_POLL_INTERVAL } from '../../../common/constants'; +import { DEFAULT_POLL_INTERVAL, MANAGEMENT_PAGE_SIZE_OPTIONS } from '../../../common/constants'; import { PolicyEmptyState, HostsEmptyState } from '../../../components/management_empty_state'; import { FormattedDate } from '../../../../common/components/formatted_date'; import { useNavigateToAppEventHandler } from '../../../../common/hooks/endpoint/use_navigate_to_app_event_handler'; @@ -99,7 +99,7 @@ export const EndpointList = () => { pageIndex, pageSize, totalItemCount, - pageSizeOptions: [10, 20, 50], + pageSizeOptions: [...MANAGEMENT_PAGE_SIZE_OPTIONS], hidePerPageOptions: false, }; }, [pageIndex, pageSize, totalItemCount]); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts new file mode 100644 index 0000000000000..9308c137cfb9c --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/service/index.ts @@ -0,0 +1,26 @@ +/* + * 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 { HttpStart } from 'kibana/public'; +import { TRUSTED_APPS_LIST_API } from '../../../../../common/endpoint/constants'; +import { + GetTrustedListAppsResponse, + GetTrustedAppsListRequest, +} from '../../../../../common/endpoint/types/trusted_apps'; + +export interface TrustedAppsService { + getTrustedAppsList(request: GetTrustedAppsListRequest): Promise; +} + +export class TrustedAppsHttpService implements TrustedAppsService { + constructor(private http: HttpStart) {} + + async getTrustedAppsList(request: GetTrustedAppsListRequest) { + return this.http.get(TRUSTED_APPS_LIST_API, { + query: request, + }); + } +} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/async_resource_state.test.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/async_resource_state.test.ts new file mode 100644 index 0000000000000..5e00d833981ed --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/async_resource_state.test.ts @@ -0,0 +1,242 @@ +/* + * 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 { + UninitialisedResourceState, + LoadingResourceState, + LoadedResourceState, + FailedResourceState, + isUninitialisedResourceState, + isLoadingResourceState, + isLoadedResourceState, + isFailedResourceState, + getLastLoadedResourceState, + getCurrentResourceError, + isOutdatedResourceState, +} from './async_resource_state'; + +interface TestData { + property: string; +} + +const data: TestData = { property: 'value' }; + +const uninitialisedResourceState: UninitialisedResourceState = { + type: 'UninitialisedResourceState', +}; + +const loadedResourceState: LoadedResourceState = { + type: 'LoadedResourceState', + data, +}; + +const failedResourceStateInitially: FailedResourceState = { + type: 'FailedResourceState', + error: {}, +}; + +const failedResourceStateSubsequently: FailedResourceState = { + type: 'FailedResourceState', + error: {}, + lastLoadedState: loadedResourceState, +}; + +const loadingResourceStateInitially: LoadingResourceState = { + type: 'LoadingResourceState', + previousState: uninitialisedResourceState, +}; + +const loadingResourceStateAfterSuccess: LoadingResourceState = { + type: 'LoadingResourceState', + previousState: loadedResourceState, +}; + +const loadingResourceStateAfterInitialFailure: LoadingResourceState = { + type: 'LoadingResourceState', + previousState: failedResourceStateInitially, +}; + +const loadingResourceStateAfterSubsequentFailure: LoadingResourceState = { + type: 'LoadingResourceState', + previousState: failedResourceStateSubsequently, +}; + +describe('AsyncResourceState', () => { + describe('guards', () => { + describe('isUninitialisedResourceState()', () => { + it('returns true for UninitialisedResourceState', () => { + expect(isUninitialisedResourceState(uninitialisedResourceState)).toBe(true); + }); + + it('returns false for LoadingResourceState', () => { + expect(isUninitialisedResourceState(loadingResourceStateInitially)).toBe(false); + }); + + it('returns false for LoadedResourceState', () => { + expect(isUninitialisedResourceState(loadedResourceState)).toBe(false); + }); + + it('returns false for FailedResourceState', () => { + expect(isUninitialisedResourceState(failedResourceStateInitially)).toBe(false); + }); + }); + + describe('isLoadingResourceState()', () => { + it('returns false for UninitialisedResourceState', () => { + expect(isLoadingResourceState(uninitialisedResourceState)).toBe(false); + }); + + it('returns true for LoadingResourceState', () => { + expect(isLoadingResourceState(loadingResourceStateInitially)).toBe(true); + }); + + it('returns false for LoadedResourceState', () => { + expect(isLoadingResourceState(loadedResourceState)).toBe(false); + }); + + it('returns false for FailedResourceState', () => { + expect(isLoadingResourceState(failedResourceStateInitially)).toBe(false); + }); + }); + + describe('isLoadedResourceState()', () => { + it('returns false for UninitialisedResourceState', () => { + expect(isLoadedResourceState(uninitialisedResourceState)).toBe(false); + }); + + it('returns false for LoadingResourceState', () => { + expect(isLoadedResourceState(loadingResourceStateInitially)).toBe(false); + }); + + it('returns true for LoadedResourceState', () => { + expect(isLoadedResourceState(loadedResourceState)).toBe(true); + }); + + it('returns false for FailedResourceState', () => { + expect(isLoadedResourceState(failedResourceStateInitially)).toBe(false); + }); + }); + + describe('isFailedResourceState()', () => { + it('returns false for UninitialisedResourceState', () => { + expect(isFailedResourceState(uninitialisedResourceState)).toBe(false); + }); + + it('returns false for LoadingResourceState', () => { + expect(isFailedResourceState(loadingResourceStateInitially)).toBe(false); + }); + + it('returns false for LoadedResourceState', () => { + expect(isFailedResourceState(loadedResourceState)).toBe(false); + }); + + it('returns true for FailedResourceState', () => { + expect(isFailedResourceState(failedResourceStateInitially)).toBe(true); + }); + }); + }); + + describe('functions', () => { + describe('getLastLoadedResourceState()', () => { + it('returns undefined for UninitialisedResourceState', () => { + expect(getLastLoadedResourceState(uninitialisedResourceState)).toBeUndefined(); + }); + + it('returns current state for LoadedResourceState', () => { + expect(getLastLoadedResourceState(loadedResourceState)).toBe(loadedResourceState); + }); + + it('returns undefined for initial FailedResourceState', () => { + expect(getLastLoadedResourceState(failedResourceStateInitially)).toBeUndefined(); + }); + + it('returns last loaded state for subsequent FailedResourceState', () => { + expect(getLastLoadedResourceState(failedResourceStateSubsequently)).toBe( + loadedResourceState + ); + }); + + it('returns undefined for initial LoadingResourceState', () => { + expect(getLastLoadedResourceState(loadingResourceStateInitially)).toBeUndefined(); + }); + + it('returns previous state for LoadingResourceState after success', () => { + expect(getLastLoadedResourceState(loadingResourceStateAfterSuccess)).toBe( + loadedResourceState + ); + }); + + it('returns undefined for LoadingResourceState after initial failure', () => { + expect(getLastLoadedResourceState(loadingResourceStateAfterInitialFailure)).toBeUndefined(); + }); + + it('returns previous state for LoadingResourceState after subsequent failure', () => { + expect(getLastLoadedResourceState(loadingResourceStateAfterSubsequentFailure)).toBe( + loadedResourceState + ); + }); + }); + + describe('getCurrentResourceError()', () => { + it('returns undefined for UninitialisedResourceState', () => { + expect(getCurrentResourceError(uninitialisedResourceState)).toBeUndefined(); + }); + + it('returns undefined for LoadedResourceState', () => { + expect(getCurrentResourceError(loadedResourceState)).toBeUndefined(); + }); + + it('returns error for FailedResourceState', () => { + expect(getCurrentResourceError(failedResourceStateSubsequently)).toStrictEqual({}); + }); + + it('returns undefined for LoadingResourceState', () => { + expect(getCurrentResourceError(loadingResourceStateAfterSubsequentFailure)).toBeUndefined(); + }); + }); + + describe('isOutdatedResourceState()', () => { + const trueFreshnessTest = (testData: TestData) => true; + const falseFreshnessTest = (testData: TestData) => false; + + it('returns true for UninitialisedResourceState', () => { + expect(isOutdatedResourceState(uninitialisedResourceState, falseFreshnessTest)).toBe(true); + }); + + it('returns false for LoadingResourceState', () => { + expect(isOutdatedResourceState(loadingResourceStateAfterSuccess, falseFreshnessTest)).toBe( + false + ); + }); + + it('returns false for LoadedResourceState and fresh data', () => { + expect(isOutdatedResourceState(loadedResourceState, trueFreshnessTest)).toBe(false); + }); + + it('returns true for LoadedResourceState and outdated data', () => { + expect(isOutdatedResourceState(loadedResourceState, falseFreshnessTest)).toBe(true); + }); + + it('returns true for initial FailedResourceState', () => { + expect(isOutdatedResourceState(failedResourceStateInitially, falseFreshnessTest)).toBe( + true + ); + }); + + it('returns false for subsequent FailedResourceState and fresh data', () => { + expect(isOutdatedResourceState(failedResourceStateSubsequently, trueFreshnessTest)).toBe( + false + ); + }); + + it('returns true for subsequent FailedResourceState and outdated data', () => { + expect(isOutdatedResourceState(failedResourceStateSubsequently, falseFreshnessTest)).toBe( + true + ); + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/async_resource_state.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/async_resource_state.ts new file mode 100644 index 0000000000000..4639a50a61865 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/async_resource_state.ts @@ -0,0 +1,138 @@ +/* + * 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. + */ + +/* + * this file contains set of types to represent state of asynchronous resource. + * Resource is defined as a reference to potential data that is loaded/updated + * using asynchronous communication with data source (for example through REST API call). + * Asynchronous update implies that next to just having data: + * - there is moment in time when data is not loaded/initialised and not in process of loading/updating + * - process performing data update can take considerable time which needs to be communicated to user + * - update can fail due to multiple reasons and also needs to be communicated to the user + */ + +import { Immutable } from '../../../../../common/endpoint/types'; +import { ServerApiError } from '../../../../common/types'; + +/** + * Data type to represent uninitialised state of asynchronous resource. + * This state indicates that no actions to load the data has be taken. + */ +export interface UninitialisedResourceState { + type: 'UninitialisedResourceState'; +} + +/** + * Data type to represent loading state of asynchronous resource. Loading state + * should be used to indicate that data is in the process of loading/updating. + * It contains reference to previous stale state that can be used to present + * previous state of resource to the user (like show previous already loaded + * data or show previous failure). + * + * @param Data - type of the data that is referenced by resource state + * @param Error - type of the error that can happen during attempt to update data + */ +export interface LoadingResourceState { + type: 'LoadingResourceState'; + previousState: StaleResourceState; +} + +/** + * Data type to represent loaded state of asynchronous resource. Loaded state + * is characterised with reference to the loaded data. + * + * @param Data - type of the data that is referenced by resource state + */ +export interface LoadedResourceState { + type: 'LoadedResourceState'; + data: Data; +} + +/** + * Data type to represent failed state of asynchronous resource. Failed state + * is characterised with error and can reference last loaded state. Reference + * to last loaded state can be used to present previous successfully loaded data. + * + * @param Data - type of the data that is referenced by resource state + * @param Error - type of the error that can happen during attempt to update data + */ +export interface FailedResourceState { + type: 'FailedResourceState'; + error: Error; + lastLoadedState?: LoadedResourceState; +} + +/** + * Data type to represent stale (not loading) state of asynchronous resource. + * + * @param Data - type of the data that is referenced by resource state + * @param Error - type of the error that can happen during attempt to update data + */ +export type StaleResourceState = + | UninitialisedResourceState + | LoadedResourceState + | FailedResourceState; + +/** + * Data type to represent any state of asynchronous resource. + * + * @param Data - type of the data that is referenced by resource state + * @param Error - type of the error that can happen during attempt to update data + */ +export type AsyncResourceState = + | UninitialisedResourceState + | LoadingResourceState + | LoadedResourceState + | FailedResourceState; + +// Set of guards to narrow the type of AsyncResourceState that make further refactoring easier + +export const isUninitialisedResourceState = ( + state: Immutable> +): state is Immutable => state.type === 'UninitialisedResourceState'; + +export const isLoadingResourceState = ( + state: Immutable> +): state is Immutable> => state.type === 'LoadingResourceState'; + +export const isLoadedResourceState = ( + state: Immutable> +): state is Immutable> => state.type === 'LoadedResourceState'; + +export const isFailedResourceState = ( + state: Immutable> +): state is Immutable> => state.type === 'FailedResourceState'; + +// Set of functions to work with AsyncResourceState + +export const getLastLoadedResourceState = ( + state: Immutable> +): Immutable> | undefined => { + if (isLoadedResourceState(state)) { + return state; + } else if (isLoadingResourceState(state)) { + return getLastLoadedResourceState(state.previousState); + } else if (isFailedResourceState(state)) { + return state.lastLoadedState; + } else { + return undefined; + } +}; + +export const getCurrentResourceError = ( + state: Immutable> +): Immutable | undefined => { + return isFailedResourceState(state) ? state.error : undefined; +}; + +export const isOutdatedResourceState = ( + state: AsyncResourceState, + isFresh: (data: Data) => boolean +): boolean => + isUninitialisedResourceState(state) || + (isLoadedResourceState(state) && !isFresh(state.data)) || + (isFailedResourceState(state) && + (!state.lastLoadedState || !isFresh(state.lastLoadedState.data))); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/index.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/index.ts new file mode 100644 index 0000000000000..99bdac57da4be --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/index.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './async_resource_state'; +export * from './trusted_apps_list_page_state'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/trusted_apps_list_page_state.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/trusted_apps_list_page_state.ts new file mode 100644 index 0000000000000..23f4cfd576c56 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/state/trusted_apps_list_page_state.ts @@ -0,0 +1,27 @@ +/* + * 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 { TrustedApp } from '../../../../../common/endpoint/types/trusted_apps'; +import { AsyncResourceState } from '.'; + +export interface PaginationInfo { + index: number; + size: number; +} + +export interface TrustedAppsListData { + items: TrustedApp[]; + totalItemsCount: number; + paginationInfo: PaginationInfo; +} + +export interface TrustedAppsListPageState { + listView: { + currentListResourceState: AsyncResourceState; + currentPaginationInfo: PaginationInfo; + }; + active: boolean; +} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/action.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/action.ts new file mode 100644 index 0000000000000..2154a0eca462e --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/action.ts @@ -0,0 +1,16 @@ +/* + * 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 { AsyncResourceState, TrustedAppsListData } from '../state'; + +export interface TrustedAppsListResourceStateChanged { + type: 'trustedAppsListResourceStateChanged'; + payload: { + newState: AsyncResourceState; + }; +} + +export type TrustedAppsPageAction = TrustedAppsListResourceStateChanged; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.test.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.test.ts new file mode 100644 index 0000000000000..c5abaae473486 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.test.ts @@ -0,0 +1,130 @@ +/* + * 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 { applyMiddleware, createStore } from 'redux'; + +import { createSpyMiddleware } from '../../../../common/store/test_utils'; + +import { + createFailedListViewWithPagination, + createLoadedListViewWithPagination, + createLoadingListViewWithPagination, + createSampleTrustedApps, + createServerApiError, + createUserChangedUrlAction, +} from '../test_utils'; + +import { TrustedAppsService } from '../service'; +import { PaginationInfo, TrustedAppsListPageState } from '../state'; +import { initialTrustedAppsPageState, trustedAppsPageReducer } from './reducer'; +import { createTrustedAppsPageMiddleware } from './middleware'; + +const createGetTrustedListAppsResponse = (pagination: PaginationInfo, totalItemsCount: number) => ({ + data: createSampleTrustedApps(pagination), + page: pagination.index, + per_page: pagination.size, + total: totalItemsCount, +}); + +const createTrustedAppsServiceMock = (): jest.Mocked => ({ + getTrustedAppsList: jest.fn(), +}); + +const createStoreSetup = (trustedAppsService: TrustedAppsService) => { + const spyMiddleware = createSpyMiddleware(); + + return { + spyMiddleware, + store: createStore( + trustedAppsPageReducer, + applyMiddleware( + createTrustedAppsPageMiddleware(trustedAppsService), + spyMiddleware.actionSpyMiddleware + ) + ), + }; +}; + +describe('middleware', () => { + describe('refreshing list resource state', () => { + it('sets initial state properly', async () => { + expect(createStoreSetup(createTrustedAppsServiceMock()).store.getState()).toStrictEqual( + initialTrustedAppsPageState + ); + }); + + it('refreshes the list when location changes and data gets outdated', async () => { + const pagination = { index: 2, size: 50 }; + const service = createTrustedAppsServiceMock(); + const { store, spyMiddleware } = createStoreSetup(service); + + service.getTrustedAppsList.mockResolvedValue( + createGetTrustedListAppsResponse(pagination, 500) + ); + + store.dispatch(createUserChangedUrlAction('/trusted_apps', '?page_index=2&page_size=50')); + + expect(store.getState()).toStrictEqual({ + listView: createLoadingListViewWithPagination(pagination), + active: true, + }); + + await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); + + expect(store.getState()).toStrictEqual({ + listView: createLoadedListViewWithPagination(pagination, pagination, 500), + active: true, + }); + }); + + it('does not refresh the list when location changes and data does not get outdated', async () => { + const pagination = { index: 2, size: 50 }; + const service = createTrustedAppsServiceMock(); + const { store, spyMiddleware } = createStoreSetup(service); + + service.getTrustedAppsList.mockResolvedValue( + createGetTrustedListAppsResponse(pagination, 500) + ); + + store.dispatch(createUserChangedUrlAction('/trusted_apps', '?page_index=2&page_size=50')); + + await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); + + store.dispatch(createUserChangedUrlAction('/trusted_apps', '?page_index=2&page_size=50')); + + expect(service.getTrustedAppsList).toBeCalledTimes(1); + expect(store.getState()).toStrictEqual({ + listView: createLoadedListViewWithPagination(pagination, pagination, 500), + active: true, + }); + }); + + it('set list resource state to faile when failing to load data', async () => { + const service = createTrustedAppsServiceMock(); + const { store, spyMiddleware } = createStoreSetup(service); + + service.getTrustedAppsList.mockRejectedValue(createServerApiError('Internal Server Error')); + + store.dispatch(createUserChangedUrlAction('/trusted_apps', '?page_index=2&page_size=50')); + + await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); + + expect(store.getState()).toStrictEqual({ + listView: createFailedListViewWithPagination( + { index: 2, size: 50 }, + createServerApiError('Internal Server Error') + ), + active: true, + }); + + const infiniteLoopTest = async () => { + await spyMiddleware.waitForAction('trustedAppsListResourceStateChanged'); + }; + + await expect(infiniteLoopTest).rejects.not.toBeNull(); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts new file mode 100644 index 0000000000000..31c301b8dbd2b --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/middleware.ts @@ -0,0 +1,99 @@ +/* + * 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 { Immutable } from '../../../../../common/endpoint/types'; +import { AppAction } from '../../../../common/store/actions'; +import { + ImmutableMiddleware, + ImmutableMiddlewareAPI, + ImmutableMiddlewareFactory, +} from '../../../../common/store'; + +import { TrustedAppsHttpService, TrustedAppsService } from '../service'; + +import { + AsyncResourceState, + StaleResourceState, + TrustedAppsListData, + TrustedAppsListPageState, +} from '../state'; + +import { TrustedAppsListResourceStateChanged } from './action'; + +import { + getCurrentListResourceState, + getLastLoadedListResourceState, + getListCurrentPageIndex, + getListCurrentPageSize, + needsRefreshOfListData, +} from './selectors'; + +const createTrustedAppsListResourceStateChangedAction = ( + newState: Immutable> +): Immutable => ({ + type: 'trustedAppsListResourceStateChanged', + payload: { newState }, +}); + +const refreshList = async ( + store: ImmutableMiddlewareAPI, + trustedAppsService: TrustedAppsService +) => { + store.dispatch( + createTrustedAppsListResourceStateChangedAction({ + type: 'LoadingResourceState', + // need to think on how to avoid the casting + previousState: getCurrentListResourceState(store.getState()) as Immutable< + StaleResourceState + >, + }) + ); + + try { + const pageIndex = getListCurrentPageIndex(store.getState()); + const pageSize = getListCurrentPageSize(store.getState()); + const response = await trustedAppsService.getTrustedAppsList({ + page: pageIndex + 1, + per_page: pageSize, + }); + + store.dispatch( + createTrustedAppsListResourceStateChangedAction({ + type: 'LoadedResourceState', + data: { + items: response.data, + totalItemsCount: response.total, + paginationInfo: { index: pageIndex, size: pageSize }, + }, + }) + ); + } catch (error) { + store.dispatch( + createTrustedAppsListResourceStateChangedAction({ + type: 'FailedResourceState', + error, + lastLoadedState: getLastLoadedListResourceState(store.getState()), + }) + ); + } +}; + +export const createTrustedAppsPageMiddleware = ( + trustedAppsService: TrustedAppsService +): ImmutableMiddleware => { + return (store) => (next) => async (action) => { + next(action); + + // TODO: need to think if failed state is a good condition to consider need for refresh + if (action.type === 'userChangedUrl' && needsRefreshOfListData(store.getState())) { + await refreshList(store, trustedAppsService); + } + }; +}; + +export const trustedAppsPageMiddlewareFactory: ImmutableMiddlewareFactory = ( + coreStart +) => createTrustedAppsPageMiddleware(new TrustedAppsHttpService(coreStart.http)); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.test.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.test.ts new file mode 100644 index 0000000000000..34325e0cf1398 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.test.ts @@ -0,0 +1,95 @@ +/* + * 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 { initialTrustedAppsPageState, trustedAppsPageReducer } from './reducer'; +import { + createListLoadedResourceState, + createLoadedListViewWithPagination, + createTrustedAppsListResourceStateChangedAction, + createUserChangedUrlAction, +} from '../test_utils'; + +describe('reducer', () => { + describe('UserChangedUrl', () => { + it('makes page state active and extracts pagination parameters', () => { + const result = trustedAppsPageReducer( + initialTrustedAppsPageState, + createUserChangedUrlAction('/trusted_apps', '?page_index=5&page_size=50') + ); + + expect(result).toStrictEqual({ + listView: { + ...initialTrustedAppsPageState.listView, + currentPaginationInfo: { index: 5, size: 50 }, + }, + active: true, + }); + }); + + it('extracts default pagination parameters when none provided', () => { + const result = trustedAppsPageReducer( + { + ...initialTrustedAppsPageState, + listView: { + ...initialTrustedAppsPageState.listView, + currentPaginationInfo: { index: 5, size: 50 }, + }, + }, + createUserChangedUrlAction('/trusted_apps', '?page_index=b&page_size=60') + ); + + expect(result).toStrictEqual({ + ...initialTrustedAppsPageState, + active: true, + }); + }); + + it('extracts default pagination parameters when invalid provided', () => { + const result = trustedAppsPageReducer( + { + ...initialTrustedAppsPageState, + listView: { + ...initialTrustedAppsPageState.listView, + currentPaginationInfo: { index: 5, size: 50 }, + }, + }, + createUserChangedUrlAction('/trusted_apps') + ); + + expect(result).toStrictEqual({ + ...initialTrustedAppsPageState, + active: true, + }); + }); + + it('makes page state inactive and resets list to uninitialised state when navigating away', () => { + const result = trustedAppsPageReducer( + { listView: createLoadedListViewWithPagination(), active: true }, + createUserChangedUrlAction('/endpoints') + ); + + expect(result).toStrictEqual(initialTrustedAppsPageState); + }); + }); + + describe('TrustedAppsListResourceStateChanged', () => { + it('sets the current list resource state', () => { + const listResourceState = createListLoadedResourceState({ index: 3, size: 50 }, 200); + const result = trustedAppsPageReducer( + initialTrustedAppsPageState, + createTrustedAppsListResourceStateChangedAction(listResourceState) + ); + + expect(result).toStrictEqual({ + ...initialTrustedAppsPageState, + listView: { + ...initialTrustedAppsPageState.listView, + currentListResourceState: listResourceState, + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.ts new file mode 100644 index 0000000000000..4fdc6f90ef40c --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/reducer.ts @@ -0,0 +1,96 @@ +/* + * 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. + */ + +// eslint-disable-next-line import/no-nodejs-modules +import { parse } from 'querystring'; +import { matchPath } from 'react-router-dom'; +import { ImmutableReducer } from '../../../../common/store'; +import { AppLocation, Immutable } from '../../../../../common/endpoint/types'; +import { UserChangedUrl } from '../../../../common/store/routing/action'; +import { AppAction } from '../../../../common/store/actions'; +import { extractListPaginationParams } from '../../../common/routing'; +import { + MANAGEMENT_ROUTING_TRUSTED_APPS_PATH, + MANAGEMENT_DEFAULT_PAGE, + MANAGEMENT_DEFAULT_PAGE_SIZE, +} from '../../../common/constants'; + +import { TrustedAppsListResourceStateChanged } from './action'; +import { TrustedAppsListPageState } from '../state'; + +type StateReducer = ImmutableReducer; +type CaseReducer = ( + state: Immutable, + action: Immutable +) => Immutable; + +const isTrustedAppsPageLocation = (location: Immutable) => { + return ( + matchPath(location.pathname ?? '', { + path: MANAGEMENT_ROUTING_TRUSTED_APPS_PATH, + exact: true, + }) !== null + ); +}; + +const trustedAppsListResourceStateChanged: CaseReducer = ( + state, + action +) => { + return { + ...state, + listView: { + ...state.listView, + currentListResourceState: action.payload.newState, + }, + }; +}; + +const userChangedUrl: CaseReducer = (state, action) => { + if (isTrustedAppsPageLocation(action.payload)) { + const paginationParams = extractListPaginationParams(parse(action.payload.search.slice(1))); + + return { + ...state, + listView: { + ...state.listView, + currentPaginationInfo: { + index: paginationParams.page_index, + size: paginationParams.page_size, + }, + }, + active: true, + }; + } else { + return initialTrustedAppsPageState; + } +}; + +export const initialTrustedAppsPageState: TrustedAppsListPageState = { + listView: { + currentListResourceState: { type: 'UninitialisedResourceState' }, + currentPaginationInfo: { + index: MANAGEMENT_DEFAULT_PAGE, + size: MANAGEMENT_DEFAULT_PAGE_SIZE, + }, + }, + active: false, +}; + +export const trustedAppsPageReducer: StateReducer = ( + state = initialTrustedAppsPageState, + action +) => { + switch (action.type) { + case 'trustedAppsListResourceStateChanged': + return trustedAppsListResourceStateChanged(state, action); + + case 'userChangedUrl': + return userChangedUrl(state, action); + } + + return state; +}; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.test.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.test.ts new file mode 100644 index 0000000000000..a969e2dee4773 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.test.ts @@ -0,0 +1,179 @@ +/* + * 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 { + getCurrentListResourceState, + getLastLoadedListResourceState, + getListCurrentPageIndex, + getListCurrentPageSize, + getListErrorMessage, + getListItems, + getListTotalItemsCount, + isListLoading, + needsRefreshOfListData, +} from './selectors'; + +import { + createDefaultListView, + createDefaultPaginationInfo, + createListComplexLoadingResourceState, + createListFailedResourceState, + createListLoadedResourceState, + createLoadedListViewWithPagination, + createSampleTrustedApps, + createUninitialisedResourceState, +} from '../test_utils'; + +describe('selectors', () => { + describe('needsRefreshOfListData()', () => { + it('returns false for outdated resource state and inactive state', () => { + expect(needsRefreshOfListData({ listView: createDefaultListView(), active: false })).toBe( + false + ); + }); + + it('returns true for outdated resource state and active state', () => { + expect(needsRefreshOfListData({ listView: createDefaultListView(), active: true })).toBe( + true + ); + }); + + it('returns true when current loaded page index is outdated', () => { + const listView = createLoadedListViewWithPagination({ index: 1, size: 20 }); + + expect(needsRefreshOfListData({ listView, active: true })).toBe(true); + }); + + it('returns true when current loaded page size is outdated', () => { + const listView = createLoadedListViewWithPagination({ index: 0, size: 50 }); + + expect(needsRefreshOfListData({ listView, active: true })).toBe(true); + }); + + it('returns false when current loaded data is up to date', () => { + const listView = createLoadedListViewWithPagination(); + + expect(needsRefreshOfListData({ listView, active: true })).toBe(false); + }); + }); + + describe('getCurrentListResourceState()', () => { + it('returns current list resource state', () => { + const listView = createDefaultListView(); + + expect(getCurrentListResourceState({ listView, active: false })).toStrictEqual( + createUninitialisedResourceState() + ); + }); + }); + + describe('getLastLoadedListResourceState()', () => { + it('returns last loaded list resource state', () => { + const listView = { + currentListResourceState: createListComplexLoadingResourceState( + createDefaultPaginationInfo(), + 200 + ), + currentPaginationInfo: createDefaultPaginationInfo(), + }; + + expect(getLastLoadedListResourceState({ listView, active: false })).toStrictEqual( + createListLoadedResourceState(createDefaultPaginationInfo(), 200) + ); + }); + }); + + describe('getListItems()', () => { + it('returns empty list when no valid data loaded', () => { + expect(getListItems({ listView: createDefaultListView(), active: false })).toStrictEqual([]); + }); + + it('returns last loaded list items', () => { + const listView = { + currentListResourceState: createListComplexLoadingResourceState( + createDefaultPaginationInfo(), + 200 + ), + currentPaginationInfo: createDefaultPaginationInfo(), + }; + + expect(getListItems({ listView, active: false })).toStrictEqual( + createSampleTrustedApps(createDefaultPaginationInfo()) + ); + }); + }); + + describe('getListTotalItemsCount()', () => { + it('returns 0 when no valid data loaded', () => { + expect(getListTotalItemsCount({ listView: createDefaultListView(), active: false })).toBe(0); + }); + + it('returns last loaded total items count', () => { + const listView = { + currentListResourceState: createListComplexLoadingResourceState( + createDefaultPaginationInfo(), + 200 + ), + currentPaginationInfo: createDefaultPaginationInfo(), + }; + + expect(getListTotalItemsCount({ listView, active: false })).toBe(200); + }); + }); + + describe('getListCurrentPageIndex()', () => { + it('returns page index', () => { + expect(getListCurrentPageIndex({ listView: createDefaultListView(), active: false })).toBe(0); + }); + }); + + describe('getListCurrentPageSize()', () => { + it('returns page index', () => { + expect(getListCurrentPageSize({ listView: createDefaultListView(), active: false })).toBe(20); + }); + }); + + describe('getListErrorMessage()', () => { + it('returns undefined when not in failed state', () => { + const listView = { + currentListResourceState: createListComplexLoadingResourceState( + createDefaultPaginationInfo(), + 200 + ), + currentPaginationInfo: createDefaultPaginationInfo(), + }; + + expect(getListErrorMessage({ listView, active: false })).toBeUndefined(); + }); + + it('returns message when not in failed state', () => { + const listView = { + currentListResourceState: createListFailedResourceState('Internal Server Error'), + currentPaginationInfo: createDefaultPaginationInfo(), + }; + + expect(getListErrorMessage({ listView, active: false })).toBe('Internal Server Error'); + }); + }); + + describe('isListLoading()', () => { + it('returns false when no loading is happening', () => { + expect(isListLoading({ listView: createDefaultListView(), active: false })).toBe(false); + }); + + it('returns true when loading is in progress', () => { + const listView = { + currentListResourceState: createListComplexLoadingResourceState( + createDefaultPaginationInfo(), + 200 + ), + currentPaginationInfo: createDefaultPaginationInfo(), + }; + + expect(isListLoading({ listView, active: false })).toBe(true); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.ts new file mode 100644 index 0000000000000..6fde779ac1cce --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/store/selectors.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Immutable, TrustedApp } from '../../../../../common/endpoint/types'; + +import { + AsyncResourceState, + getCurrentResourceError, + getLastLoadedResourceState, + isLoadingResourceState, + isOutdatedResourceState, + LoadedResourceState, + PaginationInfo, + TrustedAppsListData, + TrustedAppsListPageState, +} from '../state'; + +const pageInfosEqual = (pageInfo1: PaginationInfo, pageInfo2: PaginationInfo): boolean => + pageInfo1.index === pageInfo2.index && pageInfo1.size === pageInfo2.size; + +export const needsRefreshOfListData = (state: Immutable): boolean => { + const currentPageInfo = state.listView.currentPaginationInfo; + const currentPage = state.listView.currentListResourceState; + + return ( + state.active && + isOutdatedResourceState(currentPage, (data) => + pageInfosEqual(currentPageInfo, data.paginationInfo) + ) + ); +}; + +export const getCurrentListResourceState = ( + state: Immutable +): Immutable> | undefined => { + return state.listView.currentListResourceState; +}; + +export const getLastLoadedListResourceState = ( + state: Immutable +): Immutable> | undefined => { + return getLastLoadedResourceState(state.listView.currentListResourceState); +}; + +export const getListItems = ( + state: Immutable +): Immutable => { + return getLastLoadedResourceState(state.listView.currentListResourceState)?.data.items || []; +}; + +export const getListCurrentPageIndex = (state: Immutable): number => { + return state.listView.currentPaginationInfo.index; +}; + +export const getListCurrentPageSize = (state: Immutable): number => { + return state.listView.currentPaginationInfo.size; +}; + +export const getListTotalItemsCount = (state: Immutable): number => { + return ( + getLastLoadedResourceState(state.listView.currentListResourceState)?.data.totalItemsCount || 0 + ); +}; + +export const getListErrorMessage = ( + state: Immutable +): string | undefined => { + return getCurrentResourceError(state.listView.currentListResourceState)?.message; +}; + +export const isListLoading = (state: Immutable): boolean => { + return isLoadingResourceState(state.listView.currentListResourceState); +}; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/test_utils/index.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/test_utils/index.ts new file mode 100644 index 0000000000000..fab059a422a2a --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/test_utils/index.ts @@ -0,0 +1,135 @@ +/* + * 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 { ServerApiError } from '../../../../common/types'; +import { TrustedApp } from '../../../../../common/endpoint/types'; +import { RoutingAction } from '../../../../common/store/routing'; + +import { + AsyncResourceState, + FailedResourceState, + LoadedResourceState, + LoadingResourceState, + PaginationInfo, + StaleResourceState, + TrustedAppsListData, + TrustedAppsListPageState, + UninitialisedResourceState, +} from '../state'; + +import { TrustedAppsListResourceStateChanged } from '../store/action'; + +const OS_LIST: Array = ['windows', 'macos', 'linux']; + +export const createSampleTrustedApps = (paginationInfo: PaginationInfo): TrustedApp[] => { + return [...new Array(paginationInfo.size).keys()].map((i) => ({ + id: String(paginationInfo.index + i), + name: `trusted app ${paginationInfo.index + i}`, + description: `Trusted App ${paginationInfo.index + i}`, + created_at: '1 minute ago', + created_by: 'someone', + os: OS_LIST[i % 3], + entries: [], + })); +}; + +export const createTrustedAppsListData = ( + paginationInfo: PaginationInfo, + totalItemsCount: number +) => ({ + items: createSampleTrustedApps(paginationInfo), + totalItemsCount, + paginationInfo, +}); + +export const createServerApiError = (message: string) => ({ + statusCode: 500, + error: 'Internal Server Error', + message, +}); + +export const createUninitialisedResourceState = (): UninitialisedResourceState => ({ + type: 'UninitialisedResourceState', +}); + +export const createListLoadedResourceState = ( + paginationInfo: PaginationInfo, + totalItemsCount: number +): LoadedResourceState => ({ + type: 'LoadedResourceState', + data: createTrustedAppsListData(paginationInfo, totalItemsCount), +}); + +export const createListFailedResourceState = ( + message: string, + lastLoadedState?: LoadedResourceState +): FailedResourceState => ({ + type: 'FailedResourceState', + error: createServerApiError(message), + lastLoadedState, +}); + +export const createListLoadingResourceState = ( + previousState: StaleResourceState = createUninitialisedResourceState() +): LoadingResourceState => ({ + type: 'LoadingResourceState', + previousState, +}); + +export const createListComplexLoadingResourceState = ( + paginationInfo: PaginationInfo, + totalItemsCount: number +): LoadingResourceState => + createListLoadingResourceState( + createListFailedResourceState( + 'Internal Server Error', + createListLoadedResourceState(paginationInfo, totalItemsCount) + ) + ); + +export const createDefaultPaginationInfo = () => ({ index: 0, size: 20 }); + +export const createDefaultListView = () => ({ + currentListResourceState: createUninitialisedResourceState(), + currentPaginationInfo: createDefaultPaginationInfo(), +}); + +export const createLoadingListViewWithPagination = ( + currentPaginationInfo: PaginationInfo, + previousState: StaleResourceState = createUninitialisedResourceState() +): TrustedAppsListPageState['listView'] => ({ + currentListResourceState: { type: 'LoadingResourceState', previousState }, + currentPaginationInfo, +}); + +export const createLoadedListViewWithPagination = ( + paginationInfo: PaginationInfo = createDefaultPaginationInfo(), + currentPaginationInfo: PaginationInfo = createDefaultPaginationInfo(), + totalItemsCount: number = 200 +): TrustedAppsListPageState['listView'] => ({ + currentListResourceState: createListLoadedResourceState(paginationInfo, totalItemsCount), + currentPaginationInfo, +}); + +export const createFailedListViewWithPagination = ( + currentPaginationInfo: PaginationInfo, + error: ServerApiError, + lastLoadedState?: LoadedResourceState +): TrustedAppsListPageState['listView'] => ({ + currentListResourceState: { type: 'FailedResourceState', error, lastLoadedState }, + currentPaginationInfo, +}); + +export const createUserChangedUrlAction = (path: string, search: string = ''): RoutingAction => { + return { type: 'userChangedUrl', payload: { pathname: path, search, hash: '' } }; +}; + +export const createTrustedAppsListResourceStateChangedAction = ( + newState: AsyncResourceState +): TrustedAppsListResourceStateChanged => ({ + type: 'trustedAppsListResourceStateChanged', + payload: { newState }, +}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/__snapshots__/trusted_apps_list.test.tsx.snap b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/__snapshots__/trusted_apps_list.test.tsx.snap new file mode 100644 index 0000000000000..e0f846f5950f7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/__snapshots__/trusted_apps_list.test.tsx.snap @@ -0,0 +1,5530 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TrustedAppsList renders correctly initially 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + +
+
+
+ + Name + +
+
+
+ + OS + +
+
+
+ + Date Created + +
+
+
+ + Created By + +
+
+
+ + No items found + +
+
+
+
+
+`; + +exports[`TrustedAppsList renders correctly when failed loading data for the first time 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + +
+
+
+ + Name + +
+
+
+ + OS + +
+
+
+ + Date Created + +
+
+
+ + Created By + +
+
+
+ +
+ + Intenal Server Error + +
+
+
+
+
+`; + +exports[`TrustedAppsList renders correctly when failed loading data for the second time 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + +
+
+
+ + Name + +
+
+
+ + OS + +
+
+
+ + Date Created + +
+
+
+ + Created By + +
+
+
+ +
+ + Intenal Server Error + +
+
+
+
+
+`; + +exports[`TrustedAppsList renders correctly when loaded data 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + Name + +
+
+
+ + OS + +
+
+
+ + Date Created + +
+
+
+ + Created By + +
+
+
+ Name +
+
+ + trusted app 0 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 1 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 2 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 3 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 4 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 5 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 6 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 7 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 8 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 9 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 10 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 11 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 12 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 13 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 14 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 15 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 16 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 17 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 18 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 19 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+`; + +exports[`TrustedAppsList renders correctly when loading data for the first time 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + +
+
+
+ + Name + +
+
+
+ + OS + +
+
+
+ + Date Created + +
+
+
+ + Created By + +
+
+
+ + No items found + +
+
+
+
+
+`; + +exports[`TrustedAppsList renders correctly when loading data for the second time 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + Name + +
+
+
+ + OS + +
+
+
+ + Date Created + +
+
+
+ + Created By + +
+
+
+ Name +
+
+ + trusted app 0 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 1 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 2 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 3 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 4 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 5 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 6 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 7 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 8 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 9 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 10 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 11 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 12 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 13 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 14 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 15 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 16 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 17 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 18 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 19 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+`; + +exports[`TrustedAppsList renders correctly when new page and page sie set (not loading yet) 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + Name + +
+
+
+ + OS + +
+
+
+ + Date Created + +
+
+
+ + Created By + +
+
+
+ Name +
+
+ + trusted app 0 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 1 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 2 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 3 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 4 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 5 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 6 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 7 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 8 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 9 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 10 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 11 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 12 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 13 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 14 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 15 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 16 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 17 + +
+
+
+ OS +
+
+ Linux +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 18 + +
+
+
+ OS +
+
+ Windows +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+ Name +
+
+ + trusted app 19 + +
+
+
+ OS +
+
+ Mac OS +
+
+
+ Date Created +
+
+ 1 minute ago +
+
+
+ Created By +
+
+ + someone + +
+
+
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+`; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/__snapshots__/trusted_apps_page.test.tsx.snap b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/__snapshots__/trusted_apps_page.test.tsx.snap index 6f074f3809036..d6e9aee108cf6 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/__snapshots__/trusted_apps_page.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/__snapshots__/trusted_apps_page.test.tsx.snap @@ -17,5 +17,7 @@ exports[`TrustedAppsPage rendering 1`] = ` values={Object {}} /> } -/> +> + + `; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/hooks.ts b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/hooks.ts new file mode 100644 index 0000000000000..62610610981e0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/hooks.ts @@ -0,0 +1,22 @@ +/* + * 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 { useSelector } from 'react-redux'; + +import { State } from '../../../../common/store'; + +import { + MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE as TRUSTED_APPS_NS, + MANAGEMENT_STORE_GLOBAL_NAMESPACE as GLOBAL_NS, +} from '../../../common/constants'; + +import { TrustedAppsListPageState } from '../state'; + +export function useTrustedAppsSelector(selector: (state: TrustedAppsListPageState) => R): R { + return useSelector((state: State) => + selector(state[GLOBAL_NS][TRUSTED_APPS_NS] as TrustedAppsListPageState) + ); +} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.test.tsx new file mode 100644 index 0000000000000..0362f5c7a9de6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.test.tsx @@ -0,0 +1,123 @@ +/* + * 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 { combineReducers, createStore } from 'redux'; +import { render } from '@testing-library/react'; +import React from 'react'; +import { Provider } from 'react-redux'; + +import { + MANAGEMENT_STORE_GLOBAL_NAMESPACE, + MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE, +} from '../../../common/constants'; +import { trustedAppsPageReducer } from '../store/reducer'; +import { TrustedAppsList } from './trusted_apps_list'; +import { + createListFailedResourceState, + createListLoadedResourceState, + createListLoadingResourceState, + createTrustedAppsListResourceStateChangedAction, + createUserChangedUrlAction, +} from '../test_utils'; + +jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ + htmlIdGenerator: () => () => 'mockId', +})); + +const createStoreSetup = () => { + return createStore( + combineReducers({ + [MANAGEMENT_STORE_GLOBAL_NAMESPACE]: combineReducers({ + [MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE]: trustedAppsPageReducer, + }), + }) + ); +}; + +const renderList = (store: ReturnType) => { + const Wrapper: React.FC = ({ children }) => {children}; + + return render(, { wrapper: Wrapper }); +}; + +describe('TrustedAppsList', () => { + it('renders correctly initially', () => { + expect(renderList(createStoreSetup()).container).toMatchSnapshot(); + }); + + it('renders correctly when loading data for the first time', () => { + const store = createStoreSetup(); + + store.dispatch( + createTrustedAppsListResourceStateChangedAction(createListLoadingResourceState()) + ); + + expect(renderList(store).container).toMatchSnapshot(); + }); + + it('renders correctly when failed loading data for the first time', () => { + const store = createStoreSetup(); + + store.dispatch( + createTrustedAppsListResourceStateChangedAction( + createListFailedResourceState('Intenal Server Error') + ) + ); + + expect(renderList(store).container).toMatchSnapshot(); + }); + + it('renders correctly when loaded data', () => { + const store = createStoreSetup(); + + store.dispatch( + createTrustedAppsListResourceStateChangedAction( + createListLoadedResourceState({ index: 0, size: 20 }, 200) + ) + ); + + expect(renderList(store).container).toMatchSnapshot(); + }); + + it('renders correctly when new page and page sie set (not loading yet)', () => { + const store = createStoreSetup(); + + store.dispatch( + createTrustedAppsListResourceStateChangedAction( + createListLoadedResourceState({ index: 0, size: 20 }, 200) + ) + ); + store.dispatch(createUserChangedUrlAction('/trusted_apps', '?page_index=2&page_size=50')); + + expect(renderList(store).container).toMatchSnapshot(); + }); + + it('renders correctly when loading data for the second time', () => { + const store = createStoreSetup(); + + store.dispatch( + createTrustedAppsListResourceStateChangedAction( + createListLoadingResourceState(createListLoadedResourceState({ index: 0, size: 20 }, 200)) + ) + ); + + expect(renderList(store).container).toMatchSnapshot(); + }); + + it('renders correctly when failed loading data for the second time', () => { + const store = createStoreSetup(); + + store.dispatch( + createTrustedAppsListResourceStateChangedAction( + createListFailedResourceState( + 'Intenal Server Error', + createListLoadedResourceState({ index: 0, size: 20 }, 200) + ) + ) + ); + + expect(renderList(store).container).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.tsx new file mode 100644 index 0000000000000..a9077dd84913e --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_list.tsx @@ -0,0 +1,126 @@ +/* + * 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 React, { memo, useCallback, useMemo } from 'react'; +import { useHistory } from 'react-router-dom'; +import { EuiBasicTable, EuiBasicTableColumn } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { Immutable } from '../../../../../common/endpoint/types'; +import { TrustedApp } from '../../../../../common/endpoint/types/trusted_apps'; +import { MANAGEMENT_PAGE_SIZE_OPTIONS } from '../../../common/constants'; +import { getTrustedAppsListPath } from '../../../common/routing'; + +import { + getListCurrentPageIndex, + getListCurrentPageSize, + getListErrorMessage, + getListItems, + getListTotalItemsCount, + isListLoading, +} from '../store/selectors'; + +import { useTrustedAppsSelector } from './hooks'; + +import { FormattedDate } from '../../../../common/components/formatted_date'; + +const OS_TITLES: Readonly<{ [K in TrustedApp['os']]: string }> = { + windows: i18n.translate('xpack.securitySolution.trustedapps.os.windows', { + defaultMessage: 'Windows', + }), + macos: i18n.translate('xpack.securitySolution.trustedapps.os.macos', { + defaultMessage: 'Mac OS', + }), + linux: i18n.translate('xpack.securitySolution.trustedapps.os.linux', { + defaultMessage: 'Linux', + }), +}; + +const COLUMN_TITLES: Readonly<{ [K in keyof Omit]: string }> = { + name: i18n.translate('xpack.securitySolution.trustedapps.list.columns.name', { + defaultMessage: 'Name', + }), + os: i18n.translate('xpack.securitySolution.trustedapps.list.columns.os', { + defaultMessage: 'OS', + }), + created_at: i18n.translate('xpack.securitySolution.trustedapps.list.columns.createdAt', { + defaultMessage: 'Date Created', + }), + created_by: i18n.translate('xpack.securitySolution.trustedapps.list.columns.createdBy', { + defaultMessage: 'Created By', + }), +}; + +const getColumnDefinitions = (): Array>> => [ + { + field: 'name', + name: COLUMN_TITLES.name, + }, + { + field: 'os', + name: COLUMN_TITLES.os, + render(value: TrustedApp['os'], record: Immutable) { + return OS_TITLES[value]; + }, + }, + { + field: 'created_at', + name: COLUMN_TITLES.created_at, + render(value: TrustedApp['created_at'], record: Immutable) { + return ( + + ); + }, + }, + { + field: 'created_by', + name: COLUMN_TITLES.created_by, + }, +]; + +export const TrustedAppsList = memo(() => { + const pageIndex = useTrustedAppsSelector(getListCurrentPageIndex); + const pageSize = useTrustedAppsSelector(getListCurrentPageSize); + const totalItemCount = useTrustedAppsSelector(getListTotalItemsCount); + const listItems = useTrustedAppsSelector(getListItems); + const history = useHistory(); + + return ( + [...listItems], [listItems])} + error={useTrustedAppsSelector(getListErrorMessage)} + loading={useTrustedAppsSelector(isListLoading)} + pagination={useMemo( + () => ({ + pageIndex, + pageSize, + totalItemCount, + hidePerPageOptions: false, + pageSizeOptions: [...MANAGEMENT_PAGE_SIZE_OPTIONS], + }), + [pageIndex, pageSize, totalItemCount] + )} + onChange={useCallback( + ({ page }: { page: { index: number; size: number } }) => { + history.push( + getTrustedAppsListPath({ + page_index: page.index, + page_size: page.size, + }) + ); + }, + [history] + )} + /> + ); +}); + +TrustedAppsList.displayName = 'TrustedAppsList'; diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx index 7045fa49ffad3..c0d3b9cd699de 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/trusted_apps_page.tsx @@ -3,11 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { memo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { AdministrationListPage } from '../../../components/administration_list_page'; +import { TrustedAppsList } from './trusted_apps_list'; -export function TrustedAppsPage() { +export const TrustedAppsPage = memo(() => { return ( } - /> + > + + ); -} +}); + +TrustedAppsPage.displayName = 'TrustedAppsPage'; diff --git a/x-pack/plugins/security_solution/public/management/store/middleware.ts b/x-pack/plugins/security_solution/public/management/store/middleware.ts index c7a7d2cad0623..77d02262e93b7 100644 --- a/x-pack/plugins/security_solution/public/management/store/middleware.ts +++ b/x-pack/plugins/security_solution/public/management/store/middleware.ts @@ -9,22 +9,22 @@ import { SecuritySubPluginMiddlewareFactory, State, } from '../../common/store'; -import { policyListMiddlewareFactory } from '../pages/policy/store/policy_list'; -import { policyDetailsMiddlewareFactory } from '../pages/policy/store/policy_details'; import { MANAGEMENT_STORE_ENDPOINTS_NAMESPACE, MANAGEMENT_STORE_GLOBAL_NAMESPACE, MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE, MANAGEMENT_STORE_POLICY_LIST_NAMESPACE, + MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE, } from '../common/constants'; +import { policyListMiddlewareFactory } from '../pages/policy/store/policy_list'; +import { policyDetailsMiddlewareFactory } from '../pages/policy/store/policy_details'; import { endpointMiddlewareFactory } from '../pages/endpoint_hosts/store/middleware'; +import { trustedAppsPageMiddlewareFactory } from '../pages/trusted_apps/store/middleware'; + +type ManagementSubStateKey = keyof State[typeof MANAGEMENT_STORE_GLOBAL_NAMESPACE]; -const policyListSelector = (state: State) => - state[MANAGEMENT_STORE_GLOBAL_NAMESPACE][MANAGEMENT_STORE_POLICY_LIST_NAMESPACE]; -const policyDetailsSelector = (state: State) => - state[MANAGEMENT_STORE_GLOBAL_NAMESPACE][MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE]; -const endpointsSelector = (state: State) => - state[MANAGEMENT_STORE_GLOBAL_NAMESPACE][MANAGEMENT_STORE_ENDPOINTS_NAMESPACE]; +const createSubStateSelector = (namespace: K) => (state: State) => + state[MANAGEMENT_STORE_GLOBAL_NAMESPACE][namespace]; export const managementMiddlewareFactory: SecuritySubPluginMiddlewareFactory = ( coreStart, @@ -32,13 +32,20 @@ export const managementMiddlewareFactory: SecuritySubPluginMiddlewareFactory = ( ) => { return [ substateMiddlewareFactory( - policyListSelector, + createSubStateSelector(MANAGEMENT_STORE_POLICY_LIST_NAMESPACE), policyListMiddlewareFactory(coreStart, depsStart) ), substateMiddlewareFactory( - policyDetailsSelector, + createSubStateSelector(MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE), policyDetailsMiddlewareFactory(coreStart, depsStart) ), - substateMiddlewareFactory(endpointsSelector, endpointMiddlewareFactory(coreStart, depsStart)), + substateMiddlewareFactory( + createSubStateSelector(MANAGEMENT_STORE_ENDPOINTS_NAMESPACE), + endpointMiddlewareFactory(coreStart, depsStart) + ), + substateMiddlewareFactory( + createSubStateSelector(MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE), + trustedAppsPageMiddlewareFactory(coreStart, depsStart) + ), ]; }; diff --git a/x-pack/plugins/security_solution/public/management/store/reducer.ts b/x-pack/plugins/security_solution/public/management/store/reducer.ts index eafd69c875ff1..29eb2d289ae1c 100644 --- a/x-pack/plugins/security_solution/public/management/store/reducer.ts +++ b/x-pack/plugins/security_solution/public/management/store/reducer.ts @@ -17,6 +17,7 @@ import { MANAGEMENT_STORE_ENDPOINTS_NAMESPACE, MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE, MANAGEMENT_STORE_POLICY_LIST_NAMESPACE, + MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE, } from '../common/constants'; import { ImmutableCombineReducers } from '../../common/store'; import { Immutable } from '../../../common/endpoint/types'; @@ -25,6 +26,10 @@ import { endpointListReducer, initialEndpointListState, } from '../pages/endpoint_hosts/store/reducer'; +import { + initialTrustedAppsPageState, + trustedAppsPageReducer, +} from '../pages/trusted_apps/store/reducer'; const immutableCombineReducers: ImmutableCombineReducers = combineReducers; @@ -35,6 +40,7 @@ export const mockManagementState: Immutable = { [MANAGEMENT_STORE_POLICY_LIST_NAMESPACE]: initialPolicyListState(), [MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE]: initialPolicyDetailsState(), [MANAGEMENT_STORE_ENDPOINTS_NAMESPACE]: initialEndpointListState, + [MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE]: initialTrustedAppsPageState, }; /** @@ -44,4 +50,5 @@ export const managementReducer = immutableCombineReducers({ [MANAGEMENT_STORE_POLICY_LIST_NAMESPACE]: policyListReducer, [MANAGEMENT_STORE_POLICY_DETAILS_NAMESPACE]: policyDetailsReducer, [MANAGEMENT_STORE_ENDPOINTS_NAMESPACE]: endpointListReducer, + [MANAGEMENT_STORE_TRUSTED_APPS_NAMESPACE]: trustedAppsPageReducer, }); diff --git a/x-pack/plugins/security_solution/public/management/types.ts b/x-pack/plugins/security_solution/public/management/types.ts index 21214241d1981..8b53f4c1d8525 100644 --- a/x-pack/plugins/security_solution/public/management/types.ts +++ b/x-pack/plugins/security_solution/public/management/types.ts @@ -8,6 +8,7 @@ import { CombinedState } from 'redux'; import { SecurityPageName } from '../app/types'; import { PolicyListState, PolicyDetailsState } from './pages/policy/types'; import { EndpointState } from './pages/endpoint_hosts/types'; +import { TrustedAppsListPageState } from './pages/trusted_apps/state/trusted_apps_list_page_state'; /** * The type for the management store global namespace. Used mostly internally to reference @@ -19,6 +20,7 @@ export type ManagementState = CombinedState<{ policyList: PolicyListState; policyDetails: PolicyDetailsState; endpoints: EndpointState; + trustedApps: TrustedAppsListPageState; }>; /** diff --git a/x-pack/plugins/security_solution/public/network/components/ip_overview/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/network/components/details/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/security_solution/public/network/components/ip_overview/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/network/components/details/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/security_solution/public/network/components/ip_overview/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/details/index.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/network/components/ip_overview/index.test.tsx rename to x-pack/plugins/security_solution/public/network/components/details/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx b/x-pack/plugins/security_solution/public/network/components/details/index.tsx similarity index 88% rename from x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx rename to x-pack/plugins/security_solution/public/network/components/details/index.tsx index d6dfe1769308e..2c6840895683c 100644 --- a/x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/details/index.tsx @@ -12,7 +12,7 @@ import React from 'react'; import { DEFAULT_DARK_MODE } from '../../../../common/constants'; import { DescriptionList } from '../../../../common/utility_types'; import { useUiSetting$ } from '../../../common/lib/kibana'; -import { FlowTarget, IpOverviewData, Overview } from '../../../graphql/types'; +import { FlowTarget, NetworkDetailsStrategyResponse } from '../../../../common/search_strategy'; import { networkModel } from '../../store'; import { getEmptyTagValue } from '../../../common/components/empty_value'; @@ -34,8 +34,8 @@ import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_ca import { hasMlUserPermissions } from '../../../../common/machine_learning/has_ml_user_permissions'; import { InspectButton, InspectButtonContainer } from '../../../common/components/inspect'; -interface OwnProps { - data: IpOverviewData; +export interface IpOverviewProps { + data: NetworkDetailsStrategyResponse['networkDetails']; flowTarget: FlowTarget; id: string; ip: string; @@ -48,15 +48,11 @@ interface OwnProps { narrowDateRange: NarrowDateRange; } -export type IpOverviewProps = OwnProps; - -const getDescriptionList = (descriptionList: DescriptionList[], key: number) => { - return ( - - - - ); -}; +const getDescriptionList = (descriptionList: DescriptionList[], key: number) => ( + + + +); export const IpOverview = React.memo( ({ @@ -74,7 +70,7 @@ export const IpOverview = React.memo( const capabilities = useMlCapabilities(); const userPermissions = hasMlUserPermissions(capabilities); const [darkMode] = useUiSetting$(DEFAULT_DARK_MODE); - const typeData: Overview = data[flowTarget]!; + const typeData = data[flowTarget]!; const column: DescriptionList[] = [ { title: i18n.LOCATION, @@ -124,13 +120,14 @@ export const IpOverview = React.memo( [ { title: i18n.HOST_ID, - description: typeData - ? hostIdRenderer({ host: data.host, ipFilter: ip }) - : getEmptyTagValue(), + description: + typeData && data.host + ? hostIdRenderer({ host: data.host, ipFilter: ip }) + : getEmptyTagValue(), }, { title: i18n.HOST_NAME, - description: typeData ? hostNameRenderer(data.host, ip) : getEmptyTagValue(), + description: typeData && data.host ? hostNameRenderer(data.host, ip) : getEmptyTagValue(), }, ], [ diff --git a/x-pack/plugins/security_solution/public/network/components/ip_overview/mock.ts b/x-pack/plugins/security_solution/public/network/components/details/mock.ts similarity index 85% rename from x-pack/plugins/security_solution/public/network/components/ip_overview/mock.ts rename to x-pack/plugins/security_solution/public/network/components/details/mock.ts index aa86fb177b02a..b1187a9b22d94 100644 --- a/x-pack/plugins/security_solution/public/network/components/ip_overview/mock.ts +++ b/x-pack/plugins/security_solution/public/network/components/details/mock.ts @@ -4,9 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IpOverviewData } from '../../../graphql/types'; +import { NetworkDetailsStrategyResponse } from '../../../../common/search_strategy'; -export const mockData: Readonly> = { +export const mockData: Readonly> = { complete: { source: { firstSeen: '2019-02-07T17:19:41.636Z', @@ -16,7 +19,7 @@ export const mockData: Readonly> = { continent_name: ['North America'], city_name: ['New York'], country_iso_code: ['US'], - country_name: null, + country_name: undefined, location: { lat: [40.7214], lon: [-74.0052], @@ -33,7 +36,7 @@ export const mockData: Readonly> = { continent_name: ['North America'], city_name: ['New York'], country_iso_code: ['US'], - country_name: null, + country_name: undefined, location: { lat: [40.7214], lon: [-74.0052], diff --git a/x-pack/plugins/security_solution/public/network/components/ip_overview/translations.ts b/x-pack/plugins/security_solution/public/network/components/details/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/network/components/ip_overview/translations.ts rename to x-pack/plugins/security_solution/public/network/components/details/translations.ts diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx index 7c05e93e6876e..27fe27adc99c2 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx @@ -11,7 +11,7 @@ import '../../../../common/mock/match_media'; import { getRenderedFieldValue, PointToolTipContentComponent } from './point_tool_tip_content'; import { TestProviders } from '../../../../common/mock'; import { getEmptyStringTag } from '../../../../common/components/empty_value'; -import { HostDetailsLink, IPDetailsLink } from '../../../../common/components/links'; +import { HostDetailsLink, NetworkDetailsLink } from '../../../../common/components/links'; import { FlowTarget } from '../../../../graphql/types'; import { TooltipProperty, @@ -50,17 +50,17 @@ describe('PointToolTipContent', () => { ); }); - test('it returns IPDetailsLink if field is source.ip', () => { + test('it returns NetworkDetailsLink if field is source.ip', () => { const value = '127.0.0.1'; expect(getRenderedFieldValue('source.ip', value)).toStrictEqual( - + ); }); - test('it returns IPDetailsLink if field is destination.ip', () => { + test('it returns NetworkDetailsLink if field is destination.ip', () => { const value = '127.0.0.1'; expect(getRenderedFieldValue('destination.ip', value)).toStrictEqual( - + ); }); diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.tsx index f38f3e054a645..57113a1395778 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/map_tool_tip/point_tool_tip_content.tsx @@ -11,7 +11,7 @@ import { getOrEmptyTagFromValue, } from '../../../../common/components/empty_value'; import { DescriptionListStyled } from '../../../../common/components/page'; -import { HostDetailsLink, IPDetailsLink } from '../../../../common/components/links'; +import { HostDetailsLink, NetworkDetailsLink } from '../../../../common/components/links'; import { DefaultFieldRenderer } from '../../../../timelines/components/field_renderers/field_renderers'; import { FlowTarget } from '../../../../graphql/types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths @@ -67,7 +67,7 @@ export const getRenderedFieldValue = (field: string, value: string) => { return ; } else if (['source.ip', 'destination.ip'].includes(field)) { const flowTarget = field.split('.')[0] as FlowTarget; - return ; + return ; } return <>{value}; }; diff --git a/x-pack/plugins/security_solution/public/network/components/flow_target_select_connected/index.tsx b/x-pack/plugins/security_solution/public/network/components/flow_target_select_connected/index.tsx index 3ce623cfc97b8..6ddcf9119b215 100644 --- a/x-pack/plugins/security_solution/public/network/components/flow_target_select_connected/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/flow_target_select_connected/index.tsx @@ -11,7 +11,7 @@ import { useHistory, useLocation } from 'react-router-dom'; import styled from 'styled-components'; import { FlowDirection, FlowTarget } from '../../../graphql/types'; -import * as i18nIp from '../ip_overview/translations'; +import * as i18nIp from '../details/translations'; import { FlowTargetSelect } from '../flow_controls/flow_target_select'; import { IpOverviewId } from '../../../timelines/components/field_renderers/field_renderers'; @@ -40,7 +40,7 @@ export const FlowTargetSelectConnectedComponent: React.FC = ({ flowTarget const history = useHistory(); const location = useLocation(); - const updateIpDetailsFlowTarget = useCallback( + const updateNetworkDetailsFlowTarget = useCallback( (newFlowTarget: FlowTarget) => { const newPath = getUpdatedFlowTargetPath(location, flowTarget, newFlowTarget); history.push(newPath); @@ -56,7 +56,7 @@ export const FlowTargetSelectConnectedComponent: React.FC = ({ flowTarget selectedDirection={FlowDirection.uniDirectional} selectedTarget={flowTarget} displayTextOverride={[i18nIp.AS_SOURCE, i18nIp.AS_DESTINATION]} - updateFlowTargetAction={updateIpDetailsFlowTarget} + updateFlowTargetAction={updateNetworkDetailsFlowTarget} /> ); diff --git a/x-pack/plugins/security_solution/public/network/components/network_http_table/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/network/components/network_http_table/__snapshots__/index.test.tsx.snap index 875a490d86be3..7adee9531b1f3 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_http_table/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/network/components/network_http_table/__snapshots__/index.test.tsx.snap @@ -1,102 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`NetworkHttp Table Component rendering it renders the default NetworkHttp table 1`] = ` - -`; +exports[`NetworkHttp Table Component rendering it renders the default NetworkHttp table 1`] = `null`; diff --git a/x-pack/plugins/security_solution/public/network/components/network_http_table/columns.tsx b/x-pack/plugins/security_solution/public/network/components/network_http_table/columns.tsx index 0c5856241c5a3..42e52e3a86f43 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_http_table/columns.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_http_table/columns.tsx @@ -8,10 +8,14 @@ import React from 'react'; import numeral from '@elastic/numeral'; -import { NetworkHttpEdges, NetworkHttpFields, NetworkHttpItem } from '../../../graphql/types'; +import { + NetworkHttpEdges, + NetworkHttpFields, + NetworkHttpItem, +} from '../../../../common/search_strategy/security_solution/network'; import { escapeDataProviderId } from '../../../common/components/drag_and_drop/helpers'; import { getEmptyTagValue } from '../../../common/components/empty_value'; -import { IPDetailsLink } from '../../../common/components/links'; +import { NetworkDetailsLink } from '../../../common/components/links'; import { Columns } from '../../../common/components/paginated_table'; import * as i18n from './translations'; @@ -98,7 +102,7 @@ export const getNetworkHttpColumns = (tableId: string): NetworkHttpColumns => [ attrName: 'source.ip', idPrefix: escapeDataProviderId(`${tableId}-table-lastSourceIp-${path}`), rowItem: lastSourceIp, - render: () => , + render: () => , }) : getEmptyTagValue(), }, diff --git a/x-pack/plugins/security_solution/public/network/components/network_http_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/network_http_table/index.tsx index ed25373018207..ccb238bcee274 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_http_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_http_table/index.tsx @@ -5,17 +5,17 @@ */ import React, { useCallback, useMemo } from 'react'; -import { connect, ConnectedProps } from 'react-redux'; +import { useDispatch, useSelector, shallowEqual } from 'react-redux'; import { networkActions, networkModel, networkSelectors } from '../../store'; -import { Direction, NetworkHttpEdges, NetworkHttpFields } from '../../../graphql/types'; +import { NetworkHttpEdges, NetworkHttpFields } from '../../../../common/search_strategy'; import { State } from '../../../common/store'; import { Criteria, ItemsPerRow, PaginatedTable } from '../../../common/components/paginated_table'; import { getNetworkHttpColumns } from './columns'; import * as i18n from './translations'; -interface OwnProps { +interface NetworkHttpTableProps { data: NetworkHttpEdges[]; fakeTotalCount: number; id: string; @@ -27,8 +27,6 @@ interface OwnProps { type: networkModel.NetworkType; } -type NetworkHttpTableProps = OwnProps & PropsFromRedux; - const rowItems: ItemsPerRow[] = [ { text: i18n.ROWS_5, @@ -41,60 +39,68 @@ const rowItems: ItemsPerRow[] = [ ]; const NetworkHttpTableComponent: React.FC = ({ - activePage, data, fakeTotalCount, id, isInspect, - limit, loading, loadPage, showMorePagesIndicator, - sort, totalCount, type, - updateNetworkTable, }) => { + const dispatch = useDispatch(); + const getNetworkHttpSelector = networkSelectors.httpSelector(); + const { activePage, limit, sort } = useSelector( + (state: State) => getNetworkHttpSelector(state, type), + shallowEqual + ); const tableType = type === networkModel.NetworkType.page ? networkModel.NetworkTableType.http - : networkModel.IpDetailsTableType.http; + : networkModel.NetworkDetailsTableType.http; const updateLimitPagination = useCallback( (newLimit) => - updateNetworkTable({ - networkType: type, - tableType, - updates: { limit: newLimit }, - }), - [type, updateNetworkTable, tableType] + dispatch( + networkActions.updateNetworkTable({ + networkType: type, + tableType, + updates: { limit: newLimit }, + }) + ), + [dispatch, type, tableType] ); const updateActivePage = useCallback( (newPage) => - updateNetworkTable({ - networkType: type, - tableType, - updates: { activePage: newPage }, - }), - [type, updateNetworkTable, tableType] + dispatch( + networkActions.updateNetworkTable({ + networkType: type, + tableType, + updates: { activePage: newPage }, + }) + ), + [dispatch, type, tableType] ); const onChange = useCallback( (criteria: Criteria) => { if (criteria.sort != null && criteria.sort.direction !== sort.direction) { - updateNetworkTable({ - networkType: type, - tableType, - updates: { - sort: { - direction: criteria.sort.direction as Direction, + dispatch( + networkActions.updateNetworkTable({ + networkType: type, + tableType, + updates: { + sort: { + direction: criteria.sort.direction, + }, }, - }, - }); + }) + ); } }, - [tableType, sort.direction, type, updateNetworkTable] + [sort.direction, dispatch, type, tableType] ); const sorting = { field: `node.${NetworkHttpFields.requestCount}`, direction: sort.direction }; @@ -128,18 +134,4 @@ const NetworkHttpTableComponent: React.FC = ({ NetworkHttpTableComponent.displayName = 'NetworkHttpTableComponent'; -const makeMapStateToProps = () => { - const getNetworkHttpSelector = networkSelectors.httpSelector(); - const mapStateToProps = (state: State, { type }: OwnProps) => getNetworkHttpSelector(state, type); - return mapStateToProps; -}; - -const mapDispatchToProps = { - updateNetworkTable: networkActions.updateNetworkTable, -}; - -const connector = connect(makeMapStateToProps, mapDispatchToProps); - -type PropsFromRedux = ConnectedProps; - -export const NetworkHttpTable = connector(React.memo(NetworkHttpTableComponent)); +export const NetworkHttpTable = React.memo(NetworkHttpTableComponent); diff --git a/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/columns.tsx b/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/columns.tsx index d6661ed48197a..634bf2ba35d76 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/columns.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/columns.tsx @@ -37,7 +37,7 @@ export type NetworkTopCountriesColumns = [ Columns ]; -export type NetworkTopCountriesColumnsIpDetails = [ +export type NetworkTopCountriesColumnsNetworkDetails = [ Columns, Columns, Columns, @@ -164,7 +164,7 @@ export const getCountriesColumnsCurated = ( flowTarget: FlowTargetSourceDest, type: networkModel.NetworkType, tableId: string -): NetworkTopCountriesColumns | NetworkTopCountriesColumnsIpDetails => { +): NetworkTopCountriesColumns | NetworkTopCountriesColumnsNetworkDetails => { const columns = getNetworkTopCountriesColumns(indexPattern, flowTarget, type, tableId); // Columns to exclude from host details pages diff --git a/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.tsx index 114bca9f59d9c..2495f9e7c11c8 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.tsx @@ -88,8 +88,8 @@ const NetworkTopCountriesTableComponent: React.FC } return flowTargeted === FlowTargetSourceDest.source - ? networkModel.IpDetailsTableType.topCountriesSource - : networkModel.IpDetailsTableType.topCountriesDestination; + ? networkModel.NetworkDetailsTableType.topCountriesSource + : networkModel.NetworkDetailsTableType.topCountriesDestination; }, [flowTargeted, type]); const field = diff --git a/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/columns.tsx b/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/columns.tsx index 16c26d5077c8d..ae390e8e2ed71 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/columns.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/columns.tsx @@ -22,7 +22,7 @@ import { } from '../../../common/components/drag_and_drop/draggable_wrapper'; import { escapeDataProviderId } from '../../../common/components/drag_and_drop/helpers'; import { getEmptyTagValue } from '../../../common/components/empty_value'; -import { IPDetailsLink } from '../../../common/components/links'; +import { NetworkDetailsLink } from '../../../common/components/links'; import { Columns } from '../../../common/components/paginated_table'; import { IS_OPERATOR } from '../../../timelines/components/timeline/data_providers/data_provider'; import { Provider } from '../../../timelines/components/timeline/data_providers/provider'; @@ -43,7 +43,7 @@ export type NetworkTopNFlowColumns = [ Columns ]; -export type NetworkTopNFlowColumnsIpDetails = [ +export type NetworkTopNFlowColumnsNetworkDetails = [ Columns, Columns, Columns, @@ -86,7 +86,7 @@ export const getNetworkTopNFlowColumns = ( ) : ( - + ) } /> @@ -239,7 +239,7 @@ export const getNFlowColumnsCurated = ( flowTarget: FlowTargetSourceDest, type: networkModel.NetworkType, tableId: string -): NetworkTopNFlowColumns | NetworkTopNFlowColumnsIpDetails => { +): NetworkTopNFlowColumns | NetworkTopNFlowColumnsNetworkDetails => { const columns = getNetworkTopNFlowColumns(flowTarget, tableId); // Columns to exclude from host details pages diff --git a/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.tsx index 30b70872432f9..757b178431d90 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.tsx @@ -82,8 +82,8 @@ const NetworkTopNFlowTableComponent: React.FC = ({ } else { tableType = flowTargeted === FlowTargetSourceDest.source - ? networkModel.IpDetailsTableType.topNFlowSource - : networkModel.IpDetailsTableType.topNFlowDestination; + ? networkModel.NetworkDetailsTableType.topNFlowSource + : networkModel.NetworkDetailsTableType.topNFlowDestination; } const onChange = useCallback( diff --git a/x-pack/plugins/security_solution/public/network/components/tls_table/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/network/components/tls_table/__snapshots__/index.test.tsx.snap index 8b7d8efa7ac37..a9c3a1a006268 100644 --- a/x-pack/plugins/security_solution/public/network/components/tls_table/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/network/components/tls_table/__snapshots__/index.test.tsx.snap @@ -1,79 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Tls Table Component Rendering it renders the default Domains table 1`] = ` - -`; +exports[`Tls Table Component Rendering it renders the default Domains table 1`] = `null`; diff --git a/x-pack/plugins/security_solution/public/network/components/tls_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/tls_table/index.tsx index d0e001466518d..3d19eedc06a8e 100644 --- a/x-pack/plugins/security_solution/public/network/components/tls_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/tls_table/index.tsx @@ -5,11 +5,16 @@ */ import React, { useCallback, useMemo } from 'react'; -import { connect, ConnectedProps } from 'react-redux'; +import { useDispatch, useSelector, shallowEqual } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { networkActions, networkModel, networkSelectors } from '../../store'; -import { TlsEdges, TlsSortField, TlsFields, Direction } from '../../../graphql/types'; +import { + Direction, + NetworkTlsEdges, + NetworkTlsFields, + SortField, +} from '../../../../common/search_strategy'; import { State } from '../../../common/store'; import { Criteria, @@ -20,8 +25,8 @@ import { import { getTlsColumns } from './columns'; import * as i18n from './translations'; -interface OwnProps { - data: TlsEdges[]; +interface TlsTableProps { + data: NetworkTlsEdges[]; fakeTotalCount: number; id: string; isInspect: boolean; @@ -32,8 +37,6 @@ interface OwnProps { type: networkModel.NetworkType; } -type TlsTableProps = OwnProps & PropsFromRedux; - const rowItems: ItemsPerRow[] = [ { text: i18n.ROWS_5, @@ -47,123 +50,115 @@ const rowItems: ItemsPerRow[] = [ export const tlsTableId = 'tls-table'; -const TlsTableComponent = React.memo( - ({ - activePage, - data, - fakeTotalCount, - id, - isInspect, - limit, - loading, - loadPage, - showMorePagesIndicator, - sort, - totalCount, - type, - updateNetworkTable, - }) => { - const tableType: networkModel.TopTlsTableType = - type === networkModel.NetworkType.page - ? networkModel.NetworkTableType.tls - : networkModel.IpDetailsTableType.tls; - - const updateLimitPagination = useCallback( - (newLimit) => - updateNetworkTable({ +const TlsTableComponent: React.FC = ({ + data, + fakeTotalCount, + id, + isInspect, + loading, + loadPage, + showMorePagesIndicator, + totalCount, + type, +}) => { + const dispatch = useDispatch(); + const getTlsSelector = networkSelectors.tlsSelector(); + const { activePage, limit, sort } = useSelector( + (state: State) => getTlsSelector(state, type), + shallowEqual + ); + const tableType: networkModel.TopTlsTableType = + type === networkModel.NetworkType.page + ? networkModel.NetworkTableType.tls + : networkModel.NetworkDetailsTableType.tls; + + const updateLimitPagination = useCallback( + (newLimit) => + dispatch( + networkActions.updateNetworkTable({ networkType: type, tableType, updates: { limit: newLimit }, - }), - [type, updateNetworkTable, tableType] - ); - - const updateActivePage = useCallback( - (newPage) => - updateNetworkTable({ + }) + ), + [dispatch, type, tableType] + ); + + const updateActivePage = useCallback( + (newPage) => + dispatch( + networkActions.updateNetworkTable({ networkType: type, tableType, updates: { activePage: newPage }, - }), - [type, updateNetworkTable, tableType] - ); - - const onChange = useCallback( - (criteria: Criteria) => { - if (criteria.sort != null) { - const splitField = criteria.sort.field.split('.'); - const newTlsSort: TlsSortField = { - field: getSortFromString(splitField[splitField.length - 1]), - direction: criteria.sort.direction as Direction, - }; - if (!deepEqual(newTlsSort, sort)) { - updateNetworkTable({ + }) + ), + [dispatch, type, tableType] + ); + + const onChange = useCallback( + (criteria: Criteria) => { + if (criteria.sort != null) { + const splitField = criteria.sort.field.split('.'); + const newTlsSort: SortField = { + field: getSortFromString(splitField[splitField.length - 1]), + direction: criteria.sort.direction as Direction, + }; + if (!deepEqual(newTlsSort, sort)) { + dispatch( + networkActions.updateNetworkTable({ networkType: type, tableType, updates: { sort: newTlsSort }, - }); - } + }) + ); } - }, - [sort, type, tableType, updateNetworkTable] - ); - - // eslint-disable-next-line react-hooks/exhaustive-deps - const columns = useMemo(() => getTlsColumns(tlsTableId), [tlsTableId]); - - return ( - - ); - } -); - -TlsTableComponent.displayName = 'TlsTableComponent'; - -const makeMapStateToProps = () => { - const getTlsSelector = networkSelectors.tlsSelector(); - return (state: State, { type }: OwnProps) => getTlsSelector(state, type); + } + }, + [sort, dispatch, type, tableType] + ); + + const columns = useMemo(() => getTlsColumns(tlsTableId), []); + + return ( + + ); }; -const mapDispatchToProps = { - updateNetworkTable: networkActions.updateNetworkTable, -}; - -const connector = connect(makeMapStateToProps, mapDispatchToProps); - -type PropsFromRedux = ConnectedProps; +TlsTableComponent.displayName = 'TlsTableComponent'; -export const TlsTable = connector(TlsTableComponent); +export const TlsTable = React.memo(TlsTableComponent); -const getSortField = (sortField: TlsSortField): SortingBasicTable => ({ +const getSortField = (sortField: SortField): SortingBasicTable => ({ field: `node.${sortField.field}`, direction: sortField.direction, }); -const getSortFromString = (sortField: string): TlsFields => { +const getSortFromString = (sortField: string): NetworkTlsFields => { switch (sortField) { case '_id': - return TlsFields._id; + return NetworkTlsFields._id; default: - return TlsFields._id; + return NetworkTlsFields._id; } }; diff --git a/x-pack/plugins/security_solution/public/network/components/users_table/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/network/components/users_table/__snapshots__/index.test.tsx.snap index 634253d03291f..934a28fbc4dd0 100644 --- a/x-pack/plugins/security_solution/public/network/components/users_table/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/network/components/users_table/__snapshots__/index.test.tsx.snap @@ -1,83 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Users Table Component Rendering it renders the default Users table 1`] = ` - -`; +exports[`Users Table Component Rendering it renders the default Users table 1`] = `null`; diff --git a/x-pack/plugins/security_solution/public/network/components/users_table/index.tsx b/x-pack/plugins/security_solution/public/network/components/users_table/index.tsx index 9a971e0087d12..0355d0a30cfa4 100644 --- a/x-pack/plugins/security_solution/public/network/components/users_table/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/users_table/index.tsx @@ -5,7 +5,7 @@ */ import React, { useCallback, useMemo } from 'react'; -import { connect, ConnectedProps } from 'react-redux'; +import { useDispatch, useSelector, shallowEqual } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { assertUnreachable } from '../../../../common/utility_types'; @@ -13,11 +13,10 @@ import { networkActions, networkModel, networkSelectors } from '../../store'; import { Direction, FlowTarget, - UsersEdges, - UsersFields, - UsersSortField, -} from '../../../graphql/types'; -import { State } from '../../../common/store'; + NetworkUsersEdges, + NetworkUsersFields, + SortField, +} from '../../../../common/search_strategy'; import { Criteria, ItemsPerRow, @@ -27,10 +26,10 @@ import { import { getUsersColumns } from './columns'; import * as i18n from './translations'; -const tableType = networkModel.IpDetailsTableType.users; +const tableType = networkModel.NetworkDetailsTableType.users; -interface OwnProps { - data: UsersEdges[]; +interface UsersTableProps { + data: NetworkUsersEdges[]; flowTarget: FlowTarget; fakeTotalCount: number; id: string; @@ -42,8 +41,6 @@ interface OwnProps { type: networkModel.NetworkType; } -type UsersTableProps = OwnProps & PropsFromRedux; - const rowItems: ItemsPerRow[] = [ { text: i18n.ROWS_5, @@ -57,122 +54,110 @@ const rowItems: ItemsPerRow[] = [ export const usersTableId = 'users-table'; -const UsersTableComponent = React.memo( - ({ - activePage, - data, - fakeTotalCount, - flowTarget, - id, - isInspect, - limit, - loading, - loadPage, - showMorePagesIndicator, - totalCount, - type, - updateNetworkTable, - sort, - }) => { - const updateLimitPagination = useCallback( - (newLimit) => - updateNetworkTable({ +const UsersTableComponent: React.FC = ({ + data, + fakeTotalCount, + flowTarget, + id, + isInspect, + loading, + loadPage, + showMorePagesIndicator, + totalCount, + type, +}) => { + const dispatch = useDispatch(); + const getUsersSelector = networkSelectors.usersSelector(); + const { activePage, sort, limit } = useSelector(getUsersSelector, shallowEqual); + const updateLimitPagination = useCallback( + (newLimit) => + dispatch( + networkActions.updateNetworkTable({ networkType: type, tableType, updates: { limit: newLimit }, - }), - [type, updateNetworkTable] - ); - - const updateActivePage = useCallback( - (newPage) => - updateNetworkTable({ + }) + ), + [dispatch, type] + ); + + const updateActivePage = useCallback( + (newPage) => + dispatch( + networkActions.updateNetworkTable({ networkType: type, tableType, updates: { activePage: newPage }, - }), - [type, updateNetworkTable] - ); - - const onChange = useCallback( - (criteria: Criteria) => { - if (criteria.sort != null) { - const splitField = criteria.sort.field.split('.'); - const newUsersSort: UsersSortField = { - field: getSortFromString(splitField[splitField.length - 1]), - direction: criteria.sort.direction as Direction, - }; - if (!deepEqual(newUsersSort, sort)) { - updateNetworkTable({ + }) + ), + [dispatch, type] + ); + + const onChange = useCallback( + (criteria: Criteria) => { + if (criteria.sort != null) { + const splitField = criteria.sort.field.split('.'); + const newUsersSort: SortField = { + field: getSortFromString(splitField[splitField.length - 1]), + direction: criteria.sort.direction as Direction, + }; + if (!deepEqual(newUsersSort, sort)) { + dispatch( + networkActions.updateNetworkTable({ networkType: type, tableType, updates: { sort: newUsersSort }, - }); - } + }) + ); } - }, - [sort, type, updateNetworkTable] - ); - - // eslint-disable-next-line react-hooks/exhaustive-deps - const columns = useMemo(() => getUsersColumns(flowTarget, usersTableId), [ - flowTarget, - usersTableId, - ]); - - return ( - - ); - } -); + } + }, + [dispatch, sort, type] + ); -UsersTableComponent.displayName = 'UsersTableComponent'; - -const makeMapStateToProps = () => { - const getUsersSelector = networkSelectors.usersSelector(); - return (state: State) => ({ - ...getUsersSelector(state), - }); -}; - -const mapDispatchToProps = { - updateNetworkTable: networkActions.updateNetworkTable, + // eslint-disable-next-line react-hooks/exhaustive-deps + const columns = useMemo(() => getUsersColumns(flowTarget, usersTableId), [ + flowTarget, + usersTableId, + ]); + + return ( + + ); }; -const connector = connect(makeMapStateToProps, mapDispatchToProps); - -type PropsFromRedux = ConnectedProps; +UsersTableComponent.displayName = 'UsersTableComponent'; -export const UsersTable = connector(UsersTableComponent); +export const UsersTable = React.memo(UsersTableComponent); -const getSortField = (sortField: UsersSortField): SortingBasicTable => { +const getSortField = (sortField: SortField): SortingBasicTable => { switch (sortField.field) { - case UsersFields.name: + case NetworkUsersFields.name: return { field: `node.user.${sortField.field}`, direction: sortField.direction, }; - case UsersFields.count: + case NetworkUsersFields.count: return { field: `node.user.${sortField.field}`, direction: sortField.direction, @@ -181,13 +166,13 @@ const getSortField = (sortField: UsersSortField): SortingBasicTable => { return assertUnreachable(sortField.field); }; -const getSortFromString = (sortField: string): UsersFields => { +const getSortFromString = (sortField: string): NetworkUsersFields => { switch (sortField) { - case UsersFields.name.valueOf(): - return UsersFields.name; - case UsersFields.count.valueOf(): - return UsersFields.count; + case NetworkUsersFields.name.valueOf(): + return NetworkUsersFields.name; + case NetworkUsersFields.count.valueOf(): + return NetworkUsersFields.count; default: - return UsersFields.name; + return NetworkUsersFields.name; } }; diff --git a/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.gql_query.ts b/x-pack/plugins/security_solution/public/network/containers/details/index.gql_query.ts similarity index 100% rename from x-pack/plugins/security_solution/public/network/containers/ip_overview/index.gql_query.ts rename to x-pack/plugins/security_solution/public/network/containers/details/index.gql_query.ts diff --git a/x-pack/plugins/security_solution/public/network/containers/details/index.tsx b/x-pack/plugins/security_solution/public/network/containers/details/index.tsx new file mode 100644 index 0000000000000..597f85ff082e2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/network/containers/details/index.tsx @@ -0,0 +1,153 @@ +/* + * 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 { noop } from 'lodash/fp'; +import { useState, useEffect, useCallback, useRef } from 'react'; +import deepEqual from 'fast-deep-equal'; + +import { ESTermQuery } from '../../../../common/typed_json'; +import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; +import { inputsModel } from '../../../common/store'; +import { useKibana } from '../../../common/lib/kibana'; +import { createFilter } from '../../../common/containers/helpers'; +import { + DocValueFields, + NetworkQueries, + NetworkDetailsRequestOptions, + NetworkDetailsStrategyResponse, +} from '../../../../common/search_strategy'; +import { AbortError } from '../../../../../../../src/plugins/data/common'; +import * as i18n from './translations'; +import { getInspectResponse } from '../../../helpers'; +import { InspectResponse } from '../../../types'; + +const ID = 'networkDetailsQuery'; + +export interface NetworkDetailsArgs { + id: string; + inspect: InspectResponse; + networkDetails: NetworkDetailsStrategyResponse['networkDetails']; + refetch: inputsModel.Refetch; + isInspected: boolean; +} + +interface UseNetworkDetails { + id?: string; + docValueFields: DocValueFields[]; + ip: string; + filterQuery?: ESTermQuery | string; + skip: boolean; +} + +export const useNetworkDetails = ({ + docValueFields, + filterQuery, + id = ID, + skip, + ip, +}: UseNetworkDetails): [boolean, NetworkDetailsArgs] => { + const { data, notifications, uiSettings } = useKibana().services; + const refetch = useRef(noop); + const abortCtrl = useRef(new AbortController()); + const defaultIndex = uiSettings.get(DEFAULT_INDEX_KEY); + const [loading, setLoading] = useState(false); + + const [networkDetailsRequest, setNetworkDetailsRequest] = useState({ + defaultIndex, + docValueFields: docValueFields ?? [], + factoryQueryType: NetworkQueries.details, + filterQuery: createFilter(filterQuery), + ip, + }); + + const [networkDetailsResponse, setNetworkDetailsResponse] = useState({ + networkDetails: {}, + id, + inspect: { + dsl: [], + response: [], + }, + isInspected: false, + refetch: refetch.current, + }); + + const networkDetailsSearch = useCallback( + (request: NetworkDetailsRequestOptions) => { + let didCancel = false; + const asyncSearch = async () => { + abortCtrl.current = new AbortController(); + setLoading(true); + + const searchSubscription$ = data.search + .search(request, { + strategy: 'securitySolutionSearchStrategy', + abortSignal: abortCtrl.current.signal, + }) + .subscribe({ + next: (response) => { + if (!response.isPartial && !response.isRunning) { + if (!didCancel) { + setLoading(false); + setNetworkDetailsResponse((prevResponse) => ({ + ...prevResponse, + networkDetails: response.networkDetails, + inspect: getInspectResponse(response, prevResponse.inspect), + refetch: refetch.current, + })); + } + searchSubscription$.unsubscribe(); + } else if (response.isPartial && !response.isRunning) { + if (!didCancel) { + setLoading(false); + } + // TODO: Make response error status clearer + notifications.toasts.addWarning(i18n.ERROR_NETWORK_DETAILS); + searchSubscription$.unsubscribe(); + } + }, + error: (msg) => { + if (!(msg instanceof AbortError)) { + notifications.toasts.addDanger({ + title: i18n.FAIL_NETWORK_DETAILS, + text: msg.message, + }); + } + }, + }); + }; + abortCtrl.current.abort(); + asyncSearch(); + refetch.current = asyncSearch; + return () => { + didCancel = true; + abortCtrl.current.abort(); + }; + }, + [data.search, notifications.toasts] + ); + + useEffect(() => { + setNetworkDetailsRequest((prevRequest) => { + const myRequest = { + ...prevRequest, + defaultIndex, + ip, + docValueFields: docValueFields ?? [], + filterQuery: createFilter(filterQuery), + }; + if (!skip && !deepEqual(prevRequest, myRequest)) { + return myRequest; + } + return prevRequest; + }); + }, [defaultIndex, filterQuery, skip, ip, docValueFields]); + + useEffect(() => { + networkDetailsSearch(networkDetailsRequest); + }, [networkDetailsRequest, networkDetailsSearch]); + + return [loading, networkDetailsResponse]; +}; diff --git a/x-pack/plugins/security_solution/public/network/containers/details/translations.ts b/x-pack/plugins/security_solution/public/network/containers/details/translations.ts new file mode 100644 index 0000000000000..4aedd685630b7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/network/containers/details/translations.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ERROR_NETWORK_DETAILS = i18n.translate( + 'xpack.securitySolution.networkDetails.errorSearchDescription', + { + defaultMessage: `An error has occurred on network details search`, + } +); + +export const FAIL_NETWORK_DETAILS = i18n.translate( + 'xpack.securitySolution.networkDetails.failSearchDescription', + { + defaultMessage: `Failed to run search on network details`, + } +); diff --git a/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.tsx b/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.tsx deleted file mode 100644 index 6c8b54cc79517..0000000000000 --- a/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.tsx +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 { getOr } from 'lodash/fp'; -import React from 'react'; -import { Query } from 'react-apollo'; -import { connect, ConnectedProps } from 'react-redux'; - -import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; -import { GetIpOverviewQuery, IpOverviewData } from '../../../graphql/types'; -import { inputsModel, inputsSelectors, State } from '../../../common/store'; -import { useUiSetting } from '../../../common/lib/kibana'; -import { createFilter, getDefaultFetchPolicy } from '../../../common/containers/helpers'; -import { QueryTemplateProps } from '../../../common/containers/query_template'; -import { networkModel } from '../../store'; -import { ipOverviewQuery } from './index.gql_query'; - -const ID = 'ipOverviewQuery'; - -export interface IpOverviewArgs { - id: string; - inspect: inputsModel.InspectQuery; - ipOverviewData: IpOverviewData; - loading: boolean; - refetch: inputsModel.Refetch; -} - -export interface IpOverviewProps extends QueryTemplateProps { - children: (args: IpOverviewArgs) => React.ReactNode; - type: networkModel.NetworkType; - ip: string; -} - -const IpOverviewComponentQuery = React.memo( - ({ id = ID, docValueFields, isInspected, children, filterQuery, skip, sourceId, ip }) => ( - - query={ipOverviewQuery} - fetchPolicy={getDefaultFetchPolicy()} - notifyOnNetworkStatusChange - skip={skip} - variables={{ - sourceId, - filterQuery: createFilter(filterQuery), - ip, - defaultIndex: useUiSetting(DEFAULT_INDEX_KEY), - docValueFields: docValueFields ?? [], - inspect: isInspected, - }} - > - {({ data, loading, refetch }) => { - const init: IpOverviewData = { host: {} }; - const ipOverviewData: IpOverviewData = getOr(init, 'source.IpOverview', data); - return children({ - id, - inspect: getOr(null, 'source.IpOverview.inspect', data), - ipOverviewData, - loading, - refetch, - }); - }} - - ) -); - -IpOverviewComponentQuery.displayName = 'IpOverviewComponentQuery'; - -const makeMapStateToProps = () => { - const getQuery = inputsSelectors.globalQueryByIdSelector(); - const mapStateToProps = (state: State, { id = ID }: IpOverviewProps) => { - const { isInspected } = getQuery(state, id); - return { - isInspected, - }; - }; - return mapStateToProps; -}; - -const connector = connect(makeMapStateToProps); - -type PropsFromRedux = ConnectedProps; - -export const IpOverviewQuery = connector(IpOverviewComponentQuery); diff --git a/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx b/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx index 53d9a303ab849..6f48cba2ebda1 100644 --- a/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/network_dns/index.tsx @@ -175,10 +175,6 @@ export const useNetworkDns = ({ ); useEffect(() => { - if (skip) { - return; - } - setNetworkDnsRequest((prevRequest) => { const myRequest = { ...prevRequest, @@ -193,7 +189,7 @@ export const useNetworkDns = ({ to: endDate, }, }; - if (!deepEqual(prevRequest, myRequest)) { + if (!skip && !deepEqual(prevRequest, myRequest)) { return myRequest; } return prevRequest; diff --git a/x-pack/plugins/security_solution/public/network/containers/users/index.tsx b/x-pack/plugins/security_solution/public/network/containers/users/index.tsx index efbeb3eb00542..608ccdb084709 100644 --- a/x-pack/plugins/security_solution/public/network/containers/users/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/users/index.tsx @@ -4,154 +4,195 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getOr } from 'lodash/fp'; -import React from 'react'; -import { Query } from 'react-apollo'; -import { connect, ConnectedProps } from 'react-redux'; -import { compose } from 'redux'; +import { noop } from 'lodash/fp'; +import { useState, useEffect, useCallback, useRef } from 'react'; +import { shallowEqual, useSelector } from 'react-redux'; +import deepEqual from 'fast-deep-equal'; +import { ESTermQuery } from '../../../../common/typed_json'; import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; -import { GetUsersQuery, FlowTarget, PageInfoPaginated, UsersEdges } from '../../../graphql/types'; -import { inputsModel, State, inputsSelectors } from '../../../common/store'; -import { withKibana, WithKibanaProps } from '../../../common/lib/kibana'; -import { createFilter, getDefaultFetchPolicy } from '../../../common/containers/helpers'; +import { inputsModel } from '../../../common/store'; +import { useKibana } from '../../../common/lib/kibana'; +import { createFilter } from '../../../common/containers/helpers'; +import { PageInfoPaginated } from '../../../graphql/types'; import { generateTablePaginationOptions } from '../../../common/components/paginated_table/helpers'; +import { networkSelectors } from '../../store'; import { - QueryTemplatePaginated, - QueryTemplatePaginatedProps, -} from '../../../common/containers/query_template_paginated'; -import { networkModel, networkSelectors } from '../../store'; + FlowTarget, + NetworkQueries, + NetworkUsersRequestOptions, + NetworkUsersStrategyResponse, +} from '../../../../common/search_strategy/security_solution/network'; +import { AbortError } from '../../../../../../../src/plugins/data/common'; +import * as i18n from './translations'; +import { getInspectResponse } from '../../../helpers'; +import { InspectResponse } from '../../../types'; -import { usersQuery } from './index.gql_query'; +const ID = 'networkUsersQuery'; -const ID = 'usersQuery'; - -export interface UsersArgs { +export interface NetworkUsersArgs { id: string; - inspect: inputsModel.InspectQuery; + inspect: InspectResponse; isInspected: boolean; - loading: boolean; loadPage: (newActivePage: number) => void; + networkUsers: NetworkUsersStrategyResponse['edges']; pageInfo: PageInfoPaginated; refetch: inputsModel.Refetch; + stackByField?: string; totalCount: number; - users: UsersEdges[]; } -export interface OwnProps extends QueryTemplatePaginatedProps { - children: (args: UsersArgs) => React.ReactNode; +interface UseNetworkUsers { + id?: string; + filterQuery?: ESTermQuery | string; + endDate: string; + startDate: string; + skip: boolean; flowTarget: FlowTarget; ip: string; - type: networkModel.NetworkType; } -type UsersProps = OwnProps & PropsFromRedux & WithKibanaProps; +export const useNetworkUsers = ({ + endDate, + filterQuery, + flowTarget, + id = ID, + ip, + skip, + startDate, +}: UseNetworkUsers): [boolean, NetworkUsersArgs] => { + const getNetworkUsersSelector = networkSelectors.usersSelector(); + const { activePage, sort, limit } = useSelector(getNetworkUsersSelector, shallowEqual); + const { data, notifications, uiSettings } = useKibana().services; + const refetch = useRef(noop); + const abortCtrl = useRef(new AbortController()); + const defaultIndex = uiSettings.get(DEFAULT_INDEX_KEY); + const [loading, setLoading] = useState(false); + + const [networkUsersRequest, setNetworkUsersRequest] = useState({ + defaultIndex, + factoryQueryType: NetworkQueries.users, + filterQuery: createFilter(filterQuery), + flowTarget, + ip, + pagination: generateTablePaginationOptions(activePage, limit), + sort, + timerange: { + interval: '12h', + from: startDate ? startDate : '', + to: endDate ? endDate : new Date(Date.now()).toISOString(), + }, + }); + + const wrappedLoadMore = useCallback( + (newActivePage: number) => { + setNetworkUsersRequest((prevRequest) => ({ + ...prevRequest, + pagination: generateTablePaginationOptions(newActivePage, limit), + })); + }, + [limit] + ); -class UsersComponentQuery extends QueryTemplatePaginated< - UsersProps, - GetUsersQuery.Query, - GetUsersQuery.Variables -> { - public render() { - const { - activePage, - children, - endDate, - filterQuery, - flowTarget, - id = ID, - ip, - isInspected, - kibana, - limit, - skip, - sourceId, - startDate, - sort, - } = this.props; - const variables: GetUsersQuery.Variables = { - defaultIndex: kibana.services.uiSettings.get(DEFAULT_INDEX_KEY), - filterQuery: createFilter(filterQuery), - flowTarget, - inspect: isInspected, - ip, - pagination: generateTablePaginationOptions(activePage, limit), - sort, - sourceId, - timerange: { - interval: '12h', - from: startDate!, - to: endDate!, - }, - }; - return ( - - query={usersQuery} - fetchPolicy={getDefaultFetchPolicy()} - notifyOnNetworkStatusChange - skip={skip} - variables={variables} - > - {({ data, loading, fetchMore, networkStatus, refetch }) => { - const users = getOr([], `source.Users.edges`, data); - this.setFetchMore(fetchMore); - this.setFetchMoreOptions((newActivePage: number) => ({ - variables: { - pagination: generateTablePaginationOptions(newActivePage, limit), + const [networkUsersResponse, setNetworkUsersResponse] = useState({ + networkUsers: [], + id, + inspect: { + dsl: [], + response: [], + }, + isInspected: false, + loadPage: wrappedLoadMore, + pageInfo: { + activePage: 0, + fakeTotalCount: 0, + showMorePagesIndicator: false, + }, + refetch: refetch.current, + totalCount: -1, + }); + + const networkUsersSearch = useCallback( + (request: NetworkUsersRequestOptions) => { + let didCancel = false; + const asyncSearch = async () => { + abortCtrl.current = new AbortController(); + setLoading(true); + + const searchSubscription$ = data.search + .search(request, { + strategy: 'securitySolutionSearchStrategy', + abortSignal: abortCtrl.current.signal, + }) + .subscribe({ + next: (response) => { + if (!response.isPartial && !response.isRunning) { + if (!didCancel) { + setLoading(false); + setNetworkUsersResponse((prevResponse) => ({ + ...prevResponse, + networkUsers: response.edges, + inspect: getInspectResponse(response, prevResponse.inspect), + pageInfo: response.pageInfo, + refetch: refetch.current, + totalCount: response.totalCount, + })); + } + searchSubscription$.unsubscribe(); + } else if (response.isPartial && !response.isRunning) { + if (!didCancel) { + setLoading(false); + } + // TODO: Make response error status clearer + notifications.toasts.addWarning(i18n.ERROR_NETWORK_USERS); + searchSubscription$.unsubscribe(); + } }, - updateQuery: (prev, { fetchMoreResult }) => { - if (!fetchMoreResult) { - return prev; + error: (msg) => { + if (!(msg instanceof AbortError)) { + notifications.toasts.addDanger({ + title: i18n.FAIL_NETWORK_USERS, + text: msg.message, + }); } - return { - ...fetchMoreResult, - source: { - ...fetchMoreResult.source, - Users: { - ...fetchMoreResult.source.Users, - edges: [...fetchMoreResult.source.Users.edges], - }, - }, - }; }, - })); - const isLoading = this.isItAValidLoading(loading, variables, networkStatus); - return children({ - id, - inspect: getOr(null, 'source.Users.inspect', data), - isInspected, - loading: isLoading, - loadPage: this.wrappedLoadMore, - pageInfo: getOr({}, 'source.Users.pageInfo', data), - refetch: this.memoizedRefetchQuery(variables, limit, refetch), - totalCount: getOr(-1, 'source.Users.totalCount', data), - users, }); - }} - - ); - } -} - -const makeMapStateToProps = () => { - const getUsersSelector = networkSelectors.usersSelector(); - const getQuery = inputsSelectors.globalQueryByIdSelector(); - const mapStateToProps = (state: State, { id = ID }: OwnProps) => { - const { isInspected } = getQuery(state, id); - return { - ...getUsersSelector(state), - isInspected, - }; - }; + }; + abortCtrl.current.abort(); + asyncSearch(); + refetch.current = asyncSearch; + return () => { + didCancel = true; + abortCtrl.current.abort(); + }; + }, + [data.search, notifications.toasts] + ); - return mapStateToProps; -}; + useEffect(() => { + setNetworkUsersRequest((prevRequest) => { + const myRequest = { + ...prevRequest, + defaultIndex, + filterQuery: createFilter(filterQuery), + pagination: generateTablePaginationOptions(activePage, limit), + sort, + timerange: { + interval: '12h', + from: startDate, + to: endDate, + }, + }; + if (!skip && !deepEqual(prevRequest, myRequest)) { + return myRequest; + } + return prevRequest; + }); + }, [activePage, defaultIndex, endDate, filterQuery, limit, startDate, sort, skip]); -const connector = connect(makeMapStateToProps); + useEffect(() => { + networkUsersSearch(networkUsersRequest); + }, [networkUsersRequest, networkUsersSearch]); -type PropsFromRedux = ConnectedProps; - -export const UsersQuery = compose>( - connector, - withKibana -)(UsersComponentQuery); + return [loading, networkUsersResponse]; +}; diff --git a/x-pack/plugins/security_solution/public/network/containers/users/translations.ts b/x-pack/plugins/security_solution/public/network/containers/users/translations.ts new file mode 100644 index 0000000000000..dac260dec984b --- /dev/null +++ b/x-pack/plugins/security_solution/public/network/containers/users/translations.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ERROR_NETWORK_USERS = i18n.translate( + 'xpack.securitySolution.networkUsers.errorSearchDescription', + { + defaultMessage: `An error has occurred on network users search`, + } +); + +export const FAIL_NETWORK_USERS = i18n.translate( + 'xpack.securitySolution.networkUsers.failSearchDescription', + { + defaultMessage: `Failed to run search on network users`, + } +); diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/index.test.tsx b/x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx similarity index 67% rename from x-pack/plugins/security_solution/public/network/pages/ip_details/index.test.tsx rename to x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx index e2e458bcec2f5..beae3e4f72aaa 100644 --- a/x-pack/plugins/security_solution/public/network/pages/ip_details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx @@ -4,10 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { shallow } from 'enzyme'; import React from 'react'; -import { Router } from 'react-router-dom'; -import { ActionCreator } from 'typescript-fsa'; +import { Router, useParams } from 'react-router-dom'; import '../../../common/mock/match_media'; @@ -23,14 +21,24 @@ import { } from '../../../common/mock'; import { useMountAppended } from '../../../common/utils/use_mount_appended'; import { createStore, State } from '../../../common/store'; -import { InputsModelId } from '../../../common/store/inputs/constants'; -import { IPDetailsComponent, IPDetails } from './index'; +import { NetworkDetails } from './index'; type Action = 'PUSH' | 'POP' | 'REPLACE'; const pop: Action = 'POP'; type GlobalWithFetch = NodeJS.Global & { fetch: jest.Mock }; +jest.mock('react-router-dom', () => { + const original = jest.requireActual('react-router-dom'); + + return { + ...original, + useParams: jest.fn(), + }; +}); +jest.mock('../../containers/details', () => ({ + useNetworkDetails: jest.fn().mockReturnValue([true, { networkDetails: {} }]), +})); jest.mock('../../../common/lib/kibana'); jest.mock('../../../common/containers/source'); jest.mock('../../../common/containers/use_global_time', () => ({ @@ -70,34 +78,7 @@ const getMockHistory = (ip: string) => ({ listen: jest.fn(), }); -const to = '2018-03-23T18:49:23.132Z'; -const from = '2018-03-24T03:33:52.253Z'; -const getMockProps = (ip: string) => ({ - to, - from, - isInitializing: false, - setQuery: jest.fn(), - query: { query: 'coolQueryhuh?', language: 'keury' }, - filters: [], - flowTarget: FlowTarget.source, - history: getMockHistory(ip), - location: { - pathname: `/network/ip/${ip}`, - search: '', - state: '', - hash: '', - }, - detailName: ip, - match: { params: { detailName: ip, search: '' }, isExact: true, path: '', url: '' }, - setAbsoluteRangeDatePicker: (jest.fn() as unknown) as ActionCreator<{ - id: InputsModelId; - from: string; - to: string; - }>, - setIpDetailsTablesActivePageToZero: (jest.fn() as unknown) as ActionCreator, -}); - -describe('Ip Details', () => { +describe('Network Details', () => { const mount = useMountAppended(); beforeAll(() => { (useWithSource as jest.Mock).mockReturnValue({ @@ -139,31 +120,41 @@ describe('Ip Details', () => { }); test('it renders', () => { - const wrapper = shallow(); - expect(wrapper.find('[data-test-subj="ip-details-page"]').exists()).toBe(true); - }); - - test('it matches the snapshot', () => { - const wrapper = shallow(); - expect(wrapper).toMatchSnapshot(); + const ip = '123.456.78.90'; + (useParams as jest.Mock).mockReturnValue({ + detailName: ip, + flowTarget: FlowTarget.source, + }); + const wrapper = mount( + + + + + + ); + expect(wrapper.find('[data-test-subj="network-details-page"]').exists()).toBe(true); }); test('it renders ipv6 headline', async () => { + const ip = 'fe80--24ce-f7ff-fede-a571'; (useWithSource as jest.Mock).mockReturnValue({ indicesExist: true, indexPattern: {}, }); - const ip = 'fe80--24ce-f7ff-fede-a571'; + (useParams as jest.Mock).mockReturnValue({ + detailName: ip, + flowTarget: FlowTarget.source, + }); const wrapper = mount( - + ); expect( wrapper - .find('[data-test-subj="ip-details-headline"] [data-test-subj="header-page-title"]') + .find('[data-test-subj="network-details-headline"] [data-test-subj="header-page-title"]') .text() ).toEqual('fe80::24ce:f7ff:fede:a571'); }); diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx b/x-pack/plugins/security_solution/public/network/pages/details/index.tsx similarity index 69% rename from x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx rename to x-pack/plugins/security_solution/public/network/pages/details/index.tsx index c9ac1fc7a6e9c..085cddf53ff65 100644 --- a/x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/details/index.tsx @@ -5,39 +5,40 @@ */ import { EuiHorizontalRule, EuiSpacer, EuiFlexItem } from '@elastic/eui'; -import React, { useCallback, useEffect } from 'react'; -import { connect, ConnectedProps } from 'react-redux'; +import React, { useCallback, useEffect, useMemo } from 'react'; +import { useDispatch, useSelector, shallowEqual } from 'react-redux'; +import { useParams } from 'react-router-dom'; +import { FlowTarget } from '../../../../common/search_strategy'; import { useGlobalTime } from '../../../common/containers/use_global_time'; import { FiltersGlobal } from '../../../common/components/filters_global'; import { HeaderPage } from '../../../common/components/header_page'; import { LastEventTime } from '../../../common/components/last_event_time'; -import { AnomalyTableProvider } from '../../../common/components/ml/anomaly/anomaly_table_provider'; +import { useAnomaliesTableData } from '../../../common/components/ml/anomaly/use_anomalies_table_data'; import { networkToCriteria } from '../../../common/components/ml/criteria/network_to_criteria'; import { scoreIntervalToDateTime } from '../../../common/components/ml/score/score_interval_to_datetime'; import { AnomaliesNetworkTable } from '../../../common/components/ml/tables/anomalies_network_table'; import { manageQuery } from '../../../common/components/page/manage_query'; import { FlowTargetSelectConnected } from '../../components/flow_target_select_connected'; -import { IpOverview } from '../../components/ip_overview'; +import { IpOverview } from '../../components/details'; import { SiemSearchBar } from '../../../common/components/search_bar'; import { WrapperPage } from '../../../common/components/wrapper_page'; -import { IpOverviewQuery } from '../../containers/ip_overview'; +import { useNetworkDetails } from '../../containers/details'; import { useWithSource } from '../../../common/containers/source'; import { FlowTargetSourceDest, LastEventIndexKey } from '../../../graphql/types'; import { useKibana } from '../../../common/lib/kibana'; import { decodeIpv6 } from '../../../common/lib/helpers'; import { convertToBuildEsQuery } from '../../../common/lib/keury'; import { ConditionalFlexGroup } from '../../pages/navigation/conditional_flex_group'; -import { State, inputsSelectors } from '../../../common/store'; -import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '../../../common/store/inputs/actions'; -import { setIpDetailsTablesActivePageToZero as dispatchIpDetailsTablesActivePageToZero } from '../../store/actions'; +import { inputsSelectors } from '../../../common/store'; +import { setAbsoluteRangeDatePicker } from '../../../common/store/inputs/actions'; +import { setNetworkDetailsTablesActivePageToZero } from '../../store/actions'; import { SpyRoute } from '../../../common/utils/route/spy_routes'; import { OverviewEmpty } from '../../../overview/components/overview_empty'; import { NetworkHttpQueryTable } from './network_http_query_table'; import { NetworkTopCountriesQueryTable } from './network_top_countries_query_table'; import { NetworkTopNFlowQueryTable } from './network_top_n_flow_query_table'; import { TlsQueryTable } from './tls_query_table'; -import { IPDetailsComponentProps } from './types'; import { UsersQueryTable } from './users_query_table'; import { AnomaliesQueryTabBody } from '../../../common/containers/anomalies/anomalies_query_tab_body'; import { esQuery } from '../../../../../../../src/plugins/data/public'; @@ -45,36 +46,42 @@ import { networkModel } from '../../store'; import { SecurityPageName } from '../../../app/types'; export { getBreadcrumbs } from './utils'; -const IpOverviewManage = manageQuery(IpOverview); +const NetworkDetailsManage = manageQuery(IpOverview); -export const IPDetailsComponent: React.FC = ({ - detailName, - filters, - flowTarget, - query, - setAbsoluteRangeDatePicker, - setIpDetailsTablesActivePageToZero, -}) => { +const NetworkDetailsComponent: React.FC = () => { + const dispatch = useDispatch(); const { to, from, setQuery, isInitializing } = useGlobalTime(); + const { detailName, flowTarget } = useParams<{ + detailName: string; + flowTarget: FlowTarget; + }>(); + const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); + const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); + + const query = useSelector(getGlobalQuerySelector, shallowEqual); + const filters = useSelector(getGlobalFiltersQuerySelector, shallowEqual); + const type = networkModel.NetworkType.details; const narrowDateRange = useCallback( (score, interval) => { const fromTo = scoreIntervalToDateTime(score, interval); - setAbsoluteRangeDatePicker({ - id: 'global', - from: fromTo.from, - to: fromTo.to, - }); + dispatch( + setAbsoluteRangeDatePicker({ + id: 'global', + from: fromTo.from, + to: fromTo.to, + }) + ); }, - [setAbsoluteRangeDatePicker] + [dispatch] ); const { services: { uiSettings }, } = useKibana(); useEffect(() => { - setIpDetailsTablesActivePageToZero(); - }, [detailName, setIpDetailsTablesActivePageToZero]); + dispatch(setNetworkDetailsTablesActivePageToZero()); + }, [detailName, dispatch]); const { docValueFields, indicesExist, indexPattern } = useWithSource(); const ip = decodeIpv6(detailName); @@ -85,8 +92,27 @@ export const IPDetailsComponent: React.FC ({ field: `${flowTarget}.ip`, value: ip }), [ + flowTarget, + ip, + ]); + return ( -
+
{indicesExist ? ( <> @@ -96,50 +122,30 @@ export const IPDetailsComponent: React.FC } title={ip} > - - {({ id, inspect, ipOverviewData, loading, refetch }) => ( - - {({ isLoadingAnomaliesData, anomaliesData }) => ( - - )} - - )} - + data={networkDetails} + anomaliesData={anomaliesData} + loading={loading} + isLoadingAnomaliesData={isLoadingAnomaliesData} + type={type} + flowTarget={flowTarget} + refetch={refetch} + setQuery={setQuery} + startDate={from} + endDate={to} + narrowDateRange={narrowDateRange} + /> @@ -272,25 +278,7 @@ export const IPDetailsComponent: React.FC ); }; -IPDetailsComponent.displayName = 'IPDetailsComponent'; - -const makeMapStateToProps = () => { - const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); - const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); - - return (state: State) => ({ - query: getGlobalQuerySelector(state), - filters: getGlobalFiltersQuerySelector(state), - }); -}; - -const mapDispatchToProps = { - setAbsoluteRangeDatePicker: dispatchAbsoluteRangeDatePicker, - setIpDetailsTablesActivePageToZero: dispatchIpDetailsTablesActivePageToZero, -}; - -export const connector = connect(makeMapStateToProps, mapDispatchToProps); -type PropsFromRedux = ConnectedProps; +NetworkDetailsComponent.displayName = 'NetworkDetailsComponent'; -export const IPDetails = connector(React.memo(IPDetailsComponent)); +export const NetworkDetails = React.memo(NetworkDetailsComponent); diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/network_http_query_table.tsx b/x-pack/plugins/security_solution/public/network/pages/details/network_http_query_table.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/network/pages/ip_details/network_http_query_table.tsx rename to x-pack/plugins/security_solution/public/network/pages/details/network_http_query_table.tsx diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/network_top_countries_query_table.tsx b/x-pack/plugins/security_solution/public/network/pages/details/network_top_countries_query_table.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/network/pages/ip_details/network_top_countries_query_table.tsx rename to x-pack/plugins/security_solution/public/network/pages/details/network_top_countries_query_table.tsx diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/network_top_n_flow_query_table.tsx b/x-pack/plugins/security_solution/public/network/pages/details/network_top_n_flow_query_table.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/network/pages/ip_details/network_top_n_flow_query_table.tsx rename to x-pack/plugins/security_solution/public/network/pages/details/network_top_n_flow_query_table.tsx diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/tls_query_table.tsx b/x-pack/plugins/security_solution/public/network/pages/details/tls_query_table.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/network/pages/ip_details/tls_query_table.tsx rename to x-pack/plugins/security_solution/public/network/pages/details/tls_query_table.tsx diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/types.ts b/x-pack/plugins/security_solution/public/network/pages/details/types.ts similarity index 92% rename from x-pack/plugins/security_solution/public/network/pages/ip_details/types.ts rename to x-pack/plugins/security_solution/public/network/pages/details/types.ts index cab6e8e09b200..960df0d5e36b9 100644 --- a/x-pack/plugins/security_solution/public/network/pages/ip_details/types.ts +++ b/x-pack/plugins/security_solution/public/network/pages/details/types.ts @@ -16,11 +16,6 @@ import { GlobalTimeArgs } from '../../../common/containers/use_global_time'; export const type = NetworkType.details; -export interface IPDetailsComponentProps { - detailName: string; - flowTarget: FlowTarget; -} - export interface OwnProps { type: NetworkType; startDate: string; diff --git a/x-pack/plugins/security_solution/public/network/pages/details/users_query_table.tsx b/x-pack/plugins/security_solution/public/network/pages/details/users_query_table.tsx new file mode 100644 index 0000000000000..a7a819151579f --- /dev/null +++ b/x-pack/plugins/security_solution/public/network/pages/details/users_query_table.tsx @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { getOr } from 'lodash/fp'; +import { manageQuery } from '../../../common/components/page/manage_query'; +import { useNetworkUsers } from '../../containers/users'; +import { NetworkComponentsQueryProps } from './types'; +import { UsersTable } from '../../components/users_table'; + +const UsersTableManage = manageQuery(UsersTable); + +export const UsersQueryTable = ({ + endDate, + filterQuery, + flowTarget, + ip, + setQuery, + skip, + startDate, + type, +}: NetworkComponentsQueryProps) => { + const [ + loading, + { id, inspect, isInspected, networkUsers, totalCount, pageInfo, loadPage, refetch }, + ] = useNetworkUsers({ + endDate, + filterQuery, + flowTarget, + ip, + skip, + startDate, + }); + + return ( + + ); +}; + +UsersQueryTable.displayName = 'UsersQueryTable'; diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/utils.ts b/x-pack/plugins/security_solution/public/network/pages/details/utils.ts similarity index 94% rename from x-pack/plugins/security_solution/public/network/pages/ip_details/utils.ts rename to x-pack/plugins/security_solution/public/network/pages/details/utils.ts index 9284a808625a5..2b5c68c81a9d3 100644 --- a/x-pack/plugins/security_solution/public/network/pages/ip_details/utils.ts +++ b/x-pack/plugins/security_solution/public/network/pages/details/utils.ts @@ -8,7 +8,7 @@ import { get, isEmpty } from 'lodash/fp'; import { ChromeBreadcrumb } from '../../../../../../../src/core/public'; import { decodeIpv6 } from '../../../common/lib/helpers'; -import { getIPDetailsUrl } from '../../../common/components/link_to/redirect_to_network'; +import { getNetworkDetailsUrl } from '../../../common/components/link_to/redirect_to_network'; import { networkModel } from '../../store'; import * as i18n from '../translations'; import { NetworkRouteType } from '../navigation/types'; @@ -46,7 +46,7 @@ export const getBreadcrumbs = ( { text: decodeIpv6(params.detailName), href: getUrlForApp(`${APP_ID}:${SecurityPageName.network}`, { - path: getIPDetailsUrl( + path: getNetworkDetailsUrl( params.detailName, params.flowTarget, !isEmpty(search[0]) ? search[0] : '' diff --git a/x-pack/plugins/security_solution/public/network/pages/index.tsx b/x-pack/plugins/security_solution/public/network/pages/index.tsx index 07abe7bc8c209..9e796b6f01dfa 100644 --- a/x-pack/plugins/security_solution/public/network/pages/index.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/index.tsx @@ -11,7 +11,7 @@ import { useMlCapabilities } from '../../common/components/ml/hooks/use_ml_capab import { hasMlUserPermissions } from '../../../common/machine_learning/has_ml_user_permissions'; import { FlowTarget } from '../../graphql/types'; -import { IPDetails } from './ip_details'; +import { NetworkDetails } from './details'; import { Network } from './network'; import { getNetworkRoutePath } from './navigation'; import { NetworkRouteType } from './navigation/types'; @@ -49,14 +49,9 @@ const NetworkContainerComponent: React.FC = () => { hasMlUserPermissions={userHasMlUserPermissions} /> - } - /> + + + - - - - - -
-`; diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/users_query_table.tsx b/x-pack/plugins/security_solution/public/network/pages/ip_details/users_query_table.tsx deleted file mode 100644 index 4071790b4208a..0000000000000 --- a/x-pack/plugins/security_solution/public/network/pages/ip_details/users_query_table.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 React from 'react'; -import { getOr } from 'lodash/fp'; -import { manageQuery } from '../../../common/components/page/manage_query'; -import { UsersQuery } from '../../containers/users'; -import { NetworkComponentsQueryProps } from './types'; -import { UsersTable } from '../../components/users_table'; - -const UsersTableManage = manageQuery(UsersTable); - -export const UsersQueryTable = ({ - endDate, - filterQuery, - flowTarget, - ip, - setQuery, - skip, - startDate, - type, -}: NetworkComponentsQueryProps) => ( - - {({ id, inspect, isInspected, users, totalCount, pageInfo, loading, loadPage, refetch }) => ( - - )} - -); - -UsersQueryTable.displayName = 'UsersQueryTable'; diff --git a/x-pack/plugins/security_solution/public/network/store/actions.ts b/x-pack/plugins/security_solution/public/network/store/actions.ts index 44a0b7ce1ad10..9c0242741304e 100644 --- a/x-pack/plugins/security_solution/public/network/store/actions.ts +++ b/x-pack/plugins/security_solution/public/network/store/actions.ts @@ -11,11 +11,11 @@ const actionCreator = actionCreatorFactory('x-pack/security_solution/local/netwo export const updateNetworkTable = actionCreator<{ networkType: networkModel.NetworkType; - tableType: networkModel.NetworkTableType | networkModel.IpDetailsTableType; + tableType: networkModel.NetworkTableType | networkModel.NetworkDetailsTableType; updates: networkModel.TableUpdates; }>('UPDATE_NETWORK_TABLE'); -export const setIpDetailsTablesActivePageToZero = actionCreator( +export const setNetworkDetailsTablesActivePageToZero = actionCreator( 'SET_IP_DETAILS_TABLES_ACTIVE_PAGE_TO_ZERO' ); diff --git a/x-pack/plugins/security_solution/public/network/store/helpers.test.ts b/x-pack/plugins/security_solution/public/network/store/helpers.test.ts index a3a2a9b7f5393..944939074693b 100644 --- a/x-pack/plugins/security_solution/public/network/store/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/network/store/helpers.test.ts @@ -9,11 +9,11 @@ import { FlowTarget, NetworkDnsFields, NetworkTopTablesFields, - TlsFields, - UsersFields, -} from '../../graphql/types'; + NetworkTlsFields, + NetworkUsersFields, +} from '../../../common/search_strategy'; import { DEFAULT_TABLE_LIMIT } from '../../common/store/constants'; -import { NetworkModel, NetworkTableType, IpDetailsTableType, NetworkType } from './model'; +import { NetworkModel, NetworkTableType, NetworkDetailsTableType, NetworkType } from './model'; import { setNetworkQueriesActivePageToZero } from './helpers'; export const mockNetworkState: NetworkModel = { @@ -64,7 +64,7 @@ export const mockNetworkState: NetworkModel = { activePage: 2, limit: DEFAULT_TABLE_LIMIT, sort: { - field: TlsFields._id, + field: NetworkTlsFields._id, direction: Direction.desc, }, }, @@ -81,7 +81,7 @@ export const mockNetworkState: NetworkModel = { }, details: { queries: { - [IpDetailsTableType.topCountriesSource]: { + [NetworkDetailsTableType.topCountriesSource]: { activePage: 7, limit: DEFAULT_TABLE_LIMIT, sort: { @@ -89,7 +89,7 @@ export const mockNetworkState: NetworkModel = { direction: Direction.desc, }, }, - [IpDetailsTableType.topCountriesDestination]: { + [NetworkDetailsTableType.topCountriesDestination]: { activePage: 3, limit: DEFAULT_TABLE_LIMIT, sort: { @@ -97,7 +97,7 @@ export const mockNetworkState: NetworkModel = { direction: Direction.desc, }, }, - [IpDetailsTableType.topNFlowSource]: { + [NetworkDetailsTableType.topNFlowSource]: { activePage: 7, limit: DEFAULT_TABLE_LIMIT, sort: { @@ -105,7 +105,7 @@ export const mockNetworkState: NetworkModel = { direction: Direction.desc, }, }, - [IpDetailsTableType.topNFlowDestination]: { + [NetworkDetailsTableType.topNFlowDestination]: { activePage: 3, limit: DEFAULT_TABLE_LIMIT, sort: { @@ -113,23 +113,23 @@ export const mockNetworkState: NetworkModel = { direction: Direction.desc, }, }, - [IpDetailsTableType.tls]: { + [NetworkDetailsTableType.tls]: { activePage: 2, limit: DEFAULT_TABLE_LIMIT, sort: { - field: TlsFields._id, + field: NetworkTlsFields._id, direction: Direction.desc, }, }, - [IpDetailsTableType.users]: { + [NetworkDetailsTableType.users]: { activePage: 6, limit: DEFAULT_TABLE_LIMIT, sort: { - field: UsersFields.name, + field: NetworkUsersFields.name, direction: Direction.asc, }, }, - [IpDetailsTableType.http]: { + [NetworkDetailsTableType.http]: { activePage: 0, limit: DEFAULT_TABLE_LIMIT, sort: { direction: Direction.desc }, @@ -199,17 +199,17 @@ describe('Network redux store', () => { test('set activePage to zero for all queries in ip details ', () => { expect(setNetworkQueriesActivePageToZero(mockNetworkState, NetworkType.details)).toEqual({ - [IpDetailsTableType.topNFlowSource]: { + [NetworkDetailsTableType.topNFlowSource]: { activePage: 0, limit: 10, sort: { field: 'bytes_out', direction: 'desc' }, }, - [IpDetailsTableType.topNFlowDestination]: { + [NetworkDetailsTableType.topNFlowDestination]: { activePage: 0, limit: 10, sort: { field: 'bytes_out', direction: 'desc' }, }, - [IpDetailsTableType.topCountriesDestination]: { + [NetworkDetailsTableType.topCountriesDestination]: { activePage: 0, limit: 10, sort: { @@ -217,7 +217,7 @@ describe('Network redux store', () => { field: 'bytes_out', }, }, - [IpDetailsTableType.topCountriesSource]: { + [NetworkDetailsTableType.topCountriesSource]: { activePage: 0, limit: 10, sort: { @@ -225,19 +225,19 @@ describe('Network redux store', () => { field: 'bytes_out', }, }, - [IpDetailsTableType.http]: { + [NetworkDetailsTableType.http]: { activePage: 0, limit: 10, sort: { direction: 'desc', }, }, - [IpDetailsTableType.tls]: { + [NetworkDetailsTableType.tls]: { activePage: 0, limit: 10, sort: { field: '_id', direction: 'desc' }, }, - [IpDetailsTableType.users]: { + [NetworkDetailsTableType.users]: { activePage: 0, limit: 10, sort: { field: 'name', direction: 'asc' }, diff --git a/x-pack/plugins/security_solution/public/network/store/helpers.ts b/x-pack/plugins/security_solution/public/network/store/helpers.ts index 938de1dedf0b7..e93e5ada03591 100644 --- a/x-pack/plugins/security_solution/public/network/store/helpers.ts +++ b/x-pack/plugins/security_solution/public/network/store/helpers.ts @@ -8,9 +8,9 @@ import { NetworkModel, NetworkType, NetworkTableType, - IpDetailsTableType, + NetworkDetailsTableType, NetworkQueries, - IpOverviewQueries, + NetworkDetailsQueries, } from './model'; import { DEFAULT_TABLE_ACTIVE_PAGE } from '../../common/store/constants'; @@ -48,34 +48,34 @@ export const setNetworkPageQueriesActivePageToZero = (state: NetworkModel): Netw export const setNetworkDetailsQueriesActivePageToZero = ( state: NetworkModel -): IpOverviewQueries => ({ +): NetworkDetailsQueries => ({ ...state.details.queries, - [IpDetailsTableType.topCountriesSource]: { - ...state.details.queries[IpDetailsTableType.topCountriesSource], + [NetworkDetailsTableType.topCountriesSource]: { + ...state.details.queries[NetworkDetailsTableType.topCountriesSource], activePage: DEFAULT_TABLE_ACTIVE_PAGE, }, - [IpDetailsTableType.topCountriesDestination]: { - ...state.details.queries[IpDetailsTableType.topCountriesDestination], + [NetworkDetailsTableType.topCountriesDestination]: { + ...state.details.queries[NetworkDetailsTableType.topCountriesDestination], activePage: DEFAULT_TABLE_ACTIVE_PAGE, }, - [IpDetailsTableType.topNFlowSource]: { - ...state.details.queries[IpDetailsTableType.topNFlowSource], + [NetworkDetailsTableType.topNFlowSource]: { + ...state.details.queries[NetworkDetailsTableType.topNFlowSource], activePage: DEFAULT_TABLE_ACTIVE_PAGE, }, - [IpDetailsTableType.topNFlowDestination]: { - ...state.details.queries[IpDetailsTableType.topNFlowDestination], + [NetworkDetailsTableType.topNFlowDestination]: { + ...state.details.queries[NetworkDetailsTableType.topNFlowDestination], activePage: DEFAULT_TABLE_ACTIVE_PAGE, }, - [IpDetailsTableType.tls]: { - ...state.details.queries[IpDetailsTableType.tls], + [NetworkDetailsTableType.tls]: { + ...state.details.queries[NetworkDetailsTableType.tls], activePage: DEFAULT_TABLE_ACTIVE_PAGE, }, - [IpDetailsTableType.users]: { - ...state.details.queries[IpDetailsTableType.users], + [NetworkDetailsTableType.users]: { + ...state.details.queries[NetworkDetailsTableType.users], activePage: DEFAULT_TABLE_ACTIVE_PAGE, }, - [IpDetailsTableType.http]: { - ...state.details.queries[IpDetailsTableType.http], + [NetworkDetailsTableType.http]: { + ...state.details.queries[NetworkDetailsTableType.http], activePage: DEFAULT_TABLE_ACTIVE_PAGE, }, }); @@ -83,7 +83,7 @@ export const setNetworkDetailsQueriesActivePageToZero = ( export const setNetworkQueriesActivePageToZero = ( state: NetworkModel, type: NetworkType -): NetworkQueries | IpOverviewQueries => { +): NetworkQueries | NetworkDetailsQueries => { if (type === NetworkType.page) { return setNetworkPageQueriesActivePageToZero(state); } else if (type === NetworkType.details) { diff --git a/x-pack/plugins/security_solution/public/network/store/model.ts b/x-pack/plugins/security_solution/public/network/store/model.ts index 4ddfb84024970..f2daddbd5c3d5 100644 --- a/x-pack/plugins/security_solution/public/network/store/model.ts +++ b/x-pack/plugins/security_solution/public/network/store/model.ts @@ -5,13 +5,14 @@ */ import { + Direction, FlowTarget, - NetworkDnsSortField, - NetworkHttpSortField, - NetworkTopTablesSortField, - TlsSortField, - UsersSortField, -} from '../../graphql/types'; + NetworkDnsFields, + NetworkTopTablesFields, + NetworkTlsFields, + NetworkUsersFields, + SortField, +} from '../../../common/search_strategy'; export enum NetworkType { page = 'page', @@ -30,22 +31,22 @@ export enum NetworkTableType { } export type TopNTableType = - | IpDetailsTableType.topNFlowDestination - | IpDetailsTableType.topNFlowSource + | NetworkDetailsTableType.topNFlowDestination + | NetworkDetailsTableType.topNFlowSource | NetworkTableType.topNFlowDestination | NetworkTableType.topNFlowSource; export type TopCountriesTableType = - | IpDetailsTableType.topCountriesDestination - | IpDetailsTableType.topCountriesSource + | NetworkDetailsTableType.topCountriesDestination + | NetworkDetailsTableType.topCountriesSource | NetworkTableType.topCountriesDestination | NetworkTableType.topCountriesSource; -export type TopTlsTableType = IpDetailsTableType.tls | NetworkTableType.tls; +export type TopTlsTableType = NetworkDetailsTableType.tls | NetworkTableType.tls; -export type HttpTableType = IpDetailsTableType.http | NetworkTableType.http; +export type HttpTableType = NetworkDetailsTableType.http | NetworkTableType.http; -export enum IpDetailsTableType { +export enum NetworkDetailsTableType { http = 'http', tls = 'tls', topCountriesDestination = 'topCountriesDestination', @@ -55,7 +56,7 @@ export enum IpDetailsTableType { users = 'users', } -export type AllNetworkTables = NetworkTableType | IpDetailsTableType; +export type AllNetworkTables = NetworkTableType | NetworkDetailsTableType; export interface BasicQueryPaginated { activePage: number; @@ -64,24 +65,26 @@ export interface BasicQueryPaginated { // Network Page Models export interface TopNFlowQuery extends BasicQueryPaginated { - sort: NetworkTopTablesSortField; + sort: SortField; } export interface TopCountriesQuery extends BasicQueryPaginated { - sort: NetworkTopTablesSortField; + sort: SortField; } export interface DnsQuery extends BasicQueryPaginated { - sort: NetworkDnsSortField; + sort: SortField; isPtrIncluded: boolean; } export interface TlsQuery extends BasicQueryPaginated { - sort: TlsSortField; + sort: SortField; } export interface HttpQuery extends BasicQueryPaginated { - sort: NetworkHttpSortField; + sort: { + direction: Direction; + }; } export interface TableUpdates { @@ -89,11 +92,11 @@ export interface TableUpdates { limit?: number; isPtrIncluded?: boolean; sort?: - | NetworkDnsSortField - | NetworkHttpSortField - | NetworkTopTablesSortField - | TlsSortField - | UsersSortField; + | SortField + | HttpQuery['sort'] + | SortField + | SortField + | SortField; } export interface NetworkQueries { @@ -111,23 +114,23 @@ export interface NetworkPageModel { queries: NetworkQueries; } -export interface UsersQuery extends BasicQueryPaginated { - sort: UsersSortField; +export interface NetworkUsersQuery extends BasicQueryPaginated { + sort: SortField; } -export interface IpOverviewQueries { - [IpDetailsTableType.http]: HttpQuery; - [IpDetailsTableType.tls]: TlsQuery; - [IpDetailsTableType.topCountriesDestination]: TopCountriesQuery; - [IpDetailsTableType.topCountriesSource]: TopCountriesQuery; - [IpDetailsTableType.topNFlowDestination]: TopNFlowQuery; - [IpDetailsTableType.topNFlowSource]: TopNFlowQuery; - [IpDetailsTableType.users]: UsersQuery; +export interface NetworkDetailsQueries { + [NetworkDetailsTableType.http]: HttpQuery; + [NetworkDetailsTableType.tls]: TlsQuery; + [NetworkDetailsTableType.topCountriesDestination]: TopCountriesQuery; + [NetworkDetailsTableType.topCountriesSource]: TopCountriesQuery; + [NetworkDetailsTableType.topNFlowDestination]: TopNFlowQuery; + [NetworkDetailsTableType.topNFlowSource]: TopNFlowQuery; + [NetworkDetailsTableType.users]: NetworkUsersQuery; } export interface NetworkDetailsModel { flowTarget: FlowTarget; - queries: IpOverviewQueries; + queries: NetworkDetailsQueries; } export interface NetworkModel { diff --git a/x-pack/plugins/security_solution/public/network/store/reducer.ts b/x-pack/plugins/security_solution/public/network/store/reducer.ts index 380cd660f3e3b..e3eb2acc78d6e 100644 --- a/x-pack/plugins/security_solution/public/network/store/reducer.ts +++ b/x-pack/plugins/security_solution/public/network/store/reducer.ts @@ -11,13 +11,13 @@ import { FlowTarget, NetworkDnsFields, NetworkTopTablesFields, - TlsFields, - UsersFields, -} from '../../graphql/types'; + NetworkTlsFields, + NetworkUsersFields, +} from '../../../common/search_strategy'; import { DEFAULT_TABLE_ACTIVE_PAGE, DEFAULT_TABLE_LIMIT } from '../../common/store/constants'; import { - setIpDetailsTablesActivePageToZero, + setNetworkDetailsTablesActivePageToZero, setNetworkTablesActivePageToZero, updateNetworkTable, } from './actions'; @@ -25,7 +25,7 @@ import { setNetworkDetailsQueriesActivePageToZero, setNetworkPageQueriesActivePageToZero, } from './helpers'; -import { IpDetailsTableType, NetworkModel, NetworkTableType } from './model'; +import { NetworkDetailsTableType, NetworkModel, NetworkTableType } from './model'; export type NetworkState = NetworkModel; @@ -68,7 +68,7 @@ export const initialNetworkState: NetworkState = { activePage: DEFAULT_TABLE_ACTIVE_PAGE, limit: DEFAULT_TABLE_LIMIT, sort: { - field: TlsFields._id, + field: NetworkTlsFields._id, direction: Direction.desc, }, }, @@ -96,14 +96,14 @@ export const initialNetworkState: NetworkState = { }, details: { queries: { - [IpDetailsTableType.http]: { + [NetworkDetailsTableType.http]: { activePage: DEFAULT_TABLE_ACTIVE_PAGE, limit: DEFAULT_TABLE_LIMIT, sort: { direction: Direction.desc, }, }, - [IpDetailsTableType.topCountriesSource]: { + [NetworkDetailsTableType.topCountriesSource]: { activePage: DEFAULT_TABLE_ACTIVE_PAGE, limit: DEFAULT_TABLE_LIMIT, sort: { @@ -111,7 +111,7 @@ export const initialNetworkState: NetworkState = { direction: Direction.desc, }, }, - [IpDetailsTableType.topCountriesDestination]: { + [NetworkDetailsTableType.topCountriesDestination]: { activePage: DEFAULT_TABLE_ACTIVE_PAGE, limit: DEFAULT_TABLE_LIMIT, sort: { @@ -119,7 +119,7 @@ export const initialNetworkState: NetworkState = { direction: Direction.desc, }, }, - [IpDetailsTableType.topNFlowSource]: { + [NetworkDetailsTableType.topNFlowSource]: { activePage: DEFAULT_TABLE_ACTIVE_PAGE, limit: DEFAULT_TABLE_LIMIT, sort: { @@ -127,7 +127,7 @@ export const initialNetworkState: NetworkState = { direction: Direction.desc, }, }, - [IpDetailsTableType.topNFlowDestination]: { + [NetworkDetailsTableType.topNFlowDestination]: { activePage: DEFAULT_TABLE_ACTIVE_PAGE, limit: DEFAULT_TABLE_LIMIT, sort: { @@ -135,19 +135,19 @@ export const initialNetworkState: NetworkState = { direction: Direction.desc, }, }, - [IpDetailsTableType.tls]: { + [NetworkDetailsTableType.tls]: { activePage: DEFAULT_TABLE_ACTIVE_PAGE, limit: DEFAULT_TABLE_LIMIT, sort: { - field: TlsFields._id, + field: NetworkTlsFields._id, direction: Direction.desc, }, }, - [IpDetailsTableType.users]: { + [NetworkDetailsTableType.users]: { activePage: DEFAULT_TABLE_ACTIVE_PAGE, limit: DEFAULT_TABLE_LIMIT, sort: { - field: UsersFields.name, + field: NetworkUsersFields.name, direction: Direction.asc, }, }, @@ -181,7 +181,7 @@ export const networkReducer = reducerWithInitialState(initialNetworkState) queries: setNetworkDetailsQueriesActivePageToZero(state), }, })) - .case(setIpDetailsTablesActivePageToZero, (state) => ({ + .case(setNetworkDetailsTablesActivePageToZero, (state) => ({ ...state, details: { ...state.details, diff --git a/x-pack/plugins/security_solution/public/network/store/selectors.ts b/x-pack/plugins/security_solution/public/network/store/selectors.ts index 0246305092a32..833cb3a69789c 100644 --- a/x-pack/plugins/security_solution/public/network/store/selectors.ts +++ b/x-pack/plugins/security_solution/public/network/store/selectors.ts @@ -11,7 +11,7 @@ import { FlowTargetSourceDest } from '../../../common/search_strategy/security_s import { State } from '../../common/store/types'; import { initialNetworkState } from './reducer'; import { - IpDetailsTableType, + NetworkDetailsTableType, NetworkDetailsModel, NetworkPageModel, NetworkTableType, @@ -36,7 +36,7 @@ const selectTopNFlowByType = ( ) => { const ft = flowTarget === FlowTargetSourceDest.source ? 'topNFlowSource' : 'topNFlowDestination'; const nFlowType = - networkType === NetworkType.page ? NetworkTableType[ft] : IpDetailsTableType[ft]; + networkType === NetworkType.page ? NetworkTableType[ft] : NetworkDetailsTableType[ft]; return ( get([networkType, 'queries', nFlowType], state.network) || get([networkType, 'queries', nFlowType], initialNetworkState) @@ -46,7 +46,8 @@ const selectTopNFlowByType = ( export const topNFlowSelector = () => createSelector(selectTopNFlowByType, (topNFlowQueries) => topNFlowQueries); const selectTlsByType = (state: State, networkType: NetworkType): TlsQuery => { - const tlsType = networkType === NetworkType.page ? NetworkTableType.tls : IpDetailsTableType.tls; + const tlsType = + networkType === NetworkType.page ? NetworkTableType.tls : NetworkDetailsTableType.tls; return ( get([networkType, 'queries', tlsType], state.network) || get([networkType, 'queries', tlsType], initialNetworkState) @@ -63,7 +64,7 @@ const selectTopCountriesByType = ( const ft = flowTarget === FlowTargetSourceDest.source ? 'topCountriesSource' : 'topCountriesDestination'; const nFlowType = - networkType === NetworkType.page ? NetworkTableType[ft] : IpDetailsTableType[ft]; + networkType === NetworkType.page ? NetworkTableType[ft] : NetworkDetailsTableType[ft]; return ( get([networkType, 'queries', nFlowType], state.network) || @@ -76,7 +77,7 @@ export const topCountriesSelector = () => const selectHttpByType = (state: State, networkType: NetworkType): HttpQuery => { const httpType = - networkType === NetworkType.page ? NetworkTableType.http : IpDetailsTableType.http; + networkType === NetworkType.page ? NetworkTableType.http : NetworkDetailsTableType.http; return ( get([networkType, 'queries', httpType], state.network) || get([networkType, 'queries', httpType], initialNetworkState) diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx index 08f3f01bc99f6..7bbd7f553ac46 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx @@ -10,6 +10,7 @@ import lightTheme from '@elastic/eui/dist/eui_theme_light.json'; import { getOr } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; +import { HostItem } from '../../../../common/search_strategy'; import { DEFAULT_DARK_MODE } from '../../../../common/constants'; import { DescriptionList } from '../../../../common/utility_types'; import { useUiSetting$ } from '../../../common/lib/kibana'; @@ -19,9 +20,8 @@ import { hostIdRenderer, } from '../../../timelines/components/field_renderers/field_renderers'; import { InspectButton, InspectButtonContainer } from '../../../common/components/inspect'; -import { HostItem } from '../../../graphql/types'; import { Loader } from '../../../common/components/loader'; -import { IPDetailsLink } from '../../../common/components/links'; +import { NetworkDetailsLink } from '../../../common/components/links'; import { hasMlUserPermissions } from '../../../../common/machine_learning/has_ml_user_permissions'; import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; import { AnomalyScores } from '../../../common/components/ml/score/anomaly_scores'; @@ -154,7 +154,7 @@ export const HostOverview = React.memo( rowItems={getOr([], 'host.ip', data)} attrName={'host.ip'} idPrefix="host-overview" - render={(ip) => (ip != null ? : getEmptyTagValue())} + render={(ip) => (ip != null ? : getEmptyTagValue())} /> ), }, diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/mock.ts b/x-pack/plugins/security_solution/public/overview/components/host_overview/mock.ts index c24cb20e9087c..7fe9ac139e129 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/mock.ts +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/mock.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HostsData } from '../../../graphql/types'; +import { HostsStrategyResponse } from '../../../../common/search_strategy'; -export const mockData: { Hosts: HostsData; DateFields: string[] } = { +export const mockData: { Hosts: HostsStrategyResponse; DateFields: string[] } = { Hosts: { totalCount: 1, edges: [ @@ -47,6 +47,7 @@ export const mockData: { Hosts: HostsData; DateFields: string[] } = { fakeTotalCount: 50, showMorePagesIndicator: true, }, + rawResponse: {} as HostsStrategyResponse['rawResponse'], }, DateFields: ['lastBeat'], }; diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index 1017cbb6a2c61..10bbbbfa72719 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -21,7 +21,7 @@ import { import { Storage } from '../../../../src/plugins/kibana_utils/public'; import { initTelemetry } from './common/lib/telemetry'; import { KibanaServices } from './common/lib/kibana/services'; -import { jiraActionType, resilientActionType } from './common/lib/connectors'; +import { resilientActionType } from './common/lib/connectors'; import { PluginSetup, PluginStart, @@ -96,7 +96,6 @@ export class Plugin implements IPlugin { diff --git a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx index c3b67e3300459..bf89cc7fa9084 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.test.tsx @@ -7,7 +7,6 @@ import { shallow } from 'enzyme'; import React from 'react'; -import { FlowTarget, GetIpOverviewQuery, HostEcsFields } from '../../../graphql/types'; import { TestProviders } from '../../../common/mock'; import '../../../common/mock/match_media'; import { getEmptyValue } from '../../../common/components/empty_value'; @@ -23,10 +22,10 @@ import { DEFAULT_MORE_MAX_HEIGHT, MoreContainer, } from './field_renderers'; -import { mockData } from '../../../network/components/ip_overview/mock'; +import { mockData } from '../../../network/components/details/mock'; import { useMountAppended } from '../../../common/utils/use_mount_appended'; - -type AutonomousSystem = GetIpOverviewQuery.AutonomousSystem; +import { AutonomousSystem, FlowTarget } from '../../../../common/search_strategy'; +import { HostEcs } from '../../../../common/ecs/host'; describe('Field Renderers', () => { const mount = useMountAppended(); @@ -98,15 +97,15 @@ describe('Field Renderers', () => { }); describe('#hostIdRenderer', () => { - const emptyIdHost: Partial = { + const emptyIdHost: Partial = { name: ['test'], - id: null, + id: undefined, ip: ['10.10.10.10'], }; - const emptyIpHost: Partial = { + const emptyIpHost: Partial = { name: ['test'], id: ['test'], - ip: null, + ip: undefined, }; test('it renders correctly against snapshot', () => { const wrapper = shallow(hostNameRenderer(mockData.complete.host, '10.10.10.10')); @@ -136,18 +135,18 @@ describe('Field Renderers', () => { }); describe('#hostNameRenderer', () => { - const emptyIdHost: Partial = { + const emptyIdHost: Partial = { name: ['test'], - id: null, + id: undefined, ip: ['10.10.10.10'], }; - const emptyIpHost: Partial = { + const emptyIpHost: Partial = { name: ['test'], id: ['test'], - ip: null, + ip: undefined, }; - const emptyNameHost: Partial = { - name: null, + const emptyNameHost: Partial = { + name: undefined, id: ['test'], ip: ['10.10.10.10'], }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.tsx b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.tsx index 80fe7cb33779a..1f76c2840e8b7 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/field_renderers.tsx @@ -10,12 +10,12 @@ import { getOr } from 'lodash/fp'; import React, { Fragment, useState } from 'react'; import styled from 'styled-components'; +import { HostEcs } from '../../../../common/ecs/host'; import { AutonomousSystem, FlowTarget, - HostEcsFields, - IpOverviewData, -} from '../../../graphql/types'; + NetworkDetailsStrategyResponse, +} from '../../../../common/search_strategy'; import { escapeDataProviderId } from '../../../common/components/drag_and_drop/helpers'; import { DefaultDraggable } from '../../../common/components/draggables'; import { getEmptyTagValue } from '../../../common/components/empty_value'; @@ -27,7 +27,7 @@ import { ReputationLinkSetting, } from '../../../common/components/links'; import { Spacer } from '../../../common/components/page'; -import * as i18n from '../../../network/components/ip_overview/translations'; +import * as i18n from '../../../network/components/details/translations'; const DraggableContainerFlexGroup = styled(EuiFlexGroup)` flex-grow: unset; @@ -38,7 +38,10 @@ export const IpOverviewId = 'ip-overview'; /** The default max-height of the popover used to show "+n More" items (e.g. `+9 More`) */ export const DEFAULT_MORE_MAX_HEIGHT = '200px'; -export const locationRenderer = (fieldNames: string[], data: IpOverviewData): React.ReactElement => +export const locationRenderer = ( + fieldNames: string[], + data: NetworkDetailsStrategyResponse['networkDetails'] +): React.ReactElement => fieldNames.length > 0 && fieldNames.every((fieldName) => getOr(null, fieldName, data)) ? ( {fieldNames.map((fieldName, index) => { @@ -92,7 +95,7 @@ export const autonomousSystemRenderer = ( ); interface HostIdRendererTypes { - host: HostEcsFields; + host: HostEcs; ipFilter?: string; noLink?: boolean; } @@ -124,8 +127,12 @@ export const hostIdRenderer = ({ getEmptyTagValue() ); -export const hostNameRenderer = (host: HostEcsFields, ipFilter?: string): React.ReactElement => - host.name && host.name[0] && host.ip && (!(ipFilter != null) || host.ip.includes(ipFilter)) ? ( +export const hostNameRenderer = (host?: HostEcs, ipFilter?: string): React.ReactElement => + host && + host.name && + host.name[0] && + host.ip && + (!(ipFilter != null) || host.ip.includes(ipFilter)) ? ( JSX.Element; -// TODO: This causes breaks between elements until the ticket below is fixed -// https://github.com/elastic/ingest-dev/issues/474 export const DefaultFieldRendererComponent: React.FC = ({ attrName, displayCount = 1, diff --git a/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx index a0678fb4a437a..e4148b5581435 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/formatted_ip/index.tsx @@ -13,7 +13,7 @@ import { } from '../../../common/components/drag_and_drop/draggable_wrapper'; import { escapeDataProviderId } from '../../../common/components/drag_and_drop/helpers'; import { getOrEmptyTagFromValue } from '../../../common/components/empty_value'; -import { IPDetailsLink } from '../../../common/components/links'; +import { NetworkDetailsLink } from '../../../common/components/links'; import { parseQueryValue } from '../../../timelines/components/timeline/body/renderers/parse_query_value'; import { DataProvider, @@ -122,7 +122,7 @@ const AddressLinksComponent: React.FC<{ /> ) : ( - + ) } truncate={truncate} diff --git a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts index 6a8d56ff41a04..0ec0db9f32776 100644 --- a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts +++ b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts @@ -12,12 +12,10 @@ import { import { AgentService, IngestManagerStartContract } from '../../../ingest_manager/server'; import { getPackagePolicyCreateCallback } from './ingest_integration'; import { ManifestManager } from './services/artifacts'; -import { ExceptionListClient } from '../../../lists/server'; export type EndpointAppContextServiceStartContract = Partial< Pick > & { - exceptionsListService: ExceptionListClient; logger: Logger; manifestManager?: ManifestManager; registerIngestCallback?: IngestManagerStartContract['registerExternalCallback']; @@ -32,11 +30,9 @@ export class EndpointAppContextService { private agentService: AgentService | undefined; private manifestManager: ManifestManager | undefined; private savedObjectsStart: SavedObjectsServiceStart | undefined; - private exceptionsListService: ExceptionListClient | undefined; public start(dependencies: EndpointAppContextServiceStartContract) { this.agentService = dependencies.agentService; - this.exceptionsListService = dependencies.exceptionsListService; this.manifestManager = dependencies.manifestManager; this.savedObjectsStart = dependencies.savedObjectsStart; @@ -54,13 +50,6 @@ export class EndpointAppContextService { return this.agentService; } - public getExceptionsList() { - if (!this.exceptionsListService) { - throw new Error('exceptionsListService not set'); - } - return this.exceptionsListService; - } - public getManifestManager(): ManifestManager | undefined { return this.manifestManager; } diff --git a/x-pack/plugins/security_solution/server/endpoint/mocks.ts b/x-pack/plugins/security_solution/server/endpoint/mocks.ts index 03754c7be7a5d..b5f35a198fa9e 100644 --- a/x-pack/plugins/security_solution/server/endpoint/mocks.ts +++ b/x-pack/plugins/security_solution/server/endpoint/mocks.ts @@ -21,7 +21,6 @@ import { import { ManifestManager } from './services/artifacts/manifest_manager/manifest_manager'; import { getManifestManagerMock } from './services/artifacts/manifest_manager/manifest_manager.mock'; import { EndpointAppContext } from './types'; -import { listMock } from '../../../lists/server/mocks'; /** * Creates a mocked EndpointAppContext. @@ -59,7 +58,6 @@ export const createMockEndpointAppContextServiceStartContract = (): jest.Mocked< > => { return { agentService: createMockAgentService(), - exceptionsListService: listMock.getExceptionListClient(), logger: loggingSystemMock.create().get('mock_endpoint_app_context'), savedObjectsStart: savedObjectsServiceMock.createStartContract(), manifestManager: getManifestManagerMock(), diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/index.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/index.ts index 161a31e2ec934..144c536b4e45f 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/index.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/index.ts @@ -9,11 +9,12 @@ import { SearchResponse } from 'elasticsearch'; import { schema } from '@kbn/config-schema'; import Boom from 'boom'; -import { metadataIndexPattern } from '../../../../common/endpoint/constants'; +import { metadataCurrentIndexPattern } from '../../../../common/endpoint/constants'; import { getESQueryHostMetadataByID, kibanaRequestToMetadataListESQuery } from './query_builders'; import { HostInfo, HostMetadata, + HostMetadataDetails, HostResultList, HostStatus, } from '../../../../common/endpoint/types'; @@ -23,10 +24,6 @@ import { Agent, AgentStatus } from '../../../../../ingest_manager/common/types/m import { findAllUnenrolledAgentIds } from './support/unenroll'; import { findAgentIDsByStatus } from './support/agent_status'; -interface HitSource { - _source: HostMetadata; -} - interface MetadataRequestContext { agentService: AgentService; logger: Logger; @@ -127,7 +124,7 @@ export function registerEndpointRoutes(router: IRouter, endpointAppContext: Endp const queryParams = await kibanaRequestToMetadataListESQuery( req, endpointAppContext, - metadataIndexPattern, + metadataCurrentIndexPattern, { unenrolledAgentIds: unenrolledAgentIds.concat(IGNORED_ELASTIC_AGENT_IDS), statusAgentIDs: statusIDs, @@ -137,7 +134,7 @@ export function registerEndpointRoutes(router: IRouter, endpointAppContext: Endp const response = (await context.core.elasticsearch.legacy.client.callAsCurrentUser( 'search', queryParams - )) as SearchResponse; + )) as SearchResponse; return res.ok({ body: await mapToHostResultList(queryParams, response, metadataRequestContext), @@ -193,17 +190,17 @@ export async function getHostData( metadataRequestContext: MetadataRequestContext, id: string ): Promise { - const query = getESQueryHostMetadataByID(id, metadataIndexPattern); + const query = getESQueryHostMetadataByID(id, metadataCurrentIndexPattern); const response = (await metadataRequestContext.requestHandlerContext.core.elasticsearch.legacy.client.callAsCurrentUser( 'search', query - )) as SearchResponse; + )) as SearchResponse; if (response.hits.hits.length === 0) { return undefined; } - const hostMetadata: HostMetadata = response.hits.hits[0]._source; + const hostMetadata: HostMetadata = response.hits.hits[0]._source.HostDetails; const agent = await findAgent(metadataRequestContext, hostMetadata); if (agent && !agent.active) { @@ -241,19 +238,19 @@ async function findAgent( async function mapToHostResultList( // eslint-disable-next-line @typescript-eslint/no-explicit-any queryParams: Record, - searchResponse: SearchResponse, + searchResponse: SearchResponse, metadataRequestContext: MetadataRequestContext ): Promise { - const totalNumberOfHosts = searchResponse?.aggregations?.total?.value || 0; + const totalNumberOfHosts = + ((searchResponse.hits?.total as unknown) as { value: number; relation: string }).value || 0; if (searchResponse.hits.hits.length > 0) { return { request_page_size: queryParams.size, request_page_index: queryParams.from, hosts: await Promise.all( - searchResponse.hits.hits - .map((response) => response.inner_hits.most_recent.hits.hits) - .flatMap((data) => data as HitSource) - .map(async (entry) => enrichHostMetadata(entry._source, metadataRequestContext)) + searchResponse.hits.hits.map(async (entry) => + enrichHostMetadata(entry._source.HostDetails, metadataRequestContext) + ) ), total: totalNumberOfHosts, }; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts index 29624b35d5c9e..f784941f3539a 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts @@ -23,6 +23,7 @@ import { import { HostInfo, HostMetadata, + HostMetadataDetails, HostResultList, HostStatus, } from '../../../../common/endpoint/types'; @@ -141,7 +142,7 @@ describe('test endpoint route', () => { bool: { must_not: { terms: { - 'elastic.agent.id': [ + 'HostDetails.elastic.agent.id': [ '00000000-0000-0000-0000-000000000000', '11111111-1111-1111-1111-111111111111', ], @@ -197,7 +198,7 @@ describe('test endpoint route', () => { bool: { must_not: { terms: { - 'elastic.agent.id': [ + 'HostDetails.elastic.agent.id': [ '00000000-0000-0000-0000-000000000000', '11111111-1111-1111-1111-111111111111', ], @@ -442,7 +443,7 @@ describe('Filters Schema Test', () => { }); }); -function createSearchResponse(hostMetadata?: HostMetadata): SearchResponse { +function createSearchResponse(hostMetadata?: HostMetadata): SearchResponse { return ({ took: 15, timed_out: false, @@ -454,7 +455,7 @@ function createSearchResponse(hostMetadata?: HostMetadata): SearchResponse; + } as unknown) as SearchResponse; } diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.test.ts index e9eb7093a7631..84da4a0960820 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.test.ts @@ -7,7 +7,7 @@ import { httpServerMock, loggingSystemMock } from '../../../../../../../src/core import { kibanaRequestToMetadataListESQuery, getESQueryHostMetadataByID } from './query_builders'; import { EndpointAppContextService } from '../../endpoint_app_context_services'; import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__'; -import { metadataIndexPattern } from '../../../../common/endpoint/constants'; +import { metadataCurrentIndexPattern } from '../../../../common/endpoint/constants'; describe('query builder', () => { describe('MetadataListESQuery', () => { @@ -22,31 +22,16 @@ describe('query builder', () => { service: new EndpointAppContextService(), config: () => Promise.resolve(createMockConfig()), }, - metadataIndexPattern + metadataCurrentIndexPattern ); expect(query).toEqual({ body: { query: { match_all: {}, }, - collapse: { - field: 'host.id', - inner_hits: { - name: 'most_recent', - size: 1, - sort: [{ 'event.created': 'desc' }], - }, - }, - aggs: { - total: { - cardinality: { - field: 'host.id', - }, - }, - }, sort: [ { - 'event.created': { + 'HostDetails.event.created': { order: 'desc', }, }, @@ -54,7 +39,7 @@ describe('query builder', () => { }, from: 0, size: 10, - index: metadataIndexPattern, + index: metadataCurrentIndexPattern, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as Record); }); @@ -74,7 +59,7 @@ describe('query builder', () => { service: new EndpointAppContextService(), config: () => Promise.resolve(createMockConfig()), }, - metadataIndexPattern, + metadataCurrentIndexPattern, { unenrolledAgentIds: [unenrolledElasticAgentId], } @@ -86,29 +71,14 @@ describe('query builder', () => { bool: { must_not: { terms: { - 'elastic.agent.id': [unenrolledElasticAgentId], + 'HostDetails.elastic.agent.id': [unenrolledElasticAgentId], }, }, }, }, - collapse: { - field: 'host.id', - inner_hits: { - name: 'most_recent', - size: 1, - sort: [{ 'event.created': 'desc' }], - }, - }, - aggs: { - total: { - cardinality: { - field: 'host.id', - }, - }, - }, sort: [ { - 'event.created': { + 'HostDetails.event.created': { order: 'desc', }, }, @@ -116,7 +86,7 @@ describe('query builder', () => { }, from: 0, size: 10, - index: metadataIndexPattern, + index: metadataCurrentIndexPattern, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as Record); } @@ -127,7 +97,7 @@ describe('query builder', () => { it('test default query params for all endpoints metadata when body filter is provided', async () => { const mockRequest = httpServerMock.createKibanaRequest({ body: { - filters: { kql: 'not host.ip:10.140.73.246' }, + filters: { kql: 'not HostDetails.host.ip:10.140.73.246' }, }, }); const query = await kibanaRequestToMetadataListESQuery( @@ -137,7 +107,7 @@ describe('query builder', () => { service: new EndpointAppContextService(), config: () => Promise.resolve(createMockConfig()), }, - metadataIndexPattern + metadataCurrentIndexPattern ); expect(query).toEqual({ @@ -152,7 +122,7 @@ describe('query builder', () => { should: [ { match: { - 'host.ip': '10.140.73.246', + 'HostDetails.host.ip': '10.140.73.246', }, }, ], @@ -164,24 +134,9 @@ describe('query builder', () => { ], }, }, - collapse: { - field: 'host.id', - inner_hits: { - name: 'most_recent', - size: 1, - sort: [{ 'event.created': 'desc' }], - }, - }, - aggs: { - total: { - cardinality: { - field: 'host.id', - }, - }, - }, sort: [ { - 'event.created': { + 'HostDetails.event.created': { order: 'desc', }, }, @@ -189,7 +144,7 @@ describe('query builder', () => { }, from: 0, size: 10, - index: metadataIndexPattern, + index: metadataCurrentIndexPattern, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as Record); }); @@ -201,7 +156,7 @@ describe('query builder', () => { const unenrolledElasticAgentId = '1fdca33f-799f-49f4-939c-ea4383c77672'; const mockRequest = httpServerMock.createKibanaRequest({ body: { - filters: { kql: 'not host.ip:10.140.73.246' }, + filters: { kql: 'not HostDetails.host.ip:10.140.73.246' }, }, }); const query = await kibanaRequestToMetadataListESQuery( @@ -211,7 +166,7 @@ describe('query builder', () => { service: new EndpointAppContextService(), config: () => Promise.resolve(createMockConfig()), }, - metadataIndexPattern, + metadataCurrentIndexPattern, { unenrolledAgentIds: [unenrolledElasticAgentId], } @@ -226,7 +181,7 @@ describe('query builder', () => { bool: { must_not: { terms: { - 'elastic.agent.id': [unenrolledElasticAgentId], + 'HostDetails.elastic.agent.id': [unenrolledElasticAgentId], }, }, }, @@ -238,7 +193,7 @@ describe('query builder', () => { should: [ { match: { - 'host.ip': '10.140.73.246', + 'HostDetails.host.ip': '10.140.73.246', }, }, ], @@ -250,24 +205,9 @@ describe('query builder', () => { ], }, }, - collapse: { - field: 'host.id', - inner_hits: { - name: 'most_recent', - size: 1, - sort: [{ 'event.created': 'desc' }], - }, - }, - aggs: { - total: { - cardinality: { - field: 'host.id', - }, - }, - }, sort: [ { - 'event.created': { + 'HostDetails.event.created': { order: 'desc', }, }, @@ -275,7 +215,7 @@ describe('query builder', () => { }, from: 0, size: 10, - index: metadataIndexPattern, + index: metadataCurrentIndexPattern, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as Record); } @@ -285,15 +225,15 @@ describe('query builder', () => { describe('MetadataGetQuery', () => { it('searches for the correct ID', () => { const mockID = 'AABBCCDD-0011-2233-AA44-DEADBEEF8899'; - const query = getESQueryHostMetadataByID(mockID, metadataIndexPattern); + const query = getESQueryHostMetadataByID(mockID, metadataCurrentIndexPattern); expect(query).toEqual({ body: { - query: { match: { 'host.id': mockID } }, - sort: [{ 'event.created': { order: 'desc' } }], + query: { match: { 'HostDetails.host.id': mockID } }, + sort: [{ 'HostDetails.event.created': { order: 'desc' } }], size: 1, }, - index: metadataIndexPattern, + index: metadataCurrentIndexPattern, }); }); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts index ba9be96201dbe..9002d328efbe3 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.ts @@ -28,24 +28,9 @@ export async function kibanaRequestToMetadataListESQuery( queryBuilderOptions?.unenrolledAgentIds!, queryBuilderOptions?.statusAgentIDs! ), - collapse: { - field: 'host.id', - inner_hits: { - name: 'most_recent', - size: 1, - sort: [{ 'event.created': 'desc' }], - }, - }, - aggs: { - total: { - cardinality: { - field: 'host.id', - }, - }, - }, sort: [ { - 'event.created': { + 'HostDetails.event.created': { order: 'desc', }, }, @@ -90,7 +75,7 @@ function buildQueryBody( ? { must_not: { terms: { - 'elastic.agent.id': unerolledAgentIds, + 'HostDetails.elastic.agent.id': unerolledAgentIds, }, }, } @@ -99,7 +84,7 @@ function buildQueryBody( ? { must: { terms: { - 'elastic.agent.id': statusAgentIDs, + 'HostDetails.elastic.agent.id': statusAgentIDs, }, }, } @@ -137,12 +122,12 @@ export function getESQueryHostMetadataByID(hostID: string, index: string) { body: { query: { match: { - 'host.id': hostID, + 'HostDetails.host.id': hostID, }, }, sort: [ { - 'event.created': { + 'HostDetails.event.created': { order: 'desc', }, }, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/handlers.ts index a3e6f54f3eee8..ec4d1efb81b11 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/handlers.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandler } from 'kibana/server'; +import { RequestHandler, RequestHandlerContext } from 'kibana/server'; import { GetTrustedAppsListRequest, GetTrustedListAppsResponse, @@ -14,6 +14,17 @@ import { EndpointAppContext } from '../../types'; import { exceptionItemToTrustedAppItem, newTrustedAppItemToExceptionItem } from './utils'; import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '../../../../../lists/common/constants'; import { DeleteTrustedAppsRequestParams } from './types'; +import { ExceptionListClient } from '../../../../../lists/server'; + +const exceptionListClientFromContext = (context: RequestHandlerContext): ExceptionListClient => { + const exceptionLists = context.lists?.getExceptionListClient(); + + if (!exceptionLists) { + throw new Error('Exception List client not found'); + } + + return exceptionLists; +}; export const getTrustedAppsDeleteRouteHandler = ( endpointAppContext: EndpointAppContext @@ -21,9 +32,8 @@ export const getTrustedAppsDeleteRouteHandler = ( const logger = endpointAppContext.logFactory.get('trusted_apps'); return async (context, req, res) => { - const exceptionsListService = endpointAppContext.service.getExceptionsList(); - try { + const exceptionsListService = exceptionListClientFromContext(context); const { id } = req.params; const response = await exceptionsListService.deleteExceptionListItem({ id, @@ -49,10 +59,10 @@ export const getTrustedAppsListRouteHandler = ( const logger = endpointAppContext.logFactory.get('trusted_apps'); return async (context, req, res) => { - const exceptionsListService = endpointAppContext.service.getExceptionsList(); const { page, per_page: perPage } = req.query; try { + const exceptionsListService = exceptionListClientFromContext(context); // Ensure list is created if it does not exist await exceptionsListService.createTrustedAppsList(); const results = await exceptionsListService.findExceptionListItem({ @@ -83,11 +93,11 @@ export const getTrustedAppsCreateRouteHandler = ( ): RequestHandler => { const logger = endpointAppContext.logFactory.get('trusted_apps'); - return async (constext, req, res) => { - const exceptionsListService = endpointAppContext.service.getExceptionsList(); + return async (context, req, res) => { const newTrustedApp = req.body; try { + const exceptionsListService = exceptionListClientFromContext(context); // Ensure list is created if it does not exist await exceptionsListService.createTrustedAppsList(); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/trusted_apps.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/trusted_apps.test.ts index 2325036ef40ae..eeee2d99bf26d 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/trusted_apps.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/trusted_apps.test.ts @@ -24,15 +24,23 @@ import { import { xpackMocks } from '../../../../../../mocks'; import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '../../../../../lists/common/constants'; import { EndpointAppContext } from '../../types'; -import { ExceptionListClient } from '../../../../../lists/server'; -import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; +import { ExceptionListClient, ListClient } from '../../../../../lists/server'; +import { listMock } from '../../../../../lists/server/mocks'; import { ExceptionListItemSchema } from '../../../../../lists/common/schemas/response'; import { DeleteTrustedAppsRequestParams } from './types'; +import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; + +type RequestHandlerContextWithLists = ReturnType & { + lists?: { + getListClient: () => jest.Mocked; + getExceptionListClient: () => jest.Mocked; + }; +}; describe('when invoking endpoint trusted apps route handlers', () => { let routerMock: jest.Mocked; let endpointAppContextService: EndpointAppContextService; - let context: ReturnType; + let context: RequestHandlerContextWithLists; let response: ReturnType; let exceptionsListClient: jest.Mocked; let endpointAppContext: EndpointAppContext; @@ -41,7 +49,7 @@ describe('when invoking endpoint trusted apps route handlers', () => { routerMock = httpServiceMock.createRouter(); endpointAppContextService = new EndpointAppContextService(); const startContract = createMockEndpointAppContextServiceStartContract(); - exceptionsListClient = startContract.exceptionsListService as jest.Mocked; + exceptionsListClient = listMock.getExceptionListClient() as jest.Mocked; endpointAppContextService.start(startContract); endpointAppContext = { ...createMockEndpointAppContext(), @@ -50,7 +58,13 @@ describe('when invoking endpoint trusted apps route handlers', () => { registerTrustedAppsRoutes(routerMock, endpointAppContext); // For use in individual API calls - context = xpackMocks.createRequestHandlerContext(); + context = { + ...xpackMocks.createRequestHandlerContext(), + lists: { + getListClient: jest.fn(), + getExceptionListClient: jest.fn().mockReturnValue(exceptionsListClient), + }, + }; response = httpServerMock.createResponseFactory(); }); @@ -74,6 +88,12 @@ describe('when invoking endpoint trusted apps route handlers', () => { )!; }); + it('should use ExceptionListClient from route handler context', async () => { + const request = createListRequest(); + await routeHandler(context, request, response); + expect(context.lists?.getExceptionListClient).toHaveBeenCalled(); + }); + it('should create the Trusted Apps List first', async () => { const request = createListRequest(); await routeHandler(context, request, response); @@ -155,6 +175,12 @@ describe('when invoking endpoint trusted apps route handlers', () => { }); }); + it('should use ExceptionListClient from route handler context', async () => { + const request = createPostRequest(); + await routeHandler(context, request, response); + expect(context.lists?.getExceptionListClient).toHaveBeenCalled(); + }); + it('should create trusted app list first', async () => { const request = createPostRequest(); await routeHandler(context, request, response); @@ -238,6 +264,11 @@ describe('when invoking endpoint trusted apps route handlers', () => { }); }); + it('should use ExceptionListClient from route handler context', async () => { + await routeHandler(context, request, response); + expect(context.lists?.getExceptionListClient).toHaveBeenCalled(); + }); + it('should return 200 on successful delete', async () => { await routeHandler(context, request, response); expect(exceptionsListClient.deleteExceptionListItem).toHaveBeenCalledWith({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/signals_mapping.json b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/signals_mapping.json index 7d80a319e9e52..cfce019910071 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/signals_mapping.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/signals_mapping.json @@ -22,11 +22,33 @@ } } }, + "parents": { + "properties": { + "rule": { + "type": "keyword" + }, + "index": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "depth": { + "type": "long" + } + } + }, "ancestors": { "properties": { "rule": { "type": "keyword" }, + "index": { + "type": "keyword" + }, "id": { "type": "keyword" }, @@ -299,6 +321,9 @@ }, "threshold_count": { "type": "float" + }, + "depth": { + "type": "integer" } } } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/README.md b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/README.md index 2310ba979da20..7cf7d11e4c1f8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/README.md +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/README.md @@ -22,7 +22,7 @@ which will write a single signal document into the signals index by searching fo signal_on_signal_depth_1.json ``` -which has this key part of its query: `"query": "signal.parent.depth: 1 and _id: *"` which will only create signals +which has this key part of its query: `"query": "signal.depth: 1 and _id: *"` which will only create signals from all signals that point directly to an event (signal -> event). Then a second rule called @@ -34,7 +34,7 @@ signal_on_signal_depth_2.json which will only create signals from all signals that point directly to another signal (signal -> signal) with this query ```json -"query": "signal.parent.depth: 2 and _id: *" +"query": "signal.depth: 2 and _id: *" ``` ## Setup @@ -90,38 +90,43 @@ And then you can query against that: GET .siem-signals-default/_search ``` -Check your parent section of the signal and you will see something like this: +Check your `signal` section of the signal and you will see something like this: ```json -"parent" : { - "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", - "id" : "o8G7vm8BvLT8jmu5B1-M", - "type" : "event", - "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 -}, -"ancestors" : [ +"parents" : [ { - "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 } -] +], +"ancestors" : [ + { + "id" : "o8G7vm8BvLT8jmu5B1-M", + "type" : "event", + "index" : "filebeat-8.0.0-2019.12.18-000001", + "depth" : 0 + }, +], +"depth": 1, +"rule": { + "id": "74e0dd0c-4609-416f-b65e-90f8b2564612" +} ``` -The parent and ancestors structure is defined as: +The parents structure is defined as: ``` -rule -> The id of the rule. You can view the rule by ./get_rule_by_rule_id.sh ded57b36-9c4e-4ee4-805d-be4e92033e41 +rule -> The id of the rule, if the parent was generated by a rule. You can view the rule by ./get_rule_by_rule_id.sh ded57b36-9c4e-4ee4-805d-be4e92033e41 id -> The original _id of the document type -> The type of the document, it will be either event or signal index -> The original location of the index -depth -> The depth of this signal. It will be at least 1 to indicate it is a signal generated from a event. Otherwise 2 or more to indicate a signal on signal and what depth we are at -ancestors -> An array tracking all of the parents of this particular signal. As depth increases this will too. +depth -> The depth of the parent event/signal. It will be 0 if the parent is an event, or 1+ if the parent is another signal. ``` +The ancestors structure has the same fields as parents, but is an array of all ancestors (parents, grandparents, etc) of the signal. + This is indicating that you have a single parent of an event from the signal (signal -> event) and this document has a single ancestor of that event. Each 30 seconds that goes it will use de-duplication technique to ensure that this signal is not re-inserted. If after each 30 seconds you DO SEE multiple signals then the bug is a de-duplication bug and a critical bug. If you ever see a duplicate rule in the @@ -138,55 +143,64 @@ running in the system which are generating signals on top of signals. After 30 s documents in the signals index. The first signal is our original (signal -> event) document with a rule id: ```json -"parent" : { - "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", - "id" : "o8G7vm8BvLT8jmu5B1-M", - "type" : "event", - "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 -}, +"parents" : [ + { + "id" : "o8G7vm8BvLT8jmu5B1-M", + "type" : "event", + "index" : "filebeat-8.0.0-2019.12.18-000001", + "depth" : 0 + } +], "ancestors" : [ { - "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 } -] +], +"depth": 1, +"rule": { + "id": "74e0dd0c-4609-416f-b65e-90f8b2564612" +} ``` and the second document is a signal on top of a signal like so: ```json -"parent" : { - "rule" : "1d3b3735-66ef-4e53-b7f5-4340026cc40c", - "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", - "type" : "signal", - "index" : ".siem-signals-default-000001", - "depth" : 2 -}, -"ancestors" : [ +"parents" : [ { "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", + "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", + "type" : "signal", + "index" : ".siem-signals-default-000001", + "depth" : 1 + } +] +"ancestors" : [ + { "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 }, { - "rule" : "1d3b3735-66ef-4e53-b7f5-4340026cc40c", + "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 } -] +], +"depth": 2, +"rule": { + "id": "1d3b3735-66ef-4e53-b7f5-4340026cc40c" +} ``` Notice that the depth indicates it is at level 2 and its parent is that of a signal. Also notice that the ancestors is an array of size 2 indicating that this signal terminates at an event. Each and every signal ancestors array should terminate at an event and should ONLY contain 1 -event and NEVER 2 or more events. After 30+ seconds you should NOT see any new documents being created and you should be stable +event and NEVER 2 or more events for KQL query based rules. EQL query based rules that use sequences may have multiple parents at the same level. After 30+ seconds you should NOT see any new documents being created and you should be stable at 2. Otherwise we have AND/OR a de-duplication issue, signal on signal issue. Now, post this same rule a second time as a second instance which is going to run against these two documents. @@ -212,79 +226,93 @@ The expected behavior is that eventually you will get 3 total documents but not The original event rule 74e0dd0c-4609-416f-b65e-90f8b2564612 (event -> signal) ```json -"parent" : { - "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", - "id" : "o8G7vm8BvLT8jmu5B1-M", - "type" : "event", - "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 -}, +"parents" : [ + { + "id" : "o8G7vm8BvLT8jmu5B1-M", + "type" : "event", + "index" : "filebeat-8.0.0-2019.12.18-000001", + "depth" : 0 + } +], "ancestors" : [ { - "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 } -] +], +"depth": 1, +"rule": { + "id": "74e0dd0c-4609-416f-b65e-90f8b2564612" +} ``` The first signal to signal rule 1d3b3735-66ef-4e53-b7f5-4340026cc40c (signal -> event) ```json -"parent" : { - "rule" : "1d3b3735-66ef-4e53-b7f5-4340026cc40c", - "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", - "type" : "signal", - "index" : ".siem-signals-default-000001", - "depth" : 2 -}, -"ancestors" : [ +"parents" : [ { "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", + "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", + "type" : "signal", + "index" : ".siem-signals-default-000001", + "depth" : 1 + } +] +"ancestors" : [ + { "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 }, { - "rule" : "1d3b3735-66ef-4e53-b7f5-4340026cc40c", + "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 } -] +], +"depth": 2, +"rule": { + "id": "1d3b3735-66ef-4e53-b7f5-4340026cc40c" +} ``` Then our second signal to signal rule c93ddb57-e7e9-4973-9886-72ddefb4d22e (signal -> event) which finds the same thing as the first signal to signal ```json -"parent" : { - "rule" : "c93ddb57-e7e9-4973-9886-72ddefb4d22e", - "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", - "type" : "signal", - "index" : ".siem-signals-default-000001", - "depth" : 2 -}, -"ancestors" : [ +"parents" : [ { "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", + "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", + "type" : "signal", + "index" : ".siem-signals-default-000001", + "depth" : 1 + } +], +"ancestors" : [ + { "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 }, { - "rule" : "c93ddb57-e7e9-4973-9886-72ddefb4d22e", + "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 } -] +], +"depth": 2, +"rule": { + "id": "c93ddb57-e7e9-4973-9886-72ddefb4d22e" +} ``` We should be able to post this depth level as many times as we want and get only 1 new document each time. If we decide though to @@ -298,69 +326,79 @@ The expectation is that a document for each of the previous depth 1 documents wo depth 1 rules running then the signals at depth 2 will produce two new ones and those two will look like so: ```json -"parent" : { - "rule" : "a1f7b520-5bfd-451d-af59-428f60753fee", - "id" : "365236ce5e77770508152403b4e16613f407ae4b1a135a450dcfec427f2a3231", - "type" : "signal", - "index" : ".siem-signals-default-000001", - "depth" : 3 -}, +"parents" : [ + { + "rule" : "1d3b3735-66ef-4e53-b7f5-4340026cc40c", + "id" : "365236ce5e77770508152403b4e16613f407ae4b1a135a450dcfec427f2a3231", + "type" : "signal", + "index" : ".siem-signals-default-000001", + "depth" : 2 + } +], "ancestors" : [ { - "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 }, { - "rule" : "1d3b3735-66ef-4e53-b7f5-4340026cc40c", + "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 }, { - "rule" : "a1f7b520-5bfd-451d-af59-428f60753fee", + "rule" : "1d3b3735-66ef-4e53-b7f5-4340026cc40c", "id" : "365236ce5e77770508152403b4e16613f407ae4b1a135a450dcfec427f2a3231", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 3 + "depth" : 2 } -] +], +"depth": 3, +"rule": { + "id": "a1f7b520-5bfd-451d-af59-428f60753fee" +} ``` ```json -"parent" : { - "rule" : "a1f7b520-5bfd-451d-af59-428f60753fee", - "id" : "e8b1f1adb40fd642fa524dea89ef94232e67b05e99fb0b2683f1e47e90b759fb", - "type" : "signal", - "index" : ".siem-signals-default-000001", - "depth" : 3 -}, +"parents" : [ + { + "rule" : "c93ddb57-e7e9-4973-9886-72ddefb4d22e", + "id" : "e8b1f1adb40fd642fa524dea89ef94232e67b05e99fb0b2683f1e47e90b759fb", + "type" : "signal", + "index" : ".siem-signals-default-000001", + "depth" : 2 + } +], "ancestors" : [ { - "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 }, { - "rule" : "c93ddb57-e7e9-4973-9886-72ddefb4d22e", + "rule" : "74e0dd0c-4609-416f-b65e-90f8b2564612", "id" : "4cc69c1cbecdd2ace4075fd1d8a5c28e7d46e4bf31aecc8d2da39252c50c96b4", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 }, { - "rule" : "a1f7b520-5bfd-451d-af59-428f60753fee", + "rule" : "c93ddb57-e7e9-4973-9886-72ddefb4d22e", "id" : "e8b1f1adb40fd642fa524dea89ef94232e67b05e99fb0b2683f1e47e90b759fb", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 3 + "depth" : 2 } -] +], +"depth": 3, +"rule": { + "id": "a1f7b520-5bfd-451d-af59-428f60753fee" +} ``` The total number of documents should be 5 at this point. If you were to post this same rule a second time to get a second instance diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/query_single_id.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/query_single_id.json index dc05c656d7cf1..305aa34992623 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/query_single_id.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/query_single_id.json @@ -7,6 +7,6 @@ "from": "now-1d", "interval": "30s", "to": "now", - "query": "_id: o8G7vm8BvLT8jmu5B1-M", + "query": "event.id: 08cde4aa-d249-4e6b-8300-06f3d56c7fe7", "enabled": true } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/signal_on_signal_depth_1.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/signal_on_signal_depth_1.json index fb13413a02791..c9132ddb0a590 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/signal_on_signal_depth_1.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/signal_on_signal_depth_1.json @@ -7,7 +7,7 @@ "from": "now-1d", "interval": "30s", "to": "now", - "query": "signal.parent.depth: 1 and _id: *", + "query": "signal.depth: 1 and _id: *", "enabled": true, - "index": ".siem-signals-default" + "index": [".siem-signals-default"] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/signal_on_signal_depth_2.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/signal_on_signal_depth_2.json index c1b7594653ec7..d1a2749792686 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/signal_on_signal_depth_2.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/depth_test/signal_on_signal_depth_2.json @@ -7,7 +7,7 @@ "from": "now-1d", "interval": "30s", "to": "now", - "query": "signal.parent.depth: 2 and _id: *", + "query": "signal.depth: 2 and _id: *", "enabled": true, - "index": ".siem-signals-default" + "index": [".siem-signals-default"] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/halting_test/README.md b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/halting_test/README.md index b1a83f5317776..01b21bf762e44 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/halting_test/README.md +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/test_cases/signals_on_signals/halting_test/README.md @@ -69,38 +69,43 @@ And then you can query against that: GET .siem-signals-default/_search ``` -Check your parent section of the signal and you will see something like this: +Check your `signal` section of the signal and you will see something like this: ```json -"parent" : { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", - "id" : "o8G7vm8BvLT8jmu5B1-M", - "type" : "event", - "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 -}, -"ancestors" : [ +"parents" : [ { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 } -] +], +"ancestors" : [ + { + "id" : "o8G7vm8BvLT8jmu5B1-M", + "type" : "event", + "index" : "filebeat-8.0.0-2019.12.18-000001", + "depth" : 0 + }, +], +"depth": 1, +"rule": { + "id": "ded57b36-9c4e-4ee4-805d-be4e92033e41" +} ``` -The parent and ancestors structure is defined as: +The parents structure is defined as: ``` -rule -> The id of the rule. You can view the rule by ./get_rule_by_rule_id.sh ded57b36-9c4e-4ee4-805d-be4e92033e41 +rule -> The id of the rule, if the parent was generated by a rule. You can view the rule by ./get_rule_by_rule_id.sh ded57b36-9c4e-4ee4-805d-be4e92033e41 id -> The original _id of the document type -> The type of the document, it will be either event or signal index -> The original location of the index -depth -> The depth of this signal. It will be at least 1 to indicate it is a signal generated from a event. Otherwise 2 or more to indicate a signal on signal and what depth we are at -ancestors -> An array tracking all of the parents of this particular signal. As depth increases this will too. +depth -> The depth of the parent event/signal. It will be 0 if the parent is an event, or 1+ if the parent is another signal. ``` +The ancestors structure has the same fields as parents, but is an array of all ancestors (parents, grandparents, etc) of the signal. + This is indicating that you have a single parent of an event from the signal (signal -> event) and this document has a single ancestor of that event. Each 30 seconds that goes it will use de-duplication technique to ensure that this signal is not re-inserted. If after each 30 seconds you DO SEE multiple signals then the bug is a de-duplication bug and a critical bug. If you ever see a duplicate rule in the @@ -119,22 +124,26 @@ documents in the signals index. The first signal is our original (signal -> even (signal -> event) ```json -"parent" : { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", - "id" : "o8G7vm8BvLT8jmu5B1-M", - "type" : "event", - "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 -}, -"ancestors" : [ +"parents" : [ { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 } -] +], +"ancestors" : [ + { + "id" : "o8G7vm8BvLT8jmu5B1-M", + "type" : "event", + "index" : "filebeat-8.0.0-2019.12.18-000001", + "depth" : 0 + }, +], +"depth": 1, +"rule": { + "id": "ded57b36-9c4e-4ee4-805d-be4e92033e41" +} ``` and the second document is a signal on top of a signal like so: @@ -143,28 +152,31 @@ and the second document is a signal on top of a signal like so: ```json "parent" : { - "rule" : "161fa5b8-0b96-4985-b066-0d99b2bcb904", + "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "9d8710925adbf1a9c469621805407e74334dd08ca2c2ea414840fe971a571938", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 }, "ancestors" : [ { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 }, { - "rule" : "161fa5b8-0b96-4985-b066-0d99b2bcb904", + "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "9d8710925adbf1a9c469621805407e74334dd08ca2c2ea414840fe971a571938", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 } -] +], +"depth": 2, +"rule": { + "id": "161fa5b8-0b96-4985-b066-0d99b2bcb904" +} ``` Notice that the depth indicates it is at level 2 and its parent is that of a signal. Also notice that the ancestors is an array of size 2 @@ -195,50 +207,57 @@ The expected behavior is that eventually you will get 5 total documents but not The original event rule ded57b36-9c4e-4ee4-805d-be4e92033e41 (event -> signal) ```json -"parent" : { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", - "id" : "o8G7vm8BvLT8jmu5B1-M", - "type" : "event", - "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 -}, -"ancestors" : [ +"parents" : [ { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 } -] +], +"ancestors" : [ + { + "id" : "o8G7vm8BvLT8jmu5B1-M", + "type" : "event", + "index" : "filebeat-8.0.0-2019.12.18-000001", + "depth" : 0 + }, +], +"depth": 1, +"rule": { + "id": "ded57b36-9c4e-4ee4-805d-be4e92033e41" +} ``` The first signal to signal rule 161fa5b8-0b96-4985-b066-0d99b2bcb904 (signal -> event) ```json "parent" : { - "rule" : "161fa5b8-0b96-4985-b066-0d99b2bcb904", + "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "9d8710925adbf1a9c469621805407e74334dd08ca2c2ea414840fe971a571938", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 }, "ancestors" : [ { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 }, { - "rule" : "161fa5b8-0b96-4985-b066-0d99b2bcb904", + "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "9d8710925adbf1a9c469621805407e74334dd08ca2c2ea414840fe971a571938", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 } -] +], +"depth": 2, +"rule": { + "id": "161fa5b8-0b96-4985-b066-0d99b2bcb904" +} ``` Then our second signal to signal rule f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406 (signal -> event) which finds the same thing as the first @@ -246,28 +265,31 @@ signal to signal ```json "parent" : { - "rule" : "f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406", + "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "9d8710925adbf1a9c469621805407e74334dd08ca2c2ea414840fe971a571938", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 }, "ancestors" : [ { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 }, { - "rule" : "f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406", + "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "9d8710925adbf1a9c469621805407e74334dd08ca2c2ea414840fe971a571938", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 } -] +], +"depth": 2, +"rule": { + "id": "f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406" +} ``` But then f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406 also finds the first signal to signal rule from 161fa5b8-0b96-4985-b066-0d99b2bcb904 @@ -275,35 +297,38 @@ and writes that document out with a depth of 3. (signal -> signal -> event) ```json "parent" : { - "rule" : "f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406", + "rule" : "161fa5b8-0b96-4985-b066-0d99b2bcb904", "id" : "c627e5e2576f1b10952c6c57249947e89b6153b763a59fb9e391d0b56be8e7fe", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 3 + "depth" : 2 }, "ancestors" : [ { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 }, { - "rule" : "161fa5b8-0b96-4985-b066-0d99b2bcb904", + "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "9d8710925adbf1a9c469621805407e74334dd08ca2c2ea414840fe971a571938", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 }, { - "rule" : "f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406", + "rule" : "161fa5b8-0b96-4985-b066-0d99b2bcb904", "id" : "c627e5e2576f1b10952c6c57249947e89b6153b763a59fb9e391d0b56be8e7fe", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 3 + "depth" : 2 } -] +], +"depth": 3, +"rule": { + "id": "f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406" +} ``` Since it wrote that document, the first signal to signal 161fa5b8-0b96-4985-b066-0d99b2bcb904 writes out it found this newly created signal @@ -311,35 +336,38 @@ Since it wrote that document, the first signal to signal 161fa5b8-0b96-4985-b066 ```json "parent" : { - "rule" : "161fa5b8-0b96-4985-b066-0d99b2bcb904", + "rule" : "f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406", "id" : "efbe514e8d806a5ef3da7658cfa73961e25befefc84f622e963b45dcac798868", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 3 + "depth" : 2 }, "ancestors" : [ { - "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "o8G7vm8BvLT8jmu5B1-M", "type" : "event", "index" : "filebeat-8.0.0-2019.12.18-000001", - "depth" : 1 + "depth" : 0 }, { - "rule" : "f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406", + "rule" : "ded57b36-9c4e-4ee4-805d-be4e92033e41", "id" : "9d8710925adbf1a9c469621805407e74334dd08ca2c2ea414840fe971a571938", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 2 + "depth" : 1 }, { - "rule" : "161fa5b8-0b96-4985-b066-0d99b2bcb904", + "rule" : "f2b70c4a-4d8f-4db5-9ed7-d3ab0630e406", "id" : "efbe514e8d806a5ef3da7658cfa73961e25befefc84f622e963b45dcac798868", "type" : "signal", "index" : ".siem-signals-default-000001", - "depth" : 3 + "depth" : 2 } -] +], +"depth": 3, +"rule": { + "id": "161fa5b8-0b96-4985-b066-0d99b2bcb904" +} ``` You will be "halted" at this point as the signal ancestry and de-duplication ensures that we do not report twice on signals and that we do not diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts index 95ec753c21fd8..9d3eb29be08dd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts @@ -149,21 +149,23 @@ export const sampleDocWithAncestors = (): SignalSearchResponse => { delete sampleDoc._source.source; sampleDoc._source.signal = { parent: { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ancestors: [ { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], + rule: { + id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', + }, + depth: 1, }; return { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts index ee83c826371bc..967dc5331e46b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts @@ -48,19 +48,25 @@ describe('buildBulkBody', () => { }, signal: { parent: { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: sampleIdGuid, type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, + parents: [ + { + id: sampleIdGuid, + type: 'event', + index: 'myFakeSignalIndex', + depth: 0, + }, + ], ancestors: [ { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: sampleIdGuid, type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], original_time: '2020-04-20T21:27:45+0000', @@ -102,6 +108,7 @@ describe('buildBulkBody', () => { updated_at: fakeSignalSourceHit.signal.rule?.updated_at, exceptions_list: getListArrayMock(), }, + depth: 1, }, }; expect(fakeSignalSourceHit).toEqual(expected); @@ -151,19 +158,25 @@ describe('buildBulkBody', () => { module: 'system', }, parent: { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: sampleIdGuid, type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, + parents: [ + { + id: sampleIdGuid, + type: 'event', + index: 'myFakeSignalIndex', + depth: 0, + }, + ], ancestors: [ { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: sampleIdGuid, type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], original_time: '2020-04-20T21:27:45+0000', @@ -205,6 +218,7 @@ describe('buildBulkBody', () => { threat: [], exceptions_list: getListArrayMock(), }, + depth: 1, }, }; expect(fakeSignalSourceHit).toEqual(expected); @@ -252,19 +266,25 @@ describe('buildBulkBody', () => { module: 'system', }, parent: { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: sampleIdGuid, type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, + parents: [ + { + id: sampleIdGuid, + type: 'event', + index: 'myFakeSignalIndex', + depth: 0, + }, + ], ancestors: [ { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: sampleIdGuid, type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], original_time: '2020-04-20T21:27:45+0000', @@ -306,6 +326,7 @@ describe('buildBulkBody', () => { throttle: 'no_actions', exceptions_list: getListArrayMock(), }, + depth: 1, }, }; expect(fakeSignalSourceHit).toEqual(expected); @@ -346,19 +367,25 @@ describe('buildBulkBody', () => { kind: 'event', }, parent: { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: sampleIdGuid, type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, + parents: [ + { + id: sampleIdGuid, + type: 'event', + index: 'myFakeSignalIndex', + depth: 0, + }, + ], ancestors: [ { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: sampleIdGuid, type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], original_time: '2020-04-20T21:27:45+0000', @@ -400,6 +427,7 @@ describe('buildBulkBody', () => { throttle: 'no_actions', exceptions_list: getListArrayMock(), }, + depth: 1, }, }; expect(fakeSignalSourceHit).toEqual(expected); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts index 218750ac30a2a..7be97e46f91f2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SignalSourceHit, SignalHit } from './types'; +import { SignalSourceHit, SignalHit, Signal } from './types'; import { buildRule } from './build_rule'; -import { buildSignal } from './build_signal'; +import { additionalSignalFields, buildSignal } from './build_signal'; import { buildEventTypeSignal } from './build_event_type_signal'; import { RuleAlertAction } from '../../../../common/detection_engine/types'; import { RuleTypeParams } from '../types'; @@ -58,7 +58,10 @@ export const buildBulkBody = ({ tags, throttle, }); - const signal = buildSignal(doc, rule); + const signal: Signal = { + ...buildSignal([doc], rule), + ...additionalSignalFields(doc), + }; const event = buildEventTypeSignal(doc); const signalHit: SignalHit = { ...doc._source, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts index 7257e5952ff05..ba815a0b62f0d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.test.ts @@ -4,10 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { buildRule } from './build_rule'; +import { buildRule, removeInternalTagsFromRule } from './build_rule'; import { sampleDocNoSortId, sampleRuleAlertParams, sampleRuleGuid } from './__mocks__/es_results'; import { RulesSchema } from '../../../../common/detection_engine/schemas/response/rules_schema'; import { getListArrayMock } from '../../../../common/detection_engine/schemas/types/lists.mock'; +import { INTERNAL_RULE_ID_KEY, INTERNAL_IMMUTABLE_KEY } from '../../../../common/constants'; +import { getPartialRulesSchemaMock } from '../../../../common/detection_engine/schemas/response/rules_schema.mocks'; describe('buildRule', () => { beforeEach(() => { @@ -208,4 +210,102 @@ describe('buildRule', () => { }; expect(rule).toEqual(expected); }); + + test('it builds a rule and removes internal tags', () => { + const ruleParams = sampleRuleAlertParams(); + const rule = buildRule({ + actions: [], + doc: sampleDocNoSortId(), + ruleParams, + name: 'some-name', + id: sampleRuleGuid, + enabled: false, + createdAt: '2020-01-28T15:58:34.810Z', + updatedAt: '2020-01-28T15:59:14.004Z', + createdBy: 'elastic', + updatedBy: 'elastic', + interval: 'some interval', + tags: [ + 'some fake tag 1', + 'some fake tag 2', + `${INTERNAL_RULE_ID_KEY}:rule-1`, + `${INTERNAL_IMMUTABLE_KEY}:true`, + ], + throttle: 'no_actions', + }); + const expected: Partial = { + actions: [], + author: ['Elastic'], + building_block_type: 'default', + created_by: 'elastic', + description: 'Detecting root and admin users', + enabled: false, + false_positives: [], + from: 'now-6m', + id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', + immutable: false, + index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + interval: 'some interval', + language: 'kuery', + license: 'Elastic License', + max_signals: 10000, + name: 'some-name', + output_index: '.siem-signals', + query: 'user.name: root or user.name: admin', + references: ['http://google.com'], + risk_score: 50, + risk_score_mapping: [], + rule_id: 'rule-1', + severity: 'high', + severity_mapping: [], + tags: ['some fake tag 1', 'some fake tag 2'], + threat: [], + to: 'now', + type: 'query', + note: '', + updated_by: 'elastic', + updated_at: rule.updated_at, + created_at: rule.created_at, + throttle: 'no_actions', + exceptions_list: getListArrayMock(), + version: 1, + }; + expect(rule).toEqual(expected); + }); + + test('it removes internal tags from a typical rule', () => { + const rule = getPartialRulesSchemaMock(); + rule.tags = [ + 'some fake tag 1', + 'some fake tag 2', + `${INTERNAL_RULE_ID_KEY}:rule-1`, + `${INTERNAL_IMMUTABLE_KEY}:true`, + ]; + const noInternals = removeInternalTagsFromRule(rule); + expect(noInternals).toEqual(getPartialRulesSchemaMock()); + }); + + test('it works with an empty array', () => { + const rule = getPartialRulesSchemaMock(); + rule.tags = []; + const noInternals = removeInternalTagsFromRule(rule); + const expected = getPartialRulesSchemaMock(); + expected.tags = []; + expect(noInternals).toEqual(expected); + }); + + test('it works if tags does not exist', () => { + const rule = getPartialRulesSchemaMock(); + delete rule.tags; + const noInternals = removeInternalTagsFromRule(rule); + const expected = getPartialRulesSchemaMock(); + delete expected.tags; + expect(noInternals).toEqual(expected); + }); + + test('it works if tags contains normal values and no internal values', () => { + const rule = getPartialRulesSchemaMock(); + const noInternals = removeInternalTagsFromRule(rule); + expect(noInternals).toEqual(rule); + }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.ts index e02a0154d63c9..aacf9b8be31b4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_rule.ts @@ -12,6 +12,7 @@ import { buildRiskScoreFromMapping } from './mappings/build_risk_score_from_mapp import { SignalSourceHit } from './types'; import { buildSeverityFromMapping } from './mappings/build_severity_from_mapping'; import { buildRuleNameFromMapping } from './mappings/build_rule_name_from_mapping'; +import { INTERNAL_IDENTIFIER } from '../../../../common/constants'; interface BuildRuleParams { ruleParams: RuleTypeParams; @@ -64,7 +65,7 @@ export const buildRule = ({ const meta = { ...ruleParams.meta, ...riskScoreMeta, ...severityMeta, ...ruleNameMeta }; - return pickBy((value: unknown) => value != null, { + const rule = pickBy((value: unknown) => value != null, { id, rule_id: ruleParams.ruleId ?? '(unknown rule_id)', actions, @@ -111,4 +112,17 @@ export const buildRule = ({ anomaly_threshold: ruleParams.anomalyThreshold, threshold: ruleParams.threshold, }); + return removeInternalTagsFromRule(rule); +}; + +export const removeInternalTagsFromRule = (rule: Partial): Partial => { + if (rule.tags == null) { + return rule; + } else { + const ruleWithoutInternalTags: Partial = { + ...rule, + tags: rule.tags.filter((tag) => !tag.startsWith(INTERNAL_IDENTIFIER)), + }; + return ruleWithoutInternalTags; + } }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.test.ts index 6aebf8815659a..d684807a09126 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.test.ts @@ -5,14 +5,8 @@ */ import { sampleDocNoSortId } from './__mocks__/es_results'; -import { - buildSignal, - buildAncestor, - buildAncestorsSignal, - removeInternalTagsFromRule, -} from './build_signal'; +import { buildSignal, buildParent, buildAncestors, additionalSignalFields } from './build_signal'; import { Signal, Ancestor } from './types'; -import { INTERNAL_RULE_ID_KEY, INTERNAL_IMMUTABLE_KEY } from '../../../../common/constants'; import { getPartialRulesSchemaMock } from '../../../../common/detection_engine/schemas/response/rules_schema.mocks'; describe('buildSignal', () => { @@ -24,22 +18,31 @@ describe('buildSignal', () => { const doc = sampleDocNoSortId('d5e8eb51-a6a0-456d-8a15-4b79bfec3d71'); delete doc._source.event; const rule = getPartialRulesSchemaMock(); - const signal = buildSignal(doc, rule); + const signal = { + ...buildSignal([doc], rule), + ...additionalSignalFields(doc), + }; const expected: Signal = { parent: { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, + parents: [ + { + id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', + type: 'event', + index: 'myFakeSignalIndex', + depth: 0, + }, + ], ancestors: [ { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], original_time: '2020-04-20T21:27:45+0000', @@ -71,6 +74,7 @@ describe('buildSignal', () => { updated_at: signal.rule.updated_at, created_at: signal.rule.created_at, }, + depth: 1, }; expect(signal).toEqual(expected); }); @@ -84,94 +88,31 @@ describe('buildSignal', () => { module: 'system', }; const rule = getPartialRulesSchemaMock(); - const signal = buildSignal(doc, rule); + const signal = { + ...buildSignal([doc], rule), + ...additionalSignalFields(doc), + }; const expected: Signal = { parent: { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, - ancestors: [ + parents: [ { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], - original_time: '2020-04-20T21:27:45+0000', - original_event: { - action: 'socket_opened', - dataset: 'socket', - kind: 'event', - module: 'system', - }, - status: 'open', - rule: { - created_by: 'elastic', - description: 'Detecting root and admin users', - enabled: true, - false_positives: [], - from: 'now-6m', - id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', - immutable: false, - index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], - interval: '5m', - risk_score: 50, - rule_id: 'rule-1', - language: 'kuery', - max_signals: 100, - name: 'Detect Root/Admin Users', - output_index: '.siem-signals', - query: 'user.name: root or user.name: admin', - references: ['http://www.example.com', 'https://ww.example.com'], - severity: 'high', - updated_by: 'elastic', - tags: ['some fake tag 1', 'some fake tag 2'], - to: 'now', - type: 'query', - note: '', - updated_at: signal.rule.updated_at, - created_at: signal.rule.created_at, - }, - }; - expect(signal).toEqual(expected); - }); - - test('it builds a signal as expected with original_event if is present and without internal tags in them', () => { - const doc = sampleDocNoSortId('d5e8eb51-a6a0-456d-8a15-4b79bfec3d71'); - doc._source.event = { - action: 'socket_opened', - dataset: 'socket', - kind: 'event', - module: 'system', - }; - const rule = getPartialRulesSchemaMock(); - rule.tags = [ - 'some fake tag 1', - 'some fake tag 2', - `${INTERNAL_RULE_ID_KEY}:rule-1`, - `${INTERNAL_IMMUTABLE_KEY}:true`, - ]; - const signal = buildSignal(doc, rule); - const expected: Signal = { - parent: { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', - id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', - type: 'event', - index: 'myFakeSignalIndex', - depth: 1, - }, ancestors: [ { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], original_time: '2020-04-20T21:27:45+0000', @@ -209,6 +150,7 @@ describe('buildSignal', () => { updated_at: signal.rule.updated_at, created_at: signal.rule.created_at, }, + depth: 1, }; expect(signal).toEqual(expected); }); @@ -221,14 +163,12 @@ describe('buildSignal', () => { kind: 'event', module: 'system', }; - const rule = getPartialRulesSchemaMock(); - const signal = buildAncestor(doc, rule); + const signal = buildParent(doc); const expected: Ancestor = { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }; expect(signal).toEqual(expected); }); @@ -242,76 +182,34 @@ describe('buildSignal', () => { module: 'system', }; doc._source.signal = { - parent: { - rule: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', - id: '730ddf9e-5a00-4f85-9ddf-5878ca511a87', - type: 'event', - index: 'myFakeSignalIndex', - depth: 1, - }, - ancestors: [ + parents: [ { - rule: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', id: '730ddf9e-5a00-4f85-9ddf-5878ca511a87', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], - }; - const rule = getPartialRulesSchemaMock(); - const signal = buildAncestor(doc, rule); - const expected: Ancestor = { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', - id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', - type: 'signal', - index: 'myFakeSignalIndex', - depth: 2, - }; - expect(signal).toEqual(expected); - }); - - test('it builds a ancestor correctly if the parent does exist without internal tags in them', () => { - const doc = sampleDocNoSortId('d5e8eb51-a6a0-456d-8a15-4b79bfec3d71'); - doc._source.event = { - action: 'socket_opened', - dataset: 'socket', - kind: 'event', - module: 'system', - }; - doc._source.signal = { - parent: { - rule: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', - id: '730ddf9e-5a00-4f85-9ddf-5878ca511a87', - type: 'event', - index: 'myFakeSignalIndex', - depth: 1, - }, ancestors: [ { - rule: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', id: '730ddf9e-5a00-4f85-9ddf-5878ca511a87', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], + depth: 1, + rule: { + id: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', + }, }; - const rule = getPartialRulesSchemaMock(); - rule.tags = [ - 'some fake tag 1', - 'some fake tag 2', - `${INTERNAL_RULE_ID_KEY}:rule-1`, - `${INTERNAL_IMMUTABLE_KEY}:true`, - ]; - - const signal = buildAncestor(doc, rule); + const signal = buildParent(doc); const expected: Ancestor = { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', + rule: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'signal', index: 'myFakeSignalIndex', - depth: 2, + depth: 1, }; expect(signal).toEqual(expected); }); @@ -324,15 +222,13 @@ describe('buildSignal', () => { kind: 'event', module: 'system', }; - const rule = getPartialRulesSchemaMock(); - const signal = buildAncestorsSignal(doc, rule); + const signal = buildAncestors(doc); const expected: Ancestor[] = [ { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ]; expect(signal).toEqual(expected); @@ -347,77 +243,43 @@ describe('buildSignal', () => { module: 'system', }; doc._source.signal = { - parent: { - rule: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', - id: '730ddf9e-5a00-4f85-9ddf-5878ca511a87', - type: 'event', - index: 'myFakeSignalIndex', - depth: 1, - }, + parents: [ + { + id: '730ddf9e-5a00-4f85-9ddf-5878ca511a87', + type: 'event', + index: 'myFakeSignalIndex', + depth: 0, + }, + ], ancestors: [ { - rule: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', id: '730ddf9e-5a00-4f85-9ddf-5878ca511a87', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, ], + rule: { + id: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', + }, + depth: 1, }; - const rule = getPartialRulesSchemaMock(); - const signal = buildAncestorsSignal(doc, rule); + const signal = buildAncestors(doc); const expected: Ancestor[] = [ { - rule: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', id: '730ddf9e-5a00-4f85-9ddf-5878ca511a87', type: 'event', index: 'myFakeSignalIndex', - depth: 1, + depth: 0, }, { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', + rule: '98c0bf9e-4d38-46f4-9a6a-8a820426256b', id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', type: 'signal', index: 'myFakeSignalIndex', - depth: 2, + depth: 1, }, ]; expect(signal).toEqual(expected); }); - - test('it removes internal tags from a typical rule', () => { - const rule = getPartialRulesSchemaMock(); - rule.tags = [ - 'some fake tag 1', - 'some fake tag 2', - `${INTERNAL_RULE_ID_KEY}:rule-1`, - `${INTERNAL_IMMUTABLE_KEY}:true`, - ]; - const noInternals = removeInternalTagsFromRule(rule); - expect(noInternals).toEqual(getPartialRulesSchemaMock()); - }); - - test('it works with an empty array', () => { - const rule = getPartialRulesSchemaMock(); - rule.tags = []; - const noInternals = removeInternalTagsFromRule(rule); - const expected = getPartialRulesSchemaMock(); - expected.tags = []; - expect(noInternals).toEqual(expected); - }); - - test('it works if tags does not exist', () => { - const rule = getPartialRulesSchemaMock(); - delete rule.tags; - const noInternals = removeInternalTagsFromRule(rule); - const expected = getPartialRulesSchemaMock(); - delete expected.tags; - expect(noInternals).toEqual(expected); - }); - - test('it works if tags contains normal values and no internal values', () => { - const rule = getPartialRulesSchemaMock(); - const noInternals = removeInternalTagsFromRule(rule); - expect(noInternals).toEqual(rule); - }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts index e7098c015c165..78818779dd661 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts @@ -5,35 +5,41 @@ */ import { RulesSchema } from '../../../../common/detection_engine/schemas/response/rules_schema'; -import { INTERNAL_IDENTIFIER } from '../../../../common/constants'; import { SignalSourceHit, Signal, Ancestor } from './types'; -export const buildAncestor = (doc: SignalSourceHit, rule: Partial): Ancestor => { - const existingSignal = doc._source.signal?.parent; - if (existingSignal != null) { +/** + * Takes a parent signal or event document and extracts the information needed for the corresponding entry in the child + * signal's `signal.parents` array. + * @param doc The parent signal or event + */ +export const buildParent = (doc: SignalSourceHit): Ancestor => { + if (doc._source.signal != null) { return { - rule: rule.id != null ? rule.id : '', + rule: doc._source.signal.rule.id, id: doc._id, type: 'signal', index: doc._index, - depth: existingSignal.depth + 1, + // We first look for signal.depth and use that if it exists. If it doesn't exist, this should be a pre-7.10 signal + // and should have signal.parent.depth instead. signal.parent.depth in this case is treated as equivalent to signal.depth. + depth: doc._source.signal.depth ?? doc._source.signal.parent?.depth ?? 1, }; } else { return { - rule: rule.id != null ? rule.id : '', id: doc._id, type: 'event', index: doc._index, - depth: 1, + depth: 0, }; } }; -export const buildAncestorsSignal = ( - doc: SignalSourceHit, - rule: Partial -): Signal['ancestors'] => { - const newAncestor = buildAncestor(doc, rule); +/** + * Takes a parent signal or event document with N ancestors and adds the parent document to the ancestry array, + * creating an array of N+1 ancestors. + * @param doc The parent signal/event for which to extend the ancestry. + */ +export const buildAncestors = (doc: SignalSourceHit): Ancestor[] => { + const newAncestor = buildParent(doc); const existingAncestors = doc._source.signal?.ancestors; if (existingAncestors != null) { return [...existingAncestors, newAncestor]; @@ -42,35 +48,33 @@ export const buildAncestorsSignal = ( } }; -export const buildSignal = (doc: SignalSourceHit, rule: Partial): Signal => { - const ruleWithoutInternalTags = removeInternalTagsFromRule(rule); - const parent = buildAncestor(doc, rule); - const ancestors = buildAncestorsSignal(doc, rule); - let signal: Signal = { - parent, +/** + * Builds the `signal.*` fields that are common across all signals. + * @param docs The parent signals/events of the new signal to be built. + * @param rule The rule that is generating the new signal. + */ +export const buildSignal = (docs: SignalSourceHit[], rule: Partial): Signal => { + const parents = docs.map(buildParent); + const depth = parents.reduce((acc, parent) => Math.max(parent.depth, acc), 0) + 1; + const ancestors = docs.reduce((acc: Ancestor[], doc) => acc.concat(buildAncestors(doc)), []); + return { + parents, ancestors, - original_time: doc._source['@timestamp'], status: 'open', - rule: ruleWithoutInternalTags, + rule, + depth, }; - if (doc._source.event != null) { - signal = { ...signal, original_event: doc._source.event }; - } - if (doc._source.threshold_count != null) { - signal = { ...signal, threshold_count: doc._source.threshold_count }; - delete doc._source.threshold_count; - } - return signal; }; -export const removeInternalTagsFromRule = (rule: Partial): Partial => { - if (rule.tags == null) { - return rule; - } else { - const ruleWithoutInternalTags: Partial = { - ...rule, - tags: rule.tags.filter((tag) => !tag.startsWith(INTERNAL_IDENTIFIER)), - }; - return ruleWithoutInternalTags; - } +/** + * Creates signal fields that are only available in the special case where a signal has only 1 parent signal/event. + * @param doc The parent signal/event of the new signal to be built. + */ +export const additionalSignalFields = (doc: SignalSourceHit) => { + return { + parent: buildParent(doc), + original_time: doc._source['@timestamp'], + original_event: doc._source.event ?? undefined, + threshold_count: doc._source.threshold_count ?? undefined, + }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts index da17d4a1f123a..7ee157beec789 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/signal_rule_alert_type.ts @@ -120,7 +120,6 @@ export const signalRulesAlertType = ({ enabled, schedule: { interval }, throttle, - params: ruleParams, } = savedObject.attributes; const updatedAt = savedObject.updated_at ?? ''; const refresh = actions.length ? 'wait_for' : false; @@ -343,7 +342,7 @@ export const signalRulesAlertType = ({ if (result.success) { if (actions.length) { const notificationRuleParams: NotificationRuleTypeParams = { - ...ruleParams, + ...params, name, id: savedObject.id, }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.test.ts index 8b9fb0574efe9..41c825ea4d978 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.test.ts @@ -291,37 +291,7 @@ describe('singleBulkCreate', () => { test('filter duplicate rules will return nothing filtered when the two rule ids do not match with each other', () => { const filtered = filterDuplicateRules('some id', sampleDocWithAncestors()); - expect(filtered).toEqual([ - { - _index: 'myFakeSignalIndex', - _type: 'doc', - _score: 100, - _version: 1, - _id: 'e1e08ddc-5e37-49ff-a258-5393aa44435a', - _source: { - someKey: 'someValue', - '@timestamp': '2020-04-20T21:27:45+0000', - signal: { - parent: { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', - id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', - type: 'event', - index: 'myFakeSignalIndex', - depth: 1, - }, - ancestors: [ - { - rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', - id: 'd5e8eb51-a6a0-456d-8a15-4b79bfec3d71', - type: 'event', - index: 'myFakeSignalIndex', - depth: 1, - }, - ], - }, - }, - }, - ]); + expect(filtered).toEqual(sampleDocWithAncestors().hits.hits); }); test('filters duplicate rules will return empty array when the two rule ids match each other', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts index 74709f31563ee..be71c67615a4c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts @@ -51,7 +51,10 @@ export const filterDuplicateRules = ( if (doc._source.signal == null) { return true; } else { - return !doc._source.signal.ancestors.some((ancestor) => ancestor.rule === ruleId); + return !( + doc._source.signal.ancestors.some((ancestor) => ancestor.rule === ruleId) || + doc._source.signal.rule.id === ruleId + ); } }); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts index aecdbe10695d2..700a8fb5022d7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts @@ -44,8 +44,16 @@ export interface SignalSource { [key: string]: SearchTypes; '@timestamp': string; signal?: { - parent: Ancestor; + // parent is deprecated: new signals should populate parents instead + // both are optional until all signals with parent are gone and we can safely remove it + parent?: Ancestor; + parents?: Ancestor[]; ancestors: Ancestor[]; + rule: { + id: string; + }; + // signal.depth doesn't exist on pre-7.10 signals + depth?: number; }; } @@ -113,7 +121,7 @@ export type SignalRuleAlertTypeDefinition = Omit & { }; export interface Ancestor { - rule: string; + rule?: string; id: string; type: string; index: string; @@ -122,12 +130,15 @@ export interface Ancestor { export interface Signal { rule: Partial; - parent: Ancestor; + // DEPRECATED: use parents instead of parent + parent?: Ancestor; + parents: Ancestor[]; ancestors: Ancestor[]; - original_time: string; + original_time?: string; original_event?: SearchTypes; status: Status; threshold_count?: SearchTypes; + depth: number; } export interface SignalHit { diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 24cf1f8746d89..1f4790a8981c9 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -315,7 +315,6 @@ export class Plugin implements IPlugin { + const firstSeen = getOr(null, `firstSeen.value_as_string`, networkHit); + const lastSeen = getOr(null, `lastSeen.value_as_string`, networkHit); + const autonomousSystem: AutonomousSystem | null = getOr( + null, + `as.results.hits.hits[0]._source.${type}.as`, + networkHit + ); + const geoFields: GeoEcs | null = getOr( + null, + `geo.results.hits.hits[0]._source.${type}.geo`, + networkHit + ); + + return { + [type]: { + firstSeen, + lastSeen, + autonomousSystem: { + ...autonomousSystem, + }, + geo: { + ...geoFields, + }, + }, + }; +}; + +export const getNetworkDetailsHostAgg = (hostDetailsHit: NetworkDetailsHostHit | {}) => { + const hostFields: HostEcs | null = getOr( + null, + `results.hits.hits[0]._source.host`, + hostDetailsHit + ); + return { + host: { + ...hostFields, + }, + }; +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/index.ts new file mode 100644 index 0000000000000..8b2b79c4cd403 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/index.ts @@ -0,0 +1,46 @@ +/* + * 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 { getOr } from 'lodash/fp'; + +import { IEsSearchResponse } from '../../../../../../../../../src/plugins/data/common'; + +import { + NetworkDetailsStrategyResponse, + NetworkQueries, + NetworkDetailsRequestOptions, +} from '../../../../../../common/search_strategy/security_solution/network'; + +import { inspectStringifyObject } from '../../../../../utils/build_query'; +import { SecuritySolutionFactory } from '../../types'; + +import { getNetworkDetailsAgg, getNetworkDetailsHostAgg } from './helpers'; +import { buildNetworkDetailsQuery } from './query.details_network.dsl'; + +export const networkDetails: SecuritySolutionFactory = { + buildDsl: (options: NetworkDetailsRequestOptions) => buildNetworkDetailsQuery(options), + parse: async ( + options: NetworkDetailsRequestOptions, + response: IEsSearchResponse + ): Promise => { + const inspect = { + dsl: [inspectStringifyObject(buildNetworkDetailsQuery(options))], + }; + + return { + ...response, + inspect, + networkDetails: { + ...getNetworkDetailsAgg('source', getOr({}, 'aggregations.source', response.rawResponse)), + ...getNetworkDetailsAgg( + 'destination', + getOr({}, 'aggregations.destination', response.rawResponse) + ), + ...getNetworkDetailsHostAgg(getOr({}, 'aggregations.host', response.rawResponse)), + }, + }; + }, +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/query.details_network.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/query.details_network.dsl.ts new file mode 100644 index 0000000000000..67aeba60c4d2f --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/details/query.details_network.dsl.ts @@ -0,0 +1,126 @@ +/* + * 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 { isEmpty } from 'lodash/fp'; +import { NetworkDetailsRequestOptions } from '../../../../../../common/search_strategy/security_solution/network'; + +const getAggs = (type: string, ip: string) => { + return { + [type]: { + filter: { + term: { + [`${type}.ip`]: ip, + }, + }, + aggs: { + firstSeen: { + min: { + field: '@timestamp', + }, + }, + lastSeen: { + max: { + field: '@timestamp', + }, + }, + as: { + filter: { + exists: { + field: `${type}.as`, + }, + }, + aggs: { + results: { + top_hits: { + size: 1, + _source: [`${type}.as`], + sort: [ + { + '@timestamp': 'desc', + }, + ], + }, + }, + }, + }, + geo: { + filter: { + exists: { + field: `${type}.geo`, + }, + }, + aggs: { + results: { + top_hits: { + size: 1, + _source: [`${type}.geo`], + sort: [ + { + '@timestamp': 'desc', + }, + ], + }, + }, + }, + }, + }, + }, + }; +}; + +const getHostAggs = (ip: string) => { + return { + host: { + filter: { + term: { + 'host.ip': ip, + }, + }, + aggs: { + results: { + top_hits: { + size: 1, + _source: ['host'], + sort: [ + { + '@timestamp': 'desc', + }, + ], + }, + }, + }, + }, + }; +}; + +export const buildNetworkDetailsQuery = ({ + defaultIndex, + docValueFields, + ip, +}: NetworkDetailsRequestOptions) => { + const dslQuery = { + allowNoIndices: true, + index: defaultIndex, + ignoreUnavailable: true, + body: { + ...(isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), + aggs: { + ...getAggs('source', ip), + ...getAggs('destination', ip), + ...getHostAggs(ip), + }, + query: { + bool: { + should: [], + }, + }, + size: 0, + track_total_hits: false, + }, + }; + + return dslQuery; +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.ts index 3b927b8589999..bf5321d32b58f 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.ts @@ -10,18 +10,22 @@ import { } from '../../../../../common/search_strategy/security_solution'; import { SecuritySolutionFactory } from '../types'; +import { networkDetails } from './details'; import { networkDns } from './dns'; import { networkHttp } from './http'; import { networkOverview } from './overview'; import { networkTls } from './tls'; import { networkTopCountries } from './top_countries'; import { networkTopNFlow } from './top_n_flow'; +import { networkUsers } from './users'; export const networkFactory: Record> = { + [NetworkQueries.details]: networkDetails, [NetworkQueries.dns]: networkDns, [NetworkQueries.http]: networkHttp, [NetworkQueries.overview]: networkOverview, [NetworkQueries.tls]: networkTls, [NetworkQueries.topCountries]: networkTopCountries, [NetworkQueries.topNFlow]: networkTopNFlow, + [NetworkQueries.users]: networkUsers, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/helpers.ts index 59359fd35a34e..40653007ef43f 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/helpers.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/helpers.ts @@ -8,16 +8,16 @@ import { getOr } from 'lodash/fp'; import { IEsSearchResponse } from '../../../../../../../../../src/plugins/data/common'; import { - TlsBuckets, - TlsEdges, + NetworkTlsBuckets, + NetworkTlsEdges, } from '../../../../../../common/search_strategy/security_solution/network'; -export const getTlsEdges = (response: IEsSearchResponse): TlsEdges[] => - formatTlsEdges(getOr([], 'aggregations.sha1.buckets', response.rawResponse)); +export const getNetworkTlsEdges = (response: IEsSearchResponse): NetworkTlsEdges[] => + formatNetworkTlsEdges(getOr([], 'aggregations.sha1.buckets', response.rawResponse)); -export const formatTlsEdges = (buckets: TlsBuckets[]): TlsEdges[] => - buckets.map((bucket: TlsBuckets) => { - const edge: TlsEdges = { +export const formatNetworkTlsEdges = (buckets: NetworkTlsBuckets[]): NetworkTlsEdges[] => + buckets.map((bucket: NetworkTlsBuckets) => { + const edge: NetworkTlsEdges = { node: { _id: bucket.key, subjects: bucket.subjects.buckets.map(({ key }) => key), diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/index.ts index 32836c0ef6869..46556f46d3a50 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/index.ts @@ -13,21 +13,21 @@ import { NetworkTlsStrategyResponse, NetworkQueries, NetworkTlsRequestOptions, - TlsEdges, + NetworkTlsEdges, } from '../../../../../../common/search_strategy/security_solution/network'; import { inspectStringifyObject } from '../../../../../utils/build_query'; import { SecuritySolutionFactory } from '../../types'; -import { getTlsEdges } from './helpers'; -import { buildTlsQuery } from './query.tls_network.dsl'; +import { getNetworkTlsEdges } from './helpers'; +import { buildNetworkTlsQuery } from './query.tls_network.dsl'; export const networkTls: SecuritySolutionFactory = { buildDsl: (options: NetworkTlsRequestOptions) => { if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) { throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`); } - return buildTlsQuery(options); + return buildNetworkTlsQuery(options); }, parse: async ( options: NetworkTlsRequestOptions, @@ -35,12 +35,11 @@ export const networkTls: SecuritySolutionFactory = { ): Promise => { const { activePage, cursorStart, fakePossibleCount, querySize } = options.pagination; const totalCount = getOr(0, 'aggregations.count.value', response.rawResponse); - const tlsEdges: TlsEdges[] = getTlsEdges(response); + const networkTlsEdges: NetworkTlsEdges[] = getNetworkTlsEdges(response); const fakeTotalCount = fakePossibleCount <= totalCount ? fakePossibleCount : totalCount; - const edges = tlsEdges.splice(cursorStart, querySize - cursorStart); + const edges = networkTlsEdges.splice(cursorStart, querySize - cursorStart); const inspect = { - dsl: [inspectStringifyObject(buildTlsQuery(options))], - response: [inspectStringifyObject(response)], + dsl: [inspectStringifyObject(buildNetworkTlsQuery(options))], }; const showMorePagesIndicator = totalCount > fakeTotalCount; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/query.tls_network.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/query.tls_network.dsl.ts index 6e5ba0674a0e7..adf11175479e1 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/query.tls_network.dsl.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/tls/query.tls_network.dsl.ts @@ -8,13 +8,13 @@ import { assertUnreachable } from '../../../../../../common/utility_types'; import { createQueryFilterClauses } from '../../../../../utils/build_query'; import { + Direction, NetworkTlsRequestOptions, + NetworkTlsFields, SortField, - Direction, - TlsFields, } from '../../../../../../common/search_strategy'; -const getAggs = (querySize: number, sort: SortField) => ({ +const getAggs = (querySize: number, sort: SortField) => ({ count: { cardinality: { field: 'tls.server.hash.sha1', @@ -53,7 +53,7 @@ const getAggs = (querySize: number, sort: SortField) => ({ }, }); -export const buildTlsQuery = ({ +export const buildNetworkTlsQuery = ({ ip, sort, filterQuery, @@ -98,9 +98,9 @@ interface QueryOrder { _key: Direction; } -const getQueryOrder = (sort: SortField): QueryOrder => { +const getQueryOrder = (sort: SortField): QueryOrder => { switch (sort.field) { - case TlsFields._id: + case NetworkTlsFields._id: return { _key: sort.direction }; default: return assertUnreachable(sort.field); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/helpers.ts new file mode 100644 index 0000000000000..4068721e667a2 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/helpers.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { get, getOr } from 'lodash/fp'; +import { IEsSearchResponse } from '../../../../../../../../../src/plugins/data/common'; +import { + NetworkUsersBucketsItem, + NetworkUsersEdges, +} from '../../../../../../common/search_strategy/security_solution/network'; + +export const getUsersEdges = (response: IEsSearchResponse): NetworkUsersEdges[] => + getOr([], `aggregations.users.buckets`, response.rawResponse).map( + (bucket: NetworkUsersBucketsItem) => ({ + node: { + _id: bucket.key, + user: { + id: getOr([], 'id.buckets', bucket).map((id: NetworkUsersBucketsItem) => id.key), + name: bucket.key, + groupId: getOr([], 'groupId.buckets', bucket).map( + (groupId: NetworkUsersBucketsItem) => groupId.key + ), + groupName: getOr([], 'groupName.buckets', bucket).map( + (groupName: NetworkUsersBucketsItem) => groupName.key + ), + count: get('doc_count', bucket), + }, + }, + cursor: { + value: bucket.key, + tiebreaker: null, + }, + }) + ); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/index.ts new file mode 100644 index 0000000000000..f9b9a2fd2747f --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/index.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getOr } from 'lodash/fp'; + +import { IEsSearchResponse } from '../../../../../../../../../src/plugins/data/common'; + +import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../../../../common/constants'; +import { + NetworkUsersStrategyResponse, + NetworkQueries, + NetworkUsersRequestOptions, +} from '../../../../../../common/search_strategy/security_solution/network'; + +import { inspectStringifyObject } from '../../../../../utils/build_query'; +import { SecuritySolutionFactory } from '../../types'; + +import { getUsersEdges } from './helpers'; +import { buildUsersQuery } from './query.users_network.dsl'; + +export const networkUsers: SecuritySolutionFactory = { + buildDsl: (options: NetworkUsersRequestOptions) => { + if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) { + throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`); + } + return buildUsersQuery(options); + }, + parse: async ( + options: NetworkUsersRequestOptions, + response: IEsSearchResponse + ): Promise => { + const { activePage, cursorStart, fakePossibleCount, querySize } = options.pagination; + const totalCount = getOr(0, 'aggregations.user_count.value', response.rawResponse); + const usersEdges = getUsersEdges(response); + const fakeTotalCount = fakePossibleCount <= totalCount ? fakePossibleCount : totalCount; + const edges = usersEdges.splice(cursorStart, querySize - cursorStart); + const inspect = { + dsl: [inspectStringifyObject(buildUsersQuery(options))], + }; + const showMorePagesIndicator = totalCount > fakeTotalCount; + + return { + ...response, + edges, + inspect, + pageInfo: { + activePage: activePage ? activePage : 0, + fakeTotalCount, + showMorePagesIndicator, + }, + totalCount, + }; + }, +}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/query.users_network.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/query.users_network.dsl.ts new file mode 100644 index 0000000000000..386e83b955043 --- /dev/null +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/users/query.users_network.dsl.ts @@ -0,0 +1,104 @@ +/* + * 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 { assertUnreachable } from '../../../../../../common/utility_types'; +import { + Direction, + SortField, + NetworkUsersRequestOptions, + NetworkUsersFields, +} from '../../../../../../common/search_strategy'; +import { createQueryFilterClauses } from '../../../../../utils/build_query'; + +export const buildUsersQuery = ({ + ip, + sort, + filterQuery, + flowTarget, + pagination: { querySize }, + defaultIndex, + timerange: { from, to }, +}: NetworkUsersRequestOptions) => { + const filter = [ + ...createQueryFilterClauses(filterQuery), + { + range: { + '@timestamp': { gte: from, lte: to, format: 'strict_date_optional_time' }, + }, + }, + { term: { [`${flowTarget}.ip`]: ip } }, + ]; + + const dslQuery = { + allowNoIndices: true, + index: defaultIndex, + ignoreUnavailable: true, + body: { + aggs: { + user_count: { + cardinality: { + field: 'user.name', + }, + }, + users: { + terms: { + field: 'user.name', + size: querySize, + order: { + ...getQueryOrder(sort), + }, + }, + aggs: { + id: { + terms: { + field: 'user.id', + }, + }, + groupId: { + terms: { + field: 'user.group.id', + }, + }, + groupName: { + terms: { + field: 'user.group.name', + }, + }, + }, + }, + }, + query: { + bool: { + filter, + must_not: [ + { + term: { + 'event.category': 'authentication', + }, + }, + ], + }, + }, + size: 0, + track_total_hits: false, + }, + }; + + return dslQuery; +}; + +type QueryOrder = { _count: Direction } | { _key: Direction }; + +const getQueryOrder = (sort: SortField): QueryOrder => { + switch (sort.field) { + case NetworkUsersFields.name: + return { _key: sort.direction }; + case NetworkUsersFields.count: + return { _count: sort.direction }; + default: + return assertUnreachable(sort.field); + } +}; diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_form.helpers.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_form.helpers.ts index a3ab829ab642c..ab2963223f678 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_form.helpers.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/helpers/policy_form.helpers.ts @@ -56,4 +56,6 @@ export type PolicyFormTestSubjects = | 'showAdvancedCronLink' | 'snapshotNameInput' | 'dataStreamBadge' + | 'repositoryNotFoundWarning' + | 'repositorySelect' | 'submitButton'; diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/policy_add.test.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/policy_add.test.ts index dc568161d4fb4..f7d6a60703bc4 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/policy_add.test.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/policy_add.test.ts @@ -67,6 +67,11 @@ describe('', () => { expect(find('nextButton').props().disabled).toBe(true); }); + test('should not show repository-not-found warning', () => { + const { exists } = testBed; + expect(exists('repositoryNotFoundWarning')).toBe(false); + }); + describe('form validation', () => { describe('logistics (step 1)', () => { test('should require a policy name', async () => { diff --git a/x-pack/plugins/snapshot_restore/__jest__/client_integration/policy_edit.test.ts b/x-pack/plugins/snapshot_restore/__jest__/client_integration/policy_edit.test.ts index a5b2ec73b85cd..7c095256bd10f 100644 --- a/x-pack/plugins/snapshot_restore/__jest__/client_integration/policy_edit.test.ts +++ b/x-pack/plugins/snapshot_restore/__jest__/client_integration/policy_edit.test.ts @@ -52,6 +52,44 @@ describe('', () => { expect(find('pageTitle').text()).toEqual('Edit policy'); }); + describe('policy with pre-existing repository that was deleted', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setGetPolicyResponse({ policy: POLICY_EDIT }); + httpRequestsMockHelpers.setLoadIndicesResponse({ + indices: ['my_index'], + dataStreams: ['my_data_stream'], + }); + httpRequestsMockHelpers.setLoadRepositoriesResponse({ + repositories: [{ name: 'this-is-a-new-repository' }], + }); + + testBed = await setup(); + + await act(async () => { + await nextTick(); + testBed.component.update(); + }); + }); + + test('should show repository-not-found warning', () => { + const { exists, find } = testBed; + expect(exists('repositoryNotFoundWarning')).toBe(true); + // The select should be an empty string to allow users to select a new repository + expect(find('repositorySelect').props().value).toBe(''); + }); + + describe('validation', () => { + test('should block navigating to next step', () => { + const { exists, find, actions } = testBed; + actions.clickNextButton(); + // Assert that we are still on the repository configuration step + expect(exists('repositoryNotFoundWarning')).toBe(true); + // The select should be an empty string to allow users to select a new repository + expect(find('repositorySelect').props().value).toBe(''); + }); + }); + }); + /** * As the "edit" policy component uses the same form underneath that * the "create" policy, we won't test it again but simply make sure that diff --git a/x-pack/plugins/snapshot_restore/public/application/components/policy_form/steps/step_logistics.tsx b/x-pack/plugins/snapshot_restore/public/application/components/policy_form/steps/step_logistics.tsx index 8a7338f4db4e7..7d3ba92cf2ad7 100644 --- a/x-pack/plugins/snapshot_restore/public/application/components/policy_form/steps/step_logistics.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/components/policy_form/steps/step_logistics.tsx @@ -18,6 +18,8 @@ import { EuiLink, EuiSpacer, EuiText, + EuiCallOut, + EuiCode, } from '@elastic/eui'; import { Repository } from '../../../../../common/types'; @@ -49,11 +51,15 @@ export const PolicyStepLogistics: React.FunctionComponent = ({ name: undefined, }, }, - sendRequest: reloadRepositories, + resendRequest: reloadRepositories, } = useLoadRepositories(); const { i18n, history } = useServices(); + const [showRepositoryNotFoundWarning, setShowRepositoryNotFoundWarning] = useState( + false + ); + // State for touched inputs const [touched, setTouched] = useState({ name: false, @@ -256,13 +262,26 @@ export const PolicyStepLogistics: React.FunctionComponent = ({ } } + const doesRepositoryExist = + !!policy.repository && + repositories.some((r: { name: string }) => r.name === policy.repository); + + if (!doesRepositoryExist && !errors.repository) { + updatePolicy(policy, { repositoryDoesNotExist: true }); + } + + if (showRepositoryNotFoundWarning !== !doesRepositoryExist) { + setShowRepositoryNotFoundWarning(!doesRepositoryExist); + } + return ( ({ value: name, text: name, }))} - value={policy.repository || repositories[0].name} + hasNoInitialSelection={!doesRepositoryExist} + value={!doesRepositoryExist ? '' : policy.repository} onBlur={() => setTouched({ ...touched, repository: true })} onChange={(e) => { updatePolicy( @@ -541,8 +560,31 @@ export const PolicyStepLogistics: React.FunctionComponent = ({ - + {showRepositoryNotFoundWarning && ( + <> + + + } + color="danger" + iconType="alert" + > + {policy.repository} }} + /> + + + )} + + {renderNameField()} {renderSnapshotNameField()} {renderRepositoryField()} diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_details/policy_details.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_details/policy_details.tsx index f67e8eb586238..b4612c9df42ff 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_details/policy_details.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_details/policy_details.tsx @@ -65,7 +65,7 @@ export const PolicyDetails: React.FunctionComponent = ({ onPolicyExecuted, }) => { const { i18n, uiMetricService, history } = useServices(); - const { error, data: policyDetails, sendRequest: reload } = useLoadPolicy(policyName); + const { error, data: policyDetails, resendRequest: reload } = useLoadPolicy(policyName); const [activeTab, setActiveTab] = useState(TAB_SUMMARY); const [isPopoverOpen, setIsPopoverOpen] = useState(false); diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_list.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_list.tsx index 655bd0e9d8bb9..57f18ccbf8150 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_list.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_list.tsx @@ -45,7 +45,7 @@ export const PolicyList: React.FunctionComponent { diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_table/policy_table.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_table/policy_table.tsx index d55bbf0b324cf..e7e4a9b54ada7 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_table/policy_table.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/policy_list/policy_table/policy_table.tsx @@ -21,7 +21,7 @@ import { } from '@elastic/eui'; import { SlmPolicy } from '../../../../../../common/types'; -import { Error } from '../../../../../shared_imports'; +import { UseRequestResponse } from '../../../../../shared_imports'; import { UIM_POLICY_SHOW_DETAILS_CLICK } from '../../../../constants'; import { useServices } from '../../../../app_context'; import { @@ -30,13 +30,12 @@ import { PolicyDeleteProvider, } from '../../../../components'; import { linkToAddPolicy, linkToEditPolicy } from '../../../../services/navigation'; -import { SendRequestResponse } from '../../../../../shared_imports'; import { reactRouterNavigate } from '../../../../../../../../../src/plugins/kibana_react/public'; interface Props { policies: SlmPolicy[]; - reload: () => Promise>; + reload: UseRequestResponse['resendRequest']; openPolicyDetailsUrl: (name: SlmPolicy['name']) => string; onPolicyDeleted: (policiesDeleted: Array) => void; onPolicyExecuted: () => void; diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/repository_list/repository_list.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/repository_list/repository_list.tsx index 9afdad3806def..a3f57ce4fbf5e 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/repository_list/repository_list.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/repository_list/repository_list.tsx @@ -40,7 +40,7 @@ export const RepositoryList: React.FunctionComponent Promise>; + reload: UseRequestResponse['resendRequest']; openRepositoryDetailsUrl: (name: Repository['name']) => string; onRepositoryDeleted: (repositoriesDeleted: Array) => void; } diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/restore_list/restore_list.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/restore_list/restore_list.tsx index d7a82386926c1..d9507a101bbac 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/restore_list/restore_list.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/restore_list/restore_list.tsx @@ -52,9 +52,13 @@ export const RestoreList: React.FunctionComponent = () => { const [currentInterval, setCurrentInterval] = useState(INTERVAL_OPTIONS[1]); // Load restores - const { error, isLoading, data: restores = [], isInitialRequest, sendRequest } = useLoadRestores( - currentInterval - ); + const { + error, + isLoading, + data: restores = [], + isInitialRequest, + resendRequest, + } = useLoadRestores(currentInterval); const { uiMetricService, history } = useServices(); @@ -174,7 +178,7 @@ export const RestoreList: React.FunctionComponent = () => { key={interval} icon="empty" onClick={() => { - sendRequest(); + resendRequest(); setCurrentInterval(interval); setIsIntervalMenuOpen(false); }} diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/snapshot_list/snapshot_list.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/snapshot_list/snapshot_list.tsx index d13188fc44730..97def33ffe8f6 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/snapshot_list/snapshot_list.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/snapshot_list/snapshot_list.tsx @@ -44,7 +44,7 @@ export const SnapshotList: React.FunctionComponent Promise>; + reload: UseRequestResponse['resendRequest']; openSnapshotDetailsUrl: (repositoryName: string, snapshotId: string) => string; repositoryFilter?: string; policyFilter?: string; diff --git a/x-pack/plugins/snapshot_restore/public/application/services/validation/validate_policy.ts b/x-pack/plugins/snapshot_restore/public/application/services/validation/validate_policy.ts index 4314b703722f6..b371ec9f8fe82 100644 --- a/x-pack/plugins/snapshot_restore/public/application/services/validation/validate_policy.ts +++ b/x-pack/plugins/snapshot_restore/public/application/services/validation/validate_policy.ts @@ -41,6 +41,12 @@ export interface ValidatePolicyHelperData { * are not configuring this value - like when they are on a previous step. */ validateIndicesCount?: boolean; + + /** + * A policy might be configured with a repository that no longer exists. We want the form to + * block in this case because just having a repository configured is not enough for validity. + */ + repositoryDoesNotExist?: boolean; } export const validatePolicy = ( @@ -50,7 +56,13 @@ export const validatePolicy = ( const i18n = textService.i18n; const { name, snapshotName, schedule, repository, config, retention } = policy; - const { managedRepository, isEditing, policyName, validateIndicesCount } = validationHelperData; + const { + managedRepository, + isEditing, + policyName, + validateIndicesCount, + repositoryDoesNotExist, + } = validationHelperData; const validation: PolicyValidation = { isValid: true, @@ -99,7 +111,7 @@ export const validatePolicy = ( ); } - if (isStringEmpty(repository)) { + if (isStringEmpty(repository) || repositoryDoesNotExist) { validation.errors.repository.push( i18n.translate('xpack.snapshotRestore.policyValidation.repositoryRequiredErrorMessage', { defaultMessage: 'Repository is required.', diff --git a/x-pack/plugins/snapshot_restore/public/shared_imports.ts b/x-pack/plugins/snapshot_restore/public/shared_imports.ts index cad8ce147bd25..bd1c0e0cd395b 100644 --- a/x-pack/plugins/snapshot_restore/public/shared_imports.ts +++ b/x-pack/plugins/snapshot_restore/public/shared_imports.ts @@ -14,6 +14,7 @@ export { sendRequest, SendRequestConfig, SendRequestResponse, + UseRequestResponse, useAuthorizationContext, useRequest, UseRequestConfig, diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_mode_control.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_mode_control.tsx index 42fbf8954396e..c3e631e335ea7 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_mode_control.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_mode_control.tsx @@ -37,8 +37,7 @@ const createNewCopiesDisabled = { tooltip: i18n.translate( 'xpack.spaces.management.copyToSpace.copyModeControl.createNewCopies.disabledText', { - defaultMessage: - 'Check if each object was previously copied or imported into the destination space.', + defaultMessage: 'Check if objects were previously copied or imported into the space.', } ), }; @@ -50,33 +49,36 @@ const createNewCopiesEnabled = { ), tooltip: i18n.translate( 'xpack.spaces.management.copyToSpace.copyModeControl.createNewCopies.enabledText', - { defaultMessage: 'All copied objects will be created with new random IDs.' } + { + defaultMessage: + 'Use this option to create one or more copies of the object in the same space.', + } ), }; const overwriteEnabled = { id: 'overwriteEnabled', label: i18n.translate( 'xpack.spaces.management.copyToSpace.copyModeControl.overwrite.enabledLabel', - { defaultMessage: 'Automatically try to overwrite conflicts' } + { defaultMessage: 'Automatically overwrite conflicts' } ), }; const overwriteDisabled = { id: 'overwriteDisabled', label: i18n.translate( 'xpack.spaces.management.copyToSpace.copyModeControl.overwrite.disabledLabel', - { defaultMessage: 'Request action when conflict occurs' } + { defaultMessage: 'Request action on conflict' } ), }; const includeRelated = { id: 'includeRelated', text: i18n.translate('xpack.spaces.management.copyToSpace.copyModeControl.includeRelated.title', { - defaultMessage: 'Include related saved objects', + defaultMessage: 'Include related objects', }), tooltip: i18n.translate( 'xpack.spaces.management.copyToSpace.copyModeControl.includeRelated.text', { defaultMessage: - 'This will copy any other objects this has references to -- for example, a dashboard may have references to multiple visualizations.', + 'Copy this object and its related objects. For dashboards, related visualizations, index patterns, and saved searches are also copied.', } ), }; @@ -86,7 +88,7 @@ const copyOptionsTitle = i18n.translate( ); const relationshipOptionsTitle = i18n.translate( 'xpack.spaces.management.copyToSpace.copyModeControl.relationshipOptionsTitle', - { defaultMessage: 'Relationship options' } + { defaultMessage: 'Relationship' } ); const createLabel = ({ text, tooltip }: { text: string; tooltip: string }) => ( diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_status_indicator.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_status_indicator.tsx index 158d7a9a43ef6..d9e1418cdd412 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_status_indicator.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_status_indicator.tsx @@ -5,7 +5,7 @@ */ import React, { Fragment } from 'react'; -import { EuiLoadingSpinner, EuiIconTip, EuiSpacer } from '@elastic/eui'; +import { EuiLoadingSpinner, EuiIconTip } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { ImportRetry } from '../types'; import { SummarizedCopyToSpaceResult, SummarizedSavedObjectResult } from '..'; @@ -36,13 +36,13 @@ export const CopyStatusIndicator = (props: Props) => { // the object was overwritten ) : ( // the object was not overwritten ); return ; @@ -53,19 +53,19 @@ export const CopyStatusIndicator = (props: Props) => { // this is an "automatic overwrite", e.g., the "Overwrite all conflicts" option was selected ) : pendingObjectRetry?.overwrite ? ( // this is a manual overwrite, e.g., the individual "Overwrite?" switch was enabled ) : ( // this object is pending success, but it will not result in an overwrite ); return ; @@ -80,7 +80,7 @@ export const CopyStatusIndicator = (props: Props) => { content={ } /> @@ -88,28 +88,38 @@ export const CopyStatusIndicator = (props: Props) => { } if (hasConflicts) { - return ( - - - - - - } - /> - ); + switch (conflict!.error.type) { + case 'conflict': + return ( + + + + } + /> + ); + case 'ambiguous_conflict': + return ( + + + + } + /> + ); + } } return hasMissingReferences ? ( @@ -121,17 +131,17 @@ export const CopyStatusIndicator = (props: Props) => { overwrite ? ( ) : conflict ? ( ) : ( ) } diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_status_summary_indicator.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_status_summary_indicator.tsx index 4bc7e5cfaf31a..4dfb14e756cd6 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_status_summary_indicator.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_status_summary_indicator.tsx @@ -55,7 +55,7 @@ const renderIcon = (props: Props) => { content={ } @@ -93,7 +93,7 @@ const renderIcon = (props: Props) => { content={ } @@ -119,7 +119,7 @@ const renderIcon = (props: Props) => { content={ } diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.test.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.test.tsx index dfc908d81887a..e214db22aa9cc 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.test.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_flyout.test.tsx @@ -510,7 +510,7 @@ describe('CopyToSpaceFlyout', () => { Object { "color": "warning", "content": , @@ -604,7 +604,7 @@ describe('CopyToSpaceFlyout', () => { Object { "color": "danger", "content": , diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_form.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_form.tsx index fdc8d8c73e324..551573feebcdb 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_form.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/copy_to_space_form.tsx @@ -51,7 +51,7 @@ export const CopyToSpaceForm = (props: Props) => { label={ } fullWidth diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/processing_copy_to_space.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/processing_copy_to_space.tsx index ceaa1dc9f5e21..ab8fb0b438f67 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/processing_copy_to_space.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/processing_copy_to_space.tsx @@ -45,36 +45,30 @@ const renderCopyOptions = ({ createNewCopies, overwrite, includeRelated }: CopyO defaultMessage="Check for existing objects" /> ); - const overwriteLabel = overwrite ? ( - - ) : ( - - ); - const includeRelatedLabel = includeRelated ? ( - - ) : ( - - ); return ( {!createNewCopies && ( - + + } + /> )} - + + } + /> ); }; diff --git a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/selectable_spaces_control.tsx b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/selectable_spaces_control.tsx index 2a8b5e660f38c..d4e12b31b5b4f 100644 --- a/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/selectable_spaces_control.tsx +++ b/x-pack/plugins/spaces/public/copy_saved_objects_to_space/components/selectable_spaces_control.tsx @@ -31,7 +31,7 @@ export const SelectableSpacesControl = (props: Props) => { content={ } position="left" diff --git a/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/__snapshots__/confirm_delete_modal.test.tsx.snap b/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/__snapshots__/confirm_delete_modal.test.tsx.snap index 6e422bc13f06b..b0d0933614d12 100644 --- a/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/__snapshots__/confirm_delete_modal.test.tsx.snap +++ b/x-pack/plugins/spaces/public/management/components/confirm_delete_modal/__snapshots__/confirm_delete_modal.test.tsx.snap @@ -55,6 +55,7 @@ exports[`ConfirmDeleteModal renders as expected 1`] = ` labelType="label" > { })} > { values={{ rolesLink: ( diff --git a/x-pack/plugins/spaces/public/management/components/unauthorized_prompt/__snapshots__/unauthorized_prompt.test.tsx.snap b/x-pack/plugins/spaces/public/management/components/unauthorized_prompt/__snapshots__/unauthorized_prompt.test.tsx.snap index b53b4d6ec7caf..1e761a0f14fc9 100644 --- a/x-pack/plugins/spaces/public/management/components/unauthorized_prompt/__snapshots__/unauthorized_prompt.test.tsx.snap +++ b/x-pack/plugins/spaces/public/management/components/unauthorized_prompt/__snapshots__/unauthorized_prompt.test.tsx.snap @@ -7,7 +7,7 @@ exports[`UnauthorizedPrompt renders as expected 1`] = ` data-test-subj="permissionDeniedMessage" > diff --git a/x-pack/plugins/spaces/public/management/components/unauthorized_prompt/unauthorized_prompt.tsx b/x-pack/plugins/spaces/public/management/components/unauthorized_prompt/unauthorized_prompt.tsx index dd3f96d94eab4..50f10ec3860df 100644 --- a/x-pack/plugins/spaces/public/management/components/unauthorized_prompt/unauthorized_prompt.tsx +++ b/x-pack/plugins/spaces/public/management/components/unauthorized_prompt/unauthorized_prompt.tsx @@ -24,7 +24,7 @@ export const UnauthorizedPrompt = () => (

} diff --git a/x-pack/plugins/spaces/public/management/edit_space/customize_space/__snapshots__/customize_space_avatar.test.tsx.snap b/x-pack/plugins/spaces/public/management/edit_space/customize_space/__snapshots__/customize_space_avatar.test.tsx.snap index 269b2b6908183..058b9ecdd0f8f 100644 --- a/x-pack/plugins/spaces/public/management/edit_space/customize_space/__snapshots__/customize_space_avatar.test.tsx.snap +++ b/x-pack/plugins/spaces/public/management/edit_space/customize_space/__snapshots__/customize_space_avatar.test.tsx.snap @@ -14,6 +14,7 @@ exports[`renders without crashing 1`] = ` labelType="label" > { > { )} { fullWidth > { > { > { > { id="xpack.spaces.management.spaceIdentifier.urlIdentifierLabel" defaultMessage="URL identifier " /> - + {editLinkText}

diff --git a/x-pack/plugins/spaces/public/management/edit_space/enabled_features/__snapshots__/enabled_features.test.tsx.snap b/x-pack/plugins/spaces/public/management/edit_space/enabled_features/__snapshots__/enabled_features.test.tsx.snap index 43ae75b74c882..3835fa085c26e 100644 --- a/x-pack/plugins/spaces/public/management/edit_space/enabled_features/__snapshots__/enabled_features.test.tsx.snap +++ b/x-pack/plugins/spaces/public/management/edit_space/enabled_features/__snapshots__/enabled_features.test.tsx.snap @@ -68,6 +68,7 @@ exports[`EnabledFeatures renders as expected 1`] = ` values={ Object { "rolesLink": { values={{ rolesLink: ( { return ( { return ( diff --git a/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx b/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx index a98fae2561827..36efc68749783 100644 --- a/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx +++ b/x-pack/plugins/spaces/public/management/spaces_grid/spaces_grid_page.tsx @@ -140,7 +140,11 @@ export class SpacesGridPage extends Component { public getPrimaryActionButton() { return ( - + { { render: (record: Space) => ( { available: (record: Space) => !isReservedSpace(record), render: (record: Space) => ( diff --git a/x-pack/plugins/spaces/public/nav_control/components/manage_spaces_button.tsx b/x-pack/plugins/spaces/public/nav_control/components/manage_spaces_button.tsx index 98467ebdb790b..6ac637d6b31d6 100644 --- a/x-pack/plugins/spaces/public/nav_control/components/manage_spaces_button.tsx +++ b/x-pack/plugins/spaces/public/nav_control/components/manage_spaces_button.tsx @@ -32,6 +32,7 @@ export class ManageSpacesButton extends Component { isDisabled={this.props.isDisabled} onClick={this.navigateToManageSpaces} style={this.props.style} + data-test-subj="manageSpaces" > { return ( { const title = currentNamespaces.length === 1 ? i18n.translate('xpack.spaces.management.shareToSpace.shareNewSuccessTitle', { - defaultMessage: 'Saved Object is now shared!', + defaultMessage: 'Object is now shared', }) : i18n.translate('xpack.spaces.management.shareToSpace.shareEditSuccessTitle', { - defaultMessage: 'Saved Object updated', + defaultMessage: 'Object was updated', }); if (spacesToAdd.length > 0) { await spacesManager.shareSavedObjectAdd({ type, id }, spacesToAdd); const spaceNames = spacesToAdd.map( (spaceId) => spaces.find((space) => space.id === spaceId)!.name ); - const text = i18n.translate('xpack.spaces.management.shareToSpace.shareAddSuccessText', { - defaultMessage: `'{object}' was added to the following spaces:\n{spaces}`, - values: { object: meta.title, spaces: spaceNames.join(', ') }, - }); + const spaceCount = spaceNames.length; + const text = + spaceCount === 1 + ? i18n.translate('xpack.spaces.management.shareToSpace.shareAddSuccessTextSingular', { + defaultMessage: `'{object}' was added to 1 space.`, + values: { object: meta.title }, + }) + : i18n.translate('xpack.spaces.management.shareToSpace.shareAddSuccessTextPlural', { + defaultMessage: `'{object}' was added to {spaceCount} spaces.`, + values: { object: meta.title, spaceCount }, + }); toastNotifications.addSuccess({ title, text }); } if (spacesToRemove.length > 0) { @@ -125,10 +132,20 @@ export const ShareSavedObjectsToSpaceFlyout = (props: Props) => { const spaceNames = spacesToRemove.map( (spaceId) => spaces.find((space) => space.id === spaceId)!.name ); - const text = i18n.translate('xpack.spaces.management.shareToSpace.shareRemoveSuccessText', { - defaultMessage: `'{object}' was removed from the following spaces:\n{spaces}`, - values: { object: meta.title, spaces: spaceNames.join(', ') }, - }); + const spaceCount = spaceNames.length; + const text = + spaceCount === 1 + ? i18n.translate( + 'xpack.spaces.management.shareToSpace.shareRemoveSuccessTextSingular', + { + defaultMessage: `'{object}' was removed from 1 space.`, + values: { object: meta.title }, + } + ) + : i18n.translate('xpack.spaces.management.shareToSpace.shareRemoveSuccessTextPlural', { + defaultMessage: `'{object}' was removed from {spaceCount} spaces.`, + values: { object: meta.title, spaceCount }, + }); toastNotifications.addSuccess({ title, text }); } onObjectUpdated(); @@ -210,7 +227,7 @@ export const ShareSavedObjectsToSpaceFlyout = (props: Props) => {

diff --git a/x-pack/plugins/spaces/public/share_saved_objects_to_space/components/share_to_space_form.tsx b/x-pack/plugins/spaces/public/share_saved_objects_to_space/components/share_to_space_form.tsx index 24402fec8d771..ad84ea85d5e54 100644 --- a/x-pack/plugins/spaces/public/share_saved_objects_to_space/components/share_to_space_form.tsx +++ b/x-pack/plugins/spaces/public/share_saved_objects_to_space/components/share_to_space_form.tsx @@ -35,14 +35,14 @@ export const ShareToSpaceForm = (props: Props) => { title={ } color="warning" > { label={ } labelAppend={ diff --git a/x-pack/plugins/spaces/public/share_saved_objects_to_space/share_saved_objects_to_space_column.tsx b/x-pack/plugins/spaces/public/share_saved_objects_to_space/share_saved_objects_to_space_column.tsx index e8649faa120be..93d7bb0170519 100644 --- a/x-pack/plugins/spaces/public/share_saved_objects_to_space/share_saved_objects_to_space_column.tsx +++ b/x-pack/plugins/spaces/public/share_saved_objects_to_space/share_saved_objects_to_space_column.tsx @@ -52,7 +52,7 @@ const ColumnDisplay = ({ namespaces, data }: ColumnDataProps) => { const unauthorizedCount = (namespaces?.filter((namespace) => namespace === '?') ?? []).length; const unauthorizedTooltip = i18n.translate( 'xpack.spaces.management.shareToSpace.columnUnauthorizedLabel', - { defaultMessage: 'You do not have permission to view these spaces' } + { defaultMessage: `You don't have permission to view these spaces.` } ); const displayedSpaces = isExpanded diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index 2435d8a9aaf04..904b14a7459ad 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -51,6 +51,27 @@ } } }, + "enterprise_search": { + "properties": { + "ui_viewed": { + "properties": { + "overview": { + "type": "long" + } + } + }, + "ui_clicked": { + "properties": { + "app_search": { + "type": "long" + }, + "workplace_search": { + "type": "long" + } + } + } + } + }, "workplace_search": { "properties": { "ui_viewed": { @@ -276,6 +297,28 @@ } } }, + "security": { + "properties": { + "auditLoggingEnabled": { + "type": "boolean" + }, + "loginSelectorEnabled": { + "type": "boolean" + }, + "accessAgreementEnabled": { + "type": "boolean" + }, + "authProviderCount": { + "type": "number" + }, + "enabledAuthProviders": { + "type": "keyword" + }, + "httpAuthSchemes": { + "type": "keyword" + } + } + }, "spaces": { "properties": { "usesFeatureControls": { diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx index cf32bf0455a1b..dad0f0e5ee282 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx @@ -4,31 +4,30 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { MouseEventHandler, FC, useContext, useState } from 'react'; +import React, { MouseEventHandler, FC, useContext, useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { - Direction, - EuiBadge, + EuiBasicTable, + EuiBasicTableProps, EuiButtonEmpty, EuiButtonIcon, EuiCallOut, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, - EuiInMemoryTable, - EuiSearchBarProps, + EuiSearchBar, + EuiSpacer, EuiPopover, EuiTitle, } from '@elastic/eui'; -import { TransformId, TRANSFORM_STATE } from '../../../../../../common'; +import { TransformId } from '../../../../../../common'; import { useRefreshTransformList, TransformListRow, - TRANSFORM_MODE, TRANSFORM_LIST_COLUMN, } from '../../../../common'; import { useStopTransforms } from '../../../../hooks'; @@ -45,9 +44,11 @@ import { import { useStartAction, StartActionName, StartActionModal } from '../action_start'; import { StopActionName } from '../action_stop'; -import { ItemIdToExpandedRowMap, Clause, TermClause, FieldClause, Value } from './common'; -import { getTaskStateBadge, useColumns } from './use_columns'; +import { ItemIdToExpandedRowMap } from './common'; +import { useColumns } from './use_columns'; import { ExpandedRow } from './expanded_row'; +import { TransformSearchBar, filterTransforms } from './transform_search_bar'; +import { useTableSettings } from './use_table_settings'; function getItemIdToExpandedRowMap( itemIds: TransformId[], @@ -62,14 +63,6 @@ function getItemIdToExpandedRowMap( }, {} as ItemIdToExpandedRowMap); } -function stringMatch(str: string | undefined, substr: any) { - return ( - typeof str === 'string' && - typeof substr === 'string' && - (str.toLowerCase().match(substr.toLowerCase()) === null) === false - ); -} - interface Props { errorMessage: any; isInitialized: boolean; @@ -88,24 +81,14 @@ export const TransformList: FC = ({ const [isLoading, setIsLoading] = useState(false); const { refresh } = useRefreshTransformList({ isLoading: setIsLoading }); - const [filterActive, setFilterActive] = useState(false); - + const [searchQueryText, setSearchQueryText] = useState(''); const [filteredTransforms, setFilteredTransforms] = useState([]); const [expandedRowItemIds, setExpandedRowItemIds] = useState([]); - const [transformSelection, setTransformSelection] = useState([]); const [isActionsMenuOpen, setIsActionsMenuOpen] = useState(false); const bulkStartAction = useStartAction(false); const bulkDeleteAction = useDeleteAction(false); - const [searchError, setSearchError] = useState(undefined); - - const [pageIndex, setPageIndex] = useState(0); - const [pageSize, setPageSize] = useState(10); - - const [sortField, setSortField] = useState(TRANSFORM_LIST_COLUMN.ID); - const [sortDirection, setSortDirection] = useState('asc'); - const stopTransforms = useStopTransforms(); const { capabilities } = useContext(AuthorizationContext); @@ -114,90 +97,41 @@ export const TransformList: FC = ({ !capabilities.canPreviewTransform || !capabilities.canStartStopTransform; - const onQueryChange = ({ - query, - error, - }: Parameters>[0]) => { - if (error) { - setSearchError(error.message); + const { columns, modals: singleActionModals } = useColumns( + expandedRowItemIds, + setExpandedRowItemIds, + transformSelection + ); + + const updateFilteredItems = (queryClauses: any) => { + if (queryClauses.length) { + const filtered = filterTransforms(transforms, queryClauses); + setFilteredTransforms(filtered); } else { - let clauses: Clause[] = []; - if (query && query.ast !== undefined && query.ast.clauses !== undefined) { - clauses = query.ast.clauses; - } - if (clauses.length > 0) { - setFilterActive(true); - filterTransforms(clauses as Array); - } else { - setFilterActive(false); - } - setSearchError(undefined); + setFilteredTransforms(transforms); } }; - const filterTransforms = (clauses: Array) => { - setIsLoading(true); - // keep count of the number of matches we make as we're looping over the clauses - // we only want to return transforms which match all clauses, i.e. each search term is ANDed - // { transform-one: { transform: { id: transform-one, config: {}, state: {}, ... }, count: 0 }, transform-two: {...} } - const matches: Record = transforms.reduce((p: Record, c) => { - p[c.id] = { - transform: c, - count: 0, - }; - return p; - }, {}); - - clauses.forEach((c) => { - // the search term could be negated with a minus, e.g. -bananas - const bool = c.match === 'must'; - let ts = []; - - if (c.type === 'term') { - // filter term based clauses, e.g. bananas - // match on ID and description - // if the term has been negated, AND the matches - if (bool === true) { - ts = transforms.filter( - (transform) => - stringMatch(transform.id, c.value) === bool || - stringMatch(transform.config.description, c.value) === bool - ); - } else { - ts = transforms.filter( - (transform) => - stringMatch(transform.id, c.value) === bool && - stringMatch(transform.config.description, c.value) === bool - ); + useEffect(() => { + const filterList = () => { + if (searchQueryText !== '') { + const query = EuiSearchBar.Query.parse(searchQueryText); + let clauses: any = []; + if (query && query.ast !== undefined && query.ast.clauses !== undefined) { + clauses = query.ast.clauses; } + updateFilteredItems(clauses); } else { - // filter other clauses, i.e. the mode and status filters - if (Array.isArray(c.value)) { - // the status value is an array of string(s) e.g. ['failed', 'stopped'] - ts = transforms.filter((transform) => - (c.value as Value[]).includes(transform.stats.state) - ); - } else { - ts = transforms.filter((transform) => transform.mode === c.value); - } + updateFilteredItems([]); } - - ts.forEach((t) => matches[t.id].count++); - }); - - // loop through the matches and return only transforms which have match all the clauses - const filtered = Object.values(matches) - .filter((m) => (m && m.count) >= clauses.length) - .map((m) => m.transform); - - setFilteredTransforms(filtered); - setIsLoading(false); - }; - - const { columns, modals: singleActionModals } = useColumns( - expandedRowItemIds, - setExpandedRowItemIds, - transformSelection + }; + filterList(); + // eslint-disable-next-line + }, [searchQueryText, transforms]); // missing dependency updateFilteredItems + + const { onTableChange, pageOfItems, pagination, sorting } = useTableSettings( + TRANSFORM_LIST_COLUMN.ID, + filteredTransforms ); // Before the transforms have been loaded for the first time, display the loading indicator only. @@ -246,23 +180,8 @@ export const TransformList: FC = ({ ); } - const sorting = { - sort: { - field: sortField, - direction: sortDirection, - }, - }; - const itemIdToExpandedRowMap = getItemIdToExpandedRowMap(expandedRowItemIds, transforms); - const pagination = { - initialPageIndex: pageIndex, - initialPageSize: pageSize, - totalItemCount: transforms.length, - pageSizeOptions: [10, 20, 50], - hidePerPageOptions: false, - }; - const bulkActionMenuItems = [
bulkStartAction.openModal(transformSelection)}> @@ -331,7 +250,7 @@ export const TransformList: FC = ({ ]; }; - const renderToolsRight = () => ( + const toolsRight = ( @@ -342,56 +261,6 @@ export const TransformList: FC = ({ ); - const search = { - toolsLeft: transformSelection.length > 0 ? renderToolsLeft() : undefined, - toolsRight: renderToolsRight(), - onChange: onQueryChange, - box: { - incremental: true, - }, - filters: [ - { - type: 'field_value_selection' as const, - field: 'state.state', - name: i18n.translate('xpack.transform.statusFilter', { defaultMessage: 'Status' }), - multiSelect: 'or' as const, - options: Object.values(TRANSFORM_STATE).map((val) => ({ - value: val, - name: val, - view: getTaskStateBadge(val), - })), - }, - { - type: 'field_value_selection' as const, - field: 'mode', - name: i18n.translate('xpack.transform.modeFilter', { defaultMessage: 'Mode' }), - multiSelect: false, - options: Object.values(TRANSFORM_MODE).map((val) => ({ - value: val, - name: val, - view: ( - - {val} - - ), - })), - }, - ], - }; - - const onTableChange = ({ - page = { index: 0, size: 10 }, - sort = { field: TRANSFORM_LIST_COLUMN.ID as string, direction: 'asc' }, - }) => { - const { index, size } = page; - setPageIndex(index); - setPageSize(size); - - const { field, direction } = sort; - setSortField(field as string); - setSortDirection(direction as Direction); - }; - const selection = { onSelectionChange: (selected: TransformListRow[]) => setTransformSelection(selected), }; @@ -404,30 +273,38 @@ export const TransformList: FC = ({ {/* Single Action Modals */} {singleActionModals} - - + {transformSelection.length > 0 ? ( + {renderToolsLeft()} + ) : null} + + + + {toolsRight} + + + columns={columns} - error={searchError} hasActions={false} isExpandable={true} isSelectable={false} - items={filterActive ? filteredTransforms : transforms} + items={pageOfItems as TransformListRow[]} itemId={TRANSFORM_LIST_COLUMN.ID} itemIdToExpandedRowMap={itemIdToExpandedRowMap} loading={isLoading || transformsLoading} - onTableChange={onTableChange} - pagination={pagination} - rowProps={(item) => ({ - 'data-test-subj': `transformListRow row-${item.id}`, - })} + onChange={onTableChange as EuiBasicTableProps['onChange']} selection={selection} + pagination={pagination!} sorting={sorting} - search={search} data-test-subj={`transformListTable ${ isLoading || transformsLoading ? 'loading' : 'loaded' }`} + rowProps={(item) => ({ + 'data-test-subj': `transformListRow row-${item.id}`, + })} />
); diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_search_bar.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_search_bar.tsx new file mode 100644 index 0000000000000..fab591f881310 --- /dev/null +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_search_bar.tsx @@ -0,0 +1,181 @@ +/* + * 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 React, { Dispatch, SetStateAction, FC, Fragment, useState } from 'react'; +import { + EuiBadge, + EuiSearchBar, + EuiSearchBarProps, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + SearchFilterConfig, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { TermClause, FieldClause, Value } from './common'; +import { TRANSFORM_STATE } from '../../../../../../common'; +import { TRANSFORM_MODE, TransformListRow } from '../../../../common'; +import { getTaskStateBadge } from './use_columns'; + +const filters: SearchFilterConfig[] = [ + { + type: 'field_value_selection', + field: 'state.state', + name: i18n.translate('xpack.transform.statusFilter', { defaultMessage: 'Status' }), + multiSelect: 'or', + options: Object.values(TRANSFORM_STATE).map((val) => ({ + value: val, + name: val, + view: getTaskStateBadge(val), + })), + }, + { + type: 'field_value_selection', + field: 'mode', + name: i18n.translate('xpack.transform.modeFilter', { defaultMessage: 'Mode' }), + multiSelect: false, + options: Object.values(TRANSFORM_MODE).map((val) => ({ + value: val, + name: val, + view: ( + + {val} + + ), + })), + }, +]; + +function stringMatch(str: string | undefined, substr: any) { + return ( + typeof str === 'string' && + typeof substr === 'string' && + (str.toLowerCase().match(substr.toLowerCase()) === null) === false + ); +} + +export const filterTransforms = ( + transforms: TransformListRow[], + clauses: Array +) => { + // keep count of the number of matches we make as we're looping over the clauses + // we only want to return transforms which match all clauses, i.e. each search term is ANDed + // { transform-one: { transform: { id: transform-one, config: {}, state: {}, ... }, count: 0 }, transform-two: {...} } + const matches: Record = transforms.reduce((p: Record, c) => { + p[c.id] = { + transform: c, + count: 0, + }; + return p; + }, {}); + + clauses.forEach((c) => { + // the search term could be negated with a minus, e.g. -bananas + const bool = c.match === 'must'; + let ts = []; + + if (c.type === 'term') { + // filter term based clauses, e.g. bananas + // match on ID and description + // if the term has been negated, AND the matches + if (bool === true) { + ts = transforms.filter( + (transform) => + stringMatch(transform.id, c.value) === bool || + stringMatch(transform.config.description, c.value) === bool + ); + } else { + ts = transforms.filter( + (transform) => + stringMatch(transform.id, c.value) === bool && + stringMatch(transform.config.description, c.value) === bool + ); + } + } else { + // filter other clauses, i.e. the mode and status filters + if (Array.isArray(c.value)) { + // the status value is an array of string(s) e.g. ['failed', 'stopped'] + ts = transforms.filter((transform) => (c.value as Value[]).includes(transform.stats.state)); + } else { + ts = transforms.filter((transform) => transform.mode === c.value); + } + } + + ts.forEach((t) => matches[t.id].count++); + }); + + // loop through the matches and return only transforms which have match all the clauses + const filtered = Object.values(matches) + .filter((m) => (m && m.count) >= clauses.length) + .map((m) => m.transform); + + return filtered; +}; + +function getError(errorMessage: string | null) { + if (errorMessage) { + return i18n.translate('xpack.transform.transformList.searchBar.invalidSearchErrorMessage', { + defaultMessage: 'Invalid search: {errorMessage}', + values: { errorMessage }, + }); + } + + return ''; +} + +interface Props { + searchQueryText: string; + setSearchQueryText: Dispatch>; +} + +export const TransformSearchBar: FC = ({ searchQueryText, setSearchQueryText }) => { + const [errorMessage, setErrorMessage] = useState(null); + + const onChange: EuiSearchBarProps['onChange'] = ({ query, error }) => { + if (error) { + setErrorMessage(error.message); + } else if (query !== null && query.text !== undefined) { + setSearchQueryText(query.text); + setErrorMessage(null); + } + }; + + return ( + + + {searchQueryText === undefined && ( + + )} + {searchQueryText !== undefined && ( + + )} + + + + + + ); +}; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_table_settings.ts b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_table_settings.ts new file mode 100644 index 0000000000000..ad40a3f8103b9 --- /dev/null +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_table_settings.ts @@ -0,0 +1,135 @@ +/* + * 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 { useState } from 'react'; +import { Direction, EuiBasicTableProps, EuiTableSortingType } from '@elastic/eui'; +import sortBy from 'lodash/sortBy'; +import get from 'lodash/get'; + +const PAGE_SIZE = 10; +const PAGE_SIZE_OPTIONS = [10, 25, 50]; + +const propertyMap = { + Mode: 'mode', +}; + +// Copying from EUI EuiBasicTable types as type is not correctly picked up for table's onChange +// Can be removed when https://github.com/elastic/eui/issues/4011 is addressed in EUI +export interface Criteria { + page?: { + index: number; + size: number; + }; + sort?: { + field: keyof T; + direction: Direction; + }; +} +export interface CriteriaWithPagination extends Criteria { + page: { + index: number; + size: number; + }; +} + +interface AnalyticsBasicTableSettings { + pageIndex: number; + pageSize: number; + totalItemCount: number; + hidePerPageOptions: boolean; + sortField: keyof T; + sortDirection: Direction; +} + +interface UseTableSettingsReturnValue { + onTableChange: EuiBasicTableProps['onChange']; + pageOfItems: T[]; + pagination: EuiBasicTableProps['pagination']; + sorting: EuiTableSortingType; +} + +export function useTableSettings( + sortByField: keyof TypeOfItem, + items: TypeOfItem[] +): UseTableSettingsReturnValue { + const [tableSettings, setTableSettings] = useState>({ + pageIndex: 0, + pageSize: PAGE_SIZE, + totalItemCount: 0, + hidePerPageOptions: false, + sortField: sortByField, + sortDirection: 'asc', + }); + + const getPageOfItems = ( + list: TypeOfItem[], + index: number, + size: number, + sortField: keyof TypeOfItem, + sortDirection: Direction + ) => { + list = sortBy(list, (item) => + get(item, propertyMap[sortField as keyof typeof propertyMap] || sortField) + ); + list = sortDirection === 'asc' ? list : list.reverse(); + const listLength = list.length; + + let pageStart = index * size; + if (pageStart >= listLength && listLength !== 0) { + // if the page start is larger than the number of items due to + // filters being applied or items being deleted, calculate a new page start + pageStart = Math.floor((listLength - 1) / size) * size; + + setTableSettings({ ...tableSettings, pageIndex: pageStart / size }); + } + return { + pageOfItems: list.slice(pageStart, pageStart + size), + totalItemCount: listLength, + }; + }; + + const onTableChange: EuiBasicTableProps['onChange'] = ({ + page = { index: 0, size: PAGE_SIZE }, + sort = { field: sortByField, direction: 'asc' }, + }: CriteriaWithPagination) => { + const { index, size } = page; + const { field, direction } = sort; + + setTableSettings({ + ...tableSettings, + pageIndex: index, + pageSize: size, + sortField: field, + sortDirection: direction, + }); + }; + + const { pageIndex, pageSize, sortField, sortDirection } = tableSettings; + + const { pageOfItems, totalItemCount } = getPageOfItems( + items, + pageIndex, + pageSize, + sortField, + sortDirection + ); + + const pagination = { + pageIndex, + pageSize, + totalItemCount, + pageSizeOptions: PAGE_SIZE_OPTIONS, + }; + + const sorting = { + sort: { + field: sortField, + direction: sortDirection, + }, + }; + + return { onTableChange, pageOfItems, pagination, sorting }; +} diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 8b9409f01087c..54c92d323fcff 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2880,7 +2880,6 @@ "savedObjectsManagement.objectsTable.flyout.renderConflicts.columnSampleOfAffectedObjectsDescription": "影響されるオブジェクトのサンプル", "savedObjectsManagement.objectsTable.flyout.renderConflicts.columnSampleOfAffectedObjectsName": "影響されるオブジェクトのサンプル", "savedObjectsManagement.objectsTable.flyout.resolveImportErrorsFileErrorMessage": "ファイルを処理できませんでした。", - "savedObjectsManagement.objectsTable.flyout.selectFileToImportFormRowLabel": "インポートするファイルを選択してください", "savedObjectsManagement.objectsTable.header.exportButtonLabel": "{filteredCount, plural, one{# オブジェクト} other {# オブジェクト}}をエクスポート", "savedObjectsManagement.objectsTable.header.importButtonLabel": "インポート", "savedObjectsManagement.objectsTable.header.refreshButtonLabel": "更新", @@ -4446,7 +4445,6 @@ "xpack.actions.builtin.case.connectorApiNullError": "コネクター[apiUrl]が必要です", "xpack.actions.builtin.case.jiraTitle": "Jira", "xpack.actions.builtin.case.resilientTitle": "IBM Resilient", - "xpack.actions.builtin.configuration.apiWhitelistError": "コネクターアクションの構成エラー:{message}", "xpack.actions.builtin.email.errorSendingErrorMessage": "エラー送信メールアドレス", "xpack.actions.builtin.emailTitle": "メール", "xpack.actions.builtin.esIndex.errorIndexingErrorMessage": "エラーインデックス作成ドキュメント", @@ -14081,8 +14079,6 @@ "xpack.reporting.screencapture.waitingForRenderComplete": "レンダリングの完了を待っています", "xpack.reporting.screencapture.waitingForRenderedElements": "レンダリングされた {itemsCount} 個の要素が DOM に入るのを待っています", "xpack.reporting.screenCapturePanelContent.optimizeForPrintingLabel": "印刷用に最適化", - "xpack.reporting.selfCheck.ok": "レポートプラグイン自己チェックOK!", - "xpack.reporting.selfCheck.warning": "レポートプラグイン自己チェックで警告が発生しました: {err}", "xpack.reporting.serverConfig.autoSet.sandboxDisabled": "Chromiumサンドボックスは保護が強化されていますが、{osName} OSではサポートされていません。自動的に'{configKey}: true'を設定しています。", "xpack.reporting.serverConfig.autoSet.sandboxEnabled": "Chromiumサンドボックスは保護が強化され、{osName} OSでサポートされています。自動的にChromiumサンドボックスを有効にしています。", "xpack.reporting.serverConfig.invalidServerHostname": "Kibana構成で「server.host:\"0\"」が見つかりました。これはReportingと互換性がありません。レポートが動作するように、「{configKey}:0.0.0.0」が自動的に構成になります。設定を「server.host:0.0.0.0」に変更するか、kibana.ymlに「{configKey}:0.0.0.0'」を追加して、このメッセージが表示されないようにすることができます。", @@ -15115,7 +15111,6 @@ "xpack.securitySolution.case.configureCases.mappingFieldDescription": "説明", "xpack.securitySolution.case.configureCases.mappingFieldName": "名前", "xpack.securitySolution.case.configureCases.mappingFieldNotMapped": "マップされません", - "xpack.securitySolution.case.configureCases.mappingFieldSummary": "まとめ", "xpack.securitySolution.case.configureCases.noConnector": "コネクターを選択していません", "xpack.securitySolution.case.configureCases.updateConnector": "コネクターを更新", "xpack.securitySolution.case.configureCases.updateSelectedConnector": "{ connectorName }を更新", @@ -15139,14 +15134,6 @@ "xpack.securitySolution.case.connectors.common.requiredPasswordTextField": "パスワードが必要です", "xpack.securitySolution.case.connectors.common.requiredUsernameTextField": "ユーザー名が必要です", "xpack.securitySolution.case.connectors.common.usernameTextFieldLabel": "ユーザー名", - "xpack.securitySolution.case.connectors.jira.actionTypeTitle": "Jira", - "xpack.securitySolution.case.connectors.jira.apiTokenTextFieldLabel": "APIトークンまたはパスワード", - "xpack.securitySolution.case.connectors.jira.emailTextFieldLabel": "電子メールアドレスまたはユーザー名", - "xpack.securitySolution.case.connectors.jira.projectKey": "プロジェクトキー", - "xpack.securitySolution.case.connectors.jira.requiredApiTokenTextField": "APIトークンまたはパスワードが必要です", - "xpack.securitySolution.case.connectors.jira.requiredEmailTextField": "電子メールアドレスまたはユーザー名が必要です", - "xpack.securitySolution.case.connectors.jira.requiredProjectKeyTextField": "プロジェクトキーが必要です", - "xpack.securitySolution.case.connectors.jira.selectMessageText": "Jiraでセキュリティケースデータを更新するか、新しいインシデントにプッシュ", "xpack.securitySolution.case.connectors.resilient.actionTypeTitle": "IBM Resilient", "xpack.securitySolution.case.connectors.resilient.apiKeyId": "APIキーID", "xpack.securitySolution.case.connectors.resilient.apiKeySecret": "APIキーシークレット", @@ -17600,8 +17587,6 @@ "xpack.spaces.management.copyToSpace.actionTitle": "スペースにコピー", "xpack.spaces.management.copyToSpace.copyErrorTitle": "保存されたオブジェクトのコピー中にエラーが発生", "xpack.spaces.management.copyToSpace.copyResultsLabel": "コピー結果", - "xpack.spaces.management.copyToSpace.copyStatus.conflictsMessage": "このスペースには同じID({id})の保存されたオブジェクトが既に存在します。", - "xpack.spaces.management.copyToSpace.copyStatus.conflictsOverwriteMessage": "「上書き」をクリックしてこのバージョンをコピーされたバージョンに置き換えます。", "xpack.spaces.management.copyToSpace.copyStatus.pendingOverwriteMessage": "保存されたオブジェクトは上書きされます。「スキップ」をクリックしてこの操作をキャンセルします。", "xpack.spaces.management.copyToSpace.copyStatus.successMessage": "保存されたオブジェクトがコピーされました。", "xpack.spaces.management.copyToSpace.copyStatus.unresolvableErrorMessage": "この保存されたオブジェクトのコピー中にエラーが発生しました。", @@ -17610,8 +17595,6 @@ "xpack.spaces.management.copyToSpace.copyStatusSummary.successMessage": "{space}スペースにコピーされました。", "xpack.spaces.management.copyToSpace.copyToSpacesButton": "{spaceCount} {spaceCount, plural, one {スペース} other {スペース}}にコピー", "xpack.spaces.management.copyToSpace.disabledCopyToSpacesButton": "コピー", - "xpack.spaces.management.copyToSpace.dontIncludeRelatedLabel": "関連性のある保存されたオブジェクトを含みません", - "xpack.spaces.management.copyToSpace.dontOverwriteLabel": "保存されたオブジェクトを上書きしません", "xpack.spaces.management.copyToSpace.finishCopyToSpacesButton": "終了", "xpack.spaces.management.copyToSpace.finishedButtonLabel": "コピーが完了しました。", "xpack.spaces.management.copyToSpace.finishPendingOverwritesCopyToSpacesButton": "{overwriteCount}件のオブジェクトを上書き", @@ -17619,10 +17602,8 @@ "xpack.spaces.management.copyToSpace.inProgressButtonLabel": "コピーが進行中です。お待ちください。", "xpack.spaces.management.copyToSpace.noSpacesBody": "コピーできるスペースがありません。", "xpack.spaces.management.copyToSpace.noSpacesTitle": "スペースがありません", - "xpack.spaces.management.copyToSpace.overwriteLabel": "保存されたオブジェクトを自動的に上書きしています", "xpack.spaces.management.copyToSpace.resolveCopyErrorTitle": "保存されたオブジェクトの矛盾の解決中にエラーが発生", "xpack.spaces.management.copyToSpace.resolveCopySuccessTitle": "上書き成功", - "xpack.spaces.management.copyToSpace.selectSpacesLabel": "コピー先のスペースを選択してください", "xpack.spaces.management.copyToSpace.spacesLoadErrorTitle": "利用可能なスペースを読み込み中にエラーが発生", "xpack.spaces.management.copyToSpaceFlyoutFooter.errorCount": "エラー", "xpack.spaces.management.copyToSpaceFlyoutFooter.pendingCount": "保留中", @@ -17701,7 +17682,6 @@ "xpack.spaces.management.spacesGridPage.spacesTitle": "スペース", "xpack.spaces.management.spacesGridPage.spaceSuccessfullyDeletedNotificationMessage": "「{spaceName}」 スペースが削除されました。", "xpack.spaces.management.toggleAllFeaturesLink": "(すべて変更)", - "xpack.spaces.management.unauthorizedPrompt.permissionDeniedDescription": "スペースを管理するパーミッションがありません。", "xpack.spaces.management.unauthorizedPrompt.permissionDeniedTitle": "パーミッションが拒否されました", "xpack.spaces.management.validateSpace.describeMaxLengthErrorMessage": "説明は 2000 文字以内でなければなりません。", "xpack.spaces.management.validateSpace.nameMaxLengthErrorMessage": "名前はは 1024 文字以内でなければなりません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index b9fb6340e38cf..df721cb624662 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2881,7 +2881,6 @@ "savedObjectsManagement.objectsTable.flyout.renderConflicts.columnSampleOfAffectedObjectsDescription": "受影响对象样例", "savedObjectsManagement.objectsTable.flyout.renderConflicts.columnSampleOfAffectedObjectsName": "受影响对象样例", "savedObjectsManagement.objectsTable.flyout.resolveImportErrorsFileErrorMessage": "无法处理该文件。", - "savedObjectsManagement.objectsTable.flyout.selectFileToImportFormRowLabel": "请选择要导入的文件", "savedObjectsManagement.objectsTable.header.exportButtonLabel": "导出 {filteredCount, plural, one{# 个对象} other {# 个对象}}", "savedObjectsManagement.objectsTable.header.importButtonLabel": "导入", "savedObjectsManagement.objectsTable.header.refreshButtonLabel": "刷新", @@ -4447,7 +4446,6 @@ "xpack.actions.builtin.case.connectorApiNullError": "需要指定连接器 [apiUrl]", "xpack.actions.builtin.case.jiraTitle": "Jira", "xpack.actions.builtin.case.resilientTitle": "IBM Resilient", - "xpack.actions.builtin.configuration.apiWhitelistError": "配置连接器操作时出错:{message}", "xpack.actions.builtin.email.errorSendingErrorMessage": "发送电子邮件时出错", "xpack.actions.builtin.emailTitle": "电子邮件", "xpack.actions.builtin.esIndex.errorIndexingErrorMessage": "索引文档时出错", @@ -14090,8 +14088,6 @@ "xpack.reporting.screencapture.waitingForRenderComplete": "正在等候渲染完成", "xpack.reporting.screencapture.waitingForRenderedElements": "正在等候 {itemsCount} 个已渲染元素进入 DOM", "xpack.reporting.screenCapturePanelContent.optimizeForPrintingLabel": "打印优化", - "xpack.reporting.selfCheck.ok": "Reporting 插件自检正常!", - "xpack.reporting.selfCheck.warning": "Reporting 插件自检生成警告:{err}", "xpack.reporting.serverConfig.autoSet.sandboxDisabled": "Chromium 沙盒提供附加保护层,但不受 {osName} OS 支持。自动设置“{configKey}: true”。", "xpack.reporting.serverConfig.autoSet.sandboxEnabled": "Chromium 沙盒提供附加保护层,受 {osName} OS 支持。自动启用 Chromium 沙盒。", "xpack.reporting.serverConfig.invalidServerHostname": "在 Kibana 配置中找到“server.host:\"0\"”。其不与 Reporting 兼容。要使 Reporting 运行,“{configKey}:0.0.0.0”将自动添加到配置中。可以将该设置更改为“server.host:0.0.0.0”或在 kibana.yml 中添加“{configKey}:0.0.0.0”,以阻止此消息。", @@ -15124,7 +15120,6 @@ "xpack.securitySolution.case.configureCases.mappingFieldDescription": "描述", "xpack.securitySolution.case.configureCases.mappingFieldName": "名称", "xpack.securitySolution.case.configureCases.mappingFieldNotMapped": "未映射", - "xpack.securitySolution.case.configureCases.mappingFieldSummary": "摘要", "xpack.securitySolution.case.configureCases.noConnector": "未选择连接器", "xpack.securitySolution.case.configureCases.updateConnector": "更新连接器", "xpack.securitySolution.case.configureCases.updateSelectedConnector": "更新 { connectorName }", @@ -15148,14 +15143,6 @@ "xpack.securitySolution.case.connectors.common.requiredPasswordTextField": "“密码”必填", "xpack.securitySolution.case.connectors.common.requiredUsernameTextField": "“用户名”必填", "xpack.securitySolution.case.connectors.common.usernameTextFieldLabel": "用户名", - "xpack.securitySolution.case.connectors.jira.actionTypeTitle": "Jira", - "xpack.securitySolution.case.connectors.jira.apiTokenTextFieldLabel": "API 令牌或密码", - "xpack.securitySolution.case.connectors.jira.emailTextFieldLabel": "电子邮件或用户名", - "xpack.securitySolution.case.connectors.jira.projectKey": "项目键", - "xpack.securitySolution.case.connectors.jira.requiredApiTokenTextField": "“API 令牌或密码”必填", - "xpack.securitySolution.case.connectors.jira.requiredEmailTextField": "“电子邮件或用户名”必填", - "xpack.securitySolution.case.connectors.jira.requiredProjectKeyTextField": "“项目键”必填", - "xpack.securitySolution.case.connectors.jira.selectMessageText": "将 Security 案例数据推送或更新到 Jira 中的新问题", "xpack.securitySolution.case.connectors.resilient.actionTypeTitle": "IBM Resilient", "xpack.securitySolution.case.connectors.resilient.apiKeyId": "API 密钥 ID", "xpack.securitySolution.case.connectors.resilient.apiKeySecret": "API 密钥密码", @@ -17610,8 +17597,6 @@ "xpack.spaces.management.copyToSpace.actionTitle": "复制到工作区", "xpack.spaces.management.copyToSpace.copyErrorTitle": "复制已保存对象时出错", "xpack.spaces.management.copyToSpace.copyResultsLabel": "复制结果", - "xpack.spaces.management.copyToSpace.copyStatus.conflictsMessage": "具有匹配 ID ({id}) 的已保存对象在此工作区中已存在。", - "xpack.spaces.management.copyToSpace.copyStatus.conflictsOverwriteMessage": "单击“覆盖”可将此版本替换为复制的版本。", "xpack.spaces.management.copyToSpace.copyStatus.pendingOverwriteMessage": "已保存对象将被覆盖。单击“跳过”可取消此操作。", "xpack.spaces.management.copyToSpace.copyStatus.successMessage": "已保存对象成功复制。", "xpack.spaces.management.copyToSpace.copyStatus.unresolvableErrorMessage": "复制此已保存对象时出错。", @@ -17620,8 +17605,6 @@ "xpack.spaces.management.copyToSpace.copyStatusSummary.successMessage": "已成功复制到 {space} 工作区。", "xpack.spaces.management.copyToSpace.copyToSpacesButton": "复制到 {spaceCount} {spaceCount, plural, one {个工作区} other {个工作区}}", "xpack.spaces.management.copyToSpace.disabledCopyToSpacesButton": "复制", - "xpack.spaces.management.copyToSpace.dontIncludeRelatedLabel": "不包括相关已保存对象", - "xpack.spaces.management.copyToSpace.dontOverwriteLabel": "未覆盖已保存对象", "xpack.spaces.management.copyToSpace.finishCopyToSpacesButton": "完成", "xpack.spaces.management.copyToSpace.finishedButtonLabel": "复制已完成。", "xpack.spaces.management.copyToSpace.finishPendingOverwritesCopyToSpacesButton": "覆盖 {overwriteCount} 个对象", @@ -17629,10 +17612,8 @@ "xpack.spaces.management.copyToSpace.inProgressButtonLabel": "复制正在进行中。请稍候。", "xpack.spaces.management.copyToSpace.noSpacesBody": "没有可向其中进行复制的合格工作区。", "xpack.spaces.management.copyToSpace.noSpacesTitle": "没有可用的工作区", - "xpack.spaces.management.copyToSpace.overwriteLabel": "正在自动覆盖已保存对象", "xpack.spaces.management.copyToSpace.resolveCopyErrorTitle": "解决已保存对象冲突时出错", "xpack.spaces.management.copyToSpace.resolveCopySuccessTitle": "覆盖成功", - "xpack.spaces.management.copyToSpace.selectSpacesLabel": "选择要向其中进行复制的工作区", "xpack.spaces.management.copyToSpace.spacesLoadErrorTitle": "加载可用工作区时出错", "xpack.spaces.management.copyToSpaceFlyoutFooter.errorCount": "错误", "xpack.spaces.management.copyToSpaceFlyoutFooter.pendingCount": "待处理", @@ -17711,7 +17692,6 @@ "xpack.spaces.management.spacesGridPage.spacesTitle": "工作区", "xpack.spaces.management.spacesGridPage.spaceSuccessfullyDeletedNotificationMessage": "已删除 “{spaceName}” 空间。", "xpack.spaces.management.toggleAllFeaturesLink": "(全部更改)", - "xpack.spaces.management.unauthorizedPrompt.permissionDeniedDescription": "您没有权限管理空间。", "xpack.spaces.management.unauthorizedPrompt.permissionDeniedTitle": "权限被拒绝", "xpack.spaces.management.validateSpace.describeMaxLengthErrorMessage": "描述不能超过 2000 个字符。", "xpack.spaces.management.validateSpace.nameMaxLengthErrorMessage": "名称不能超过 1024 个字符。", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/field_mapping.tsx similarity index 95% rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx rename to x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/field_mapping.tsx index 52b881a1eb75f..a3382513d2bcb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/field_mapping.tsx @@ -13,9 +13,8 @@ import * as i18n from './translations'; import { setActionTypeToMapping, setThirdPartyToMapping } from './utils'; import { ThirdPartyField as ConnectorConfigurationThirdPartyField } from './types'; -import { CasesConfigurationMapping } from '../types'; -import { connectorConfiguration } from '../config'; -import { createDefaultMapping } from '../servicenow_connectors'; +import { CasesConfigurationMapping } from './types'; +import { createDefaultMapping } from './utils'; const FieldRowWrapper = styled.div` margin-top: 8px; @@ -70,15 +69,15 @@ const getThirdPartyOptions = ( export interface FieldMappingProps { disabled: boolean; mapping: CasesConfigurationMapping[] | null; - connectorActionTypeId: string; onChangeMapping: (newMapping: CasesConfigurationMapping[]) => void; + connectorConfiguration: Record; } const FieldMappingComponent: React.FC = ({ disabled, mapping, onChangeMapping, - connectorActionTypeId, + connectorConfiguration, }) => { const onChangeActionType = useCallback( (caseField: string, newActionType: string) => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping_row.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/field_mapping_row.tsx similarity index 100% rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping_row.tsx rename to x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/field_mapping_row.tsx diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/index.ts new file mode 100644 index 0000000000000..2de9b87ead3fe --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/index.ts @@ -0,0 +1,10 @@ +/* + * 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. + */ + +export * from './types'; +export * from './field_mapping'; +export * from './field_mapping_row'; +export * from './utils'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/translations.ts similarity index 100% rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/translations.ts rename to x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/translations.ts diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/types.ts similarity index 72% rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts rename to x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/types.ts index 6cd2200e1dc74..3571db39b596a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/types.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ActionType } from '../../../../../types'; +import { ActionType } from '../../../../types'; export { ActionType }; @@ -14,3 +14,8 @@ export interface ThirdPartyField { defaultSourceField: string; defaultActionType: string; } +export interface CasesConfigurationMapping { + source: string; + target: string; + actionType: string; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/utils.ts similarity index 76% rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts rename to x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/utils.ts index a173d90515302..b14b1b76427c6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/case_mappings/utils.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { CasesConfigurationMapping } from '../types'; +import { CasesConfigurationMapping } from './types'; export const setActionTypeToMapping = ( caseField: string, @@ -36,3 +36,13 @@ export const setThirdPartyToMapping = ( } return item; }); + +export const createDefaultMapping = (fields: Record): CasesConfigurationMapping[] => + Object.keys(fields).map( + (key) => + ({ + source: fields[key].defaultSourceField, + target: key, + actionType: fields[key].defaultActionType, + } as CasesConfigurationMapping) + ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_params.test.tsx index ecdfefa109f58..be3e8a31820c4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_params.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_params.test.tsx @@ -17,6 +17,7 @@ describe('EmailParamsFields renders', () => { subject: 'test', message: 'test message', }; + const wrapper = mountWithIntl( > { + return await http.post(`${BASE_ACTION_API_PATH}/action/${connectorId}/_execute`, { + body: JSON.stringify({ + params: { subAction: 'issueTypes', subActionParams: {} }, + }), + signal, + }); +} + +export async function getFieldsByIssueType({ + http, + signal, + connectorId, + id, +}: { + http: HttpSetup; + signal: AbortSignal; + connectorId: string; + id: string; +}): Promise> { + return await http.post(`${BASE_ACTION_API_PATH}/action/${connectorId}/_execute`, { + body: JSON.stringify({ + params: { subAction: 'fieldsByIssueType', subActionParams: { id } }, + }), + signal, + }); +} diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/config.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/config.ts similarity index 87% rename from x-pack/plugins/security_solution/public/common/lib/connectors/jira/config.ts rename to x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/config.ts index e6151a54bff74..628600ee91c8e 100644 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/config.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/config.ts @@ -4,19 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ConnectorConfiguration } from './types'; - import * as i18n from './translations'; import logo from './logo.svg'; -export const connector: ConnectorConfiguration = { +export const connectorConfiguration = { id: '.jira', name: i18n.JIRA_TITLE, logo, enabled: true, enabledInConfig: true, enabledInLicense: true, - minimumLicenseRequired: 'platinum', + minimumLicenseRequired: 'gold', fields: { summary: { label: i18n.MAPPING_FIELD_SUMMARY, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/index.ts new file mode 100644 index 0000000000000..a0170f9d84e9b --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { getActionType as getJiraActionType } from './jira'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira.test.tsx new file mode 100644 index 0000000000000..61923d8f78b51 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira.test.tsx @@ -0,0 +1,100 @@ +/* + * 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 { TypeRegistry } from '../../../type_registry'; +import { registerBuiltInActionTypes } from '.././index'; +import { ActionTypeModel } from '../../../../types'; +import { JiraActionConnector } from './types'; + +const ACTION_TYPE_ID = '.jira'; +let actionTypeModel: ActionTypeModel; + +beforeAll(() => { + const actionTypeRegistry = new TypeRegistry(); + registerBuiltInActionTypes({ actionTypeRegistry }); + const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); + if (getResult !== null) { + actionTypeModel = getResult; + } +}); + +describe('actionTypeRegistry.get() works', () => { + test('action type static data is as expected', () => { + expect(actionTypeModel.id).toEqual(ACTION_TYPE_ID); + }); +}); + +describe('jira connector validation', () => { + test('connector validation succeeds when connector config is valid', () => { + const actionConnector = { + secrets: { + email: 'email', + apiToken: 'apiToken', + }, + id: 'test', + actionTypeId: '.jira', + name: 'jira', + isPreconfigured: false, + config: { + apiUrl: 'https://siem-kibana.atlassian.net', + projectKey: 'CK', + }, + } as JiraActionConnector; + + expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ + errors: { + apiUrl: [], + email: [], + apiToken: [], + projectKey: [], + }, + }); + }); + + test('connector validation fails when connector config is not valid', () => { + const actionConnector = ({ + secrets: { + email: 'user', + }, + id: '.jira', + actionTypeId: '.jira', + name: 'jira', + config: {}, + } as unknown) as JiraActionConnector; + + expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ + errors: { + apiUrl: ['URL is required.'], + email: [], + apiToken: ['API token or Password is required'], + projectKey: ['Project key is required'], + }, + }); + }); +}); + +describe('jira action params validation', () => { + test('action params validation succeeds when action params is valid', () => { + const actionParams = { + subActionParams: { title: 'some title {{test}}' }, + }; + + expect(actionTypeModel.validateParams(actionParams)).toEqual({ + errors: { title: [] }, + }); + }); + + test('params validation fails when body is not valid', () => { + const actionParams = { + subActionParams: { title: '' }, + }; + + expect(actionTypeModel.validateParams(actionParams)).toEqual({ + errors: { + title: ['Title is required.'], + }, + }); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira.tsx new file mode 100644 index 0000000000000..fd36bd6aeab0a --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira.tsx @@ -0,0 +1,69 @@ +/* + * 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 { lazy } from 'react'; +import { ValidationResult, ActionTypeModel } from '../../../../types'; +import { connectorConfiguration } from './config'; +import logo from './logo.svg'; +import { JiraActionConnector, JiraActionParams } from './types'; +import * as i18n from './translations'; +import { isValidUrl } from '../../../lib/value_validators'; + +const validateConnector = (action: JiraActionConnector): ValidationResult => { + const validationResult = { errors: {} }; + const errors = { + apiUrl: new Array(), + projectKey: new Array(), + email: new Array(), + apiToken: new Array(), + }; + validationResult.errors = errors; + + if (!action.config.apiUrl) { + errors.apiUrl = [...errors.apiUrl, i18n.API_URL_REQUIRED]; + } + + if (action.config.apiUrl && !isValidUrl(action.config.apiUrl, 'https:')) { + errors.apiUrl = [...errors.apiUrl, i18n.API_URL_INVALID]; + } + + if (!action.config.projectKey) { + errors.projectKey = [...errors.projectKey, i18n.JIRA_PROJECT_KEY_REQUIRED]; + } + + if (!action.secrets.email) { + errors.email = [...errors.email, i18n.JIRA_EMAIL_REQUIRED]; + } + + if (!action.secrets.apiToken) { + errors.apiToken = [...errors.apiToken, i18n.JIRA_API_TOKEN_REQUIRED]; + } + + return validationResult; +}; + +export function getActionType(): ActionTypeModel { + return { + id: connectorConfiguration.id, + iconClass: logo, + selectMessage: i18n.JIRA_DESC, + actionTypeTitle: connectorConfiguration.name, + validateConnector, + actionConnectorFields: lazy(() => import('./jira_connectors')), + validateParams: (actionParams: JiraActionParams): ValidationResult => { + const validationResult = { errors: {} }; + const errors = { + title: new Array(), + }; + validationResult.errors = errors; + if (actionParams.subActionParams && !actionParams.subActionParams.title?.length) { + errors.title.push(i18n.TITLE_REQUIRED); + } + return validationResult; + }, + actionParamsFields: lazy(() => import('./jira_params')), + }; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx new file mode 100644 index 0000000000000..2cac1819d552d --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.test.tsx @@ -0,0 +1,99 @@ +/* + * 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 React from 'react'; +import { mountWithIntl } from 'test_utils/enzyme_helpers'; +import { DocLinksStart } from 'kibana/public'; +import JiraConnectorFields from './jira_connectors'; +import { JiraActionConnector } from './types'; + +describe('JiraActionConnectorFields renders', () => { + test('alerting Jira connector fields is rendered', () => { + const actionConnector = { + secrets: { + email: 'email', + apiToken: 'token', + }, + id: 'test', + actionTypeId: '.jira', + isPreconfigured: false, + name: 'jira', + config: { + apiUrl: 'https://test/', + projectKey: 'CK', + }, + } as JiraActionConnector; + const deps = { + docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart, + }; + const wrapper = mountWithIntl( + {}} + editActionSecrets={() => {}} + docLinks={deps!.docLinks} + readOnly={false} + /> + ); + + expect(wrapper.find('[data-test-subj="apiUrlFromInput"]').length > 0).toBeTruthy(); + expect( + wrapper.find('[data-test-subj="connector-jira-project-key-form-input"]').length > 0 + ).toBeTruthy(); + + expect( + wrapper.find('[data-test-subj="connector-jira-email-form-input"]').length > 0 + ).toBeTruthy(); + + expect( + wrapper.find('[data-test-subj="connector-jira-apiToken-form-input"]').length > 0 + ).toBeTruthy(); + }); + + test('case specific Jira connector fields is rendered', () => { + const actionConnector = { + secrets: { + email: 'email', + apiToken: 'token', + }, + id: 'test', + actionTypeId: '.jira', + isPreconfigured: false, + name: 'jira', + config: { + apiUrl: 'https://test/', + projectKey: 'CK', + }, + } as JiraActionConnector; + const deps = { + docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart, + }; + const wrapper = mountWithIntl( + {}} + editActionSecrets={() => {}} + docLinks={deps!.docLinks} + readOnly={false} + consumer={'case'} + /> + ); + expect(wrapper.find('[data-test-subj="case-jira-mappings"]').length > 0).toBeTruthy(); + expect(wrapper.find('[data-test-subj="apiUrlFromInput"]').length > 0).toBeTruthy(); + expect( + wrapper.find('[data-test-subj="connector-jira-project-key-form-input"]').length > 0 + ).toBeTruthy(); + + expect( + wrapper.find('[data-test-subj="connector-jira-email-form-input"]').length > 0 + ).toBeTruthy(); + + expect( + wrapper.find('[data-test-subj="connector-jira-apiToken-form-input"]').length > 0 + ).toBeTruthy(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.tsx new file mode 100644 index 0000000000000..2ab9843c143b9 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_connectors.tsx @@ -0,0 +1,209 @@ +/* + * 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 React, { useCallback } from 'react'; + +import { + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiFieldPassword, + EuiSpacer, +} from '@elastic/eui'; + +import { isEmpty } from 'lodash'; +import { ActionConnectorFieldsProps } from '../../../../types'; +import { CasesConfigurationMapping, FieldMapping, createDefaultMapping } from '../case_mappings'; + +import * as i18n from './translations'; +import { JiraActionConnector } from './types'; +import { connectorConfiguration } from './config'; + +const JiraConnectorFields: React.FC> = ({ + action, + editActionSecrets, + editActionConfig, + errors, + consumer, + readOnly, + docLinks, +}) => { + // TODO: remove incidentConfiguration later, when Case Jira will move their fields to the level of action execution + const { apiUrl, projectKey, incidentConfiguration, isCaseOwned } = action.config; + const mapping = incidentConfiguration ? incidentConfiguration.mapping : []; + + const isApiUrlInvalid: boolean = errors.apiUrl.length > 0 && apiUrl != null; + + const { email, apiToken } = action.secrets; + + const isProjectKeyInvalid: boolean = errors.projectKey.length > 0 && projectKey != null; + const isEmailInvalid: boolean = errors.email.length > 0 && email != null; + const isApiTokenInvalid: boolean = errors.apiToken.length > 0 && apiToken != null; + + // TODO: remove this block later, when Case ServiceNow will move their fields to the level of action execution + if (consumer === 'case') { + if (isEmpty(mapping)) { + editActionConfig('incidentConfiguration', { + mapping: createDefaultMapping(connectorConfiguration.fields as any), + }); + } + if (!isCaseOwned) { + editActionConfig('isCaseOwned', true); + } + } + + const handleOnChangeActionConfig = useCallback( + (key: string, value: string) => editActionConfig(key, value), + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + const handleOnChangeSecretConfig = useCallback( + (key: string, value: string) => editActionSecrets(key, value), + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + const handleOnChangeMappingConfig = useCallback( + (newMapping: CasesConfigurationMapping[]) => + editActionConfig('incidentConfiguration', { + ...action.config.incidentConfiguration, + mapping: newMapping, + }), + // eslint-disable-next-line react-hooks/exhaustive-deps + [action.config] + ); + + return ( + <> + + + + handleOnChangeActionConfig('apiUrl', evt.target.value)} + onBlur={() => { + if (!apiUrl) { + editActionConfig('apiUrl', ''); + } + }} + /> + + + + + + + + handleOnChangeActionConfig('projectKey', evt.target.value)} + onBlur={() => { + if (!projectKey) { + editActionConfig('projectKey', ''); + } + }} + /> + + + + + + + + handleOnChangeSecretConfig('email', evt.target.value)} + onBlur={() => { + if (!email) { + editActionSecrets('email', ''); + } + }} + /> + + + + + + + + handleOnChangeSecretConfig('apiToken', evt.target.value)} + onBlur={() => { + if (!apiToken) { + editActionSecrets('apiToken', ''); + } + }} + /> + + + + {consumer === 'case' && ( // TODO: remove this block later, when Case Jira will move their fields to the level of action execution + <> + + + + + + + + )} + + ); +}; + +// eslint-disable-next-line import/no-default-export +export { JiraConnectorFields as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_params.test.tsx new file mode 100644 index 0000000000000..26d358310741c --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_params.test.tsx @@ -0,0 +1,233 @@ +/* + * 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 React from 'react'; +import { mountWithIntl } from 'test_utils/enzyme_helpers'; +import JiraParamsFields from './jira_params'; +import { DocLinksStart } from 'kibana/public'; + +import { useGetIssueTypes } from './use_get_issue_types'; +import { useGetFieldsByIssueType } from './use_get_fields_by_issue_type'; + +jest.mock('../../../app_context', () => { + const post = jest.fn(); + return { + useAppDependencies: jest.fn(() => ({ http: { post } })), + }; +}); + +jest.mock('./use_get_issue_types'); +jest.mock('./use_get_fields_by_issue_type'); + +const useGetIssueTypesMock = useGetIssueTypes as jest.Mock; +const useGetFieldsByIssueTypeMock = useGetFieldsByIssueType as jest.Mock; + +const actionParams = { + subAction: 'pushToService', + subActionParams: { + title: 'sn title', + description: 'some description', + comments: [{ commentId: '1', comment: 'comment for jira' }], + issueType: '10006', + labels: ['kibana'], + priority: 'High', + savedObjectId: '123', + externalId: null, + }, +}; +const connector = { + secrets: {}, + config: {}, + id: 'test', + actionTypeId: '.test', + name: 'Test', + isPreconfigured: false, +}; + +describe('JiraParamsFields renders', () => { + const useGetIssueTypesResponse = { + isLoading: false, + issueTypes: [ + { + id: '10006', + name: 'Task', + }, + { + id: '10007', + name: 'Bug', + }, + ], + }; + + const useGetFieldsByIssueTypeResponse = { + isLoading: false, + fields: { + summary: { allowedValues: [], defaultValue: {} }, + labels: { allowedValues: [], defaultValue: {} }, + description: { allowedValues: [], defaultValue: {} }, + priority: { + allowedValues: [ + { + name: 'Medium', + id: '3', + }, + ], + defaultValue: { name: 'Medium', id: '3' }, + }, + }, + }; + + beforeEach(() => { + useGetIssueTypesMock.mockReturnValue(useGetIssueTypesResponse); + useGetFieldsByIssueTypeMock.mockReturnValue(useGetFieldsByIssueTypeResponse); + }); + + test('all params fields are rendered', () => { + const wrapper = mountWithIntl( + {}} + index={0} + messageVariables={[]} + docLinks={{ ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart} + actionConnector={connector} + /> + ); + expect(wrapper.find('[data-test-subj="issueTypeSelect"]').first().prop('value')).toStrictEqual( + '10006' + ); + expect(wrapper.find('[data-test-subj="prioritySelect"]').first().prop('value')).toStrictEqual( + 'High' + ); + expect(wrapper.find('[data-test-subj="titleInput"]').length > 0).toBeTruthy(); + expect(wrapper.find('[data-test-subj="descriptionTextArea"]').length > 0).toBeTruthy(); + expect(wrapper.find('[data-test-subj="labelsComboBox"]').length > 0).toBeTruthy(); + expect(wrapper.find('[data-test-subj="commentsTextArea"]').length > 0).toBeTruthy(); + }); + + test('it shows loading when loading issue types', () => { + useGetIssueTypesMock.mockReturnValue({ ...useGetIssueTypesResponse, isLoading: true }); + const wrapper = mountWithIntl( + {}} + index={0} + messageVariables={[]} + docLinks={{ ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart} + actionConnector={connector} + /> + ); + + expect( + wrapper.find('[data-test-subj="issueTypeSelect"]').first().prop('isLoading') + ).toBeTruthy(); + }); + + test('it shows loading when loading fields', () => { + useGetFieldsByIssueTypeMock.mockReturnValue({ + ...useGetFieldsByIssueTypeResponse, + isLoading: true, + }); + + const wrapper = mountWithIntl( + {}} + index={0} + messageVariables={[]} + docLinks={{ ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart} + actionConnector={connector} + /> + ); + + expect( + wrapper.find('[data-test-subj="prioritySelect"]').first().prop('isLoading') + ).toBeTruthy(); + expect( + wrapper.find('[data-test-subj="labelsComboBox"]').first().prop('isLoading') + ).toBeTruthy(); + }); + + test('it disabled the fields when loading issue types', () => { + useGetIssueTypesMock.mockReturnValue({ ...useGetIssueTypesResponse, isLoading: true }); + + const wrapper = mountWithIntl( + {}} + index={0} + messageVariables={[]} + docLinks={{ ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart} + actionConnector={connector} + /> + ); + + expect( + wrapper.find('[data-test-subj="issueTypeSelect"]').first().prop('disabled') + ).toBeTruthy(); + expect(wrapper.find('[data-test-subj="prioritySelect"]').first().prop('disabled')).toBeTruthy(); + expect( + wrapper.find('[data-test-subj="labelsComboBox"]').first().prop('isDisabled') + ).toBeTruthy(); + }); + + test('it disabled the fields when loading fields', () => { + useGetFieldsByIssueTypeMock.mockReturnValue({ + ...useGetFieldsByIssueTypeResponse, + isLoading: true, + }); + + const wrapper = mountWithIntl( + {}} + index={0} + messageVariables={[]} + docLinks={{ ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart} + actionConnector={connector} + /> + ); + + expect( + wrapper.find('[data-test-subj="issueTypeSelect"]').first().prop('disabled') + ).toBeTruthy(); + expect(wrapper.find('[data-test-subj="prioritySelect"]').first().prop('disabled')).toBeTruthy(); + expect( + wrapper.find('[data-test-subj="labelsComboBox"]').first().prop('isDisabled') + ).toBeTruthy(); + }); + + test('hide unsupported fields', () => { + useGetIssueTypesMock.mockReturnValue(useGetIssueTypesResponse); + useGetFieldsByIssueTypeMock.mockReturnValue({ + ...useGetFieldsByIssueTypeResponse, + fields: {}, + }); + const wrapper = mountWithIntl( + {}} + index={0} + messageVariables={[]} + docLinks={{ ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart} + actionConnector={connector} + /> + ); + + expect(wrapper.find('[data-test-subj="issueTypeSelect"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="titleInput"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="commentsTextArea"]').exists()).toBeTruthy(); + + expect(wrapper.find('[data-test-subj="prioritySelect"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="descriptionTextArea"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="labelsComboBox"]').exists()).toBeFalsy(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_params.tsx new file mode 100644 index 0000000000000..bde3d67ffd65f --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/jira_params.tsx @@ -0,0 +1,319 @@ +/* + * 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 React, { Fragment, useEffect, useState, useMemo } from 'react'; +import { map } from 'lodash/fp'; +import { EuiFormRow, EuiComboBox, EuiSelectOption, EuiHorizontalRule } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { EuiSelect } from '@elastic/eui'; +import { EuiFlexGroup } from '@elastic/eui'; +import { EuiFlexItem } from '@elastic/eui'; +import { EuiSpacer } from '@elastic/eui'; + +import { useAppDependencies } from '../../../app_context'; +import { ActionParamsProps } from '../../../../types'; +import { TextAreaWithMessageVariables } from '../../text_area_with_message_variables'; +import { TextFieldWithMessageVariables } from '../../text_field_with_message_variables'; +import { JiraActionParams } from './types'; +import { useGetIssueTypes } from './use_get_issue_types'; +import { useGetFieldsByIssueType } from './use_get_fields_by_issue_type'; + +const JiraParamsFields: React.FunctionComponent> = ({ + actionParams, + editAction, + index, + errors, + messageVariables, + actionConnector, +}) => { + const { title, description, comments, issueType, priority, labels, savedObjectId } = + actionParams.subActionParams || {}; + + const [issueTypesSelectOptions, setIssueTypesSelectOptions] = useState([]); + const [firstLoad, setFirstLoad] = useState(false); + const [prioritiesSelectOptions, setPrioritiesSelectOptions] = useState([]); + const { http, toastNotifications } = useAppDependencies(); + + useEffect(() => { + setFirstLoad(true); + }, []); + + const { isLoading: isLoadingIssueTypes, issueTypes } = useGetIssueTypes({ + http, + toastNotifications, + actionConnector, + }); + + const { isLoading: isLoadingFields, fields } = useGetFieldsByIssueType({ + http, + toastNotifications, + actionConnector, + issueType, + }); + + const hasLabels = useMemo(() => Object.prototype.hasOwnProperty.call(fields, 'labels'), [fields]); + const hasDescription = useMemo( + () => Object.prototype.hasOwnProperty.call(fields, 'description'), + [fields] + ); + const hasPriority = useMemo(() => Object.prototype.hasOwnProperty.call(fields, 'priority'), [ + fields, + ]); + + useEffect(() => { + const options = issueTypes.map((type) => ({ + value: type.id ?? '', + text: type.name ?? '', + })); + + setIssueTypesSelectOptions(options); + }, [issueTypes]); + + useEffect(() => { + if (issueType != null && fields != null) { + const priorities = fields.priority?.allowedValues ?? []; + const options = map( + (p) => ({ + value: p.name, + text: p.name, + }), + priorities + ); + setPrioritiesSelectOptions(options); + } + }, [fields, issueType]); + + const labelOptions = useMemo(() => (labels ? labels.map((label: string) => ({ label })) : []), [ + labels, + ]); + + const editSubActionProperty = (key: string, value: any) => { + const newProps = { ...actionParams.subActionParams, [key]: value }; + editAction('subActionParams', newProps, index); + }; + + // Reset parameters when changing connector + useEffect(() => { + if (!firstLoad) { + return; + } + + setIssueTypesSelectOptions([]); + editAction('subActionParams', { title, comments, description: '', savedObjectId }, index); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [actionConnector]); + + // Reset fields when changing connector or issue type + useEffect(() => { + if (!firstLoad) { + return; + } + + setPrioritiesSelectOptions([]); + editAction( + 'subActionParams', + { title, issueType, comments, description: '', savedObjectId }, + index + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [issueType, savedObjectId]); + + useEffect(() => { + if (!actionParams.subAction) { + editAction('subAction', 'pushToService', index); + } + if (!savedObjectId && messageVariables?.find((variable) => variable.name === 'alertId')) { + editSubActionProperty('savedObjectId', '{{alertId}}'); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + actionConnector, + actionParams.subAction, + index, + savedObjectId, + issueTypesSelectOptions, + issueType, + ]); + + // Set default issue type + useEffect(() => { + if (!issueType && issueTypesSelectOptions.length > 0) { + editSubActionProperty('issueType', issueTypesSelectOptions[0].value as string); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [issueTypes, issueTypesSelectOptions]); + + // Set default priority + useEffect(() => { + if (!priority && prioritiesSelectOptions.length > 0) { + editSubActionProperty('priority', prioritiesSelectOptions[0].value as string); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [actionConnector, issueType, prioritiesSelectOptions]); + + return ( + + <> + + { + editSubActionProperty('issueType', e.target.value); + }} + /> + + + <> + {hasPriority && ( + <> + + + + { + editSubActionProperty('priority', e.target.value); + }} + /> + + + + + + )} + 0 && title !== undefined} + label={i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.titleFieldLabel', + { + defaultMessage: 'Summary', + } + )} + > + + + + {hasLabels && ( + <> + + + + { + const newOptions = [...labelOptions, { label: searchValue }]; + editSubActionProperty( + 'labels', + newOptions.map((newOption) => newOption.label) + ); + }} + onChange={(selectedOptions: Array<{ label: string }>) => { + editSubActionProperty( + 'labels', + selectedOptions.map((selectedOption) => selectedOption.label) + ); + }} + onBlur={() => { + if (!labels) { + editSubActionProperty('labels', []); + } + }} + isClearable={true} + data-test-subj="labelsComboBox" + /> + + + + + + )} + {hasDescription && ( + + )} + { + editSubActionProperty(key, [{ commentId: '1', comment: value }]); + }} + messageVariables={messageVariables} + paramsProperty={'comments'} + inputTargetValue={comments && comments.length > 0 ? comments[0].comment : ''} + label={i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.commentsTextAreaFieldLabel', + { + defaultMessage: 'Additional comments (optional)', + } + )} + errors={errors.comments as string[]} + /> + + + + ); +}; + +// eslint-disable-next-line import/no-default-export +export { JiraParamsFields as default }; diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/jira/logo.svg b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/logo.svg similarity index 100% rename from x-pack/plugins/security_solution/public/common/lib/connectors/jira/logo.svg rename to x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/logo.svg diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/translations.ts new file mode 100644 index 0000000000000..bfcb72d1cb977 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/translations.ts @@ -0,0 +1,133 @@ +/* + * 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 { i18n } from '@kbn/i18n'; + +export const JIRA_DESC = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.selectMessageText', + { + defaultMessage: 'Push or update data to a new issue in Jira', + } +); + +export const JIRA_TITLE = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.actionTypeTitle', + { + defaultMessage: 'Jira', + } +); + +export const API_URL_LABEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.apiUrlTextFieldLabel', + { + defaultMessage: 'URL', + } +); + +export const API_URL_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.requiredApiUrlTextField', + { + defaultMessage: 'URL is required.', + } +); + +export const API_URL_INVALID = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.invalidApiUrlTextField', + { + defaultMessage: 'URL is invalid.', + } +); + +export const JIRA_PROJECT_KEY_LABEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.projectKey', + { + defaultMessage: 'Project key', + } +); + +export const JIRA_PROJECT_KEY_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.requiredProjectKeyTextField', + { + defaultMessage: 'Project key is required', + } +); + +export const JIRA_EMAIL_LABEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.emailTextFieldLabel', + { + defaultMessage: 'Email or Username', + } +); + +export const JIRA_EMAIL_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.requiredEmailTextField', + { + defaultMessage: 'Email or Username is required', + } +); + +export const JIRA_API_TOKEN_LABEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.apiTokenTextFieldLabel', + { + defaultMessage: 'API token or Password', + } +); + +export const JIRA_API_TOKEN_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.requiredApiTokenTextField', + { + defaultMessage: 'API token or Password is required', + } +); + +export const MAPPING_FIELD_SUMMARY = i18n.translate( + 'xpack.triggersActionsUI.case.configureCases.mappingFieldSummary', + { + defaultMessage: 'Summary', + } +); + +export const DESCRIPTION_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.requiredDescriptionTextField', + { + defaultMessage: 'Description is required.', + } +); + +export const TITLE_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.requiredTitleTextField', + { + defaultMessage: 'Title is required.', + } +); + +export const MAPPING_FIELD_DESC = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.mappingFieldDescription', + { + defaultMessage: 'Description', + } +); + +export const MAPPING_FIELD_COMMENTS = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.mappingFieldComments', + { + defaultMessage: 'Comments', + } +); + +export const ISSUE_TYPES_API_ERROR = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.unableToGetIssueTypesMessage', + { + defaultMessage: 'Unable to get issue types', + } +); + +export const FIELDS_API_ERROR = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.jira.unableToGetFieldsMessage', + { + defaultMessage: 'Unable to get fields', + } +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/types.ts new file mode 100644 index 0000000000000..ff11199f35fea --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/types.ts @@ -0,0 +1,44 @@ +/* + * 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 { CasesConfigurationMapping } from '../case_mappings'; + +export interface JiraActionConnector { + config: JiraConfig; + secrets: JiraSecrets; +} + +export interface JiraActionParams { + subAction: string; + subActionParams: { + savedObjectId: string; + title: string; + description: string; + comments: Array<{ commentId: string; comment: string }>; + externalId: string | null; + issueType: string; + priority: string; + labels: string[]; + }; +} + +interface IncidentConfiguration { + mapping: CasesConfigurationMapping[]; +} + +interface JiraConfig { + apiUrl: string; + projectKey: string; + incidentConfiguration?: IncidentConfiguration; + isCaseOwned?: boolean; +} + +interface JiraSecrets { + email: string; + apiToken: string; +} + +// to remove diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/use_get_fields_by_issue_type.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/use_get_fields_by_issue_type.tsx new file mode 100644 index 0000000000000..08715822e5277 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/use_get_fields_by_issue_type.tsx @@ -0,0 +1,97 @@ +/* + * 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 { useState, useEffect, useRef } from 'react'; +import { HttpSetup, ToastsApi } from 'kibana/public'; +import { ActionConnector } from '../../../../types'; +import { getFieldsByIssueType } from './api'; +import * as i18n from './translations'; + +interface Fields { + [key: string]: { + allowedValues: Array<{ name: string; id: string }> | []; + defaultValue: { name: string; id: string } | {}; + }; +} + +interface Props { + http: HttpSetup; + toastNotifications: Pick< + ToastsApi, + 'get$' | 'add' | 'remove' | 'addSuccess' | 'addWarning' | 'addDanger' | 'addError' + >; + issueType: string; + actionConnector?: ActionConnector; +} + +export interface UseGetFieldsByIssueType { + fields: Fields; + isLoading: boolean; +} + +export const useGetFieldsByIssueType = ({ + http, + toastNotifications, + actionConnector, + issueType, +}: Props): UseGetFieldsByIssueType => { + const [isLoading, setIsLoading] = useState(true); + const [fields, setFields] = useState({}); + const abortCtrl = useRef(new AbortController()); + + useEffect(() => { + let didCancel = false; + const fetchData = async () => { + if (!actionConnector || !issueType) { + setIsLoading(false); + return; + } + + abortCtrl.current = new AbortController(); + setIsLoading(true); + try { + const res = await getFieldsByIssueType({ + http, + signal: abortCtrl.current.signal, + connectorId: actionConnector.id, + id: issueType, + }); + + if (!didCancel) { + setIsLoading(false); + setFields(res.data ?? {}); + if (res.status && res.status === 'error') { + toastNotifications.addDanger({ + title: i18n.FIELDS_API_ERROR, + text: `${res.serviceMessage ?? res.message}`, + }); + } + } + } catch (error) { + if (!didCancel) { + toastNotifications.addDanger({ + title: i18n.FIELDS_API_ERROR, + text: error.message, + }); + } + } + }; + + abortCtrl.current.abort(); + fetchData(); + + return () => { + didCancel = true; + setIsLoading(false); + abortCtrl.current.abort(); + }; + }, [http, actionConnector, issueType, toastNotifications]); + + return { + isLoading, + fields, + }; +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/use_get_issue_types.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/use_get_issue_types.tsx new file mode 100644 index 0000000000000..9ebaf5882d9b9 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/jira/use_get_issue_types.tsx @@ -0,0 +1,90 @@ +/* + * 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 { useState, useEffect, useRef } from 'react'; +import { HttpSetup, ToastsApi } from 'kibana/public'; +import { ActionConnector } from '../../../../types'; +import { getIssueTypes } from './api'; +import * as i18n from './translations'; + +type IssueTypes = Array<{ id: string; name: string }>; + +interface Props { + http: HttpSetup; + toastNotifications: Pick< + ToastsApi, + 'get$' | 'add' | 'remove' | 'addSuccess' | 'addWarning' | 'addDanger' | 'addError' + >; + actionConnector?: ActionConnector; +} + +export interface UseGetIssueTypes { + issueTypes: IssueTypes; + isLoading: boolean; +} + +export const useGetIssueTypes = ({ + http, + actionConnector, + toastNotifications, +}: Props): UseGetIssueTypes => { + const [isLoading, setIsLoading] = useState(true); + const [issueTypes, setIssueTypes] = useState([]); + const abortCtrl = useRef(new AbortController()); + + useEffect(() => { + let didCancel = false; + const fetchData = async () => { + if (!actionConnector) { + setIsLoading(false); + return; + } + + abortCtrl.current = new AbortController(); + setIsLoading(true); + + try { + const res = await getIssueTypes({ + http, + signal: abortCtrl.current.signal, + connectorId: actionConnector.id, + }); + + if (!didCancel) { + setIsLoading(false); + setIssueTypes(res.data ?? []); + if (res.status && res.status === 'error') { + toastNotifications.addDanger({ + title: i18n.ISSUE_TYPES_API_ERROR, + text: `${res.serviceMessage ?? res.message}`, + }); + } + } + } catch (error) { + if (!didCancel) { + toastNotifications.addDanger({ + title: i18n.ISSUE_TYPES_API_ERROR, + text: error.message, + }); + } + } + }; + + abortCtrl.current.abort(); + fetchData(); + + return () => { + didCancel = true; + setIsLoading(false); + abortCtrl.current.abort(); + }; + }, [http, actionConnector, toastNotifications]); + + return { + issueTypes, + isLoading, + }; +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index f99a276305d75..a8f1ed8d55447 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -18,10 +18,11 @@ import { import { isEmpty } from 'lodash'; import { FormattedMessage } from '@kbn/i18n/react'; import { ActionConnectorFieldsProps } from '../../../../types'; +import { CasesConfigurationMapping, FieldMapping, createDefaultMapping } from '../case_mappings'; + import * as i18n from './translations'; -import { ServiceNowActionConnector, CasesConfigurationMapping } from './types'; +import { ServiceNowActionConnector } from './types'; import { connectorConfiguration } from './config'; -import { FieldMapping } from './case_mappings/field_mapping'; const ServiceNowConnectorFields: React.FC @@ -184,15 +185,5 @@ const ServiceNowConnectorFields: React.FC): CasesConfigurationMapping[] => - Object.keys(fields).map( - (key) => - ({ - source: fields[key].defaultSourceField, - target: key, - actionType: fields[key].defaultActionType, - } as CasesConfigurationMapping) - ); - // eslint-disable-next-line import/no-default-export export { ServiceNowConnectorFields as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx index 2a29018d83ff4..2a2efdfbe35b1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx @@ -79,7 +79,14 @@ const ServiceNowParamsFields: React.FunctionComponent -

Incident

+

+ {i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.title', + { + defaultMessage: 'Incident', + } + )} +

) : null} diff --git a/x-pack/plugins/triggers_actions_ui/public/common/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/index.ts index 9dd3fd787f860..8b728b5e178b5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/index.ts @@ -7,3 +7,4 @@ export * from './expression_items'; export { connectorConfiguration as ServiceNowConnectorConfiguration } from '../application/components/builtin_action_types/servicenow/config'; +export { connectorConfiguration as JiraConnectorConfiguration } from '../application/components/builtin_action_types/jira/config'; diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 762f41ba3691c..109d473c56e66 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -54,6 +54,7 @@ export interface ActionParamsProps { messageVariables?: ActionVariable[]; defaultMessage?: string; docLinks: DocLinksStart; + actionConnector?: ActionConnector; } export interface Pagination { diff --git a/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/watch_visualization.tsx b/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/watch_visualization.tsx index 2ff0f53d07e91..935f0209e73c2 100644 --- a/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/watch_visualization.tsx +++ b/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/watch_visualization.tsx @@ -126,7 +126,7 @@ export const WatchVisualization = () => { isLoading, data: watchVisualizationData, error, - sendRequest: reload, + resendRequest: reload, } = useGetWatchVisualizationData(watchWithoutActions, visualizeOptions); useEffect( diff --git a/x-pack/test/accessibility/apps/spaces.ts b/x-pack/test/accessibility/apps/spaces.ts new file mode 100644 index 0000000000000..e11de1376e400 --- /dev/null +++ b/x-pack/test/accessibility/apps/spaces.ts @@ -0,0 +1,142 @@ +/* + * 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. + */ + +// a11y tests for spaces, space selection and spacce creation and feature controls + +import { FtrProviderContext } from '../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['common', 'spaceSelector', 'home', 'header', 'security']); + const a11y = getService('a11y'); + const browser = getService('browser'); + const esArchiver = getService('esArchiver'); + const testSubjects = getService('testSubjects'); + const retry = getService('retry'); + const toasts = getService('toasts'); + + describe('Kibana spaces page meets a11y validations', () => { + before(async () => { + await esArchiver.load('empty_kibana'); + await PageObjects.common.navigateToApp('home'); + }); + + it('a11y test for manage spaces menu from top nav on Kibana home', async () => { + await PageObjects.spaceSelector.openSpacesNav(); + await retry.waitFor( + 'Manage spaces option visible', + async () => await testSubjects.exists('manageSpaces') + ); + await a11y.testAppSnapshot(); + }); + + it('a11y test for manage spaces page', async () => { + await PageObjects.spaceSelector.clickManageSpaces(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await toasts.dismissAllToasts(); + await retry.waitFor( + 'Manage spaces page visible', + async () => await testSubjects.exists('createSpace') + ); + await a11y.testAppSnapshot(); + }); + + it('a11y test for click on create space page', async () => { + await PageObjects.spaceSelector.clickCreateSpace(); + await a11y.testAppSnapshot(); + }); + + it('a11y test for for customize space card', async () => { + await PageObjects.spaceSelector.clickEnterSpaceName(); + await PageObjects.spaceSelector.addSpaceName('space_a'); + await PageObjects.spaceSelector.clickSpaceAcustomAvatar(); + await a11y.testAppSnapshot(); + await browser.pressKeys(browser.keys.ESCAPE); + }); + + // EUI issue - https://github.com/elastic/eui/issues/3999 + it.skip('a11y test for color picker', async () => { + await PageObjects.spaceSelector.clickColorPicker(); + await a11y.testAppSnapshot(); + await browser.pressKeys(browser.keys.ESCAPE); + }); + + it('a11y test for customize and reset space URL identifier', async () => { + await PageObjects.spaceSelector.clickOnCustomizeURL(); + await a11y.testAppSnapshot(); + await PageObjects.spaceSelector.clickOnCustomizeURL(); + await a11y.testAppSnapshot(); + }); + + it('a11y test for describe space text space', async () => { + await PageObjects.spaceSelector.clickOnDescriptionOfSpace(); + await a11y.testAppSnapshot(); + }); + + it('a11y test for click on "show" button to open customize feature display', async () => { + await retry.waitFor( + 'show button is visible', + async () => await testSubjects.exists('show-hide-section-link') + ); + await PageObjects.spaceSelector.clickShowFeatures(); + await a11y.testAppSnapshot(); + }); + + it('a11y test for change all option for feature visibility popover', async () => { + await PageObjects.spaceSelector.clickFeaturesVisibilityButton(); + await a11y.testAppSnapshot(); + }); + + it('a11y test for hide all feature visibility popover option', async () => { + await PageObjects.spaceSelector.clickHideAllFeatures(); + await a11y.testAppSnapshot(); + }); + + it('a11y test for toggle individual feature - using enterprise feature visibility', async () => { + await PageObjects.spaceSelector.clickFeaturesVisibilityButton(); + await PageObjects.spaceSelector.clickShowAllFeatures(); + await PageObjects.spaceSelector.toggleFeatureVisibility('enterpriseSearch'); + await a11y.testAppSnapshot(); + }); + + it('a11y test for space listing page', async () => { + await PageObjects.spaceSelector.clickSaveSpaceCreation(); + await a11y.testAppSnapshot(); + }); + + it('a11y test for updating a space', async () => { + await PageObjects.spaceSelector.clickSpaceEditButton('space_a'); + await a11y.testAppSnapshot(); + await PageObjects.spaceSelector.clickCancelSpaceCreation(); + }); + + // creating space b and making it the current space so space selector page gets displayed when space b gets deleted + it('a11y test for delete space button', async () => { + await PageObjects.spaceSelector.clickCreateSpace(); + await PageObjects.spaceSelector.clickEnterSpaceName(); + await PageObjects.spaceSelector.addSpaceName('space_b'); + await PageObjects.spaceSelector.clickSaveSpaceCreation(); + await PageObjects.common.navigateToApp('home'); + await PageObjects.spaceSelector.openSpacesNav(); + await PageObjects.spaceSelector.clickSpaceAvatar('space_b'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.spaceSelector.openSpacesNav(); + await PageObjects.spaceSelector.clickManageSpaces(); + await PageObjects.spaceSelector.clickOnDeleteSpaceButton('space_b'); + await a11y.testAppSnapshot(); + // a11y test for no space name in confirm dialogue box + await PageObjects.spaceSelector.confirmDeletingSpace(); + await a11y.testAppSnapshot(); + }); + + // test starts with deleting space b so we can get the space selection page instead of logging out in the test + it('a11y test for space selection page', async () => { + await PageObjects.spaceSelector.setSpaceNameTobeDeleted('space_b'); + await PageObjects.spaceSelector.confirmDeletingSpace(); + await a11y.testAppSnapshot(); + await PageObjects.spaceSelector.clickSpaceCard('default'); + }); + }); +} diff --git a/x-pack/test/accessibility/config.ts b/x-pack/test/accessibility/config.ts index 0a95805754314..bae7b688fd28c 100644 --- a/x-pack/test/accessibility/config.ts +++ b/x-pack/test/accessibility/config.ts @@ -20,7 +20,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { require.resolve('./apps/grok_debugger'), require.resolve('./apps/search_profiler'), require.resolve('./apps/uptime'), - require.resolve('./apps/painless_lab'), + require.resolve('./apps/spaces'), ], pageObjects, services, diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/jira.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/jira.ts new file mode 100644 index 0000000000000..025fd558ee1ca --- /dev/null +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/jira.ts @@ -0,0 +1,97 @@ +/* + * 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 { FtrProviderContext } from '../../../../common/ftr_provider_context'; + +import { + getExternalServiceSimulatorPath, + ExternalServiceSimulator, +} from '../../../../common/fixtures/plugins/actions_simulators/server/plugin'; + +// node ../scripts/functional_test_runner.js --grep "Actions.servicenddd" --config=test/alerting_api_integration/security_and_spaces/config.ts + +const mapping = [ + { + source: 'title', + target: 'summary', + actionType: 'nothing', + }, + { + source: 'description', + target: 'description', + actionType: 'nothing', + }, + { + source: 'comments', + target: 'comments', + actionType: 'nothing', + }, +]; + +// eslint-disable-next-line import/no-default-export +export default function jiraTest({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const kibanaServer = getService('kibanaServer'); + const mockJira = { + config: { + apiUrl: 'www.jiraisinkibanaactions.com', + incidentConfiguration: { mapping: [...mapping] }, + isCaseOwned: true, + }, + secrets: { + email: 'elastic', + apiToken: 'changeme', + }, + params: { + savedObjectId: '123', + title: 'a title', + description: 'a description', + labels: ['kibana'], + issueType: '10006', + priority: 'High', + externalId: null, + comments: [ + { + commentId: '456', + comment: 'first comment', + }, + ], + }, + }; + describe('jira', () => { + let jiraSimulatorURL: string = ''; + + // need to wait for kibanaServer to settle ... + before(() => { + jiraSimulatorURL = kibanaServer.resolveUrl( + getExternalServiceSimulatorPath(ExternalServiceSimulator.JIRA) + ); + }); + + it('should return 403 when creating a jira action', async () => { + await supertest + .post('/api/actions/action') + .set('kbn-xsrf', 'foo') + .send({ + name: 'A jira action', + actionTypeId: '.jira', + config: { + apiUrl: jiraSimulatorURL, + projectKey: 'CK', + incidentConfiguration: { ...mockJira.config.incidentConfiguration }, + isCaseOwned: true, + }, + secrets: mockJira.secrets, + }) + .expect(403, { + statusCode: 403, + error: 'Forbidden', + message: + 'Action type .jira is disabled because your basic license does not support it. Please upgrade your license.', + }); + }); + }); +} diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/index.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/index.ts index 1788a12afebf2..8f31e7f96b562 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/index.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/index.ts @@ -11,6 +11,7 @@ export default function actionsTests({ loadTestFile }: FtrProviderContext) { describe('Actions', () => { loadTestFile(require.resolve('./builtin_action_types/email')); loadTestFile(require.resolve('./builtin_action_types/es_index')); + loadTestFile(require.resolve('./builtin_action_types/jira')); loadTestFile(require.resolve('./builtin_action_types/pagerduty')); loadTestFile(require.resolve('./builtin_action_types/server_log')); loadTestFile(require.resolve('./builtin_action_types/servicenow')); diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/jira_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/jira_simulation.ts index 4b65b7a8f2636..6041251dc28a4 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/jira_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/jira_simulation.ts @@ -105,6 +105,57 @@ export function initPlugin(router: IRouter, path: string) { }); } ); + + router.get( + { + path: `${path}/rest/capabilities`, + options: { + authRequired: false, + }, + validate: {}, + }, + async function ( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + return jsonResponse(res, 200, { + capabilities: {}, + }); + } + ); + + router.get( + { + path: `${path}/rest/api/2/issue/createmeta`, + options: { + authRequired: false, + }, + validate: {}, + }, + async function ( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + return jsonResponse(res, 200, { + projects: [ + { + issuetypes: [ + { + id: '10006', + name: 'Task', + }, + { + id: '10007', + name: 'Sub-task', + }, + ], + }, + ], + }); + } + ); } function jsonResponse( diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin.ts index 0f7acf5ead1a1..88f0f02794c9b 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin.ts @@ -38,6 +38,7 @@ export function getAllExternalServiceSimulatorPaths(): string[] { ); allPaths.push(`/api/_${NAME}/${ExternalServiceSimulator.SERVICENOW}/api/now/v2/table/incident`); allPaths.push(`/api/_${NAME}/${ExternalServiceSimulator.JIRA}/rest/api/2/issue`); + allPaths.push(`/api/_${NAME}/${ExternalServiceSimulator.JIRA}/rest/api/2/createmeta`); allPaths.push(`/api/_${NAME}/${ExternalServiceSimulator.RESILIENT}/rest/orgs/201/incidents`); return allPaths; } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts index 3ffd58b945ddb..84fad699525a9 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts @@ -43,7 +43,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { config: { apiUrl: 'www.jiraisinkibanaactions.com', projectKey: 'CK', - casesConfiguration: { mapping }, + incidentConfiguration: { mapping }, }, secrets: { apiToken: 'elastic', @@ -94,6 +94,8 @@ export default function jiraTest({ getService }: FtrProviderContext) { config: { ...mockJira.config, apiUrl: jiraSimulatorURL, + incidentConfiguration: mockJira.config.incidentConfiguration, + isCaseOwned: true, }, secrets: mockJira.secrets, }) @@ -107,7 +109,8 @@ export default function jiraTest({ getService }: FtrProviderContext) { config: { apiUrl: jiraSimulatorURL, projectKey: mockJira.config.projectKey, - casesConfiguration: mockJira.config.casesConfiguration, + incidentConfiguration: mockJira.config.incidentConfiguration, + isCaseOwned: true, }, }); @@ -123,7 +126,8 @@ export default function jiraTest({ getService }: FtrProviderContext) { config: { apiUrl: jiraSimulatorURL, projectKey: mockJira.config.projectKey, - casesConfiguration: mockJira.config.casesConfiguration, + incidentConfiguration: mockJira.config.incidentConfiguration, + isCaseOwned: true, }, }); }); @@ -178,7 +182,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { config: { apiUrl: 'http://jira.mynonexistent.com', projectKey: mockJira.config.projectKey, - casesConfiguration: mockJira.config.casesConfiguration, + incidentConfiguration: mockJira.config.incidentConfiguration, }, secrets: mockJira.secrets, }) @@ -203,7 +207,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { config: { apiUrl: jiraSimulatorURL, projectKey: mockJira.config.projectKey, - casesConfiguration: mockJira.config.casesConfiguration, + incidentConfiguration: mockJira.config.incidentConfiguration, }, }) .expect(400) @@ -217,30 +221,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { }); }); - it('should respond with a 400 Bad Request when creating a jira action without casesConfiguration', async () => { - await supertest - .post('/api/actions/action') - .set('kbn-xsrf', 'foo') - .send({ - name: 'A jira action', - actionTypeId: '.jira', - config: { - apiUrl: jiraSimulatorURL, - projectKey: mockJira.config.projectKey, - }, - secrets: mockJira.secrets, - }) - .expect(400) - .then((resp: any) => { - expect(resp.body).to.eql({ - statusCode: 400, - error: 'Bad Request', - message: - 'error validating action type config: [casesConfiguration.mapping]: expected value of type [array] but got [undefined]', - }); - }); - }); - it('should respond with a 400 Bad Request when creating a jira action with empty mapping', async () => { await supertest .post('/api/actions/action') @@ -251,7 +231,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { config: { apiUrl: jiraSimulatorURL, projectKey: mockJira.config.projectKey, - casesConfiguration: { mapping: [] }, + incidentConfiguration: { mapping: [] }, }, secrets: mockJira.secrets, }) @@ -261,7 +241,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { statusCode: 400, error: 'Bad Request', message: - 'error validating action type config: [casesConfiguration.mapping]: expected non-empty but got empty', + 'error validating action type config: [incidentConfiguration.mapping]: expected non-empty but got empty', }); }); }); @@ -276,7 +256,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { config: { apiUrl: jiraSimulatorURL, projectKey: mockJira.config.projectKey, - casesConfiguration: { + incidentConfiguration: { mapping: [ { source: 'title', @@ -307,7 +287,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { config: { apiUrl: jiraSimulatorURL, projectKey: mockJira.config.projectKey, - casesConfiguration: mockJira.config.casesConfiguration, + incidentConfiguration: mockJira.config.incidentConfiguration, }, secrets: mockJira.secrets, }); @@ -353,7 +333,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subAction]: expected value to equal [pushToService]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subAction]: expected value to equal [pushToService]\n- [3.subAction]: expected value to equal [issueTypes]\n- [4.subAction]: expected value to equal [fieldsByIssueType]', }); }); }); @@ -371,7 +351,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.savedObjectId]: expected value of type [string] but got [undefined]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.savedObjectId]: expected value of type [string] but got [undefined]\n- [3.subAction]: expected value to equal [issueTypes]\n- [4.subAction]: expected value to equal [fieldsByIssueType]', }); }); }); @@ -389,7 +369,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.savedObjectId]: expected value of type [string] but got [undefined]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.savedObjectId]: expected value of type [string] but got [undefined]\n- [3.subAction]: expected value to equal [issueTypes]\n- [4.subAction]: expected value to equal [fieldsByIssueType]', }); }); }); @@ -412,31 +392,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.title]: expected value of type [string] but got [undefined]', - }); - }); - }); - - it('should handle failing with a simulated success without createdAt', async () => { - await supertest - .post(`/api/actions/action/${simulatedActionId}/_execute`) - .set('kbn-xsrf', 'foo') - .send({ - params: { - ...mockJira.params, - subActionParams: { - savedObjectId: 'success', - title: 'success', - }, - }, - }) - .then((resp: any) => { - expect(resp.body).to.eql({ - actionId: simulatedActionId, - status: 'error', - retry: false, - message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.createdAt]: expected value of type [string] but got [undefined]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.title]: expected value of type [string] but got [undefined]\n- [3.subAction]: expected value to equal [issueTypes]\n- [4.subAction]: expected value to equal [fieldsByIssueType]', }); }); }); @@ -464,7 +420,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.commentId]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.commentId]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [3.subAction]: expected value to equal [issueTypes]\n- [4.subAction]: expected value to equal [fieldsByIssueType]', }); }); }); @@ -492,35 +448,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.comment]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]', - }); - }); - }); - - it('should handle failing with a simulated success without comment.createdAt', async () => { - await supertest - .post(`/api/actions/action/${simulatedActionId}/_execute`) - .set('kbn-xsrf', 'foo') - .send({ - params: { - ...mockJira.params, - subActionParams: { - ...mockJira.params.subActionParams, - savedObjectId: 'success', - title: 'success', - createdAt: 'success', - createdBy: { username: 'elastic' }, - comments: [{ commentId: 'success', comment: 'success' }], - }, - }, - }) - .then((resp: any) => { - expect(resp.body).to.eql({ - actionId: simulatedActionId, - status: 'error', - retry: false, - message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.createdAt]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.comment]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]\n- [3.subAction]: expected value to equal [issueTypes]\n- [4.subAction]: expected value to equal [fieldsByIssueType]', }); }); }); @@ -537,6 +465,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { subActionParams: { ...mockJira.params.subActionParams, comments: [], + issueType: '10006', }, }, }) diff --git a/x-pack/test/api_integration/apis/lens/field_stats.ts b/x-pack/test/api_integration/apis/lens/field_stats.ts index 87c9d97be9b60..ccaea03691f01 100644 --- a/x-pack/test/api_integration/apis/lens/field_stats.ts +++ b/x-pack/test/api_integration/apis/lens/field_stats.ts @@ -279,6 +279,139 @@ export default ({ getService }: FtrProviderContext) => { }); }); + it('should return top values for ip fields', async () => { + const { body } = await supertest + .post('/api/lens/index_stats/logstash-2015.09.22/field') + .set(COMMON_HEADERS) + .send({ + dslQuery: { match_all: {} }, + fromDate: TEST_START_TIME, + toDate: TEST_END_TIME, + timeFieldName: '@timestamp', + field: { + name: 'ip', + type: 'ip', + }, + }) + .expect(200); + + expect(body).to.eql({ + totalDocuments: 4634, + sampledDocuments: 4634, + sampledValues: 4633, + topValues: { + buckets: [ + { + count: 13, + key: '177.194.175.66', + }, + { + count: 12, + key: '18.55.141.62', + }, + { + count: 12, + key: '53.55.251.105', + }, + { + count: 11, + key: '21.111.249.239', + }, + { + count: 11, + key: '97.63.84.25', + }, + { + count: 11, + key: '100.99.207.174', + }, + { + count: 11, + key: '112.34.138.226', + }, + { + count: 11, + key: '194.68.89.92', + }, + { + count: 11, + key: '235.186.79.201', + }, + { + count: 10, + key: '57.79.108.136', + }, + ], + }, + }); + }); + + it('should return histograms for scripted date fields', async () => { + const { body } = await supertest + .post('/api/lens/index_stats/logstash-2015.09.22/field') + .set(COMMON_HEADERS) + .send({ + dslQuery: { match_all: {} }, + fromDate: TEST_START_TIME, + toDate: TEST_END_TIME, + timeFieldName: '@timestamp', + field: { + name: 'scripted date', + type: 'date', + scripted: true, + script: '1234', + lang: 'painless', + }, + }) + .expect(200); + + expect(body).to.eql({ + histogram: { + buckets: [ + { + count: 4634, + key: 0, + }, + ], + }, + totalDocuments: 4634, + }); + }); + + it('should return top values for scripted string fields', async () => { + const { body } = await supertest + .post('/api/lens/index_stats/logstash-2015.09.22/field') + .set(COMMON_HEADERS) + .send({ + dslQuery: { match_all: {} }, + fromDate: TEST_START_TIME, + toDate: TEST_END_TIME, + timeFieldName: '@timestamp', + field: { + name: 'scripted string', + type: 'string', + scripted: true, + script: 'return "hello"', + lang: 'painless', + }, + }) + .expect(200); + + expect(body).to.eql({ + totalDocuments: 4634, + sampledDocuments: 4634, + sampledValues: 4634, + topValues: { + buckets: [ + { + count: 4634, + key: 'hello', + }, + ], + }, + }); + }); + it('should apply filters and queries', async () => { const { body } = await supertest .post('/api/lens/index_stats/logstash-2015.09.22/field') diff --git a/x-pack/test/api_integration/apis/metrics_ui/snapshot.ts b/x-pack/test/api_integration/apis/metrics_ui/snapshot.ts index bb0934b73a4c7..7339c142fb028 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/snapshot.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/snapshot.ts @@ -67,7 +67,6 @@ export default function ({ getService }: FtrProviderContext) { 'value', '242fddb9d376bbf0e38025d81764847ee5ec0308adfa095918fd3266f9d06c6a' ); - expect(first(firstNode.path)).to.have.property('label', 'docker-autodiscovery_nginx_1'); expect(firstNode).to.have.property('metrics'); expect(firstNode.metrics).to.eql([ { @@ -136,7 +135,7 @@ export default function ({ getService }: FtrProviderContext) { expect(snapshot).to.have.property('nodes'); if (snapshot) { const { nodes } = snapshot; - expect(nodes.length).to.equal(136); + expect(nodes.length).to.equal(135); const firstNode = first(nodes) as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(1); @@ -295,7 +294,7 @@ export default function ({ getService }: FtrProviderContext) { expect(firstNode).to.have.property('metrics'); expect(firstNode.metrics).to.eql([ { - name: 'custom', + name: 'custom_0', value: 0.0016, max: 0.0018333333333333333, avg: 0.0013666666666666669, diff --git a/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts b/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts index 4ec8ae0429a6b..5fe0dd5ee5e4f 100644 --- a/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts +++ b/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts @@ -33,7 +33,7 @@ export default ({ getService }: FtrProviderContext) => { ], samplerShardSize: -1, // No sampling, as otherwise counts could vary on each run. timeFieldName: '@timestamp', - interval: '1d', + interval: 86400000, maxExamples: 10, }, expected: { @@ -41,7 +41,7 @@ export default ({ getService }: FtrProviderContext) => { responseBody: [ { documentCounts: { - interval: '1d', + interval: 86400000, buckets: { '1454803200000': 846, '1454889600000': 846, @@ -145,6 +145,7 @@ export default ({ getService }: FtrProviderContext) => { ], samplerShardSize: -1, // No sampling, as otherwise counts could vary on each run. timeFieldName: '@timestamp', + interval: 86400000, maxExamples: 10, }, expected: { diff --git a/x-pack/test/api_integration/apis/ml/jobs/jobs_exist.ts b/x-pack/test/api_integration/apis/ml/jobs/jobs_exist.ts new file mode 100644 index 0000000000000..c48376b6a14f3 --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/jobs/jobs_exist.ts @@ -0,0 +1,145 @@ +/* + * 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 expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; +import { USER } from '../../../../functional/services/ml/security_common'; +import { SINGLE_METRIC_JOB_CONFIG, DATAFEED_CONFIG } from './common_jobs'; + +export default ({ getService }: FtrProviderContext) => { + const esArchiver = getService('esArchiver'); + const supertest = getService('supertestWithoutAuth'); + const ml = getService('ml'); + + const testSetupJobConfigs = [SINGLE_METRIC_JOB_CONFIG]; + + const responseBody = { + [SINGLE_METRIC_JOB_CONFIG.job_id]: true, + [`${SINGLE_METRIC_JOB_CONFIG.job_id.slice(0, 10)}*`]: true, // wildcard, use first 10 chars + [`${SINGLE_METRIC_JOB_CONFIG.job_id}_fail`]: false, + [`${SINGLE_METRIC_JOB_CONFIG.job_id.slice(0, 10)}_fail*`]: false, // wildcard, use first 10 chars + }; + + const testDataList = [ + { + testTitle: 'as ML Poweruser', + user: USER.ML_POWERUSER, + requestBody: { + jobIds: Object.keys(responseBody), + }, + expected: { + responseCode: 200, + responseBody, + }, + }, + { + testTitle: 'as ML Viewer', + user: USER.ML_VIEWER, + requestBody: { + jobIds: Object.keys(responseBody), + }, + expected: { + responseCode: 200, + responseBody, + }, + }, + ]; + + const testDataListUnauthorized = [ + { + testTitle: 'as ML Unauthorized user', + user: USER.ML_UNAUTHORIZED, + requestBody: { + jobIds: Object.keys(responseBody), + }, + expected: { + responseCode: 404, + error: 'Not Found', + }, + }, + ]; + + async function runJobsExistRequest( + user: USER, + requestBody: object, + expectedResponsecode: number + ): Promise { + const { body } = await supertest + .post('/api/ml/jobs/jobs_exist') + .auth(user, ml.securityCommon.getPasswordForUser(user)) + .set(COMMON_REQUEST_HEADERS) + .send(requestBody) + .expect(expectedResponsecode); + + return body; + } + + describe('jobs_exist', function () { + before(async () => { + await esArchiver.loadIfNeeded('ml/farequote'); + await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.setKibanaTimeZoneToUTC(); + }); + + after(async () => { + await ml.api.cleanMlIndices(); + }); + + it('sets up jobs', async () => { + for (const job of testSetupJobConfigs) { + const datafeedId = `datafeed-${job.job_id}`; + await ml.api.createAnomalyDetectionJob(job); + await ml.api.openAnomalyDetectionJob(job.job_id); + await ml.api.createDatafeed({ + ...DATAFEED_CONFIG, + datafeed_id: datafeedId, + job_id: job.job_id, + }); + } + }); + + describe('jobs exist', function () { + for (const testData of testDataList) { + it(`${testData.testTitle}`, async () => { + const body = await runJobsExistRequest( + testData.user, + testData.requestBody, + testData.expected.responseCode + ); + const expectedResponse = testData.expected.responseBody; + const expectedRspJobIds = Object.keys(expectedResponse).sort((a, b) => + a.localeCompare(b) + ); + const actualRspJobIds = Object.keys(body).sort((a, b) => a.localeCompare(b)); + + expect(actualRspJobIds).to.have.length(expectedRspJobIds.length); + expect(actualRspJobIds).to.eql(expectedRspJobIds); + expectedRspJobIds.forEach((id) => { + expect(body[id]).to.eql(testData.expected.responseBody[id]); + }); + }); + } + }); + + describe('rejects request', function () { + for (const testData of testDataListUnauthorized) { + describe('fails to check jobs exist', function () { + it(`${testData.testTitle}`, async () => { + const body = await runJobsExistRequest( + testData.user, + testData.requestBody, + testData.expected.responseCode + ); + + expect(body).to.have.property('error').eql(testData.expected.error); + }); + }); + } + }); + }); +}; diff --git a/x-pack/test/api_integration/apis/security/basic_login.js b/x-pack/test/api_integration/apis/security/basic_login.js index 4b39b1bf32d5b..43ef8e6b81eac 100644 --- a/x-pack/test/api_integration/apis/security/basic_login.js +++ b/x-pack/test/api_integration/apis/security/basic_login.js @@ -148,11 +148,8 @@ export default function ({ getService }) { ]); expect(apiResponse.body.username).to.be(validUsername); expect(apiResponse.body.authentication_provider).to.eql('__http__'); - expect(apiResponse.body.authentication_realm).to.eql({ - name: 'reserved', - type: 'reserved', - }); expect(apiResponse.body.authentication_type).to.be('realm'); + // Do not assert on the `authentication_realm`, as the value differes for on-prem vs cloud }); describe('with session cookie', () => { @@ -197,11 +194,8 @@ export default function ({ getService }) { ]); expect(apiResponse.body.username).to.be(validUsername); expect(apiResponse.body.authentication_provider).to.eql('basic'); - expect(apiResponse.body.authentication_realm).to.eql({ - name: 'reserved', - type: 'reserved', - }); expect(apiResponse.body.authentication_type).to.be('realm'); + // Do not assert on the `authentication_realm`, as the value differes for on-prem vs cloud }); it('should extend cookie on every successful non-system API call', async () => { diff --git a/x-pack/test/api_integration/apis/security_solution/ip_overview.ts b/x-pack/test/api_integration/apis/security_solution/network_details.ts similarity index 97% rename from x-pack/test/api_integration/apis/security_solution/ip_overview.ts rename to x-pack/test/api_integration/apis/security_solution/network_details.ts index 6493c07617991..cffcd790fa19c 100644 --- a/x-pack/test/api_integration/apis/security_solution/ip_overview.ts +++ b/x-pack/test/api_integration/apis/security_solution/network_details.ts @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { ipOverviewQuery } from '../../../../plugins/security_solution/public/network/containers/ip_overview/index.gql_query'; +import { ipOverviewQuery } from '../../../../plugins/security_solution/public/network/containers/details/index.gql_query'; import { GetIpOverviewQuery } from '../../../../plugins/security_solution/public/graphql/types'; import { FtrProviderContext } from '../../ftr_provider_context'; diff --git a/x-pack/test/apm_api_integration/basic/tests/services/agent_name.ts b/x-pack/test/apm_api_integration/basic/tests/services/agent_name.ts index 5be5e43b359f5..e4cceca573ce8 100644 --- a/x-pack/test/apm_api_integration/basic/tests/services/agent_name.ts +++ b/x-pack/test/apm_api_integration/basic/tests/services/agent_name.ts @@ -6,14 +6,15 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; +import archives from '../../../common/archives_metadata'; export default function ApiTest({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); - // url parameters - const start = encodeURIComponent('2020-06-29T06:45:00.000Z'); - const end = encodeURIComponent('2020-06-29T06:49:00.000Z'); + const range = archives['apm_8.0.0']; + const start = encodeURIComponent(range.start); + const end = encodeURIComponent(range.end); describe('Agent name', () => { describe('when data is not loaded ', () => { @@ -28,8 +29,8 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); describe('when data is loaded', () => { - before(() => esArchiver.load('8.0.0')); - after(() => esArchiver.unload('8.0.0')); + before(() => esArchiver.load('apm_8.0.0')); + after(() => esArchiver.unload('apm_8.0.0')); it('returns the agent name', async () => { const response = await supertest.get( diff --git a/x-pack/test/apm_api_integration/common/archives_metadata.ts b/x-pack/test/apm_api_integration/common/archives_metadata.ts new file mode 100644 index 0000000000000..38dde685dd3f4 --- /dev/null +++ b/x-pack/test/apm_api_integration/common/archives_metadata.ts @@ -0,0 +1,12 @@ +/* + * 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. + */ + +export default { + 'apm_8.0.0': { + start: '2020-09-10T08:07:13.274Z', + end: '2020-09-10T08:37:13.274Z', + }, +}; diff --git a/x-pack/test/apm_api_integration/common/config.ts b/x-pack/test/apm_api_integration/common/config.ts index 110f42115397e..5edf1bf23e594 100644 --- a/x-pack/test/apm_api_integration/common/config.ts +++ b/x-pack/test/apm_api_integration/common/config.ts @@ -7,6 +7,7 @@ import { FtrConfigProviderContext } from '@kbn/test/types/ftr'; import supertestAsPromised from 'supertest-as-promised'; import { format, UrlObject } from 'url'; +import path from 'path'; import { InheritedFtrProviderContext, InheritedServices } from './ftr_provider_context'; import { PromiseReturnType } from '../../../plugins/apm/typings/common'; import { createApmUser, APM_TEST_PASSWORD, ApmUser } from './authentication'; @@ -49,6 +50,9 @@ export function createTestConfig(settings: Settings) { return { testFiles, servers, + esArchiver: { + directory: path.resolve(__dirname, './fixtures/es_archiver'), + }, services: { ...services, supertest: supertestAsApmReadUser, diff --git a/x-pack/test/apm_api_integration/basic/fixtures/es_archiver/8.0.0/data.json.gz b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/8.0.0/data.json.gz similarity index 100% rename from x-pack/test/apm_api_integration/basic/fixtures/es_archiver/8.0.0/data.json.gz rename to x-pack/test/apm_api_integration/common/fixtures/es_archiver/8.0.0/data.json.gz diff --git a/x-pack/test/apm_api_integration/basic/fixtures/es_archiver/8.0.0/mappings.json b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/8.0.0/mappings.json similarity index 100% rename from x-pack/test/apm_api_integration/basic/fixtures/es_archiver/8.0.0/mappings.json rename to x-pack/test/apm_api_integration/common/fixtures/es_archiver/8.0.0/mappings.json diff --git a/x-pack/test/apm_api_integration/common/fixtures/es_archiver/apm_8.0.0/data.json.gz b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/apm_8.0.0/data.json.gz new file mode 100644 index 0000000000000..34b673790ec01 Binary files /dev/null and b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/apm_8.0.0/data.json.gz differ diff --git a/x-pack/test/apm_api_integration/common/fixtures/es_archiver/apm_8.0.0/mappings.json b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/apm_8.0.0/mappings.json new file mode 100644 index 0000000000000..5171ea03fb49f --- /dev/null +++ b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/apm_8.0.0/mappings.json @@ -0,0 +1,63363 @@ +{ + "type": "index", + "value": { + "aliases": { + ".ml-anomalies-.write-android_homepage_high_latency_by_geo": { + "is_hidden": true + }, + ".ml-anomalies-.write-apm-environment_not_defined-7ed6-high_mean_transaction_duration": { + "is_hidden": true + }, + ".ml-anomalies-.write-apm-production-229a-high_mean_transaction_duration": { + "is_hidden": true + }, + ".ml-anomalies-.write-apm-testing-d457-high_mean_transaction_duration": { + "is_hidden": true + }, + ".ml-anomalies-.write-auto_http_0x73c4bc9426fb6908_high_latency_by_geo": { + "is_hidden": true + }, + ".ml-anomalies-.write-auto_http_0xa1e2426c5b01459d_high_latency_by_geo": { + "is_hidden": true + }, + ".ml-anomalies-.write-kibana-logs-ui-default-default-log-entry-categories-count": { + "is_hidden": true + }, + ".ml-anomalies-.write-kibana-logs-ui-default-default-log-entry-rate": { + "is_hidden": true + }, + ".ml-anomalies-android_homepage_high_latency_by_geo": { + "filter": { + "term": { + "job_id": { + "boost": 1, + "value": "android_homepage_high_latency_by_geo" + } + } + }, + "is_hidden": true + }, + ".ml-anomalies-apm-environment_not_defined-7ed6-high_mean_transaction_duration": { + "filter": { + "term": { + "job_id": { + "boost": 1, + "value": "apm-environment_not_defined-7ed6-high_mean_transaction_duration" + } + } + }, + "is_hidden": true + }, + ".ml-anomalies-apm-production-229a-high_mean_transaction_duration": { + "filter": { + "term": { + "job_id": { + "boost": 1, + "value": "apm-production-229a-high_mean_transaction_duration" + } + } + }, + "is_hidden": true + }, + ".ml-anomalies-apm-testing-d457-high_mean_transaction_duration": { + "filter": { + "term": { + "job_id": { + "boost": 1, + "value": "apm-testing-d457-high_mean_transaction_duration" + } + } + }, + "is_hidden": true + }, + ".ml-anomalies-auto_http_0x73c4bc9426fb6908_high_latency_by_geo": { + "filter": { + "term": { + "job_id": { + "boost": 1, + "value": "auto_http_0x73c4bc9426fb6908_high_latency_by_geo" + } + } + }, + "is_hidden": true + }, + ".ml-anomalies-auto_http_0xa1e2426c5b01459d_high_latency_by_geo": { + "filter": { + "term": { + "job_id": { + "boost": 1, + "value": "auto_http_0xa1e2426c5b01459d_high_latency_by_geo" + } + } + }, + "is_hidden": true + }, + ".ml-anomalies-kibana-logs-ui-default-default-log-entry-categories-count": { + "filter": { + "term": { + "job_id": { + "boost": 1, + "value": "kibana-logs-ui-default-default-log-entry-categories-count" + } + } + }, + "is_hidden": true + }, + ".ml-anomalies-kibana-logs-ui-default-default-log-entry-rate": { + "filter": { + "term": { + "job_id": { + "boost": 1, + "value": "kibana-logs-ui-default-default-log-entry-rate" + } + } + }, + "is_hidden": true + } + }, + "index": ".ml-anomalies-shared", + "mappings": { + "_meta": { + "version": "8.0.0" + }, + "dynamic_templates": [ + { + "strings_as_keywords": { + "mapping": { + "type": "keyword" + }, + "match": "*" + } + } + ], + "properties": { + "actual": { + "type": "double" + }, + "all_field_values": { + "analyzer": "whitespace", + "type": "text" + }, + "anomaly_score": { + "type": "double" + }, + "average_bucket_processing_time_ms": { + "type": "double" + }, + "bucket_allocation_failures_count": { + "type": "long" + }, + "bucket_count": { + "type": "long" + }, + "bucket_influencers": { + "properties": { + "anomaly_score": { + "type": "double" + }, + "bucket_span": { + "type": "long" + }, + "influencer_field_name": { + "type": "keyword" + }, + "initial_anomaly_score": { + "type": "double" + }, + "is_interim": { + "type": "boolean" + }, + "job_id": { + "type": "keyword" + }, + "probability": { + "type": "double" + }, + "raw_anomaly_score": { + "type": "double" + }, + "result_type": { + "type": "keyword" + }, + "timestamp": { + "type": "date" + } + }, + "type": "nested" + }, + "bucket_span": { + "type": "long" + }, + "by_field_name": { + "type": "keyword" + }, + "by_field_value": { + "copy_to": [ + "all_field_values" + ], + "type": "keyword" + }, + "categorization_status": { + "type": "keyword" + }, + "categorized_doc_count": { + "type": "keyword" + }, + "category_id": { + "type": "long" + }, + "causes": { + "properties": { + "actual": { + "type": "double" + }, + "by_field_name": { + "type": "keyword" + }, + "by_field_value": { + "copy_to": [ + "all_field_values" + ], + "type": "keyword" + }, + "correlated_by_field_value": { + "copy_to": [ + "all_field_values" + ], + "type": "keyword" + }, + "field_name": { + "type": "keyword" + }, + "function": { + "type": "keyword" + }, + "function_description": { + "type": "keyword" + }, + "geo_results": { + "properties": { + "actual_point": { + "type": "geo_point" + }, + "typical_point": { + "type": "geo_point" + } + } + }, + "over_field_name": { + "type": "keyword" + }, + "over_field_value": { + "copy_to": [ + "all_field_values" + ], + "type": "keyword" + }, + "partition_field_name": { + "type": "keyword" + }, + "partition_field_value": { + "copy_to": [ + "all_field_values" + ], + "type": "keyword" + }, + "probability": { + "type": "double" + }, + "typical": { + "type": "double" + } + }, + "type": "nested" + }, + "dead_category_count": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "detector_index": { + "type": "integer" + }, + "earliest_record_timestamp": { + "type": "date" + }, + "empty_bucket_count": { + "type": "long" + }, + "event": { + "properties": { + "dataset": { + "type": "keyword" + } + } + }, + "event_count": { + "type": "long" + }, + "examples": { + "type": "text" + }, + "exponential_average_bucket_processing_time_ms": { + "type": "double" + }, + "exponential_average_calculation_context": { + "properties": { + "incremental_metric_value_ms": { + "type": "double" + }, + "latest_timestamp": { + "type": "date" + }, + "previous_exponential_average_ms": { + "type": "double" + } + } + }, + "failed_category_count": { + "type": "keyword" + }, + "field_name": { + "type": "keyword" + }, + "forecast_create_timestamp": { + "type": "date" + }, + "forecast_end_timestamp": { + "type": "date" + }, + "forecast_expiry_timestamp": { + "type": "date" + }, + "forecast_id": { + "type": "keyword" + }, + "forecast_lower": { + "type": "double" + }, + "forecast_memory_bytes": { + "type": "long" + }, + "forecast_messages": { + "type": "keyword" + }, + "forecast_prediction": { + "type": "double" + }, + "forecast_progress": { + "type": "double" + }, + "forecast_start_timestamp": { + "type": "date" + }, + "forecast_status": { + "type": "keyword" + }, + "forecast_upper": { + "type": "double" + }, + "frequent_category_count": { + "type": "keyword" + }, + "function": { + "type": "keyword" + }, + "function_description": { + "type": "keyword" + }, + "geo_results": { + "properties": { + "actual_point": { + "type": "geo_point" + }, + "typical_point": { + "type": "geo_point" + } + } + }, + "influencer_field_name": { + "type": "keyword" + }, + "influencer_field_value": { + "copy_to": [ + "all_field_values" + ], + "type": "keyword" + }, + "influencer_score": { + "type": "double" + }, + "influencers": { + "properties": { + "influencer_field_name": { + "type": "keyword" + }, + "influencer_field_values": { + "copy_to": [ + "all_field_values" + ], + "type": "keyword" + } + }, + "type": "nested" + }, + "initial_anomaly_score": { + "type": "double" + }, + "initial_influencer_score": { + "type": "double" + }, + "initial_record_score": { + "type": "double" + }, + "input_bytes": { + "type": "long" + }, + "input_field_count": { + "type": "long" + }, + "input_record_count": { + "type": "long" + }, + "invalid_date_count": { + "type": "long" + }, + "is_interim": { + "type": "boolean" + }, + "job_id": { + "copy_to": [ + "all_field_values" + ], + "type": "keyword" + }, + "last_data_time": { + "type": "date" + }, + "latest_empty_bucket_timestamp": { + "type": "date" + }, + "latest_record_time_stamp": { + "type": "date" + }, + "latest_record_timestamp": { + "type": "date" + }, + "latest_result_time_stamp": { + "type": "date" + }, + "latest_sparse_bucket_timestamp": { + "type": "date" + }, + "log_time": { + "type": "date" + }, + "max_matching_length": { + "type": "long" + }, + "maximum_bucket_processing_time_ms": { + "type": "double" + }, + "memory_status": { + "type": "keyword" + }, + "min_version": { + "type": "keyword" + }, + "minimum_bucket_processing_time_ms": { + "type": "double" + }, + "missing_field_count": { + "type": "long" + }, + "mlcategory": { + "type": "keyword" + }, + "model_bytes": { + "type": "long" + }, + "model_bytes_exceeded": { + "type": "keyword" + }, + "model_bytes_memory_limit": { + "type": "keyword" + }, + "model_feature": { + "type": "keyword" + }, + "model_lower": { + "type": "double" + }, + "model_median": { + "type": "double" + }, + "model_size_stats": { + "properties": { + "bucket_allocation_failures_count": { + "type": "long" + }, + "categorization_status": { + "type": "keyword" + }, + "categorized_doc_count": { + "type": "keyword" + }, + "dead_category_count": { + "type": "keyword" + }, + "failed_category_count": { + "type": "keyword" + }, + "frequent_category_count": { + "type": "keyword" + }, + "job_id": { + "type": "keyword" + }, + "log_time": { + "type": "date" + }, + "memory_status": { + "type": "keyword" + }, + "model_bytes": { + "type": "long" + }, + "model_bytes_exceeded": { + "type": "keyword" + }, + "model_bytes_memory_limit": { + "type": "keyword" + }, + "peak_model_bytes": { + "type": "long" + }, + "rare_category_count": { + "type": "keyword" + }, + "result_type": { + "type": "keyword" + }, + "timestamp": { + "type": "date" + }, + "total_by_field_count": { + "type": "long" + }, + "total_category_count": { + "type": "keyword" + }, + "total_over_field_count": { + "type": "long" + }, + "total_partition_field_count": { + "type": "long" + } + } + }, + "model_upper": { + "type": "double" + }, + "monitor": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + } + } + }, + "multi_bucket_impact": { + "type": "double" + }, + "num_matches": { + "type": "long" + }, + "observer": { + "properties": { + "geo": { + "properties": { + "name": { + "type": "keyword" + } + } + } + } + }, + "out_of_order_timestamp_count": { + "type": "long" + }, + "over_field_name": { + "type": "keyword" + }, + "over_field_value": { + "copy_to": [ + "all_field_values" + ], + "type": "keyword" + }, + "partition_field_name": { + "type": "keyword" + }, + "partition_field_value": { + "copy_to": [ + "all_field_values" + ], + "type": "keyword" + }, + "peak_model_bytes": { + "type": "keyword" + }, + "preferred_to_categories": { + "type": "long" + }, + "probability": { + "type": "double" + }, + "processed_field_count": { + "type": "long" + }, + "processed_record_count": { + "type": "long" + }, + "processing_time_ms": { + "type": "long" + }, + "quantiles": { + "enabled": false, + "type": "object" + }, + "rare_category_count": { + "type": "keyword" + }, + "raw_anomaly_score": { + "type": "double" + }, + "record_score": { + "type": "double" + }, + "regex": { + "type": "keyword" + }, + "result_type": { + "type": "keyword" + }, + "retain": { + "type": "boolean" + }, + "scheduled_events": { + "type": "keyword" + }, + "search_count": { + "type": "long" + }, + "service": { + "properties": { + "name": { + "type": "keyword" + } + } + }, + "snapshot_doc_count": { + "type": "integer" + }, + "snapshot_id": { + "type": "keyword" + }, + "sparse_bucket_count": { + "type": "long" + }, + "terms": { + "type": "text" + }, + "timestamp": { + "type": "date" + }, + "total_by_field_count": { + "type": "long" + }, + "total_category_count": { + "type": "keyword" + }, + "total_over_field_count": { + "type": "long" + }, + "total_partition_field_count": { + "type": "long" + }, + "total_search_time_ms": { + "type": "double" + }, + "transaction": { + "properties": { + "type": { + "type": "keyword" + } + } + }, + "typical": { + "type": "double" + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "hidden": "true", + "number_of_replicas": "1", + "number_of_shards": "1", + "translog": { + "durability": "async" + } + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + }, + "index": ".ml-config", + "mappings": { + "_meta": { + "version": "8.0.0" + }, + "dynamic_templates": [ + { + "strings_as_keywords": { + "mapping": { + "type": "keyword" + }, + "match": "*" + } + } + ], + "properties": { + "aggregations": { + "enabled": false, + "type": "object" + }, + "allow_lazy_open": { + "type": "keyword" + }, + "analysis": { + "properties": { + "classification": { + "properties": { + "class_assignment_objective": { + "type": "keyword" + }, + "dependent_variable": { + "type": "keyword" + }, + "eta": { + "type": "double" + }, + "feature_bag_fraction": { + "type": "double" + }, + "gamma": { + "type": "double" + }, + "lambda": { + "type": "double" + }, + "max_trees": { + "type": "integer" + }, + "num_top_classes": { + "type": "integer" + }, + "num_top_feature_importance_values": { + "type": "integer" + }, + "prediction_field_name": { + "type": "keyword" + }, + "training_percent": { + "type": "double" + } + } + }, + "outlier_detection": { + "properties": { + "feature_influence_threshold": { + "type": "double" + }, + "method": { + "type": "keyword" + }, + "n_neighbors": { + "type": "integer" + } + } + }, + "regression": { + "properties": { + "dependent_variable": { + "type": "keyword" + }, + "eta": { + "type": "double" + }, + "feature_bag_fraction": { + "type": "double" + }, + "gamma": { + "type": "double" + }, + "lambda": { + "type": "double" + }, + "loss_function": { + "type": "keyword" + }, + "loss_function_parameter": { + "type": "double" + }, + "max_trees": { + "type": "integer" + }, + "num_top_feature_importance_values": { + "type": "integer" + }, + "prediction_field_name": { + "type": "keyword" + }, + "training_percent": { + "type": "double" + } + } + } + } + }, + "analysis_config": { + "properties": { + "bucket_span": { + "type": "keyword" + }, + "categorization_analyzer": { + "enabled": false, + "type": "object" + }, + "categorization_field_name": { + "type": "keyword" + }, + "categorization_filters": { + "type": "keyword" + }, + "detectors": { + "properties": { + "by_field_name": { + "type": "keyword" + }, + "custom_rules": { + "properties": { + "actions": { + "type": "keyword" + }, + "conditions": { + "properties": { + "applies_to": { + "type": "keyword" + }, + "operator": { + "type": "keyword" + }, + "value": { + "type": "double" + } + }, + "type": "nested" + }, + "scope": { + "enabled": false, + "type": "object" + } + }, + "type": "nested" + }, + "detector_description": { + "type": "text" + }, + "detector_index": { + "type": "integer" + }, + "exclude_frequent": { + "type": "keyword" + }, + "field_name": { + "type": "keyword" + }, + "function": { + "type": "keyword" + }, + "over_field_name": { + "type": "keyword" + }, + "partition_field_name": { + "type": "keyword" + }, + "use_null": { + "type": "boolean" + } + } + }, + "influencers": { + "type": "keyword" + }, + "latency": { + "type": "keyword" + }, + "multivariate_by_fields": { + "type": "boolean" + }, + "per_partition_categorization": { + "properties": { + "enabled": { + "type": "boolean" + }, + "stop_on_warn": { + "type": "boolean" + } + } + }, + "summary_count_field_name": { + "type": "keyword" + } + } + }, + "analysis_limits": { + "properties": { + "categorization_examples_limit": { + "type": "long" + }, + "model_memory_limit": { + "type": "keyword" + } + } + }, + "analyzed_fields": { + "enabled": false, + "type": "object" + }, + "background_persist_interval": { + "type": "keyword" + }, + "chunking_config": { + "properties": { + "mode": { + "type": "keyword" + }, + "time_span": { + "type": "keyword" + } + } + }, + "config_type": { + "type": "keyword" + }, + "create_time": { + "type": "date" + }, + "custom_settings": { + "enabled": false, + "type": "object" + }, + "daily_model_snapshot_retention_after_days": { + "type": "long" + }, + "data_description": { + "properties": { + "field_delimiter": { + "type": "keyword" + }, + "format": { + "type": "keyword" + }, + "quote_character": { + "type": "keyword" + }, + "time_field": { + "type": "keyword" + }, + "time_format": { + "type": "keyword" + } + } + }, + "datafeed_id": { + "type": "keyword" + }, + "delayed_data_check_config": { + "properties": { + "check_window": { + "type": "keyword" + }, + "enabled": { + "type": "boolean" + } + } + }, + "deleting": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "dest": { + "properties": { + "index": { + "type": "keyword" + }, + "results_field": { + "type": "keyword" + } + } + }, + "finished_time": { + "type": "date" + }, + "frequency": { + "type": "keyword" + }, + "groups": { + "type": "keyword" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "id": { + "type": "keyword" + }, + "indices": { + "type": "keyword" + }, + "indices_options": { + "enabled": false, + "type": "object" + }, + "job_id": { + "type": "keyword" + }, + "job_type": { + "type": "keyword" + }, + "job_version": { + "type": "keyword" + }, + "max_empty_searches": { + "type": "keyword" + }, + "max_num_threads": { + "type": "integer" + }, + "model_plot_config": { + "properties": { + "annotations_enabled": { + "type": "boolean" + }, + "enabled": { + "type": "boolean" + }, + "terms": { + "type": "keyword" + } + } + }, + "model_snapshot_id": { + "type": "keyword" + }, + "model_snapshot_min_version": { + "type": "keyword" + }, + "model_snapshot_retention_days": { + "type": "long" + }, + "query": { + "enabled": false, + "type": "object" + }, + "query_delay": { + "type": "keyword" + }, + "renormalization_window_days": { + "type": "long" + }, + "results_index_name": { + "type": "keyword" + }, + "results_retention_days": { + "type": "long" + }, + "script_fields": { + "enabled": false, + "type": "object" + }, + "scroll_size": { + "type": "long" + }, + "source": { + "properties": { + "_source": { + "enabled": false, + "type": "object" + }, + "index": { + "type": "keyword" + }, + "query": { + "enabled": false, + "type": "object" + } + } + }, + "version": { + "type": "keyword" + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "max_result_window": "10000", + "number_of_replicas": "1", + "number_of_shards": "1" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-error": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-error-000001", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "company": { + "type": "keyword" + }, + "foo": { + "type": "keyword" + }, + "lorem": { + "type": "keyword" + }, + "multi-line": { + "type": "keyword" + }, + "this-is-a-very-long-tag-name-without-any-spaces": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "false", + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-error" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "0", + "number_of_shards": "1", + "priority": "50", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-error": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-error-000002", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "company": { + "type": "keyword" + }, + "customer_tier": { + "type": "keyword" + }, + "foo": { + "type": "keyword" + }, + "lorem": { + "type": "keyword" + }, + "multi-line": { + "type": "keyword" + }, + "request_id": { + "type": "keyword" + }, + "this-is-a-very-long-tag-name-without-any-spaces": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "false", + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-error" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "0", + "number_of_shards": "1", + "priority": "50", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-error": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-error-2020.07.31-000001", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels_string": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels_boolean": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels_*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "path": "agent.name", + "type": "alias" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "child": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "dynamic": "false", + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "company": { + "type": "keyword" + }, + "customer_tier": { + "type": "keyword" + }, + "foo": { + "type": "keyword" + }, + "lorem": { + "type": "keyword" + }, + "multi-line": { + "type": "keyword" + }, + "request_id": { + "type": "keyword" + }, + "this-is-a-very-long-tag-name-without-any-spaces": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "histogram": { + "type": "histogram" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "root": { + "type": "boolean" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-error" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "1", + "priority": "100", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-error": { + "is_write_index": true + } + }, + "index": "apm-8.0.0-error-2020.07.31-000002", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels_string": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels_boolean": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels_*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "path": "agent.name", + "type": "alias" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "child": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "dynamic": "false", + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "company": { + "type": "keyword" + }, + "customer_tier": { + "type": "keyword" + }, + "request_id": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "histogram": { + "type": "histogram" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "root": { + "type": "boolean" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "codec": "best_compression", + "lifecycle": { + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-error" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "1", + "priority": "100", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-metric": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-metric-000001", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "golang": { + "properties": { + "goroutines": { + "type": "long" + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "active": { + "type": "float" + }, + "allocated": { + "type": "float" + }, + "frees": { + "type": "float" + }, + "idle": { + "type": "float" + }, + "mallocs": { + "type": "float" + }, + "objects": { + "type": "long" + }, + "total": { + "type": "float" + } + } + }, + "gc": { + "properties": { + "cpu_fraction": { + "type": "float" + }, + "next_gc_limit": { + "type": "float" + }, + "total_count": { + "type": "long" + }, + "total_pause": { + "properties": { + "ns": { + "type": "float" + } + } + } + } + }, + "system": { + "properties": { + "obtained": { + "type": "float" + }, + "released": { + "type": "float" + }, + "stack": { + "type": "long" + }, + "total": { + "type": "float" + } + } + } + } + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "jvm": { + "properties": { + "gc": { + "properties": { + "alloc": { + "type": "float" + }, + "count": { + "type": "long" + }, + "time": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "heap": { + "properties": { + "committed": { + "type": "float" + }, + "max": { + "type": "float" + }, + "used": { + "type": "float" + } + } + }, + "non_heap": { + "properties": { + "committed": { + "type": "float" + }, + "max": { + "type": "long" + }, + "used": { + "type": "float" + } + } + } + } + }, + "thread": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "env": { + "type": "keyword" + }, + "hostname": { + "type": "keyword" + }, + "name": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "nodejs": { + "properties": { + "eventloop": { + "properties": { + "delay": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "float" + } + } + }, + "ns": { + "type": "long" + } + } + } + } + }, + "handles": { + "properties": { + "active": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "heap": { + "properties": { + "allocated": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "float" + } + } + } + } + } + } + }, + "requests": { + "properties": { + "active": { + "type": "long" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ruby": { + "properties": { + "gc": { + "properties": { + "count": { + "type": "long" + } + } + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "total": { + "type": "float" + } + } + }, + "slots": { + "properties": { + "free": { + "type": "long" + }, + "live": { + "type": "long" + } + } + } + } + }, + "threads": { + "type": "long" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "system": { + "properties": { + "norm": { + "properties": { + "pct": { + "type": "float" + } + } + } + } + }, + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "user": { + "properties": { + "norm": { + "properties": { + "pct": { + "type": "float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "false", + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-metric" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "0", + "number_of_shards": "1", + "priority": "50", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-metric": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-metric-000002", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "golang": { + "properties": { + "goroutines": { + "type": "long" + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "active": { + "type": "float" + }, + "allocated": { + "type": "float" + }, + "frees": { + "type": "long" + }, + "idle": { + "type": "float" + }, + "mallocs": { + "type": "long" + }, + "objects": { + "type": "long" + }, + "total": { + "type": "float" + } + } + }, + "gc": { + "properties": { + "cpu_fraction": { + "type": "float" + }, + "next_gc_limit": { + "type": "float" + }, + "total_count": { + "type": "long" + }, + "total_pause": { + "properties": { + "ns": { + "type": "float" + } + } + } + } + }, + "system": { + "properties": { + "obtained": { + "type": "float" + }, + "released": { + "type": "float" + }, + "stack": { + "type": "long" + }, + "total": { + "type": "float" + } + } + } + } + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "jvm": { + "properties": { + "gc": { + "properties": { + "alloc": { + "type": "float" + }, + "count": { + "type": "long" + }, + "time": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "heap": { + "properties": { + "committed": { + "type": "float" + }, + "max": { + "type": "float" + }, + "used": { + "type": "float" + } + } + }, + "non_heap": { + "properties": { + "committed": { + "type": "float" + }, + "max": { + "type": "long" + }, + "used": { + "type": "float" + } + } + } + } + }, + "thread": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "env": { + "type": "keyword" + }, + "hostname": { + "type": "keyword" + }, + "name": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "nodejs": { + "properties": { + "eventloop": { + "properties": { + "delay": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "float" + } + } + }, + "ns": { + "type": "long" + } + } + } + } + }, + "handles": { + "properties": { + "active": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "arrayBuffers": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "external": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "heap": { + "properties": { + "allocated": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "float" + } + } + } + } + } + } + }, + "requests": { + "properties": { + "active": { + "type": "long" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ruby": { + "properties": { + "gc": { + "properties": { + "count": { + "type": "long" + } + } + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "total": { + "type": "float" + } + } + }, + "slots": { + "properties": { + "free": { + "type": "long" + }, + "live": { + "type": "long" + } + } + } + } + }, + "threads": { + "type": "long" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "system": { + "properties": { + "norm": { + "properties": { + "pct": { + "type": "float" + } + } + } + } + }, + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "user": { + "properties": { + "norm": { + "properties": { + "pct": { + "type": "float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "false", + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-metric" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "0", + "number_of_shards": "1", + "priority": "50", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-metric": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-metric-2020.07.31-000001", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels_string": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels_boolean": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels_*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "path": "agent.name", + "type": "alias" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "child": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "dynamic": "false", + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "clr": { + "properties": { + "gc": { + "properties": { + "count": { + "type": "long" + }, + "gen0size": { + "type": "float" + }, + "gen1size": { + "type": "float" + }, + "gen2size": { + "type": "float" + }, + "gen3size": { + "type": "float" + } + } + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "golang": { + "properties": { + "goroutines": { + "type": "long" + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "active": { + "type": "float" + }, + "allocated": { + "type": "float" + }, + "frees": { + "type": "long" + }, + "idle": { + "type": "float" + }, + "mallocs": { + "type": "long" + }, + "objects": { + "type": "long" + }, + "total": { + "type": "float" + } + } + }, + "gc": { + "properties": { + "cpu_fraction": { + "type": "float" + }, + "next_gc_limit": { + "type": "float" + }, + "total_count": { + "type": "long" + }, + "total_pause": { + "properties": { + "ns": { + "type": "long" + } + } + } + } + }, + "system": { + "properties": { + "obtained": { + "type": "float" + }, + "released": { + "type": "float" + }, + "stack": { + "type": "long" + }, + "total": { + "type": "float" + } + } + } + } + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "jvm": { + "properties": { + "gc": { + "properties": { + "alloc": { + "type": "float" + }, + "count": { + "type": "long" + }, + "time": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "heap": { + "properties": { + "committed": { + "type": "float" + }, + "max": { + "type": "float" + }, + "pool": { + "properties": { + "committed": { + "type": "float" + }, + "max": { + "type": "float" + }, + "used": { + "type": "long" + } + } + }, + "used": { + "type": "float" + } + } + }, + "non_heap": { + "properties": { + "committed": { + "type": "float" + }, + "max": { + "type": "long" + }, + "used": { + "type": "float" + } + } + } + } + }, + "thread": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "env": { + "type": "keyword" + }, + "hostname": { + "type": "keyword" + }, + "name": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "nodejs": { + "properties": { + "eventloop": { + "properties": { + "delay": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "float" + } + } + }, + "ns": { + "type": "long" + } + } + } + } + }, + "handles": { + "properties": { + "active": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "arrayBuffers": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "external": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "heap": { + "properties": { + "allocated": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "float" + } + } + } + } + } + } + }, + "requests": { + "properties": { + "active": { + "type": "long" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ruby": { + "properties": { + "gc": { + "properties": { + "count": { + "type": "long" + } + } + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "total": { + "type": "long" + } + } + }, + "slots": { + "properties": { + "free": { + "type": "long" + }, + "live": { + "type": "long" + } + } + } + } + }, + "threads": { + "type": "long" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cgroup": { + "properties": { + "memory": { + "properties": { + "mem": { + "properties": { + "limit": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "float" + } + } + } + } + }, + "stats": { + "properties": { + "inactive_file": { + "properties": { + "bytes": { + "type": "float" + } + } + } + } + } + } + } + } + }, + "cpu": { + "properties": { + "system": { + "properties": { + "norm": { + "properties": { + "pct": { + "type": "float" + } + } + } + } + }, + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "user": { + "properties": { + "norm": { + "properties": { + "pct": { + "type": "float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "histogram": { + "type": "histogram" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "root": { + "type": "boolean" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-metric" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "1", + "priority": "100", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-metric": { + "is_write_index": true + } + }, + "index": "apm-8.0.0-metric-2020.07.31-000002", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels_string": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels_boolean": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels_*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "path": "agent.name", + "type": "alias" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "child": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "dynamic": "false", + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "clr": { + "properties": { + "gc": { + "properties": { + "count": { + "type": "long" + }, + "gen0size": { + "type": "float" + }, + "gen1size": { + "type": "float" + }, + "gen2size": { + "type": "float" + }, + "gen3size": { + "type": "float" + } + } + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "golang": { + "properties": { + "goroutines": { + "type": "long" + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "active": { + "type": "float" + }, + "allocated": { + "type": "float" + }, + "frees": { + "type": "float" + }, + "idle": { + "type": "float" + }, + "mallocs": { + "type": "float" + }, + "objects": { + "type": "long" + }, + "total": { + "type": "float" + } + } + }, + "gc": { + "properties": { + "cpu_fraction": { + "type": "float" + }, + "next_gc_limit": { + "type": "float" + }, + "total_count": { + "type": "long" + }, + "total_pause": { + "properties": { + "ns": { + "type": "float" + } + } + } + } + }, + "system": { + "properties": { + "obtained": { + "type": "float" + }, + "released": { + "type": "float" + }, + "stack": { + "type": "long" + }, + "total": { + "type": "float" + } + } + } + } + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "jvm": { + "properties": { + "gc": { + "properties": { + "alloc": { + "type": "float" + }, + "count": { + "type": "long" + }, + "time": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "heap": { + "properties": { + "committed": { + "type": "float" + }, + "max": { + "type": "float" + }, + "pool": { + "properties": { + "committed": { + "type": "float" + }, + "max": { + "type": "float" + }, + "used": { + "type": "float" + } + } + }, + "used": { + "type": "float" + } + } + }, + "non_heap": { + "properties": { + "committed": { + "type": "float" + }, + "max": { + "type": "long" + }, + "used": { + "type": "float" + } + } + } + } + }, + "thread": { + "properties": { + "count": { + "type": "long" + } + } + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "env": { + "type": "keyword" + }, + "hostname": { + "type": "keyword" + }, + "name": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "nodejs": { + "properties": { + "eventloop": { + "properties": { + "delay": { + "properties": { + "avg": { + "properties": { + "ms": { + "type": "float" + } + } + }, + "ns": { + "type": "long" + } + } + } + } + }, + "handles": { + "properties": { + "active": { + "type": "long" + } + } + }, + "memory": { + "properties": { + "arrayBuffers": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "external": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "heap": { + "properties": { + "allocated": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "used": { + "properties": { + "bytes": { + "type": "float" + } + } + } + } + } + } + }, + "requests": { + "properties": { + "active": { + "type": "long" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ruby": { + "properties": { + "gc": { + "properties": { + "count": { + "type": "long" + } + } + }, + "heap": { + "properties": { + "allocations": { + "properties": { + "total": { + "type": "float" + } + } + }, + "slots": { + "properties": { + "free": { + "type": "long" + }, + "live": { + "type": "long" + } + } + } + } + }, + "threads": { + "type": "long" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cgroup": { + "properties": { + "memory": { + "properties": { + "mem": { + "properties": { + "limit": { + "properties": { + "bytes": { + "type": "float" + } + } + }, + "usage": { + "properties": { + "bytes": { + "type": "float" + } + } + } + } + }, + "stats": { + "properties": { + "inactive_file": { + "properties": { + "bytes": { + "type": "float" + } + } + } + } + } + } + } + } + }, + "cpu": { + "properties": { + "system": { + "properties": { + "norm": { + "properties": { + "pct": { + "type": "float" + } + } + } + } + }, + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + }, + "user": { + "properties": { + "norm": { + "properties": { + "pct": { + "type": "float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "histogram": { + "type": "histogram" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "root": { + "type": "boolean" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "codec": "best_compression", + "lifecycle": { + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-metric" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "1", + "priority": "100", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-span": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-span-000001", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "foo": { + "type": "keyword" + }, + "productId": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "false", + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-span" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "0", + "number_of_shards": "1", + "priority": "50", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-span": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-span-000002", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "foo": { + "type": "keyword" + }, + "productId": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "false", + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-span" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "0", + "number_of_shards": "1", + "priority": "50", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-span": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-span-2020.07.31-000001", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels_string": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels_boolean": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels_*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "path": "agent.name", + "type": "alias" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "child": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "dynamic": "false", + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "foo": { + "type": "keyword" + }, + "productId": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "histogram": { + "type": "histogram" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "root": { + "type": "boolean" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-span" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "1", + "priority": "100", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-span": { + "is_write_index": true + } + }, + "index": "apm-8.0.0-span-2020.07.31-000002", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels_string": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels_boolean": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels_*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "path": "agent.name", + "type": "alias" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "child": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "dynamic": "false", + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "foo": { + "type": "keyword" + }, + "productId": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "histogram": { + "type": "histogram" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "root": { + "type": "boolean" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "codec": "best_compression", + "lifecycle": { + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-span" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "1", + "priority": "100", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-transaction": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-transaction-000001", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "company": { + "type": "keyword" + }, + "customer_email": { + "type": "keyword" + }, + "customer_name": { + "type": "keyword" + }, + "foo": { + "type": "keyword" + }, + "lorem": { + "type": "keyword" + }, + "multi-line": { + "type": "keyword" + }, + "served_from_cache": { + "type": "keyword" + }, + "this-is-a-very-long-tag-name-without-any-spaces": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + }, + "agent": { + "properties": { + "domComplete": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domInteractive": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "firstContentfulPaint": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "largestContentfulPaint": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "timeToFirstByte": { + "scaling_factor": 1000000, + "type": "scaled_float" + } + } + }, + "navigationTiming": { + "properties": { + "connectEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "connectStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domComplete": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domContentLoadedEventEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domContentLoadedEventStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domInteractive": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domLoading": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domainLookupEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domainLookupStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "fetchStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "loadEventEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "loadEventStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "requestStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "responseEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "responseStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "false", + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-transaction" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "0", + "number_of_shards": "1", + "priority": "50", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-transaction": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-transaction-000002", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "company": { + "type": "keyword" + }, + "customer_email": { + "type": "keyword" + }, + "customer_name": { + "type": "keyword" + }, + "customer_tier": { + "type": "keyword" + }, + "foo": { + "type": "keyword" + }, + "lorem": { + "type": "keyword" + }, + "multi-line": { + "type": "keyword" + }, + "request_id": { + "type": "keyword" + }, + "served_from_cache": { + "type": "keyword" + }, + "this-is-a-very-long-tag-name-without-any-spaces": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + }, + "agent": { + "properties": { + "domComplete": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domInteractive": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "firstContentfulPaint": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "largestContentfulPaint": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "timeToFirstByte": { + "scaling_factor": 1000000, + "type": "scaled_float" + } + } + }, + "navigationTiming": { + "properties": { + "connectEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "connectStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domComplete": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domContentLoadedEventEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domContentLoadedEventStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domInteractive": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domLoading": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domainLookupEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domainLookupStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "fetchStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "loadEventEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "loadEventStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "requestStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "responseEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "responseStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "false", + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-transaction" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "0", + "number_of_shards": "1", + "priority": "50", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-transaction": { + "is_write_index": false + } + }, + "index": "apm-8.0.0-transaction-2020.07.31-000001", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels_string": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels_boolean": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels_*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "path": "agent.name", + "type": "alias" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "child": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "dynamic": "false", + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "company": { + "type": "keyword" + }, + "customer_email": { + "type": "keyword" + }, + "customer_name": { + "type": "keyword" + }, + "customer_tier": { + "type": "keyword" + }, + "foo": { + "type": "keyword" + }, + "lorem": { + "type": "keyword" + }, + "multi-line": { + "type": "keyword" + }, + "request_id": { + "type": "keyword" + }, + "served_from_cache": { + "type": "keyword" + }, + "this-is-a-very-long-tag-name-without-any-spaces": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "histogram": { + "type": "histogram" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + }, + "agent": { + "properties": { + "domComplete": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domInteractive": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "timeToFirstByte": { + "scaling_factor": 1000000, + "type": "scaled_float" + } + } + }, + "navigationTiming": { + "properties": { + "connectEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "connectStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domComplete": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domContentLoadedEventEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domContentLoadedEventStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domInteractive": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domLoading": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domainLookupEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domainLookupStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "fetchStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "loadEventEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "loadEventStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "requestStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "responseEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "responseStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "root": { + "type": "boolean" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "codec": "best_compression", + "lifecycle": { + "indexing_complete": "true", + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-transaction" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "1", + "priority": "100", + "refresh_interval": "5s" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "apm-8.0.0-transaction": { + "is_write_index": true + } + }, + "index": "apm-8.0.0-transaction-2020.07.31-000002", + "mappings": { + "_meta": { + "beat": "apm", + "version": "8.0.0" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "network.inner": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "network.inner.*" + } + }, + { + "observer.egress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.egress.*" + } + }, + { + "observer.ingress": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "observer.ingress.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "labels_string": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "labels_boolean": { + "mapping": { + "type": "boolean" + }, + "match_mapping_type": "boolean", + "path_match": "labels.*" + } + }, + { + "labels_*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "labels.*" + } + }, + { + "transaction.marks": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "transaction.marks.*" + } + }, + { + "transaction.marks.*.*": { + "mapping": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "path_match": "transaction.marks.*.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "dynamic": "false", + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "path": "agent.name", + "type": "alias" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "child": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "dynamic": "false", + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "container": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "dynamic": "false", + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "culprit": { + "ignore_above": 1024, + "type": "keyword" + }, + "exception": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "handled": { + "type": "boolean" + }, + "message": { + "norms": false, + "type": "text" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "grouping_key": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "param_message": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "experimental": { + "dynamic": "true", + "type": "object" + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "dynamic": "false", + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "dynamic": "false", + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "finished": { + "type": "boolean" + }, + "headers": { + "enabled": false, + "type": "object" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "dynamic": "false", + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "dynamic": "true", + "properties": { + "company": { + "type": "keyword" + }, + "customer_email": { + "type": "keyword" + }, + "customer_name": { + "type": "keyword" + }, + "customer_tier": { + "type": "keyword" + }, + "foo": { + "type": "keyword" + }, + "lorem": { + "type": "keyword" + }, + "multi-line": { + "type": "keyword" + }, + "request_id": { + "type": "keyword" + }, + "served_from_cache": { + "type": "keyword" + }, + "this-is-a-very-long-tag-name-without-any-spaces": { + "type": "keyword" + } + } + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "dynamic": "false", + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "listening": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_major": { + "type": "byte" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "parent": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "dynamic": "false", + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "exists": { + "type": "boolean" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "processor": { + "properties": { + "event": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "profile": { + "dynamic": "false", + "properties": { + "alloc_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "alloc_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "cpu": { + "properties": { + "ns": { + "type": "long" + } + } + }, + "duration": { + "type": "long" + }, + "inuse_objects": { + "properties": { + "count": { + "type": "long" + } + } + }, + "inuse_space": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "samples": { + "properties": { + "count": { + "type": "long" + } + } + }, + "stack": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + }, + "top": { + "dynamic": "false", + "properties": { + "filename": { + "ignore_above": 1024, + "type": "keyword" + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "line": { + "type": "long" + } + } + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "dynamic": "false", + "properties": { + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "framework": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "language": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "runtime": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "dynamic": "false", + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "sourcemap": { + "dynamic": "false", + "properties": { + "bundle_filepath": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "dynamic": "false", + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "db": { + "dynamic": "false", + "properties": { + "link": { + "ignore_above": 1024, + "type": "keyword" + }, + "rows_affected": { + "type": "long" + } + } + }, + "destination": { + "dynamic": "false", + "properties": { + "service": { + "dynamic": "false", + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "start": { + "properties": { + "us": { + "type": "long" + } + } + }, + "subtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "sync": { + "type": "boolean" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "system": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "actual": { + "properties": { + "free": { + "type": "long" + } + } + }, + "total": { + "type": "long" + } + } + }, + "process": { + "properties": { + "cpu": { + "properties": { + "total": { + "properties": { + "norm": { + "properties": { + "pct": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + } + } + } + } + }, + "memory": { + "properties": { + "rss": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "size": { + "type": "long" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timestamp": { + "properties": { + "us": { + "type": "long" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "dynamic": "false", + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "transaction": { + "dynamic": "false", + "properties": { + "breakdown": { + "properties": { + "count": { + "type": "long" + } + } + }, + "duration": { + "properties": { + "count": { + "type": "long" + }, + "histogram": { + "type": "histogram" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + }, + "us": { + "type": "long" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "marks": { + "dynamic": "true", + "properties": { + "*": { + "properties": { + "*": { + "dynamic": "true", + "type": "object" + } + } + }, + "agent": { + "properties": { + "domComplete": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domInteractive": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "firstContentfulPaint": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "largestContentfulPaint": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "timeToFirstByte": { + "scaling_factor": 1000000, + "type": "scaled_float" + } + } + }, + "navigationTiming": { + "properties": { + "connectEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "connectStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domComplete": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domContentLoadedEventEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domContentLoadedEventStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domInteractive": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domLoading": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domainLookupEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "domainLookupStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "fetchStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "loadEventEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "loadEventStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "requestStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "responseEnd": { + "scaling_factor": 1000000, + "type": "scaled_float" + }, + "responseStart": { + "scaling_factor": 1000000, + "type": "scaled_float" + } + } + } + } + }, + "message": { + "dynamic": "false", + "properties": { + "age": { + "properties": { + "ms": { + "type": "long" + } + } + }, + "queue": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "root": { + "type": "boolean" + }, + "sampled": { + "type": "boolean" + }, + "self_time": { + "properties": { + "count": { + "type": "long" + }, + "sum": { + "properties": { + "us": { + "type": "long" + } + } + } + } + }, + "span_count": { + "properties": { + "dropped": { + "type": "long" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "dynamic": "false", + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "dynamic": "false", + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "view spans": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "codec": "best_compression", + "lifecycle": { + "name": "apm-rollover-30-days", + "rollover_alias": "apm-8.0.0-transaction" + }, + "mapping": { + "total_fields": { + "limit": "2000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "1", + "priority": "100", + "refresh_interval": "5s" + } + } + } +} \ No newline at end of file diff --git a/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/ml_8.0.0/data.json.gz b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/ml_8.0.0/data.json.gz similarity index 100% rename from x-pack/test/apm_api_integration/trial/fixtures/es_archiver/ml_8.0.0/data.json.gz rename to x-pack/test/apm_api_integration/common/fixtures/es_archiver/ml_8.0.0/data.json.gz diff --git a/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/ml_8.0.0/mappings.json b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/ml_8.0.0/mappings.json similarity index 100% rename from x-pack/test/apm_api_integration/trial/fixtures/es_archiver/ml_8.0.0/mappings.json rename to x-pack/test/apm_api_integration/common/fixtures/es_archiver/ml_8.0.0/mappings.json diff --git a/x-pack/test/apm_api_integration/basic/fixtures/es_archiver/observability_overview/data.json.gz b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/observability_overview/data.json.gz similarity index 100% rename from x-pack/test/apm_api_integration/basic/fixtures/es_archiver/observability_overview/data.json.gz rename to x-pack/test/apm_api_integration/common/fixtures/es_archiver/observability_overview/data.json.gz diff --git a/x-pack/test/apm_api_integration/basic/fixtures/es_archiver/observability_overview/mappings.json b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/observability_overview/mappings.json similarity index 100% rename from x-pack/test/apm_api_integration/basic/fixtures/es_archiver/observability_overview/mappings.json rename to x-pack/test/apm_api_integration/common/fixtures/es_archiver/observability_overview/mappings.json diff --git a/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/rum_8.0.0/data.json.gz b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/rum_8.0.0/data.json.gz similarity index 100% rename from x-pack/test/apm_api_integration/trial/fixtures/es_archiver/rum_8.0.0/data.json.gz rename to x-pack/test/apm_api_integration/common/fixtures/es_archiver/rum_8.0.0/data.json.gz diff --git a/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/rum_8.0.0/mappings.json b/x-pack/test/apm_api_integration/common/fixtures/es_archiver/rum_8.0.0/mappings.json similarity index 100% rename from x-pack/test/apm_api_integration/trial/fixtures/es_archiver/rum_8.0.0/mappings.json rename to x-pack/test/apm_api_integration/common/fixtures/es_archiver/rum_8.0.0/mappings.json diff --git a/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/8.0.0/data.json.gz b/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/8.0.0/data.json.gz deleted file mode 100644 index e9360878b7bb7..0000000000000 Binary files a/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/8.0.0/data.json.gz and /dev/null differ diff --git a/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/8.0.0/mappings.json b/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/8.0.0/mappings.json deleted file mode 100644 index 5e9f9f52be8d3..0000000000000 --- a/x-pack/test/apm_api_integration/trial/fixtures/es_archiver/8.0.0/mappings.json +++ /dev/null @@ -1,25698 +0,0 @@ -{ - "type": "index", - "value": { - "aliases": { - "apm-8.0.0-error": { - "is_write_index": true - } - }, - "index": "apm-8.0.0-error-000001", - "mappings": { - "_meta": { - "beat": "apm", - "version": "8.0.0" - }, - "date_detection": false, - "dynamic_templates": [ - { - "labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "container.labels.*" - } - }, - { - "dns.answers": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "dns.answers.*" - } - }, - { - "log.syslog": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "log.syslog.*" - } - }, - { - "network.inner": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "network.inner.*" - } - }, - { - "observer.egress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.egress.*" - } - }, - { - "observer.ingress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.ingress.*" - } - }, - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "kubernetes.labels.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.labels.*" - } - }, - { - "kubernetes.annotations.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.annotations.*" - } - }, - { - "labels_string": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "labels_boolean": { - "mapping": { - "type": "boolean" - }, - "match_mapping_type": "boolean", - "path_match": "labels.*" - } - }, - { - "labels_*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "labels.*" - } - }, - { - "transaction.marks": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "transaction.marks.*" - } - }, - { - "transaction.marks.*.*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "transaction.marks.*.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } - } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "agent": { - "dynamic": "false", - "properties": { - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "path": "agent.name", - "type": "alias" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "child": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "client": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "cloud": { - "properties": { - "account": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "instance": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "machine": { - "dynamic": "false", - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "project": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "container": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "tag": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "runtime": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "destination": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dll": { - "properties": { - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dns": { - "properties": { - "answers": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "data": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "ttl": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "header_flags": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "op_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "question": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "subdomain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "resolved_ip": { - "type": "ip" - }, - "response_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "docker": { - "properties": { - "container": { - "properties": { - "labels": { - "type": "object" - } - } - } - } - }, - "ecs": { - "properties": { - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "dynamic": "false", - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "culprit": { - "ignore_above": 1024, - "type": "keyword" - }, - "exception": { - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "handled": { - "type": "boolean" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "grouping_key": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "param_message": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "stack_trace": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "event": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "long" - }, - "end": { - "type": "date" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingested": { - "type": "date" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "outcome": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "risk_score": { - "type": "float" - }, - "risk_score_norm": { - "type": "float" - }, - "sequence": { - "type": "long" - }, - "severity": { - "type": "long" - }, - "start": { - "type": "date" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "experimental": { - "dynamic": "true", - "type": "object" - }, - "fields": { - "type": "object" - }, - "file": { - "properties": { - "accessed": { - "type": "date" - }, - "attributes": { - "ignore_above": 1024, - "type": "keyword" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "created": { - "type": "date" - }, - "ctime": { - "type": "date" - }, - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "directory": { - "ignore_above": 1024, - "type": "keyword" - }, - "drive_letter": { - "ignore_above": 1, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "gid": { - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "inode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mime_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mtime": { - "type": "date" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "owner": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "size": { - "type": "long" - }, - "target_path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "host": { - "dynamic": "false", - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "containerized": { - "type": "boolean" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "build": { - "ignore_above": 1024, - "type": "keyword" - }, - "codename": { - "ignore_above": 1024, - "type": "keyword" - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "http": { - "dynamic": "false", - "properties": { - "request": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "response": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "finished": { - "type": "boolean" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "status_code": { - "type": "long" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "kubernetes": { - "dynamic": "false", - "properties": { - "annotations": { - "properties": { - "*": { - "type": "object" - } - } - }, - "container": { - "properties": { - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "deployment": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "properties": { - "*": { - "type": "object" - } - } - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pod": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "replicaset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "statefulset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "labels": { - "dynamic": "true", - "properties": { - "foo": { - "type": "keyword" - }, - "lorem": { - "type": "keyword" - }, - "multi-line": { - "type": "keyword" - }, - "this-is-a-very-long-tag-name-without-any-spaces": { - "type": "keyword" - } - } - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger": { - "ignore_above": 1024, - "type": "keyword" - }, - "origin": { - "properties": { - "file": { - "properties": { - "line": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "syslog": { - "properties": { - "facility": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "priority": { - "type": "long" - }, - "severity": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "network": { - "properties": { - "application": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "community_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "forwarded_ip": { - "type": "ip" - }, - "iana_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "inner": { - "properties": { - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "transport": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "observer": { - "dynamic": "false", - "properties": { - "egress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "listening": { - "ignore_above": 1024, - "type": "keyword" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vendor": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_major": { - "type": "byte" - } - } - }, - "organization": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "package": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "build_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "checksum": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "install_scope": { - "ignore_above": 1024, - "type": "keyword" - }, - "installed": { - "type": "date" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "parent": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "process": { - "dynamic": "false", - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "parent": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "processor": { - "properties": { - "event": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "profile": { - "dynamic": "false", - "properties": { - "alloc_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "alloc_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "cpu": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "duration": { - "type": "long" - }, - "inuse_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "inuse_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "samples": { - "properties": { - "count": { - "type": "long" - } - } - }, - "stack": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - }, - "top": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - } - } - }, - "registry": { - "properties": { - "data": { - "properties": { - "bytes": { - "ignore_above": 1024, - "type": "keyword" - }, - "strings": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hive": { - "ignore_above": 1024, - "type": "keyword" - }, - "key": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "related": { - "properties": { - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "rule": { - "properties": { - "author": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "ruleset": { - "ignore_above": 1024, - "type": "keyword" - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "service": { - "dynamic": "false", - "properties": { - "environment": { - "ignore_above": 1024, - "type": "keyword" - }, - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "framework": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "language": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "runtime": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "source": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "sourcemap": { - "dynamic": "false", - "properties": { - "bundle_filepath": { - "ignore_above": 1024, - "type": "keyword" - }, - "service": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "span": { - "dynamic": "false", - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "db": { - "dynamic": "false", - "properties": { - "link": { - "ignore_above": 1024, - "type": "keyword" - }, - "rows_affected": { - "type": "long" - } - } - }, - "destination": { - "dynamic": "false", - "properties": { - "service": { - "dynamic": "false", - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "duration": { - "properties": { - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "start": { - "properties": { - "us": { - "type": "long" - } - } - }, - "subtype": { - "ignore_above": 1024, - "type": "keyword" - }, - "sync": { - "type": "boolean" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "system": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "actual": { - "properties": { - "free": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "process": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "rss": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "size": { - "type": "long" - } - } - } - } - } - } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "threat": { - "properties": { - "framework": { - "ignore_above": 1024, - "type": "keyword" - }, - "tactic": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "technique": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "timeseries": { - "properties": { - "instance": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "properties": { - "us": { - "type": "long" - } - } - }, - "tls": { - "properties": { - "cipher": { - "ignore_above": 1024, - "type": "keyword" - }, - "client": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - }, - "supported_ciphers": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "curve": { - "ignore_above": 1024, - "type": "keyword" - }, - "established": { - "type": "boolean" - }, - "next_protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "resumed": { - "type": "boolean" - }, - "server": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3s": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_protocol": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "trace": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "tracing": { - "properties": { - "trace": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "transaction": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "transaction": { - "dynamic": "false", - "properties": { - "breakdown": { - "properties": { - "count": { - "type": "long" - } - } - }, - "duration": { - "properties": { - "count": { - "type": "long" - }, - "histogram": { - "type": "histogram" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - }, - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "marks": { - "dynamic": "true", - "properties": { - "*": { - "properties": { - "*": { - "dynamic": "true", - "type": "object" - } - } - } - } - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "result": { - "ignore_above": 1024, - "type": "keyword" - }, - "root": { - "type": "boolean" - }, - "sampled": { - "type": "boolean" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "span_count": { - "properties": { - "dropped": { - "type": "long" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "url": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "fragment": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "password": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheme": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "username": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_agent": { - "dynamic": "false", - "properties": { - "device": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "view spans": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vulnerability": { - "properties": { - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "classification": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "enumeration": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "report_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "scanner": { - "properties": { - "vendor": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "score": { - "properties": { - "base": { - "type": "float" - }, - "environmental": { - "type": "float" - }, - "temporal": { - "type": "float" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "settings": { - "index": { - "codec": "best_compression", - "lifecycle": { - "name": "apm-rollover-30-days", - "rollover_alias": "apm-8.0.0-error" - }, - "mapping": { - "total_fields": { - "limit": "2000" - } - }, - "number_of_replicas": "0", - "number_of_shards": "1", - "priority": "100", - "query": { - "default_field": [ - "message", - "tags", - "agent.ephemeral_id", - "agent.id", - "agent.name", - "agent.type", - "agent.version", - "as.organization.name", - "client.address", - "client.as.organization.name", - "client.domain", - "client.geo.city_name", - "client.geo.continent_name", - "client.geo.country_iso_code", - "client.geo.country_name", - "client.geo.name", - "client.geo.region_iso_code", - "client.geo.region_name", - "client.mac", - "client.registered_domain", - "client.top_level_domain", - "client.user.domain", - "client.user.email", - "client.user.full_name", - "client.user.group.domain", - "client.user.group.id", - "client.user.group.name", - "client.user.hash", - "client.user.id", - "client.user.name", - "cloud.account.id", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.provider", - "cloud.region", - "container.id", - "container.image.name", - "container.image.tag", - "container.name", - "container.runtime", - "destination.address", - "destination.as.organization.name", - "destination.domain", - "destination.geo.city_name", - "destination.geo.continent_name", - "destination.geo.country_iso_code", - "destination.geo.country_name", - "destination.geo.name", - "destination.geo.region_iso_code", - "destination.geo.region_name", - "destination.mac", - "destination.registered_domain", - "destination.top_level_domain", - "destination.user.domain", - "destination.user.email", - "destination.user.full_name", - "destination.user.group.domain", - "destination.user.group.id", - "destination.user.group.name", - "destination.user.hash", - "destination.user.id", - "destination.user.name", - "dns.answers.class", - "dns.answers.data", - "dns.answers.name", - "dns.answers.type", - "dns.header_flags", - "dns.id", - "dns.op_code", - "dns.question.class", - "dns.question.name", - "dns.question.registered_domain", - "dns.question.subdomain", - "dns.question.top_level_domain", - "dns.question.type", - "dns.response_code", - "dns.type", - "ecs.version", - "error.code", - "error.id", - "error.message", - "error.stack_trace", - "error.type", - "event.action", - "event.category", - "event.code", - "event.dataset", - "event.hash", - "event.id", - "event.kind", - "event.module", - "event.original", - "event.outcome", - "event.provider", - "event.timezone", - "event.type", - "file.device", - "file.directory", - "file.extension", - "file.gid", - "file.group", - "file.hash.md5", - "file.hash.sha1", - "file.hash.sha256", - "file.hash.sha512", - "file.inode", - "file.mode", - "file.name", - "file.owner", - "file.path", - "file.target_path", - "file.type", - "file.uid", - "geo.city_name", - "geo.continent_name", - "geo.country_iso_code", - "geo.country_name", - "geo.name", - "geo.region_iso_code", - "geo.region_name", - "group.domain", - "group.id", - "group.name", - "hash.md5", - "hash.sha1", - "hash.sha256", - "hash.sha512", - "host.architecture", - "host.geo.city_name", - "host.geo.continent_name", - "host.geo.country_iso_code", - "host.geo.country_name", - "host.geo.name", - "host.geo.region_iso_code", - "host.geo.region_name", - "host.hostname", - "host.id", - "host.mac", - "host.name", - "host.os.family", - "host.os.full", - "host.os.kernel", - "host.os.name", - "host.os.platform", - "host.os.version", - "host.type", - "host.user.domain", - "host.user.email", - "host.user.full_name", - "host.user.group.domain", - "host.user.group.id", - "host.user.group.name", - "host.user.hash", - "host.user.id", - "host.user.name", - "http.request.body.content", - "http.request.method", - "http.request.referrer", - "http.response.body.content", - "http.version", - "log.level", - "log.logger", - "log.origin.file.name", - "log.origin.function", - "log.original", - "log.syslog.facility.name", - "log.syslog.severity.name", - "network.application", - "network.community_id", - "network.direction", - "network.iana_number", - "network.name", - "network.protocol", - "network.transport", - "network.type", - "observer.geo.city_name", - "observer.geo.continent_name", - "observer.geo.country_iso_code", - "observer.geo.country_name", - "observer.geo.name", - "observer.geo.region_iso_code", - "observer.geo.region_name", - "observer.hostname", - "observer.mac", - "observer.name", - "observer.os.family", - "observer.os.full", - "observer.os.kernel", - "observer.os.name", - "observer.os.platform", - "observer.os.version", - "observer.product", - "observer.serial_number", - "observer.type", - "observer.vendor", - "observer.version", - "organization.id", - "organization.name", - "os.family", - "os.full", - "os.kernel", - "os.name", - "os.platform", - "os.version", - "package.architecture", - "package.checksum", - "package.description", - "package.install_scope", - "package.license", - "package.name", - "package.path", - "package.version", - "process.args", - "text", - "process.executable", - "process.hash.md5", - "process.hash.sha1", - "process.hash.sha256", - "process.hash.sha512", - "process.name", - "text", - "text", - "text", - "text", - "text", - "process.thread.name", - "process.title", - "process.working_directory", - "server.address", - "server.as.organization.name", - "server.domain", - "server.geo.city_name", - "server.geo.continent_name", - "server.geo.country_iso_code", - "server.geo.country_name", - "server.geo.name", - "server.geo.region_iso_code", - "server.geo.region_name", - "server.mac", - "server.registered_domain", - "server.top_level_domain", - "server.user.domain", - "server.user.email", - "server.user.full_name", - "server.user.group.domain", - "server.user.group.id", - "server.user.group.name", - "server.user.hash", - "server.user.id", - "server.user.name", - "service.ephemeral_id", - "service.id", - "service.name", - "service.node.name", - "service.state", - "service.type", - "service.version", - "source.address", - "source.as.organization.name", - "source.domain", - "source.geo.city_name", - "source.geo.continent_name", - "source.geo.country_iso_code", - "source.geo.country_name", - "source.geo.name", - "source.geo.region_iso_code", - "source.geo.region_name", - "source.mac", - "source.registered_domain", - "source.top_level_domain", - "source.user.domain", - "source.user.email", - "source.user.full_name", - "source.user.group.domain", - "source.user.group.id", - "source.user.group.name", - "source.user.hash", - "source.user.id", - "source.user.name", - "threat.framework", - "threat.tactic.id", - "threat.tactic.name", - "threat.tactic.reference", - "threat.technique.id", - "threat.technique.name", - "threat.technique.reference", - "tracing.trace.id", - "tracing.transaction.id", - "url.domain", - "url.extension", - "url.fragment", - "url.full", - "url.original", - "url.password", - "url.path", - "url.query", - "url.registered_domain", - "url.scheme", - "url.top_level_domain", - "url.username", - "user.domain", - "user.email", - "user.full_name", - "user.group.domain", - "user.group.id", - "user.group.name", - "user.hash", - "user.id", - "user.name", - "user_agent.device.name", - "user_agent.name", - "text", - "user_agent.original", - "user_agent.os.family", - "user_agent.os.full", - "user_agent.os.kernel", - "user_agent.os.name", - "user_agent.os.platform", - "user_agent.os.version", - "user_agent.version", - "text", - "timeseries.instance", - "cloud.project.id", - "cloud.image.id", - "host.os.build", - "host.os.codename", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.replicaset.name", - "kubernetes.deployment.name", - "kubernetes.statefulset.name", - "kubernetes.container.name", - "kubernetes.container.image", - "processor.name", - "processor.event", - "url.scheme", - "url.full", - "url.domain", - "url.path", - "url.query", - "url.fragment", - "http.version", - "http.request.method", - "http.request.referrer", - "service.name", - "service.version", - "service.environment", - "service.node.name", - "service.language.name", - "service.language.version", - "service.runtime.name", - "service.runtime.version", - "service.framework.name", - "service.framework.version", - "transaction.id", - "transaction.type", - "text", - "transaction.name", - "span.type", - "span.subtype", - "trace.id", - "parent.id", - "agent.name", - "agent.version", - "agent.ephemeral_id", - "container.id", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "host.architecture", - "host.hostname", - "host.name", - "host.os.platform", - "process.args", - "process.title", - "observer.listening", - "observer.hostname", - "observer.version", - "observer.type", - "user.name", - "user.id", - "user.email", - "destination.address", - "text", - "user_agent.original", - "user_agent.name", - "user_agent.version", - "user_agent.device.name", - "user_agent.os.platform", - "user_agent.os.name", - "user_agent.os.full", - "user_agent.os.family", - "user_agent.os.version", - "user_agent.os.kernel", - "cloud.account.id", - "cloud.account.name", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.project.id", - "cloud.project.name", - "cloud.provider", - "cloud.region", - "error.id", - "error.culprit", - "error.grouping_key", - "error.exception.code", - "error.exception.message", - "error.exception.module", - "error.exception.type", - "error.log.level", - "error.log.logger_name", - "error.log.message", - "error.log.param_message", - "profile.top.id", - "profile.top.function", - "profile.top.filename", - "profile.stack.id", - "profile.stack.function", - "profile.stack.filename", - "sourcemap.service.name", - "sourcemap.service.version", - "sourcemap.bundle_filepath", - "view spans", - "child.id", - "span.id", - "span.name", - "span.action", - "span.db.link", - "span.destination.service.type", - "span.destination.service.name", - "span.destination.service.resource", - "span.message.queue.name", - "transaction.result", - "transaction.message.queue.name", - "fields.*" - ] - }, - "refresh_interval": "1ms" - } - } - } -} - -{ - "type": "index", - "value": { - "aliases": { - "apm-8.0.0-metric": { - "is_write_index": true - } - }, - "index": "apm-8.0.0-metric-000001", - "mappings": { - "_meta": { - "beat": "apm", - "version": "8.0.0" - }, - "date_detection": false, - "dynamic_templates": [ - { - "labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "container.labels.*" - } - }, - { - "dns.answers": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "dns.answers.*" - } - }, - { - "log.syslog": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "log.syslog.*" - } - }, - { - "network.inner": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "network.inner.*" - } - }, - { - "observer.egress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.egress.*" - } - }, - { - "observer.ingress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.ingress.*" - } - }, - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "kubernetes.labels.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.labels.*" - } - }, - { - "kubernetes.annotations.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.annotations.*" - } - }, - { - "labels_string": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "labels_boolean": { - "mapping": { - "type": "boolean" - }, - "match_mapping_type": "boolean", - "path_match": "labels.*" - } - }, - { - "labels_*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "labels.*" - } - }, - { - "transaction.marks": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "transaction.marks.*" - } - }, - { - "transaction.marks.*.*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "transaction.marks.*.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } - } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "agent": { - "dynamic": "false", - "properties": { - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "path": "agent.name", - "type": "alias" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "child": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "client": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "cloud": { - "properties": { - "account": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "instance": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "machine": { - "dynamic": "false", - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "project": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "container": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "tag": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "runtime": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "destination": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dll": { - "properties": { - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dns": { - "properties": { - "answers": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "data": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "ttl": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "header_flags": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "op_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "question": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "subdomain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "resolved_ip": { - "type": "ip" - }, - "response_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "docker": { - "properties": { - "container": { - "properties": { - "labels": { - "type": "object" - } - } - } - } - }, - "ecs": { - "properties": { - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "dynamic": "false", - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "culprit": { - "ignore_above": 1024, - "type": "keyword" - }, - "exception": { - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "handled": { - "type": "boolean" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "grouping_key": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "param_message": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "stack_trace": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "event": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "long" - }, - "end": { - "type": "date" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingested": { - "type": "date" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "outcome": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "risk_score": { - "type": "float" - }, - "risk_score_norm": { - "type": "float" - }, - "sequence": { - "type": "long" - }, - "severity": { - "type": "long" - }, - "start": { - "type": "date" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "experimental": { - "dynamic": "true", - "type": "object" - }, - "fields": { - "type": "object" - }, - "file": { - "properties": { - "accessed": { - "type": "date" - }, - "attributes": { - "ignore_above": 1024, - "type": "keyword" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "created": { - "type": "date" - }, - "ctime": { - "type": "date" - }, - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "directory": { - "ignore_above": 1024, - "type": "keyword" - }, - "drive_letter": { - "ignore_above": 1, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "gid": { - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "inode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mime_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mtime": { - "type": "date" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "owner": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "size": { - "type": "long" - }, - "target_path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "host": { - "dynamic": "false", - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "containerized": { - "type": "boolean" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "build": { - "ignore_above": 1024, - "type": "keyword" - }, - "codename": { - "ignore_above": 1024, - "type": "keyword" - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "http": { - "dynamic": "false", - "properties": { - "request": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "response": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "finished": { - "type": "boolean" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "status_code": { - "type": "long" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "jvm": { - "properties": { - "gc": { - "properties": { - "alloc": { - "type": "float" - }, - "count": { - "type": "long" - }, - "time": { - "type": "long" - } - } - }, - "memory": { - "properties": { - "heap": { - "properties": { - "committed": { - "type": "float" - }, - "max": { - "type": "float" - }, - "used": { - "type": "float" - } - } - }, - "non_heap": { - "properties": { - "committed": { - "type": "float" - }, - "max": { - "type": "long" - }, - "used": { - "type": "float" - } - } - } - } - }, - "thread": { - "properties": { - "count": { - "type": "long" - } - } - } - } - }, - "kubernetes": { - "dynamic": "false", - "properties": { - "annotations": { - "properties": { - "*": { - "type": "object" - } - } - }, - "container": { - "properties": { - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "deployment": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "properties": { - "*": { - "type": "object" - } - } - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pod": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "replicaset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "statefulset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "labels": { - "dynamic": "true", - "properties": { - "env": { - "type": "keyword" - }, - "hostname": { - "type": "keyword" - }, - "name": { - "type": "keyword" - } - } - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger": { - "ignore_above": 1024, - "type": "keyword" - }, - "origin": { - "properties": { - "file": { - "properties": { - "line": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "syslog": { - "properties": { - "facility": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "priority": { - "type": "long" - }, - "severity": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "network": { - "properties": { - "application": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "community_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "forwarded_ip": { - "type": "ip" - }, - "iana_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "inner": { - "properties": { - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "transport": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "nodejs": { - "properties": { - "eventloop": { - "properties": { - "delay": { - "properties": { - "avg": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "ns": { - "type": "long" - } - } - } - } - }, - "handles": { - "properties": { - "active": { - "type": "long" - } - } - }, - "memory": { - "properties": { - "arrayBuffers": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "external": { - "properties": { - "bytes": { - "type": "float" - } - } - }, - "heap": { - "properties": { - "allocated": { - "properties": { - "bytes": { - "type": "float" - } - } - }, - "used": { - "properties": { - "bytes": { - "type": "float" - } - } - } - } - } - } - }, - "requests": { - "properties": { - "active": { - "type": "long" - } - } - } - } - }, - "observer": { - "dynamic": "false", - "properties": { - "egress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "listening": { - "ignore_above": 1024, - "type": "keyword" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vendor": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_major": { - "type": "byte" - } - } - }, - "organization": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "package": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "build_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "checksum": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "install_scope": { - "ignore_above": 1024, - "type": "keyword" - }, - "installed": { - "type": "date" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "parent": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "process": { - "dynamic": "false", - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "parent": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "processor": { - "properties": { - "event": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "profile": { - "dynamic": "false", - "properties": { - "alloc_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "alloc_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "cpu": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "duration": { - "type": "long" - }, - "inuse_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "inuse_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "samples": { - "properties": { - "count": { - "type": "long" - } - } - }, - "stack": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - }, - "top": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - } - } - }, - "registry": { - "properties": { - "data": { - "properties": { - "bytes": { - "ignore_above": 1024, - "type": "keyword" - }, - "strings": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hive": { - "ignore_above": 1024, - "type": "keyword" - }, - "key": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "related": { - "properties": { - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "rule": { - "properties": { - "author": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "ruleset": { - "ignore_above": 1024, - "type": "keyword" - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "service": { - "dynamic": "false", - "properties": { - "environment": { - "ignore_above": 1024, - "type": "keyword" - }, - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "framework": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "language": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "runtime": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "source": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "sourcemap": { - "dynamic": "false", - "properties": { - "bundle_filepath": { - "ignore_above": 1024, - "type": "keyword" - }, - "service": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "span": { - "dynamic": "false", - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "db": { - "dynamic": "false", - "properties": { - "link": { - "ignore_above": 1024, - "type": "keyword" - }, - "rows_affected": { - "type": "long" - } - } - }, - "destination": { - "dynamic": "false", - "properties": { - "service": { - "dynamic": "false", - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "duration": { - "properties": { - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "start": { - "properties": { - "us": { - "type": "long" - } - } - }, - "subtype": { - "ignore_above": 1024, - "type": "keyword" - }, - "sync": { - "type": "boolean" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "system": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "actual": { - "properties": { - "free": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "process": { - "properties": { - "cpu": { - "properties": { - "system": { - "properties": { - "norm": { - "properties": { - "pct": { - "type": "float" - } - } - } - } - }, - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - }, - "user": { - "properties": { - "norm": { - "properties": { - "pct": { - "type": "float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "rss": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "size": { - "type": "long" - } - } - } - } - } - } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "threat": { - "properties": { - "framework": { - "ignore_above": 1024, - "type": "keyword" - }, - "tactic": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "technique": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "timeseries": { - "properties": { - "instance": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "properties": { - "us": { - "type": "long" - } - } - }, - "tls": { - "properties": { - "cipher": { - "ignore_above": 1024, - "type": "keyword" - }, - "client": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - }, - "supported_ciphers": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "curve": { - "ignore_above": 1024, - "type": "keyword" - }, - "established": { - "type": "boolean" - }, - "next_protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "resumed": { - "type": "boolean" - }, - "server": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3s": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_protocol": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "trace": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "tracing": { - "properties": { - "trace": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "transaction": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "transaction": { - "dynamic": "false", - "properties": { - "breakdown": { - "properties": { - "count": { - "type": "long" - } - } - }, - "duration": { - "properties": { - "count": { - "type": "long" - }, - "histogram": { - "type": "histogram" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - }, - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "marks": { - "dynamic": "true", - "properties": { - "*": { - "properties": { - "*": { - "dynamic": "true", - "type": "object" - } - } - } - } - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "result": { - "ignore_above": 1024, - "type": "keyword" - }, - "root": { - "type": "boolean" - }, - "sampled": { - "type": "boolean" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "span_count": { - "properties": { - "dropped": { - "type": "long" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "url": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "fragment": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "password": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheme": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "username": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_agent": { - "dynamic": "false", - "properties": { - "device": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "view spans": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vulnerability": { - "properties": { - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "classification": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "enumeration": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "report_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "scanner": { - "properties": { - "vendor": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "score": { - "properties": { - "base": { - "type": "float" - }, - "environmental": { - "type": "float" - }, - "temporal": { - "type": "float" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "settings": { - "index": { - "codec": "best_compression", - "lifecycle": { - "name": "apm-rollover-30-days", - "rollover_alias": "apm-8.0.0-metric" - }, - "mapping": { - "total_fields": { - "limit": "2000" - } - }, - "number_of_replicas": "0", - "number_of_shards": "1", - "priority": "100", - "query": { - "default_field": [ - "message", - "tags", - "agent.ephemeral_id", - "agent.id", - "agent.name", - "agent.type", - "agent.version", - "as.organization.name", - "client.address", - "client.as.organization.name", - "client.domain", - "client.geo.city_name", - "client.geo.continent_name", - "client.geo.country_iso_code", - "client.geo.country_name", - "client.geo.name", - "client.geo.region_iso_code", - "client.geo.region_name", - "client.mac", - "client.registered_domain", - "client.top_level_domain", - "client.user.domain", - "client.user.email", - "client.user.full_name", - "client.user.group.domain", - "client.user.group.id", - "client.user.group.name", - "client.user.hash", - "client.user.id", - "client.user.name", - "cloud.account.id", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.provider", - "cloud.region", - "container.id", - "container.image.name", - "container.image.tag", - "container.name", - "container.runtime", - "destination.address", - "destination.as.organization.name", - "destination.domain", - "destination.geo.city_name", - "destination.geo.continent_name", - "destination.geo.country_iso_code", - "destination.geo.country_name", - "destination.geo.name", - "destination.geo.region_iso_code", - "destination.geo.region_name", - "destination.mac", - "destination.registered_domain", - "destination.top_level_domain", - "destination.user.domain", - "destination.user.email", - "destination.user.full_name", - "destination.user.group.domain", - "destination.user.group.id", - "destination.user.group.name", - "destination.user.hash", - "destination.user.id", - "destination.user.name", - "dns.answers.class", - "dns.answers.data", - "dns.answers.name", - "dns.answers.type", - "dns.header_flags", - "dns.id", - "dns.op_code", - "dns.question.class", - "dns.question.name", - "dns.question.registered_domain", - "dns.question.subdomain", - "dns.question.top_level_domain", - "dns.question.type", - "dns.response_code", - "dns.type", - "ecs.version", - "error.code", - "error.id", - "error.message", - "error.stack_trace", - "error.type", - "event.action", - "event.category", - "event.code", - "event.dataset", - "event.hash", - "event.id", - "event.kind", - "event.module", - "event.original", - "event.outcome", - "event.provider", - "event.timezone", - "event.type", - "file.device", - "file.directory", - "file.extension", - "file.gid", - "file.group", - "file.hash.md5", - "file.hash.sha1", - "file.hash.sha256", - "file.hash.sha512", - "file.inode", - "file.mode", - "file.name", - "file.owner", - "file.path", - "file.target_path", - "file.type", - "file.uid", - "geo.city_name", - "geo.continent_name", - "geo.country_iso_code", - "geo.country_name", - "geo.name", - "geo.region_iso_code", - "geo.region_name", - "group.domain", - "group.id", - "group.name", - "hash.md5", - "hash.sha1", - "hash.sha256", - "hash.sha512", - "host.architecture", - "host.geo.city_name", - "host.geo.continent_name", - "host.geo.country_iso_code", - "host.geo.country_name", - "host.geo.name", - "host.geo.region_iso_code", - "host.geo.region_name", - "host.hostname", - "host.id", - "host.mac", - "host.name", - "host.os.family", - "host.os.full", - "host.os.kernel", - "host.os.name", - "host.os.platform", - "host.os.version", - "host.type", - "host.user.domain", - "host.user.email", - "host.user.full_name", - "host.user.group.domain", - "host.user.group.id", - "host.user.group.name", - "host.user.hash", - "host.user.id", - "host.user.name", - "http.request.body.content", - "http.request.method", - "http.request.referrer", - "http.response.body.content", - "http.version", - "log.level", - "log.logger", - "log.origin.file.name", - "log.origin.function", - "log.original", - "log.syslog.facility.name", - "log.syslog.severity.name", - "network.application", - "network.community_id", - "network.direction", - "network.iana_number", - "network.name", - "network.protocol", - "network.transport", - "network.type", - "observer.geo.city_name", - "observer.geo.continent_name", - "observer.geo.country_iso_code", - "observer.geo.country_name", - "observer.geo.name", - "observer.geo.region_iso_code", - "observer.geo.region_name", - "observer.hostname", - "observer.mac", - "observer.name", - "observer.os.family", - "observer.os.full", - "observer.os.kernel", - "observer.os.name", - "observer.os.platform", - "observer.os.version", - "observer.product", - "observer.serial_number", - "observer.type", - "observer.vendor", - "observer.version", - "organization.id", - "organization.name", - "os.family", - "os.full", - "os.kernel", - "os.name", - "os.platform", - "os.version", - "package.architecture", - "package.checksum", - "package.description", - "package.install_scope", - "package.license", - "package.name", - "package.path", - "package.version", - "process.args", - "text", - "process.executable", - "process.hash.md5", - "process.hash.sha1", - "process.hash.sha256", - "process.hash.sha512", - "process.name", - "text", - "text", - "text", - "text", - "text", - "process.thread.name", - "process.title", - "process.working_directory", - "server.address", - "server.as.organization.name", - "server.domain", - "server.geo.city_name", - "server.geo.continent_name", - "server.geo.country_iso_code", - "server.geo.country_name", - "server.geo.name", - "server.geo.region_iso_code", - "server.geo.region_name", - "server.mac", - "server.registered_domain", - "server.top_level_domain", - "server.user.domain", - "server.user.email", - "server.user.full_name", - "server.user.group.domain", - "server.user.group.id", - "server.user.group.name", - "server.user.hash", - "server.user.id", - "server.user.name", - "service.ephemeral_id", - "service.id", - "service.name", - "service.node.name", - "service.state", - "service.type", - "service.version", - "source.address", - "source.as.organization.name", - "source.domain", - "source.geo.city_name", - "source.geo.continent_name", - "source.geo.country_iso_code", - "source.geo.country_name", - "source.geo.name", - "source.geo.region_iso_code", - "source.geo.region_name", - "source.mac", - "source.registered_domain", - "source.top_level_domain", - "source.user.domain", - "source.user.email", - "source.user.full_name", - "source.user.group.domain", - "source.user.group.id", - "source.user.group.name", - "source.user.hash", - "source.user.id", - "source.user.name", - "threat.framework", - "threat.tactic.id", - "threat.tactic.name", - "threat.tactic.reference", - "threat.technique.id", - "threat.technique.name", - "threat.technique.reference", - "tracing.trace.id", - "tracing.transaction.id", - "url.domain", - "url.extension", - "url.fragment", - "url.full", - "url.original", - "url.password", - "url.path", - "url.query", - "url.registered_domain", - "url.scheme", - "url.top_level_domain", - "url.username", - "user.domain", - "user.email", - "user.full_name", - "user.group.domain", - "user.group.id", - "user.group.name", - "user.hash", - "user.id", - "user.name", - "user_agent.device.name", - "user_agent.name", - "text", - "user_agent.original", - "user_agent.os.family", - "user_agent.os.full", - "user_agent.os.kernel", - "user_agent.os.name", - "user_agent.os.platform", - "user_agent.os.version", - "user_agent.version", - "text", - "timeseries.instance", - "cloud.project.id", - "cloud.image.id", - "host.os.build", - "host.os.codename", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.replicaset.name", - "kubernetes.deployment.name", - "kubernetes.statefulset.name", - "kubernetes.container.name", - "kubernetes.container.image", - "processor.name", - "processor.event", - "url.scheme", - "url.full", - "url.domain", - "url.path", - "url.query", - "url.fragment", - "http.version", - "http.request.method", - "http.request.referrer", - "service.name", - "service.version", - "service.environment", - "service.node.name", - "service.language.name", - "service.language.version", - "service.runtime.name", - "service.runtime.version", - "service.framework.name", - "service.framework.version", - "transaction.id", - "transaction.type", - "text", - "transaction.name", - "span.type", - "span.subtype", - "trace.id", - "parent.id", - "agent.name", - "agent.version", - "agent.ephemeral_id", - "container.id", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "host.architecture", - "host.hostname", - "host.name", - "host.os.platform", - "process.args", - "process.title", - "observer.listening", - "observer.hostname", - "observer.version", - "observer.type", - "user.name", - "user.id", - "user.email", - "destination.address", - "text", - "user_agent.original", - "user_agent.name", - "user_agent.version", - "user_agent.device.name", - "user_agent.os.platform", - "user_agent.os.name", - "user_agent.os.full", - "user_agent.os.family", - "user_agent.os.version", - "user_agent.os.kernel", - "cloud.account.id", - "cloud.account.name", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.project.id", - "cloud.project.name", - "cloud.provider", - "cloud.region", - "error.id", - "error.culprit", - "error.grouping_key", - "error.exception.code", - "error.exception.message", - "error.exception.module", - "error.exception.type", - "error.log.level", - "error.log.logger_name", - "error.log.message", - "error.log.param_message", - "profile.top.id", - "profile.top.function", - "profile.top.filename", - "profile.stack.id", - "profile.stack.function", - "profile.stack.filename", - "sourcemap.service.name", - "sourcemap.service.version", - "sourcemap.bundle_filepath", - "view spans", - "child.id", - "span.id", - "span.name", - "span.action", - "span.db.link", - "span.destination.service.type", - "span.destination.service.name", - "span.destination.service.resource", - "span.message.queue.name", - "transaction.result", - "transaction.message.queue.name", - "fields.*" - ] - }, - "refresh_interval": "1ms" - } - } - } -} - -{ - "type": "index", - "value": { - "aliases": { - }, - "index": "apm-8.0.0-onboarding-2020.06.29", - "mappings": { - "_meta": { - "beat": "apm", - "version": "8.0.0" - }, - "date_detection": false, - "dynamic_templates": [ - { - "labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "container.labels.*" - } - }, - { - "dns.answers": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "dns.answers.*" - } - }, - { - "log.syslog": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "log.syslog.*" - } - }, - { - "network.inner": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "network.inner.*" - } - }, - { - "observer.egress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.egress.*" - } - }, - { - "observer.ingress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.ingress.*" - } - }, - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "kubernetes.labels.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.labels.*" - } - }, - { - "kubernetes.annotations.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.annotations.*" - } - }, - { - "labels_string": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "labels_boolean": { - "mapping": { - "type": "boolean" - }, - "match_mapping_type": "boolean", - "path_match": "labels.*" - } - }, - { - "labels_*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "labels.*" - } - }, - { - "transaction.marks": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "transaction.marks.*" - } - }, - { - "transaction.marks.*.*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "transaction.marks.*.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } - } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "agent": { - "dynamic": "false", - "properties": { - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "path": "agent.name", - "type": "alias" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "child": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "client": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "cloud": { - "properties": { - "account": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "instance": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "machine": { - "dynamic": "false", - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "project": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "container": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "tag": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "runtime": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "destination": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dll": { - "properties": { - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dns": { - "properties": { - "answers": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "data": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "ttl": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "header_flags": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "op_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "question": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "subdomain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "resolved_ip": { - "type": "ip" - }, - "response_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "docker": { - "properties": { - "container": { - "properties": { - "labels": { - "type": "object" - } - } - } - } - }, - "ecs": { - "properties": { - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "dynamic": "false", - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "culprit": { - "ignore_above": 1024, - "type": "keyword" - }, - "exception": { - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "handled": { - "type": "boolean" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "grouping_key": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "param_message": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "stack_trace": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "event": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "long" - }, - "end": { - "type": "date" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingested": { - "type": "date" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "outcome": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "risk_score": { - "type": "float" - }, - "risk_score_norm": { - "type": "float" - }, - "sequence": { - "type": "long" - }, - "severity": { - "type": "long" - }, - "start": { - "type": "date" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "experimental": { - "dynamic": "true", - "type": "object" - }, - "fields": { - "type": "object" - }, - "file": { - "properties": { - "accessed": { - "type": "date" - }, - "attributes": { - "ignore_above": 1024, - "type": "keyword" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "created": { - "type": "date" - }, - "ctime": { - "type": "date" - }, - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "directory": { - "ignore_above": 1024, - "type": "keyword" - }, - "drive_letter": { - "ignore_above": 1, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "gid": { - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "inode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mime_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mtime": { - "type": "date" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "owner": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "size": { - "type": "long" - }, - "target_path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "host": { - "dynamic": "false", - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "containerized": { - "type": "boolean" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "build": { - "ignore_above": 1024, - "type": "keyword" - }, - "codename": { - "ignore_above": 1024, - "type": "keyword" - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "http": { - "dynamic": "false", - "properties": { - "request": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "response": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "finished": { - "type": "boolean" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "status_code": { - "type": "long" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "kubernetes": { - "dynamic": "false", - "properties": { - "annotations": { - "properties": { - "*": { - "type": "object" - } - } - }, - "container": { - "properties": { - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "deployment": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "properties": { - "*": { - "type": "object" - } - } - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pod": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "replicaset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "statefulset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "labels": { - "dynamic": "true", - "type": "object" - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger": { - "ignore_above": 1024, - "type": "keyword" - }, - "origin": { - "properties": { - "file": { - "properties": { - "line": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "syslog": { - "properties": { - "facility": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "priority": { - "type": "long" - }, - "severity": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "network": { - "properties": { - "application": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "community_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "forwarded_ip": { - "type": "ip" - }, - "iana_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "inner": { - "properties": { - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "transport": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "observer": { - "dynamic": "false", - "properties": { - "egress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "listening": { - "ignore_above": 1024, - "type": "keyword" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vendor": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_major": { - "type": "byte" - } - } - }, - "organization": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "package": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "build_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "checksum": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "install_scope": { - "ignore_above": 1024, - "type": "keyword" - }, - "installed": { - "type": "date" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "parent": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "process": { - "dynamic": "false", - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "parent": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "processor": { - "properties": { - "event": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "profile": { - "dynamic": "false", - "properties": { - "alloc_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "alloc_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "cpu": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "duration": { - "type": "long" - }, - "inuse_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "inuse_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "samples": { - "properties": { - "count": { - "type": "long" - } - } - }, - "stack": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - }, - "top": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - } - } - }, - "registry": { - "properties": { - "data": { - "properties": { - "bytes": { - "ignore_above": 1024, - "type": "keyword" - }, - "strings": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hive": { - "ignore_above": 1024, - "type": "keyword" - }, - "key": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "related": { - "properties": { - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "rule": { - "properties": { - "author": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "ruleset": { - "ignore_above": 1024, - "type": "keyword" - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "service": { - "dynamic": "false", - "properties": { - "environment": { - "ignore_above": 1024, - "type": "keyword" - }, - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "framework": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "language": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "runtime": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "source": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "sourcemap": { - "dynamic": "false", - "properties": { - "bundle_filepath": { - "ignore_above": 1024, - "type": "keyword" - }, - "service": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "span": { - "dynamic": "false", - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "db": { - "dynamic": "false", - "properties": { - "link": { - "ignore_above": 1024, - "type": "keyword" - }, - "rows_affected": { - "type": "long" - } - } - }, - "destination": { - "dynamic": "false", - "properties": { - "service": { - "dynamic": "false", - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "duration": { - "properties": { - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "start": { - "properties": { - "us": { - "type": "long" - } - } - }, - "subtype": { - "ignore_above": 1024, - "type": "keyword" - }, - "sync": { - "type": "boolean" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "system": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "actual": { - "properties": { - "free": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "process": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "rss": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "size": { - "type": "long" - } - } - } - } - } - } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "threat": { - "properties": { - "framework": { - "ignore_above": 1024, - "type": "keyword" - }, - "tactic": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "technique": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "timeseries": { - "properties": { - "instance": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "properties": { - "us": { - "type": "long" - } - } - }, - "tls": { - "properties": { - "cipher": { - "ignore_above": 1024, - "type": "keyword" - }, - "client": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - }, - "supported_ciphers": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "curve": { - "ignore_above": 1024, - "type": "keyword" - }, - "established": { - "type": "boolean" - }, - "next_protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "resumed": { - "type": "boolean" - }, - "server": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3s": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_protocol": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "trace": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "tracing": { - "properties": { - "trace": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "transaction": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "transaction": { - "dynamic": "false", - "properties": { - "breakdown": { - "properties": { - "count": { - "type": "long" - } - } - }, - "duration": { - "properties": { - "count": { - "type": "long" - }, - "histogram": { - "type": "histogram" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - }, - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "marks": { - "dynamic": "true", - "properties": { - "*": { - "properties": { - "*": { - "dynamic": "true", - "type": "object" - } - } - } - } - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "result": { - "ignore_above": 1024, - "type": "keyword" - }, - "root": { - "type": "boolean" - }, - "sampled": { - "type": "boolean" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "span_count": { - "properties": { - "dropped": { - "type": "long" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "url": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "fragment": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "password": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheme": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "username": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_agent": { - "dynamic": "false", - "properties": { - "device": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "view spans": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vulnerability": { - "properties": { - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "classification": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "enumeration": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "report_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "scanner": { - "properties": { - "vendor": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "score": { - "properties": { - "base": { - "type": "float" - }, - "environmental": { - "type": "float" - }, - "temporal": { - "type": "float" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "settings": { - "index": { - "codec": "best_compression", - "mapping": { - "total_fields": { - "limit": "2000" - } - }, - "number_of_replicas": "0", - "number_of_shards": "1", - "query": { - "default_field": [ - "message", - "tags", - "agent.ephemeral_id", - "agent.id", - "agent.name", - "agent.type", - "agent.version", - "as.organization.name", - "client.address", - "client.as.organization.name", - "client.domain", - "client.geo.city_name", - "client.geo.continent_name", - "client.geo.country_iso_code", - "client.geo.country_name", - "client.geo.name", - "client.geo.region_iso_code", - "client.geo.region_name", - "client.mac", - "client.registered_domain", - "client.top_level_domain", - "client.user.domain", - "client.user.email", - "client.user.full_name", - "client.user.group.domain", - "client.user.group.id", - "client.user.group.name", - "client.user.hash", - "client.user.id", - "client.user.name", - "cloud.account.id", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.provider", - "cloud.region", - "container.id", - "container.image.name", - "container.image.tag", - "container.name", - "container.runtime", - "destination.address", - "destination.as.organization.name", - "destination.domain", - "destination.geo.city_name", - "destination.geo.continent_name", - "destination.geo.country_iso_code", - "destination.geo.country_name", - "destination.geo.name", - "destination.geo.region_iso_code", - "destination.geo.region_name", - "destination.mac", - "destination.registered_domain", - "destination.top_level_domain", - "destination.user.domain", - "destination.user.email", - "destination.user.full_name", - "destination.user.group.domain", - "destination.user.group.id", - "destination.user.group.name", - "destination.user.hash", - "destination.user.id", - "destination.user.name", - "dns.answers.class", - "dns.answers.data", - "dns.answers.name", - "dns.answers.type", - "dns.header_flags", - "dns.id", - "dns.op_code", - "dns.question.class", - "dns.question.name", - "dns.question.registered_domain", - "dns.question.subdomain", - "dns.question.top_level_domain", - "dns.question.type", - "dns.response_code", - "dns.type", - "ecs.version", - "error.code", - "error.id", - "error.message", - "error.stack_trace", - "error.type", - "event.action", - "event.category", - "event.code", - "event.dataset", - "event.hash", - "event.id", - "event.kind", - "event.module", - "event.original", - "event.outcome", - "event.provider", - "event.timezone", - "event.type", - "file.device", - "file.directory", - "file.extension", - "file.gid", - "file.group", - "file.hash.md5", - "file.hash.sha1", - "file.hash.sha256", - "file.hash.sha512", - "file.inode", - "file.mode", - "file.name", - "file.owner", - "file.path", - "file.target_path", - "file.type", - "file.uid", - "geo.city_name", - "geo.continent_name", - "geo.country_iso_code", - "geo.country_name", - "geo.name", - "geo.region_iso_code", - "geo.region_name", - "group.domain", - "group.id", - "group.name", - "hash.md5", - "hash.sha1", - "hash.sha256", - "hash.sha512", - "host.architecture", - "host.geo.city_name", - "host.geo.continent_name", - "host.geo.country_iso_code", - "host.geo.country_name", - "host.geo.name", - "host.geo.region_iso_code", - "host.geo.region_name", - "host.hostname", - "host.id", - "host.mac", - "host.name", - "host.os.family", - "host.os.full", - "host.os.kernel", - "host.os.name", - "host.os.platform", - "host.os.version", - "host.type", - "host.user.domain", - "host.user.email", - "host.user.full_name", - "host.user.group.domain", - "host.user.group.id", - "host.user.group.name", - "host.user.hash", - "host.user.id", - "host.user.name", - "http.request.body.content", - "http.request.method", - "http.request.referrer", - "http.response.body.content", - "http.version", - "log.level", - "log.logger", - "log.origin.file.name", - "log.origin.function", - "log.original", - "log.syslog.facility.name", - "log.syslog.severity.name", - "network.application", - "network.community_id", - "network.direction", - "network.iana_number", - "network.name", - "network.protocol", - "network.transport", - "network.type", - "observer.geo.city_name", - "observer.geo.continent_name", - "observer.geo.country_iso_code", - "observer.geo.country_name", - "observer.geo.name", - "observer.geo.region_iso_code", - "observer.geo.region_name", - "observer.hostname", - "observer.mac", - "observer.name", - "observer.os.family", - "observer.os.full", - "observer.os.kernel", - "observer.os.name", - "observer.os.platform", - "observer.os.version", - "observer.product", - "observer.serial_number", - "observer.type", - "observer.vendor", - "observer.version", - "organization.id", - "organization.name", - "os.family", - "os.full", - "os.kernel", - "os.name", - "os.platform", - "os.version", - "package.architecture", - "package.checksum", - "package.description", - "package.install_scope", - "package.license", - "package.name", - "package.path", - "package.version", - "process.args", - "text", - "process.executable", - "process.hash.md5", - "process.hash.sha1", - "process.hash.sha256", - "process.hash.sha512", - "process.name", - "text", - "text", - "text", - "text", - "text", - "process.thread.name", - "process.title", - "process.working_directory", - "server.address", - "server.as.organization.name", - "server.domain", - "server.geo.city_name", - "server.geo.continent_name", - "server.geo.country_iso_code", - "server.geo.country_name", - "server.geo.name", - "server.geo.region_iso_code", - "server.geo.region_name", - "server.mac", - "server.registered_domain", - "server.top_level_domain", - "server.user.domain", - "server.user.email", - "server.user.full_name", - "server.user.group.domain", - "server.user.group.id", - "server.user.group.name", - "server.user.hash", - "server.user.id", - "server.user.name", - "service.ephemeral_id", - "service.id", - "service.name", - "service.node.name", - "service.state", - "service.type", - "service.version", - "source.address", - "source.as.organization.name", - "source.domain", - "source.geo.city_name", - "source.geo.continent_name", - "source.geo.country_iso_code", - "source.geo.country_name", - "source.geo.name", - "source.geo.region_iso_code", - "source.geo.region_name", - "source.mac", - "source.registered_domain", - "source.top_level_domain", - "source.user.domain", - "source.user.email", - "source.user.full_name", - "source.user.group.domain", - "source.user.group.id", - "source.user.group.name", - "source.user.hash", - "source.user.id", - "source.user.name", - "threat.framework", - "threat.tactic.id", - "threat.tactic.name", - "threat.tactic.reference", - "threat.technique.id", - "threat.technique.name", - "threat.technique.reference", - "tracing.trace.id", - "tracing.transaction.id", - "url.domain", - "url.extension", - "url.fragment", - "url.full", - "url.original", - "url.password", - "url.path", - "url.query", - "url.registered_domain", - "url.scheme", - "url.top_level_domain", - "url.username", - "user.domain", - "user.email", - "user.full_name", - "user.group.domain", - "user.group.id", - "user.group.name", - "user.hash", - "user.id", - "user.name", - "user_agent.device.name", - "user_agent.name", - "text", - "user_agent.original", - "user_agent.os.family", - "user_agent.os.full", - "user_agent.os.kernel", - "user_agent.os.name", - "user_agent.os.platform", - "user_agent.os.version", - "user_agent.version", - "text", - "timeseries.instance", - "cloud.project.id", - "cloud.image.id", - "host.os.build", - "host.os.codename", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.replicaset.name", - "kubernetes.deployment.name", - "kubernetes.statefulset.name", - "kubernetes.container.name", - "kubernetes.container.image", - "processor.name", - "processor.event", - "url.scheme", - "url.full", - "url.domain", - "url.path", - "url.query", - "url.fragment", - "http.version", - "http.request.method", - "http.request.referrer", - "service.name", - "service.version", - "service.environment", - "service.node.name", - "service.language.name", - "service.language.version", - "service.runtime.name", - "service.runtime.version", - "service.framework.name", - "service.framework.version", - "transaction.id", - "transaction.type", - "text", - "transaction.name", - "span.type", - "span.subtype", - "trace.id", - "parent.id", - "agent.name", - "agent.version", - "agent.ephemeral_id", - "container.id", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "host.architecture", - "host.hostname", - "host.name", - "host.os.platform", - "process.args", - "process.title", - "observer.listening", - "observer.hostname", - "observer.version", - "observer.type", - "user.name", - "user.id", - "user.email", - "destination.address", - "text", - "user_agent.original", - "user_agent.name", - "user_agent.version", - "user_agent.device.name", - "user_agent.os.platform", - "user_agent.os.name", - "user_agent.os.full", - "user_agent.os.family", - "user_agent.os.version", - "user_agent.os.kernel", - "cloud.account.id", - "cloud.account.name", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.project.id", - "cloud.project.name", - "cloud.provider", - "cloud.region", - "error.id", - "error.culprit", - "error.grouping_key", - "error.exception.code", - "error.exception.message", - "error.exception.module", - "error.exception.type", - "error.log.level", - "error.log.logger_name", - "error.log.message", - "error.log.param_message", - "profile.top.id", - "profile.top.function", - "profile.top.filename", - "profile.stack.id", - "profile.stack.function", - "profile.stack.filename", - "sourcemap.service.name", - "sourcemap.service.version", - "sourcemap.bundle_filepath", - "view spans", - "child.id", - "span.id", - "span.name", - "span.action", - "span.db.link", - "span.destination.service.type", - "span.destination.service.name", - "span.destination.service.resource", - "span.message.queue.name", - "transaction.result", - "transaction.message.queue.name", - "fields.*" - ] - }, - "refresh_interval": "1ms" - } - } - } -} - -{ - "type": "index", - "value": { - "aliases": { - "apm-8.0.0-profile": { - "is_write_index": true - } - }, - "index": "apm-8.0.0-profile-000001", - "mappings": { - "_meta": { - "beat": "apm", - "version": "8.0.0" - }, - "date_detection": false, - "dynamic_templates": [ - { - "labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "container.labels.*" - } - }, - { - "dns.answers": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "dns.answers.*" - } - }, - { - "log.syslog": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "log.syslog.*" - } - }, - { - "network.inner": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "network.inner.*" - } - }, - { - "observer.egress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.egress.*" - } - }, - { - "observer.ingress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.ingress.*" - } - }, - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "kubernetes.labels.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.labels.*" - } - }, - { - "kubernetes.annotations.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.annotations.*" - } - }, - { - "labels_string": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "labels_boolean": { - "mapping": { - "type": "boolean" - }, - "match_mapping_type": "boolean", - "path_match": "labels.*" - } - }, - { - "labels_*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "labels.*" - } - }, - { - "transaction.marks": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "transaction.marks.*" - } - }, - { - "transaction.marks.*.*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "transaction.marks.*.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } - } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "agent": { - "dynamic": "false", - "properties": { - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "path": "agent.name", - "type": "alias" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "child": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "client": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "cloud": { - "properties": { - "account": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "instance": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "machine": { - "dynamic": "false", - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "project": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "container": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "tag": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "runtime": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "destination": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dll": { - "properties": { - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dns": { - "properties": { - "answers": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "data": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "ttl": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "header_flags": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "op_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "question": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "subdomain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "resolved_ip": { - "type": "ip" - }, - "response_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "docker": { - "properties": { - "container": { - "properties": { - "labels": { - "type": "object" - } - } - } - } - }, - "ecs": { - "properties": { - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "dynamic": "false", - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "culprit": { - "ignore_above": 1024, - "type": "keyword" - }, - "exception": { - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "handled": { - "type": "boolean" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "grouping_key": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "param_message": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "stack_trace": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "event": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "long" - }, - "end": { - "type": "date" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingested": { - "type": "date" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "outcome": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "risk_score": { - "type": "float" - }, - "risk_score_norm": { - "type": "float" - }, - "sequence": { - "type": "long" - }, - "severity": { - "type": "long" - }, - "start": { - "type": "date" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "experimental": { - "dynamic": "true", - "type": "object" - }, - "fields": { - "type": "object" - }, - "file": { - "properties": { - "accessed": { - "type": "date" - }, - "attributes": { - "ignore_above": 1024, - "type": "keyword" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "created": { - "type": "date" - }, - "ctime": { - "type": "date" - }, - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "directory": { - "ignore_above": 1024, - "type": "keyword" - }, - "drive_letter": { - "ignore_above": 1, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "gid": { - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "inode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mime_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mtime": { - "type": "date" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "owner": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "size": { - "type": "long" - }, - "target_path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "host": { - "dynamic": "false", - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "containerized": { - "type": "boolean" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "build": { - "ignore_above": 1024, - "type": "keyword" - }, - "codename": { - "ignore_above": 1024, - "type": "keyword" - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "http": { - "dynamic": "false", - "properties": { - "request": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "response": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "finished": { - "type": "boolean" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "status_code": { - "type": "long" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "kubernetes": { - "dynamic": "false", - "properties": { - "annotations": { - "properties": { - "*": { - "type": "object" - } - } - }, - "container": { - "properties": { - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "deployment": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "properties": { - "*": { - "type": "object" - } - } - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pod": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "replicaset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "statefulset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "labels": { - "dynamic": "true", - "type": "object" - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger": { - "ignore_above": 1024, - "type": "keyword" - }, - "origin": { - "properties": { - "file": { - "properties": { - "line": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "syslog": { - "properties": { - "facility": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "priority": { - "type": "long" - }, - "severity": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "network": { - "properties": { - "application": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "community_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "forwarded_ip": { - "type": "ip" - }, - "iana_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "inner": { - "properties": { - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "transport": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "observer": { - "dynamic": "false", - "properties": { - "egress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "listening": { - "ignore_above": 1024, - "type": "keyword" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vendor": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_major": { - "type": "byte" - } - } - }, - "organization": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "package": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "build_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "checksum": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "install_scope": { - "ignore_above": 1024, - "type": "keyword" - }, - "installed": { - "type": "date" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "parent": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "process": { - "dynamic": "false", - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "parent": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "processor": { - "properties": { - "event": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "profile": { - "dynamic": "false", - "properties": { - "alloc_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "alloc_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "cpu": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "duration": { - "type": "long" - }, - "inuse_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "inuse_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "samples": { - "properties": { - "count": { - "type": "long" - } - } - }, - "stack": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - }, - "top": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - } - } - }, - "registry": { - "properties": { - "data": { - "properties": { - "bytes": { - "ignore_above": 1024, - "type": "keyword" - }, - "strings": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hive": { - "ignore_above": 1024, - "type": "keyword" - }, - "key": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "related": { - "properties": { - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "rule": { - "properties": { - "author": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "ruleset": { - "ignore_above": 1024, - "type": "keyword" - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "service": { - "dynamic": "false", - "properties": { - "environment": { - "ignore_above": 1024, - "type": "keyword" - }, - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "framework": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "language": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "runtime": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "source": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "sourcemap": { - "dynamic": "false", - "properties": { - "bundle_filepath": { - "ignore_above": 1024, - "type": "keyword" - }, - "service": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "span": { - "dynamic": "false", - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "db": { - "dynamic": "false", - "properties": { - "link": { - "ignore_above": 1024, - "type": "keyword" - }, - "rows_affected": { - "type": "long" - } - } - }, - "destination": { - "dynamic": "false", - "properties": { - "service": { - "dynamic": "false", - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "duration": { - "properties": { - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "start": { - "properties": { - "us": { - "type": "long" - } - } - }, - "subtype": { - "ignore_above": 1024, - "type": "keyword" - }, - "sync": { - "type": "boolean" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "system": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "actual": { - "properties": { - "free": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "process": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "rss": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "size": { - "type": "long" - } - } - } - } - } - } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "threat": { - "properties": { - "framework": { - "ignore_above": 1024, - "type": "keyword" - }, - "tactic": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "technique": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "timeseries": { - "properties": { - "instance": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "properties": { - "us": { - "type": "long" - } - } - }, - "tls": { - "properties": { - "cipher": { - "ignore_above": 1024, - "type": "keyword" - }, - "client": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - }, - "supported_ciphers": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "curve": { - "ignore_above": 1024, - "type": "keyword" - }, - "established": { - "type": "boolean" - }, - "next_protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "resumed": { - "type": "boolean" - }, - "server": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3s": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_protocol": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "trace": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "tracing": { - "properties": { - "trace": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "transaction": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "transaction": { - "dynamic": "false", - "properties": { - "breakdown": { - "properties": { - "count": { - "type": "long" - } - } - }, - "duration": { - "properties": { - "count": { - "type": "long" - }, - "histogram": { - "type": "histogram" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - }, - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "marks": { - "dynamic": "true", - "properties": { - "*": { - "properties": { - "*": { - "dynamic": "true", - "type": "object" - } - } - } - } - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "result": { - "ignore_above": 1024, - "type": "keyword" - }, - "root": { - "type": "boolean" - }, - "sampled": { - "type": "boolean" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "span_count": { - "properties": { - "dropped": { - "type": "long" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "url": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "fragment": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "password": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheme": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "username": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_agent": { - "dynamic": "false", - "properties": { - "device": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "view spans": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vulnerability": { - "properties": { - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "classification": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "enumeration": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "report_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "scanner": { - "properties": { - "vendor": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "score": { - "properties": { - "base": { - "type": "float" - }, - "environmental": { - "type": "float" - }, - "temporal": { - "type": "float" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "settings": { - "index": { - "codec": "best_compression", - "lifecycle": { - "name": "apm-rollover-30-days", - "rollover_alias": "apm-8.0.0-profile" - }, - "mapping": { - "total_fields": { - "limit": "2000" - } - }, - "number_of_replicas": "0", - "number_of_shards": "1", - "priority": "100", - "query": { - "default_field": [ - "message", - "tags", - "agent.ephemeral_id", - "agent.id", - "agent.name", - "agent.type", - "agent.version", - "as.organization.name", - "client.address", - "client.as.organization.name", - "client.domain", - "client.geo.city_name", - "client.geo.continent_name", - "client.geo.country_iso_code", - "client.geo.country_name", - "client.geo.name", - "client.geo.region_iso_code", - "client.geo.region_name", - "client.mac", - "client.registered_domain", - "client.top_level_domain", - "client.user.domain", - "client.user.email", - "client.user.full_name", - "client.user.group.domain", - "client.user.group.id", - "client.user.group.name", - "client.user.hash", - "client.user.id", - "client.user.name", - "cloud.account.id", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.provider", - "cloud.region", - "container.id", - "container.image.name", - "container.image.tag", - "container.name", - "container.runtime", - "destination.address", - "destination.as.organization.name", - "destination.domain", - "destination.geo.city_name", - "destination.geo.continent_name", - "destination.geo.country_iso_code", - "destination.geo.country_name", - "destination.geo.name", - "destination.geo.region_iso_code", - "destination.geo.region_name", - "destination.mac", - "destination.registered_domain", - "destination.top_level_domain", - "destination.user.domain", - "destination.user.email", - "destination.user.full_name", - "destination.user.group.domain", - "destination.user.group.id", - "destination.user.group.name", - "destination.user.hash", - "destination.user.id", - "destination.user.name", - "dns.answers.class", - "dns.answers.data", - "dns.answers.name", - "dns.answers.type", - "dns.header_flags", - "dns.id", - "dns.op_code", - "dns.question.class", - "dns.question.name", - "dns.question.registered_domain", - "dns.question.subdomain", - "dns.question.top_level_domain", - "dns.question.type", - "dns.response_code", - "dns.type", - "ecs.version", - "error.code", - "error.id", - "error.message", - "error.stack_trace", - "error.type", - "event.action", - "event.category", - "event.code", - "event.dataset", - "event.hash", - "event.id", - "event.kind", - "event.module", - "event.original", - "event.outcome", - "event.provider", - "event.timezone", - "event.type", - "file.device", - "file.directory", - "file.extension", - "file.gid", - "file.group", - "file.hash.md5", - "file.hash.sha1", - "file.hash.sha256", - "file.hash.sha512", - "file.inode", - "file.mode", - "file.name", - "file.owner", - "file.path", - "file.target_path", - "file.type", - "file.uid", - "geo.city_name", - "geo.continent_name", - "geo.country_iso_code", - "geo.country_name", - "geo.name", - "geo.region_iso_code", - "geo.region_name", - "group.domain", - "group.id", - "group.name", - "hash.md5", - "hash.sha1", - "hash.sha256", - "hash.sha512", - "host.architecture", - "host.geo.city_name", - "host.geo.continent_name", - "host.geo.country_iso_code", - "host.geo.country_name", - "host.geo.name", - "host.geo.region_iso_code", - "host.geo.region_name", - "host.hostname", - "host.id", - "host.mac", - "host.name", - "host.os.family", - "host.os.full", - "host.os.kernel", - "host.os.name", - "host.os.platform", - "host.os.version", - "host.type", - "host.user.domain", - "host.user.email", - "host.user.full_name", - "host.user.group.domain", - "host.user.group.id", - "host.user.group.name", - "host.user.hash", - "host.user.id", - "host.user.name", - "http.request.body.content", - "http.request.method", - "http.request.referrer", - "http.response.body.content", - "http.version", - "log.level", - "log.logger", - "log.origin.file.name", - "log.origin.function", - "log.original", - "log.syslog.facility.name", - "log.syslog.severity.name", - "network.application", - "network.community_id", - "network.direction", - "network.iana_number", - "network.name", - "network.protocol", - "network.transport", - "network.type", - "observer.geo.city_name", - "observer.geo.continent_name", - "observer.geo.country_iso_code", - "observer.geo.country_name", - "observer.geo.name", - "observer.geo.region_iso_code", - "observer.geo.region_name", - "observer.hostname", - "observer.mac", - "observer.name", - "observer.os.family", - "observer.os.full", - "observer.os.kernel", - "observer.os.name", - "observer.os.platform", - "observer.os.version", - "observer.product", - "observer.serial_number", - "observer.type", - "observer.vendor", - "observer.version", - "organization.id", - "organization.name", - "os.family", - "os.full", - "os.kernel", - "os.name", - "os.platform", - "os.version", - "package.architecture", - "package.checksum", - "package.description", - "package.install_scope", - "package.license", - "package.name", - "package.path", - "package.version", - "process.args", - "text", - "process.executable", - "process.hash.md5", - "process.hash.sha1", - "process.hash.sha256", - "process.hash.sha512", - "process.name", - "text", - "text", - "text", - "text", - "text", - "process.thread.name", - "process.title", - "process.working_directory", - "server.address", - "server.as.organization.name", - "server.domain", - "server.geo.city_name", - "server.geo.continent_name", - "server.geo.country_iso_code", - "server.geo.country_name", - "server.geo.name", - "server.geo.region_iso_code", - "server.geo.region_name", - "server.mac", - "server.registered_domain", - "server.top_level_domain", - "server.user.domain", - "server.user.email", - "server.user.full_name", - "server.user.group.domain", - "server.user.group.id", - "server.user.group.name", - "server.user.hash", - "server.user.id", - "server.user.name", - "service.ephemeral_id", - "service.id", - "service.name", - "service.node.name", - "service.state", - "service.type", - "service.version", - "source.address", - "source.as.organization.name", - "source.domain", - "source.geo.city_name", - "source.geo.continent_name", - "source.geo.country_iso_code", - "source.geo.country_name", - "source.geo.name", - "source.geo.region_iso_code", - "source.geo.region_name", - "source.mac", - "source.registered_domain", - "source.top_level_domain", - "source.user.domain", - "source.user.email", - "source.user.full_name", - "source.user.group.domain", - "source.user.group.id", - "source.user.group.name", - "source.user.hash", - "source.user.id", - "source.user.name", - "threat.framework", - "threat.tactic.id", - "threat.tactic.name", - "threat.tactic.reference", - "threat.technique.id", - "threat.technique.name", - "threat.technique.reference", - "tracing.trace.id", - "tracing.transaction.id", - "url.domain", - "url.extension", - "url.fragment", - "url.full", - "url.original", - "url.password", - "url.path", - "url.query", - "url.registered_domain", - "url.scheme", - "url.top_level_domain", - "url.username", - "user.domain", - "user.email", - "user.full_name", - "user.group.domain", - "user.group.id", - "user.group.name", - "user.hash", - "user.id", - "user.name", - "user_agent.device.name", - "user_agent.name", - "text", - "user_agent.original", - "user_agent.os.family", - "user_agent.os.full", - "user_agent.os.kernel", - "user_agent.os.name", - "user_agent.os.platform", - "user_agent.os.version", - "user_agent.version", - "text", - "timeseries.instance", - "cloud.project.id", - "cloud.image.id", - "host.os.build", - "host.os.codename", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.replicaset.name", - "kubernetes.deployment.name", - "kubernetes.statefulset.name", - "kubernetes.container.name", - "kubernetes.container.image", - "processor.name", - "processor.event", - "url.scheme", - "url.full", - "url.domain", - "url.path", - "url.query", - "url.fragment", - "http.version", - "http.request.method", - "http.request.referrer", - "service.name", - "service.version", - "service.environment", - "service.node.name", - "service.language.name", - "service.language.version", - "service.runtime.name", - "service.runtime.version", - "service.framework.name", - "service.framework.version", - "transaction.id", - "transaction.type", - "text", - "transaction.name", - "span.type", - "span.subtype", - "trace.id", - "parent.id", - "agent.name", - "agent.version", - "agent.ephemeral_id", - "container.id", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "host.architecture", - "host.hostname", - "host.name", - "host.os.platform", - "process.args", - "process.title", - "observer.listening", - "observer.hostname", - "observer.version", - "observer.type", - "user.name", - "user.id", - "user.email", - "destination.address", - "text", - "user_agent.original", - "user_agent.name", - "user_agent.version", - "user_agent.device.name", - "user_agent.os.platform", - "user_agent.os.name", - "user_agent.os.full", - "user_agent.os.family", - "user_agent.os.version", - "user_agent.os.kernel", - "cloud.account.id", - "cloud.account.name", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.project.id", - "cloud.project.name", - "cloud.provider", - "cloud.region", - "error.id", - "error.culprit", - "error.grouping_key", - "error.exception.code", - "error.exception.message", - "error.exception.module", - "error.exception.type", - "error.log.level", - "error.log.logger_name", - "error.log.message", - "error.log.param_message", - "profile.top.id", - "profile.top.function", - "profile.top.filename", - "profile.stack.id", - "profile.stack.function", - "profile.stack.filename", - "sourcemap.service.name", - "sourcemap.service.version", - "sourcemap.bundle_filepath", - "view spans", - "child.id", - "span.id", - "span.name", - "span.action", - "span.db.link", - "span.destination.service.type", - "span.destination.service.name", - "span.destination.service.resource", - "span.message.queue.name", - "transaction.result", - "transaction.message.queue.name", - "fields.*" - ] - }, - "refresh_interval": "1ms" - } - } - } -} - -{ - "type": "index", - "value": { - "aliases": { - "apm-8.0.0-span": { - "is_write_index": true - } - }, - "index": "apm-8.0.0-span-000001", - "mappings": { - "_meta": { - "beat": "apm", - "version": "8.0.0" - }, - "date_detection": false, - "dynamic_templates": [ - { - "labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "container.labels.*" - } - }, - { - "dns.answers": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "dns.answers.*" - } - }, - { - "log.syslog": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "log.syslog.*" - } - }, - { - "network.inner": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "network.inner.*" - } - }, - { - "observer.egress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.egress.*" - } - }, - { - "observer.ingress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.ingress.*" - } - }, - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "kubernetes.labels.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.labels.*" - } - }, - { - "kubernetes.annotations.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.annotations.*" - } - }, - { - "labels_string": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "labels_boolean": { - "mapping": { - "type": "boolean" - }, - "match_mapping_type": "boolean", - "path_match": "labels.*" - } - }, - { - "labels_*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "labels.*" - } - }, - { - "transaction.marks": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "transaction.marks.*" - } - }, - { - "transaction.marks.*.*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "transaction.marks.*.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } - } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "agent": { - "dynamic": "false", - "properties": { - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "path": "agent.name", - "type": "alias" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "child": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "client": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "cloud": { - "properties": { - "account": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "instance": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "machine": { - "dynamic": "false", - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "project": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "container": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "tag": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "runtime": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "destination": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dll": { - "properties": { - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dns": { - "properties": { - "answers": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "data": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "ttl": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "header_flags": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "op_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "question": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "subdomain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "resolved_ip": { - "type": "ip" - }, - "response_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "docker": { - "properties": { - "container": { - "properties": { - "labels": { - "type": "object" - } - } - } - } - }, - "ecs": { - "properties": { - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "dynamic": "false", - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "culprit": { - "ignore_above": 1024, - "type": "keyword" - }, - "exception": { - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "handled": { - "type": "boolean" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "grouping_key": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "param_message": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "stack_trace": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "event": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "long" - }, - "end": { - "type": "date" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingested": { - "type": "date" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "outcome": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "risk_score": { - "type": "float" - }, - "risk_score_norm": { - "type": "float" - }, - "sequence": { - "type": "long" - }, - "severity": { - "type": "long" - }, - "start": { - "type": "date" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "experimental": { - "dynamic": "true", - "type": "object" - }, - "fields": { - "type": "object" - }, - "file": { - "properties": { - "accessed": { - "type": "date" - }, - "attributes": { - "ignore_above": 1024, - "type": "keyword" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "created": { - "type": "date" - }, - "ctime": { - "type": "date" - }, - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "directory": { - "ignore_above": 1024, - "type": "keyword" - }, - "drive_letter": { - "ignore_above": 1, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "gid": { - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "inode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mime_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mtime": { - "type": "date" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "owner": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "size": { - "type": "long" - }, - "target_path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "host": { - "dynamic": "false", - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "containerized": { - "type": "boolean" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "build": { - "ignore_above": 1024, - "type": "keyword" - }, - "codename": { - "ignore_above": 1024, - "type": "keyword" - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "http": { - "dynamic": "false", - "properties": { - "request": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "response": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "finished": { - "type": "boolean" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "status_code": { - "type": "long" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "kubernetes": { - "dynamic": "false", - "properties": { - "annotations": { - "properties": { - "*": { - "type": "object" - } - } - }, - "container": { - "properties": { - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "deployment": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "properties": { - "*": { - "type": "object" - } - } - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pod": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "replicaset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "statefulset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "labels": { - "dynamic": "true", - "properties": { - "foo": { - "type": "keyword" - }, - "productId": { - "type": "keyword" - } - } - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger": { - "ignore_above": 1024, - "type": "keyword" - }, - "origin": { - "properties": { - "file": { - "properties": { - "line": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "syslog": { - "properties": { - "facility": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "priority": { - "type": "long" - }, - "severity": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "network": { - "properties": { - "application": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "community_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "forwarded_ip": { - "type": "ip" - }, - "iana_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "inner": { - "properties": { - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "transport": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "observer": { - "dynamic": "false", - "properties": { - "egress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "listening": { - "ignore_above": 1024, - "type": "keyword" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vendor": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_major": { - "type": "byte" - } - } - }, - "organization": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "package": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "build_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "checksum": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "install_scope": { - "ignore_above": 1024, - "type": "keyword" - }, - "installed": { - "type": "date" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "parent": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "process": { - "dynamic": "false", - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "parent": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "processor": { - "properties": { - "event": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "profile": { - "dynamic": "false", - "properties": { - "alloc_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "alloc_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "cpu": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "duration": { - "type": "long" - }, - "inuse_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "inuse_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "samples": { - "properties": { - "count": { - "type": "long" - } - } - }, - "stack": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - }, - "top": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - } - } - }, - "registry": { - "properties": { - "data": { - "properties": { - "bytes": { - "ignore_above": 1024, - "type": "keyword" - }, - "strings": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hive": { - "ignore_above": 1024, - "type": "keyword" - }, - "key": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "related": { - "properties": { - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "rule": { - "properties": { - "author": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "ruleset": { - "ignore_above": 1024, - "type": "keyword" - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "service": { - "dynamic": "false", - "properties": { - "environment": { - "ignore_above": 1024, - "type": "keyword" - }, - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "framework": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "language": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "runtime": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "source": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "sourcemap": { - "dynamic": "false", - "properties": { - "bundle_filepath": { - "ignore_above": 1024, - "type": "keyword" - }, - "service": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "span": { - "dynamic": "false", - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "db": { - "dynamic": "false", - "properties": { - "link": { - "ignore_above": 1024, - "type": "keyword" - }, - "rows_affected": { - "type": "long" - } - } - }, - "destination": { - "dynamic": "false", - "properties": { - "service": { - "dynamic": "false", - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "duration": { - "properties": { - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "start": { - "properties": { - "us": { - "type": "long" - } - } - }, - "subtype": { - "ignore_above": 1024, - "type": "keyword" - }, - "sync": { - "type": "boolean" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "system": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "actual": { - "properties": { - "free": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "process": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "rss": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "size": { - "type": "long" - } - } - } - } - } - } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "threat": { - "properties": { - "framework": { - "ignore_above": 1024, - "type": "keyword" - }, - "tactic": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "technique": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "timeseries": { - "properties": { - "instance": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "properties": { - "us": { - "type": "long" - } - } - }, - "tls": { - "properties": { - "cipher": { - "ignore_above": 1024, - "type": "keyword" - }, - "client": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - }, - "supported_ciphers": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "curve": { - "ignore_above": 1024, - "type": "keyword" - }, - "established": { - "type": "boolean" - }, - "next_protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "resumed": { - "type": "boolean" - }, - "server": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3s": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_protocol": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "trace": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "tracing": { - "properties": { - "trace": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "transaction": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "transaction": { - "dynamic": "false", - "properties": { - "breakdown": { - "properties": { - "count": { - "type": "long" - } - } - }, - "duration": { - "properties": { - "count": { - "type": "long" - }, - "histogram": { - "type": "histogram" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - }, - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "marks": { - "dynamic": "true", - "properties": { - "*": { - "properties": { - "*": { - "dynamic": "true", - "type": "object" - } - } - } - } - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "result": { - "ignore_above": 1024, - "type": "keyword" - }, - "root": { - "type": "boolean" - }, - "sampled": { - "type": "boolean" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "span_count": { - "properties": { - "dropped": { - "type": "long" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "url": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "fragment": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "password": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheme": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "username": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_agent": { - "dynamic": "false", - "properties": { - "device": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "view spans": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vulnerability": { - "properties": { - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "classification": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "enumeration": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "report_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "scanner": { - "properties": { - "vendor": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "score": { - "properties": { - "base": { - "type": "float" - }, - "environmental": { - "type": "float" - }, - "temporal": { - "type": "float" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "settings": { - "index": { - "codec": "best_compression", - "lifecycle": { - "name": "apm-rollover-30-days", - "rollover_alias": "apm-8.0.0-span" - }, - "mapping": { - "total_fields": { - "limit": "2000" - } - }, - "number_of_replicas": "0", - "number_of_shards": "1", - "priority": "100", - "query": { - "default_field": [ - "message", - "tags", - "agent.ephemeral_id", - "agent.id", - "agent.name", - "agent.type", - "agent.version", - "as.organization.name", - "client.address", - "client.as.organization.name", - "client.domain", - "client.geo.city_name", - "client.geo.continent_name", - "client.geo.country_iso_code", - "client.geo.country_name", - "client.geo.name", - "client.geo.region_iso_code", - "client.geo.region_name", - "client.mac", - "client.registered_domain", - "client.top_level_domain", - "client.user.domain", - "client.user.email", - "client.user.full_name", - "client.user.group.domain", - "client.user.group.id", - "client.user.group.name", - "client.user.hash", - "client.user.id", - "client.user.name", - "cloud.account.id", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.provider", - "cloud.region", - "container.id", - "container.image.name", - "container.image.tag", - "container.name", - "container.runtime", - "destination.address", - "destination.as.organization.name", - "destination.domain", - "destination.geo.city_name", - "destination.geo.continent_name", - "destination.geo.country_iso_code", - "destination.geo.country_name", - "destination.geo.name", - "destination.geo.region_iso_code", - "destination.geo.region_name", - "destination.mac", - "destination.registered_domain", - "destination.top_level_domain", - "destination.user.domain", - "destination.user.email", - "destination.user.full_name", - "destination.user.group.domain", - "destination.user.group.id", - "destination.user.group.name", - "destination.user.hash", - "destination.user.id", - "destination.user.name", - "dns.answers.class", - "dns.answers.data", - "dns.answers.name", - "dns.answers.type", - "dns.header_flags", - "dns.id", - "dns.op_code", - "dns.question.class", - "dns.question.name", - "dns.question.registered_domain", - "dns.question.subdomain", - "dns.question.top_level_domain", - "dns.question.type", - "dns.response_code", - "dns.type", - "ecs.version", - "error.code", - "error.id", - "error.message", - "error.stack_trace", - "error.type", - "event.action", - "event.category", - "event.code", - "event.dataset", - "event.hash", - "event.id", - "event.kind", - "event.module", - "event.original", - "event.outcome", - "event.provider", - "event.timezone", - "event.type", - "file.device", - "file.directory", - "file.extension", - "file.gid", - "file.group", - "file.hash.md5", - "file.hash.sha1", - "file.hash.sha256", - "file.hash.sha512", - "file.inode", - "file.mode", - "file.name", - "file.owner", - "file.path", - "file.target_path", - "file.type", - "file.uid", - "geo.city_name", - "geo.continent_name", - "geo.country_iso_code", - "geo.country_name", - "geo.name", - "geo.region_iso_code", - "geo.region_name", - "group.domain", - "group.id", - "group.name", - "hash.md5", - "hash.sha1", - "hash.sha256", - "hash.sha512", - "host.architecture", - "host.geo.city_name", - "host.geo.continent_name", - "host.geo.country_iso_code", - "host.geo.country_name", - "host.geo.name", - "host.geo.region_iso_code", - "host.geo.region_name", - "host.hostname", - "host.id", - "host.mac", - "host.name", - "host.os.family", - "host.os.full", - "host.os.kernel", - "host.os.name", - "host.os.platform", - "host.os.version", - "host.type", - "host.user.domain", - "host.user.email", - "host.user.full_name", - "host.user.group.domain", - "host.user.group.id", - "host.user.group.name", - "host.user.hash", - "host.user.id", - "host.user.name", - "http.request.body.content", - "http.request.method", - "http.request.referrer", - "http.response.body.content", - "http.version", - "log.level", - "log.logger", - "log.origin.file.name", - "log.origin.function", - "log.original", - "log.syslog.facility.name", - "log.syslog.severity.name", - "network.application", - "network.community_id", - "network.direction", - "network.iana_number", - "network.name", - "network.protocol", - "network.transport", - "network.type", - "observer.geo.city_name", - "observer.geo.continent_name", - "observer.geo.country_iso_code", - "observer.geo.country_name", - "observer.geo.name", - "observer.geo.region_iso_code", - "observer.geo.region_name", - "observer.hostname", - "observer.mac", - "observer.name", - "observer.os.family", - "observer.os.full", - "observer.os.kernel", - "observer.os.name", - "observer.os.platform", - "observer.os.version", - "observer.product", - "observer.serial_number", - "observer.type", - "observer.vendor", - "observer.version", - "organization.id", - "organization.name", - "os.family", - "os.full", - "os.kernel", - "os.name", - "os.platform", - "os.version", - "package.architecture", - "package.checksum", - "package.description", - "package.install_scope", - "package.license", - "package.name", - "package.path", - "package.version", - "process.args", - "text", - "process.executable", - "process.hash.md5", - "process.hash.sha1", - "process.hash.sha256", - "process.hash.sha512", - "process.name", - "text", - "text", - "text", - "text", - "text", - "process.thread.name", - "process.title", - "process.working_directory", - "server.address", - "server.as.organization.name", - "server.domain", - "server.geo.city_name", - "server.geo.continent_name", - "server.geo.country_iso_code", - "server.geo.country_name", - "server.geo.name", - "server.geo.region_iso_code", - "server.geo.region_name", - "server.mac", - "server.registered_domain", - "server.top_level_domain", - "server.user.domain", - "server.user.email", - "server.user.full_name", - "server.user.group.domain", - "server.user.group.id", - "server.user.group.name", - "server.user.hash", - "server.user.id", - "server.user.name", - "service.ephemeral_id", - "service.id", - "service.name", - "service.node.name", - "service.state", - "service.type", - "service.version", - "source.address", - "source.as.organization.name", - "source.domain", - "source.geo.city_name", - "source.geo.continent_name", - "source.geo.country_iso_code", - "source.geo.country_name", - "source.geo.name", - "source.geo.region_iso_code", - "source.geo.region_name", - "source.mac", - "source.registered_domain", - "source.top_level_domain", - "source.user.domain", - "source.user.email", - "source.user.full_name", - "source.user.group.domain", - "source.user.group.id", - "source.user.group.name", - "source.user.hash", - "source.user.id", - "source.user.name", - "threat.framework", - "threat.tactic.id", - "threat.tactic.name", - "threat.tactic.reference", - "threat.technique.id", - "threat.technique.name", - "threat.technique.reference", - "tracing.trace.id", - "tracing.transaction.id", - "url.domain", - "url.extension", - "url.fragment", - "url.full", - "url.original", - "url.password", - "url.path", - "url.query", - "url.registered_domain", - "url.scheme", - "url.top_level_domain", - "url.username", - "user.domain", - "user.email", - "user.full_name", - "user.group.domain", - "user.group.id", - "user.group.name", - "user.hash", - "user.id", - "user.name", - "user_agent.device.name", - "user_agent.name", - "text", - "user_agent.original", - "user_agent.os.family", - "user_agent.os.full", - "user_agent.os.kernel", - "user_agent.os.name", - "user_agent.os.platform", - "user_agent.os.version", - "user_agent.version", - "text", - "timeseries.instance", - "cloud.project.id", - "cloud.image.id", - "host.os.build", - "host.os.codename", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.replicaset.name", - "kubernetes.deployment.name", - "kubernetes.statefulset.name", - "kubernetes.container.name", - "kubernetes.container.image", - "processor.name", - "processor.event", - "url.scheme", - "url.full", - "url.domain", - "url.path", - "url.query", - "url.fragment", - "http.version", - "http.request.method", - "http.request.referrer", - "service.name", - "service.version", - "service.environment", - "service.node.name", - "service.language.name", - "service.language.version", - "service.runtime.name", - "service.runtime.version", - "service.framework.name", - "service.framework.version", - "transaction.id", - "transaction.type", - "text", - "transaction.name", - "span.type", - "span.subtype", - "trace.id", - "parent.id", - "agent.name", - "agent.version", - "agent.ephemeral_id", - "container.id", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "host.architecture", - "host.hostname", - "host.name", - "host.os.platform", - "process.args", - "process.title", - "observer.listening", - "observer.hostname", - "observer.version", - "observer.type", - "user.name", - "user.id", - "user.email", - "destination.address", - "text", - "user_agent.original", - "user_agent.name", - "user_agent.version", - "user_agent.device.name", - "user_agent.os.platform", - "user_agent.os.name", - "user_agent.os.full", - "user_agent.os.family", - "user_agent.os.version", - "user_agent.os.kernel", - "cloud.account.id", - "cloud.account.name", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.project.id", - "cloud.project.name", - "cloud.provider", - "cloud.region", - "error.id", - "error.culprit", - "error.grouping_key", - "error.exception.code", - "error.exception.message", - "error.exception.module", - "error.exception.type", - "error.log.level", - "error.log.logger_name", - "error.log.message", - "error.log.param_message", - "profile.top.id", - "profile.top.function", - "profile.top.filename", - "profile.stack.id", - "profile.stack.function", - "profile.stack.filename", - "sourcemap.service.name", - "sourcemap.service.version", - "sourcemap.bundle_filepath", - "view spans", - "child.id", - "span.id", - "span.name", - "span.action", - "span.db.link", - "span.destination.service.type", - "span.destination.service.name", - "span.destination.service.resource", - "span.message.queue.name", - "transaction.result", - "transaction.message.queue.name", - "fields.*" - ] - }, - "refresh_interval": "1ms" - } - } - } -} - -{ - "type": "index", - "value": { - "aliases": { - "apm-8.0.0-transaction": { - "is_write_index": true - } - }, - "index": "apm-8.0.0-transaction-000001", - "mappings": { - "_meta": { - "beat": "apm", - "version": "8.0.0" - }, - "date_detection": false, - "dynamic_templates": [ - { - "labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "container.labels.*" - } - }, - { - "dns.answers": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "dns.answers.*" - } - }, - { - "log.syslog": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "log.syslog.*" - } - }, - { - "network.inner": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "network.inner.*" - } - }, - { - "observer.egress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.egress.*" - } - }, - { - "observer.ingress": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "observer.ingress.*" - } - }, - { - "fields": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "fields.*" - } - }, - { - "docker.container.labels": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "docker.container.labels.*" - } - }, - { - "kubernetes.labels.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.labels.*" - } - }, - { - "kubernetes.annotations.*": { - "mapping": { - "type": "keyword" - }, - "path_match": "kubernetes.annotations.*" - } - }, - { - "labels_string": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "labels.*" - } - }, - { - "labels_boolean": { - "mapping": { - "type": "boolean" - }, - "match_mapping_type": "boolean", - "path_match": "labels.*" - } - }, - { - "labels_*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "labels.*" - } - }, - { - "transaction.marks": { - "mapping": { - "type": "keyword" - }, - "match_mapping_type": "string", - "path_match": "transaction.marks.*" - } - }, - { - "transaction.marks.*.*": { - "mapping": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "path_match": "transaction.marks.*.*" - } - }, - { - "strings_as_keyword": { - "mapping": { - "ignore_above": 1024, - "type": "keyword" - }, - "match_mapping_type": "string" - } - } - ], - "properties": { - "@timestamp": { - "type": "date" - }, - "agent": { - "dynamic": "false", - "properties": { - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "hostname": { - "path": "agent.name", - "type": "alias" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "child": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "client": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "cloud": { - "properties": { - "account": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "availability_zone": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "instance": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "machine": { - "dynamic": "false", - "properties": { - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "project": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "region": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "container": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "image": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "tag": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "type": "object" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "runtime": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "destination": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dll": { - "properties": { - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "dns": { - "properties": { - "answers": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "data": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "ttl": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "header_flags": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "op_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "question": { - "properties": { - "class": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "subdomain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "resolved_ip": { - "type": "ip" - }, - "response_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "docker": { - "properties": { - "container": { - "properties": { - "labels": { - "type": "object" - } - } - } - } - }, - "ecs": { - "properties": { - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "error": { - "dynamic": "false", - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "culprit": { - "ignore_above": 1024, - "type": "keyword" - }, - "exception": { - "properties": { - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "handled": { - "type": "boolean" - }, - "message": { - "norms": false, - "type": "text" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "grouping_key": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "norms": false, - "type": "text" - }, - "param_message": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "stack_trace": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "event": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "long" - }, - "end": { - "type": "date" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingested": { - "type": "date" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "outcome": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "risk_score": { - "type": "float" - }, - "risk_score_norm": { - "type": "float" - }, - "sequence": { - "type": "long" - }, - "severity": { - "type": "long" - }, - "start": { - "type": "date" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "experimental": { - "dynamic": "true", - "type": "object" - }, - "fields": { - "type": "object" - }, - "file": { - "properties": { - "accessed": { - "type": "date" - }, - "attributes": { - "ignore_above": 1024, - "type": "keyword" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "created": { - "type": "date" - }, - "ctime": { - "type": "date" - }, - "device": { - "ignore_above": 1024, - "type": "keyword" - }, - "directory": { - "ignore_above": 1024, - "type": "keyword" - }, - "drive_letter": { - "ignore_above": 1, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "gid": { - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "inode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mime_type": { - "ignore_above": 1024, - "type": "keyword" - }, - "mode": { - "ignore_above": 1024, - "type": "keyword" - }, - "mtime": { - "type": "date" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "owner": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "size": { - "type": "long" - }, - "target_path": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "host": { - "dynamic": "false", - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "containerized": { - "type": "boolean" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "build": { - "ignore_above": 1024, - "type": "keyword" - }, - "codename": { - "ignore_above": 1024, - "type": "keyword" - }, - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "http": { - "dynamic": "false", - "properties": { - "request": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "method": { - "ignore_above": 1024, - "type": "keyword" - }, - "referrer": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "response": { - "properties": { - "body": { - "properties": { - "bytes": { - "type": "long" - }, - "content": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "bytes": { - "type": "long" - }, - "finished": { - "type": "boolean" - }, - "headers": { - "enabled": false, - "type": "object" - }, - "status_code": { - "type": "long" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "kubernetes": { - "dynamic": "false", - "properties": { - "annotations": { - "properties": { - "*": { - "type": "object" - } - } - }, - "container": { - "properties": { - "image": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "deployment": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "labels": { - "properties": { - "*": { - "type": "object" - } - } - }, - "namespace": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pod": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "uid": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "replicaset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "statefulset": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "labels": { - "dynamic": "true", - "properties": { - "foo": { - "type": "keyword" - }, - "lorem": { - "type": "keyword" - }, - "multi-line": { - "type": "keyword" - }, - "this-is-a-very-long-tag-name-without-any-spaces": { - "type": "keyword" - } - } - }, - "log": { - "properties": { - "level": { - "ignore_above": 1024, - "type": "keyword" - }, - "logger": { - "ignore_above": 1024, - "type": "keyword" - }, - "origin": { - "properties": { - "file": { - "properties": { - "line": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "original": { - "ignore_above": 1024, - "type": "keyword" - }, - "syslog": { - "properties": { - "facility": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "priority": { - "type": "long" - }, - "severity": { - "properties": { - "code": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - } - } - }, - "message": { - "norms": false, - "type": "text" - }, - "network": { - "properties": { - "application": { - "ignore_above": 1024, - "type": "keyword" - }, - "bytes": { - "type": "long" - }, - "community_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "direction": { - "ignore_above": 1024, - "type": "keyword" - }, - "forwarded_ip": { - "type": "ip" - }, - "iana_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "inner": { - "properties": { - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "packets": { - "type": "long" - }, - "protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "transport": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "observer": { - "dynamic": "false", - "properties": { - "egress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hostname": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingress": { - "properties": { - "interface": { - "properties": { - "alias": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "zone": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "listening": { - "ignore_above": 1024, - "type": "keyword" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - }, - "serial_number": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "vendor": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_major": { - "type": "byte" - } - } - }, - "organization": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "package": { - "properties": { - "architecture": { - "ignore_above": 1024, - "type": "keyword" - }, - "build_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "checksum": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "install_scope": { - "ignore_above": 1024, - "type": "keyword" - }, - "installed": { - "type": "date" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "size": { - "type": "long" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "parent": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "process": { - "dynamic": "false", - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "parent": { - "properties": { - "args": { - "ignore_above": 1024, - "type": "keyword" - }, - "args_count": { - "type": "long" - }, - "code_signature": { - "properties": { - "exists": { - "type": "boolean" - }, - "status": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "trusted": { - "type": "boolean" - }, - "valid": { - "type": "boolean" - } - } - }, - "command_line": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "entity_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "executable": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "exit_code": { - "type": "long" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha512": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pe": { - "properties": { - "company": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "file_version": { - "ignore_above": 1024, - "type": "keyword" - }, - "original_file_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "product": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "pgid": { - "type": "long" - }, - "pid": { - "type": "long" - }, - "ppid": { - "type": "long" - }, - "start": { - "type": "date" - }, - "thread": { - "properties": { - "id": { - "type": "long" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "title": { - "ignore_above": 1024, - "type": "keyword" - }, - "uptime": { - "type": "long" - }, - "working_directory": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "processor": { - "properties": { - "event": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "profile": { - "dynamic": "false", - "properties": { - "alloc_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "alloc_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "cpu": { - "properties": { - "ns": { - "type": "long" - } - } - }, - "duration": { - "type": "long" - }, - "inuse_objects": { - "properties": { - "count": { - "type": "long" - } - } - }, - "inuse_space": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "samples": { - "properties": { - "count": { - "type": "long" - } - } - }, - "stack": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - }, - "top": { - "dynamic": "false", - "properties": { - "filename": { - "ignore_above": 1024, - "type": "keyword" - }, - "function": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "line": { - "type": "long" - } - } - } - } - }, - "registry": { - "properties": { - "data": { - "properties": { - "bytes": { - "ignore_above": 1024, - "type": "keyword" - }, - "strings": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hive": { - "ignore_above": 1024, - "type": "keyword" - }, - "key": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "value": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "related": { - "properties": { - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "ip": { - "type": "ip" - }, - "user": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "rule": { - "properties": { - "author": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "license": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "ruleset": { - "ignore_above": 1024, - "type": "keyword" - }, - "uuid": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "server": { - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "service": { - "dynamic": "false", - "properties": { - "environment": { - "ignore_above": 1024, - "type": "keyword" - }, - "ephemeral_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "framework": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "language": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "node": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "runtime": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "state": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "source": { - "dynamic": "false", - "properties": { - "address": { - "ignore_above": 1024, - "type": "keyword" - }, - "as": { - "properties": { - "number": { - "type": "long" - }, - "organization": { - "properties": { - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "bytes": { - "type": "long" - }, - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "geo": { - "properties": { - "city_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "continent_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "country_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "location": { - "type": "geo_point" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_iso_code": { - "ignore_above": 1024, - "type": "keyword" - }, - "region_name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "ip": { - "type": "ip" - }, - "mac": { - "ignore_above": 1024, - "type": "keyword" - }, - "nat": { - "properties": { - "ip": { - "type": "ip" - }, - "port": { - "type": "long" - } - } - }, - "packets": { - "type": "long" - }, - "port": { - "type": "long" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "user": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "sourcemap": { - "dynamic": "false", - "properties": { - "bundle_filepath": { - "ignore_above": 1024, - "type": "keyword" - }, - "service": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "span": { - "dynamic": "false", - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "db": { - "dynamic": "false", - "properties": { - "link": { - "ignore_above": 1024, - "type": "keyword" - }, - "rows_affected": { - "type": "long" - } - } - }, - "destination": { - "dynamic": "false", - "properties": { - "service": { - "dynamic": "false", - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "resource": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "duration": { - "properties": { - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "start": { - "properties": { - "us": { - "type": "long" - } - } - }, - "subtype": { - "ignore_above": 1024, - "type": "keyword" - }, - "sync": { - "type": "boolean" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "system": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "actual": { - "properties": { - "free": { - "type": "long" - } - } - }, - "total": { - "type": "long" - } - } - }, - "process": { - "properties": { - "cpu": { - "properties": { - "total": { - "properties": { - "norm": { - "properties": { - "pct": { - "scaling_factor": 1000, - "type": "scaled_float" - } - } - } - } - } - } - }, - "memory": { - "properties": { - "rss": { - "properties": { - "bytes": { - "type": "long" - } - } - }, - "size": { - "type": "long" - } - } - } - } - } - } - }, - "tags": { - "ignore_above": 1024, - "type": "keyword" - }, - "threat": { - "properties": { - "framework": { - "ignore_above": 1024, - "type": "keyword" - }, - "tactic": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "technique": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "timeseries": { - "properties": { - "instance": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "timestamp": { - "properties": { - "us": { - "type": "long" - } - } - }, - "tls": { - "properties": { - "cipher": { - "ignore_above": 1024, - "type": "keyword" - }, - "client": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "server_name": { - "ignore_above": 1024, - "type": "keyword" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - }, - "supported_ciphers": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "curve": { - "ignore_above": 1024, - "type": "keyword" - }, - "established": { - "type": "boolean" - }, - "next_protocol": { - "ignore_above": 1024, - "type": "keyword" - }, - "resumed": { - "type": "boolean" - }, - "server": { - "properties": { - "certificate": { - "ignore_above": 1024, - "type": "keyword" - }, - "certificate_chain": { - "ignore_above": 1024, - "type": "keyword" - }, - "hash": { - "properties": { - "md5": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha1": { - "ignore_above": 1024, - "type": "keyword" - }, - "sha256": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "issuer": { - "ignore_above": 1024, - "type": "keyword" - }, - "ja3s": { - "ignore_above": 1024, - "type": "keyword" - }, - "not_after": { - "type": "date" - }, - "not_before": { - "type": "date" - }, - "subject": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - }, - "version_protocol": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "trace": { - "dynamic": "false", - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "tracing": { - "properties": { - "trace": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "transaction": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "transaction": { - "dynamic": "false", - "properties": { - "breakdown": { - "properties": { - "count": { - "type": "long" - } - } - }, - "duration": { - "properties": { - "count": { - "type": "long" - }, - "histogram": { - "type": "histogram" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - }, - "us": { - "type": "long" - } - } - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "marks": { - "dynamic": "true", - "properties": { - "*": { - "properties": { - "*": { - "dynamic": "true", - "type": "object" - } - } - }, - "agent": { - "properties": { - "domComplete": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "domInteractive": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "firstContentfulPaint": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "largestContentfulPaint": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "timeToFirstByte": { - "scaling_factor": 1000000, - "type": "scaled_float" - } - } - }, - "navigationTiming": { - "properties": { - "connectEnd": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "connectStart": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "domComplete": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "domContentLoadedEventEnd": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "domContentLoadedEventStart": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "domInteractive": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "domLoading": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "domainLookupEnd": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "domainLookupStart": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "fetchStart": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "loadEventEnd": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "loadEventStart": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "requestStart": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "responseEnd": { - "scaling_factor": 1000000, - "type": "scaled_float" - }, - "responseStart": { - "scaling_factor": 1000000, - "type": "scaled_float" - } - } - } - } - }, - "message": { - "dynamic": "false", - "properties": { - "age": { - "properties": { - "ms": { - "type": "long" - } - } - }, - "queue": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "result": { - "ignore_above": 1024, - "type": "keyword" - }, - "root": { - "type": "boolean" - }, - "sampled": { - "type": "boolean" - }, - "self_time": { - "properties": { - "count": { - "type": "long" - }, - "sum": { - "properties": { - "us": { - "type": "long" - } - } - } - } - }, - "span_count": { - "properties": { - "dropped": { - "type": "long" - } - } - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "url": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "extension": { - "ignore_above": 1024, - "type": "keyword" - }, - "fragment": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "password": { - "ignore_above": 1024, - "type": "keyword" - }, - "path": { - "ignore_above": 1024, - "type": "keyword" - }, - "port": { - "type": "long" - }, - "query": { - "ignore_above": 1024, - "type": "keyword" - }, - "registered_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "scheme": { - "ignore_above": 1024, - "type": "keyword" - }, - "top_level_domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "username": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user": { - "dynamic": "false", - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "email": { - "ignore_above": 1024, - "type": "keyword" - }, - "full_name": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "group": { - "properties": { - "domain": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "user_agent": { - "dynamic": "false", - "properties": { - "device": { - "properties": { - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "os": { - "properties": { - "family": { - "ignore_above": 1024, - "type": "keyword" - }, - "full": { - "ignore_above": 1024, - "type": "keyword" - }, - "kernel": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - }, - "platform": { - "ignore_above": 1024, - "type": "keyword" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "view spans": { - "ignore_above": 1024, - "type": "keyword" - }, - "vlan": { - "properties": { - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "name": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "vulnerability": { - "properties": { - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "classification": { - "ignore_above": 1024, - "type": "keyword" - }, - "description": { - "fields": { - "text": { - "norms": false, - "type": "text" - } - }, - "ignore_above": 1024, - "type": "keyword" - }, - "enumeration": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "report_id": { - "ignore_above": 1024, - "type": "keyword" - }, - "scanner": { - "properties": { - "vendor": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "score": { - "properties": { - "base": { - "type": "float" - }, - "environmental": { - "type": "float" - }, - "temporal": { - "type": "float" - }, - "version": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, - "severity": { - "ignore_above": 1024, - "type": "keyword" - } - } - } - } - }, - "settings": { - "index": { - "codec": "best_compression", - "lifecycle": { - "name": "apm-rollover-30-days", - "rollover_alias": "apm-8.0.0-transaction" - }, - "mapping": { - "total_fields": { - "limit": "2000" - } - }, - "number_of_replicas": "0", - "number_of_shards": "1", - "priority": "100", - "query": { - "default_field": [ - "message", - "tags", - "agent.ephemeral_id", - "agent.id", - "agent.name", - "agent.type", - "agent.version", - "as.organization.name", - "client.address", - "client.as.organization.name", - "client.domain", - "client.geo.city_name", - "client.geo.continent_name", - "client.geo.country_iso_code", - "client.geo.country_name", - "client.geo.name", - "client.geo.region_iso_code", - "client.geo.region_name", - "client.mac", - "client.registered_domain", - "client.top_level_domain", - "client.user.domain", - "client.user.email", - "client.user.full_name", - "client.user.group.domain", - "client.user.group.id", - "client.user.group.name", - "client.user.hash", - "client.user.id", - "client.user.name", - "cloud.account.id", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.provider", - "cloud.region", - "container.id", - "container.image.name", - "container.image.tag", - "container.name", - "container.runtime", - "destination.address", - "destination.as.organization.name", - "destination.domain", - "destination.geo.city_name", - "destination.geo.continent_name", - "destination.geo.country_iso_code", - "destination.geo.country_name", - "destination.geo.name", - "destination.geo.region_iso_code", - "destination.geo.region_name", - "destination.mac", - "destination.registered_domain", - "destination.top_level_domain", - "destination.user.domain", - "destination.user.email", - "destination.user.full_name", - "destination.user.group.domain", - "destination.user.group.id", - "destination.user.group.name", - "destination.user.hash", - "destination.user.id", - "destination.user.name", - "dns.answers.class", - "dns.answers.data", - "dns.answers.name", - "dns.answers.type", - "dns.header_flags", - "dns.id", - "dns.op_code", - "dns.question.class", - "dns.question.name", - "dns.question.registered_domain", - "dns.question.subdomain", - "dns.question.top_level_domain", - "dns.question.type", - "dns.response_code", - "dns.type", - "ecs.version", - "error.code", - "error.id", - "error.message", - "error.stack_trace", - "error.type", - "event.action", - "event.category", - "event.code", - "event.dataset", - "event.hash", - "event.id", - "event.kind", - "event.module", - "event.original", - "event.outcome", - "event.provider", - "event.timezone", - "event.type", - "file.device", - "file.directory", - "file.extension", - "file.gid", - "file.group", - "file.hash.md5", - "file.hash.sha1", - "file.hash.sha256", - "file.hash.sha512", - "file.inode", - "file.mode", - "file.name", - "file.owner", - "file.path", - "file.target_path", - "file.type", - "file.uid", - "geo.city_name", - "geo.continent_name", - "geo.country_iso_code", - "geo.country_name", - "geo.name", - "geo.region_iso_code", - "geo.region_name", - "group.domain", - "group.id", - "group.name", - "hash.md5", - "hash.sha1", - "hash.sha256", - "hash.sha512", - "host.architecture", - "host.geo.city_name", - "host.geo.continent_name", - "host.geo.country_iso_code", - "host.geo.country_name", - "host.geo.name", - "host.geo.region_iso_code", - "host.geo.region_name", - "host.hostname", - "host.id", - "host.mac", - "host.name", - "host.os.family", - "host.os.full", - "host.os.kernel", - "host.os.name", - "host.os.platform", - "host.os.version", - "host.type", - "host.user.domain", - "host.user.email", - "host.user.full_name", - "host.user.group.domain", - "host.user.group.id", - "host.user.group.name", - "host.user.hash", - "host.user.id", - "host.user.name", - "http.request.body.content", - "http.request.method", - "http.request.referrer", - "http.response.body.content", - "http.version", - "log.level", - "log.logger", - "log.origin.file.name", - "log.origin.function", - "log.original", - "log.syslog.facility.name", - "log.syslog.severity.name", - "network.application", - "network.community_id", - "network.direction", - "network.iana_number", - "network.name", - "network.protocol", - "network.transport", - "network.type", - "observer.geo.city_name", - "observer.geo.continent_name", - "observer.geo.country_iso_code", - "observer.geo.country_name", - "observer.geo.name", - "observer.geo.region_iso_code", - "observer.geo.region_name", - "observer.hostname", - "observer.mac", - "observer.name", - "observer.os.family", - "observer.os.full", - "observer.os.kernel", - "observer.os.name", - "observer.os.platform", - "observer.os.version", - "observer.product", - "observer.serial_number", - "observer.type", - "observer.vendor", - "observer.version", - "organization.id", - "organization.name", - "os.family", - "os.full", - "os.kernel", - "os.name", - "os.platform", - "os.version", - "package.architecture", - "package.checksum", - "package.description", - "package.install_scope", - "package.license", - "package.name", - "package.path", - "package.version", - "process.args", - "text", - "process.executable", - "process.hash.md5", - "process.hash.sha1", - "process.hash.sha256", - "process.hash.sha512", - "process.name", - "text", - "text", - "text", - "text", - "text", - "process.thread.name", - "process.title", - "process.working_directory", - "server.address", - "server.as.organization.name", - "server.domain", - "server.geo.city_name", - "server.geo.continent_name", - "server.geo.country_iso_code", - "server.geo.country_name", - "server.geo.name", - "server.geo.region_iso_code", - "server.geo.region_name", - "server.mac", - "server.registered_domain", - "server.top_level_domain", - "server.user.domain", - "server.user.email", - "server.user.full_name", - "server.user.group.domain", - "server.user.group.id", - "server.user.group.name", - "server.user.hash", - "server.user.id", - "server.user.name", - "service.ephemeral_id", - "service.id", - "service.name", - "service.node.name", - "service.state", - "service.type", - "service.version", - "source.address", - "source.as.organization.name", - "source.domain", - "source.geo.city_name", - "source.geo.continent_name", - "source.geo.country_iso_code", - "source.geo.country_name", - "source.geo.name", - "source.geo.region_iso_code", - "source.geo.region_name", - "source.mac", - "source.registered_domain", - "source.top_level_domain", - "source.user.domain", - "source.user.email", - "source.user.full_name", - "source.user.group.domain", - "source.user.group.id", - "source.user.group.name", - "source.user.hash", - "source.user.id", - "source.user.name", - "threat.framework", - "threat.tactic.id", - "threat.tactic.name", - "threat.tactic.reference", - "threat.technique.id", - "threat.technique.name", - "threat.technique.reference", - "tracing.trace.id", - "tracing.transaction.id", - "url.domain", - "url.extension", - "url.fragment", - "url.full", - "url.original", - "url.password", - "url.path", - "url.query", - "url.registered_domain", - "url.scheme", - "url.top_level_domain", - "url.username", - "user.domain", - "user.email", - "user.full_name", - "user.group.domain", - "user.group.id", - "user.group.name", - "user.hash", - "user.id", - "user.name", - "user_agent.device.name", - "user_agent.name", - "text", - "user_agent.original", - "user_agent.os.family", - "user_agent.os.full", - "user_agent.os.kernel", - "user_agent.os.name", - "user_agent.os.platform", - "user_agent.os.version", - "user_agent.version", - "text", - "timeseries.instance", - "cloud.project.id", - "cloud.image.id", - "host.os.build", - "host.os.codename", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.replicaset.name", - "kubernetes.deployment.name", - "kubernetes.statefulset.name", - "kubernetes.container.name", - "kubernetes.container.image", - "processor.name", - "processor.event", - "url.scheme", - "url.full", - "url.domain", - "url.path", - "url.query", - "url.fragment", - "http.version", - "http.request.method", - "http.request.referrer", - "service.name", - "service.version", - "service.environment", - "service.node.name", - "service.language.name", - "service.language.version", - "service.runtime.name", - "service.runtime.version", - "service.framework.name", - "service.framework.version", - "transaction.id", - "transaction.type", - "text", - "transaction.name", - "span.type", - "span.subtype", - "trace.id", - "parent.id", - "agent.name", - "agent.version", - "agent.ephemeral_id", - "container.id", - "kubernetes.namespace", - "kubernetes.node.name", - "kubernetes.pod.name", - "kubernetes.pod.uid", - "host.architecture", - "host.hostname", - "host.name", - "host.os.platform", - "process.args", - "process.title", - "observer.listening", - "observer.hostname", - "observer.version", - "observer.type", - "user.name", - "user.id", - "user.email", - "destination.address", - "text", - "user_agent.original", - "user_agent.name", - "user_agent.version", - "user_agent.device.name", - "user_agent.os.platform", - "user_agent.os.name", - "user_agent.os.full", - "user_agent.os.family", - "user_agent.os.version", - "user_agent.os.kernel", - "cloud.account.id", - "cloud.account.name", - "cloud.availability_zone", - "cloud.instance.id", - "cloud.instance.name", - "cloud.machine.type", - "cloud.project.id", - "cloud.project.name", - "cloud.provider", - "cloud.region", - "error.id", - "error.culprit", - "error.grouping_key", - "error.exception.code", - "error.exception.message", - "error.exception.module", - "error.exception.type", - "error.log.level", - "error.log.logger_name", - "error.log.message", - "error.log.param_message", - "profile.top.id", - "profile.top.function", - "profile.top.filename", - "profile.stack.id", - "profile.stack.function", - "profile.stack.filename", - "sourcemap.service.name", - "sourcemap.service.version", - "sourcemap.bundle_filepath", - "view spans", - "child.id", - "span.id", - "span.name", - "span.action", - "span.db.link", - "span.destination.service.type", - "span.destination.service.name", - "span.destination.service.resource", - "span.message.queue.name", - "transaction.result", - "transaction.message.queue.name", - "fields.*" - ] - }, - "refresh_interval": "1ms" - } - } - } -} \ No newline at end of file diff --git a/x-pack/test/case_api_integration/common/lib/utils.ts b/x-pack/test/case_api_integration/common/lib/utils.ts index fb6f4fce3c29a..c23df53c4feef 100644 --- a/x-pack/test/case_api_integration/common/lib/utils.ts +++ b/x-pack/test/case_api_integration/common/lib/utils.ts @@ -66,7 +66,7 @@ export const getJiraConnector = () => ({ config: { apiUrl: 'http://some.non.existent.com', projectKey: 'pkey', - casesConfiguration: { + incidentConfiguration: { mapping: [ { source: 'title', @@ -85,6 +85,7 @@ export const getJiraConnector = () => ({ }, ], }, + isCaseOwned: true, }, }); diff --git a/x-pack/test/functional/apps/maps/index.js b/x-pack/test/functional/apps/maps/index.js index ef8b4ad4c0f19..03b75601ec2a8 100644 --- a/x-pack/test/functional/apps/maps/index.js +++ b/x-pack/test/functional/apps/maps/index.js @@ -28,7 +28,7 @@ export default function ({ loadTestFile, getService }) { }); describe('', function () { - this.tags('ciGroup7'); + this.tags('ciGroup9'); loadTestFile(require.resolve('./documents_source')); loadTestFile(require.resolve('./blended_vector_layer')); loadTestFile(require.resolve('./vector_styling')); diff --git a/x-pack/test/functional/page_objects/space_selector_page.ts b/x-pack/test/functional/page_objects/space_selector_page.ts index 90196c89170dd..b272175ff2b21 100644 --- a/x-pack/test/functional/page_objects/space_selector_page.ts +++ b/x-pack/test/functional/page_objects/space_selector_page.ts @@ -50,6 +50,126 @@ export function SpaceSelectorPageProvider({ getService, getPageObjects }: FtrPro return await testSubjects.click('spacesNavSelector'); } + async clickManageSpaces() { + await testSubjects.click('manageSpaces'); + } + + async clickCreateSpace() { + await testSubjects.click('createSpace'); + } + + async clickEnterSpaceName() { + await testSubjects.click('addSpaceName'); + } + + async addSpaceName(spaceName: string) { + await testSubjects.setValue('addSpaceName', spaceName); + } + + async clickSpaceAcustomAvatar() { + await testSubjects.click('space-avatar-space_a'); + } + + async clickSpaceInitials() { + await testSubjects.click('spaceLetterInitial'); + } + + async addSpaceInitials(spaceInitials: string) { + await testSubjects.setValue('spaceLetterInitial', spaceInitials); + } + + async clickColorPicker() { + await testSubjects.click('colorPickerAnchor'); + } + + async setColorinPicker(hexValue: string) { + await testSubjects.setValue('colorPickerAnchor', hexValue); + } + + async clickShowFeatures() { + await testSubjects.click('show-hide-section-link'); + } + + async clickChangeAllPriv() { + await testSubjects.click('changeAllPrivilegesButton'); + } + + async clickSaveSpaceCreation() { + await testSubjects.click('save-space-button'); + } + + async clickSpaceEditButton(spaceName: string) { + await testSubjects.click(`${spaceName}-editSpace`); + } + + async clickGoToRolesPage() { + await testSubjects.click('rolesManagementPage'); + } + + async clickCancelSpaceCreation() { + await testSubjects.click('cancel-space-button'); + } + + async clickOnCustomizeURL() { + await testSubjects.click('CustomizeOrReset'); + } + + async clickOnSpaceURLDisplay() { + await testSubjects.click('spaceURLDisplay'); + } + + async setSpaceURL(spaceURL: string) { + await testSubjects.setValue('spaceURLDisplay', spaceURL); + } + + async clickFeaturesVisibilityButton() { + await testSubjects.click('changeAllFeatureVisibilityPopover'); + } + + async clickHideAllFeatures() { + await testSubjects.click('spc-toggle-all-features-hide'); + } + + async clickShowAllFeatures() { + await testSubjects.click('spc-toggle-all-features-show'); + } + + async toggleFeatureVisibility(featureName: string) { + await testSubjects.click(`feature-${featureName}-toggle`); + } + + async clickOnDescriptionOfSpace() { + await testSubjects.click('descriptionSpaceText'); + } + + async setOnDescriptionOfSpace(descriptionSpace: string) { + await testSubjects.setValue('descriptionSpaceText', descriptionSpace); + } + + async clickOnDeleteSpaceButton(spaceName: string) { + await testSubjects.click(`${spaceName}-deleteSpace`); + } + + async setSpaceNameTobeDeleted(spaceName: string) { + await testSubjects.setValue('deleteSpaceInput', spaceName); + } + + async cancelDeletingSpace() { + await testSubjects.click('confirmModalCancelButton'); + } + + async confirmDeletingSpace() { + await testSubjects.click('confirmModalConfirmButton'); + } + + async clickOnSpaceb() { + await testSubjects.click('space-avatar-space_b'); + } + + async goToSpecificSpace(spaceName: string) { + await testSubjects.click(`${spaceName}-gotoSpace`); + } + async clickSpaceAvatar(spaceId: string) { return await retry.try(async () => { log.info(`SpaceSelectorPage:clickSpaceAvatar(${spaceId})`); diff --git a/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts b/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts index ffa1d9fd46c75..e01e065867ac7 100644 --- a/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts +++ b/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts @@ -10,25 +10,9 @@ import { FtrProviderContext } from '../../ftr_provider_context'; import { MlCommonUI } from './common_ui'; import { MlApi } from './api'; import { - ClassificationAnalysis, - RegressionAnalysis, -} from '../../../../plugins/ml/common/types/data_frame_analytics'; - -enum ANALYSIS_CONFIG_TYPE { - OUTLIER_DETECTION = 'outlier_detection', - REGRESSION = 'regression', - CLASSIFICATION = 'classification', -} - -const isRegressionAnalysis = (arg: any): arg is RegressionAnalysis => { - const keys = Object.keys(arg); - return keys.length === 1 && keys[0] === ANALYSIS_CONFIG_TYPE.REGRESSION; -}; - -const isClassificationAnalysis = (arg: any): arg is ClassificationAnalysis => { - const keys = Object.keys(arg); - return keys.length === 1 && keys[0] === ANALYSIS_CONFIG_TYPE.CLASSIFICATION; -}; + isRegressionAnalysis, + isClassificationAnalysis, +} from '../../../../plugins/ml/common/util/analytics_utils'; export function MachineLearningDataFrameAnalyticsCreationProvider( { getService }: FtrProviderContext, diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts index c7cfee565b2e9..198c129b7482f 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/install_remove_assets.ts @@ -84,6 +84,13 @@ export default function (providerContext: FtrProviderContext) { }); expect(resSettings.statusCode).equal(200); }); + it('should have installed the transform components', async function () { + const res = await es.transport.request({ + method: 'GET', + path: `/_transform/${logsTemplateName}-default-${pkgVersion}`, + }); + expect(res.statusCode).equal(200); + }); it('should have installed the kibana assets', async function () { const resIndexPatternLogs = await kibanaServer.savedObjects.get({ type: 'index-pattern', @@ -161,6 +168,10 @@ export default function (providerContext: FtrProviderContext) { id: 'metrics-all_assets.test_metrics', type: 'index_template', }, + { + id: 'logs-all_assets.test_logs-default-0.1.0', + type: 'transform', + }, ], es_index_patterns: { test_logs: 'logs-all_assets.test_logs-*', @@ -237,6 +248,18 @@ export default function (providerContext: FtrProviderContext) { ); expect(resPipeline2.statusCode).equal(404); }); + it('should have uninstalled the transforms', async function () { + const res = await es.transport.request( + { + method: 'GET', + path: `/_transform/${logsTemplateName}-default-${pkgVersion}`, + }, + { + ignore: [404], + } + ); + expect(res.statusCode).equal(404); + }); it('should have uninstalled the kibana assets', async function () { let resDashboard; try { diff --git a/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/elasticsearch/transform/default.json b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/elasticsearch/transform/default.json new file mode 100644 index 0000000000000..27f75af131eed --- /dev/null +++ b/x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/dataset/test_logs/elasticsearch/transform/default.json @@ -0,0 +1,35 @@ +{ + "source": { + "index": "logs-all_assets.test_log-default*" + }, + "dest": { + "index": "logs-all_assets.test_log_current-default" + }, + "pivot": { + "group_by": { + "agent.id": { + "terms": { + "field": "agent.id" + } + } + }, + "aggregations": { + "HostDetails": { + "scripted_metric": { + "init_script": "state.timestamp_latest = 0L; state.last_doc=''", + "map_script": "def current_date = doc['@timestamp'].getValue().toInstant().toEpochMilli(); if (current_date \u003e state.timestamp_latest) {state.timestamp_latest = current_date;state.last_doc = new HashMap(params['_source']);}", + "combine_script": "return state", + "reduce_script": "def last_doc = '';def timestamp_latest = 0L; for (s in states) {if (s.timestamp_latest \u003e (timestamp_latest)) {timestamp_latest = s.timestamp_latest; last_doc = s.last_doc;}} return last_doc" + } + } + } + }, + "description": "collapse and update the latest document for each host", + "frequency": "1m", + "sync": { + "time": { + "field": "event.ingested", + "delay": "60s" + } + } +} diff --git a/x-pack/test/ingest_manager_api_integration/config.ts b/x-pack/test/ingest_manager_api_integration/config.ts index 08d5da148b51e..94fbee0593d3e 100644 --- a/x-pack/test/ingest_manager_api_integration/config.ts +++ b/x-pack/test/ingest_manager_api_integration/config.ts @@ -12,7 +12,7 @@ import { defineDockerServersConfig } from '@kbn/test'; // Docker image to use for Ingest Manager API integration tests. // This hash comes from the commit hash here: https://github.com/elastic/package-storage/commit export const dockerImage = - 'docker.elastic.co/package-registry/distribution:f6b01daec8cfe355101e366de9941d35a4c3763e'; + 'docker.elastic.co/package-registry/distribution:5e0e12ce1bc2cb0c2f67f2e07d11b9a6043bcf25'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { const xPackAPITestsConfig = await readConfigFile(require.resolve('../api_integration/config.ts')); diff --git a/x-pack/test/kerberos_api_integration/apis/security/kerberos_login.ts b/x-pack/test/kerberos_api_integration/apis/security/kerberos_login.ts index 1f4428e198539..459dc4739897c 100644 --- a/x-pack/test/kerberos_api_integration/apis/security/kerberos_login.ts +++ b/x-pack/test/kerberos_api_integration/apis/security/kerberos_login.ts @@ -79,9 +79,9 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); expect(user.username).to.eql(username); - expect(user.authentication_realm).to.eql({ name: 'reserved', type: 'reserved' }); expect(user.authentication_provider).to.eql('basic'); expect(user.authentication_type).to.eql('realm'); + // Do not assert on the `authentication_realm`, as the value differes for on-prem vs cloud }); describe('initiating SPNEGO', () => { diff --git a/x-pack/test/login_selector_api_integration/apis/login_selector.ts b/x-pack/test/login_selector_api_integration/apis/login_selector.ts index 7eb1f07d67506..44582355cf890 100644 --- a/x-pack/test/login_selector_api_integration/apis/login_selector.ts +++ b/x-pack/test/login_selector_api_integration/apis/login_selector.ts @@ -36,7 +36,7 @@ export default function ({ getService }: FtrProviderContext) { sessionCookie: Cookie, username: string, providerName: string, - authenticationRealm: { name: string; type: string }, + authenticationRealm: { name: string; type: string } | null, authenticationType: string ) { expect(sessionCookie.key).to.be('sid'); @@ -67,7 +67,9 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.body.username).to.be(username); expect(apiResponse.body.authentication_provider).to.be(providerName); - expect(apiResponse.body.authentication_realm).to.eql(authenticationRealm); + if (authenticationRealm) { + expect(apiResponse.body.authentication_realm).to.eql(authenticationRealm); + } expect(apiResponse.body.authentication_type).to.be(authenticationType); } @@ -228,16 +230,9 @@ export default function ({ getService }: FtrProviderContext) { const basicSessionCookie = request.cookie( basicAuthenticationResponse.headers['set-cookie'][0] )!; - await checkSessionCookie( - basicSessionCookie, - 'elastic', - 'basic1', - { - name: 'reserved', - type: 'reserved', - }, - 'realm' - ); + // Skip auth provider check since this comes from the reserved realm, + // which is not available when running on ESS + await checkSessionCookie(basicSessionCookie, 'elastic', 'basic1', null, 'realm'); const authenticationResponse = await supertest .post('/api/security/saml/callback') diff --git a/x-pack/test/oidc_api_integration/apis/authorization_code_flow/oidc_auth.ts b/x-pack/test/oidc_api_integration/apis/authorization_code_flow/oidc_auth.ts index 0a230ac84d991..c2335cf04504f 100644 --- a/x-pack/test/oidc_api_integration/apis/authorization_code_flow/oidc_auth.ts +++ b/x-pack/test/oidc_api_integration/apis/authorization_code_flow/oidc_auth.ts @@ -43,9 +43,9 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); expect(user.username).to.eql(username); - expect(user.authentication_realm).to.eql({ name: 'reserved', type: 'reserved' }); expect(user.authentication_provider).to.eql('basic'); expect(user.authentication_type).to.be('realm'); + // Do not assert on the `authentication_realm`, as the value differes for on-prem vs cloud }); describe('initiating handshake', () => { diff --git a/x-pack/test/pki_api_integration/apis/security/pki_auth.ts b/x-pack/test/pki_api_integration/apis/security/pki_auth.ts index 2f6b088ab7190..0559e9e96fe3f 100644 --- a/x-pack/test/pki_api_integration/apis/security/pki_auth.ts +++ b/x-pack/test/pki_api_integration/apis/security/pki_auth.ts @@ -93,8 +93,8 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); expect(user.username).to.eql(username); - expect(user.authentication_realm).to.eql({ name: 'reserved', type: 'reserved' }); expect(user.authentication_provider).to.eql('basic'); + // Do not assert on the `authentication_realm`, as the value differes for on-prem vs cloud }); it('should properly set cookie and authenticate user', async () => { diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/spaces.ts b/x-pack/test/reporting_api_integration/reporting_and_security/spaces.ts index 6a68bd530cf63..9eafd0c318383 100644 --- a/x-pack/test/reporting_api_integration/reporting_and_security/spaces.ts +++ b/x-pack/test/reporting_api_integration/reporting_and_security/spaces.ts @@ -27,8 +27,7 @@ export default function ({ getService }: FtrProviderContext) { ); }; - // FLAKY: https://github.com/elastic/kibana/issues/76551 - describe.skip('Exports from Non-default Space', () => { + describe('Exports from Non-default Space', () => { before(async () => { await esArchiver.load('reporting/ecommerce'); await esArchiver.load('reporting/ecommerce_kibana_spaces'); // dashboard in non default space @@ -54,7 +53,8 @@ export default function ({ getService }: FtrProviderContext) { expect(reportCompleted).to.match(/^"order_date",/); }); - it('should complete a job of PNG export of a dashboard in non-default space', async () => { + // FLAKY: https://github.com/elastic/kibana/issues/76551 + it.skip('should complete a job of PNG export of a dashboard in non-default space', async () => { const downloadPath = await reportingAPI.postJob( `/s/non_default_space/api/reporting/generate/png?jobParams=%28browserTimezone%3AUTC%2Clayout%3A%28dimensions%3A%28height%3A512%2Cwidth%3A2402%29%2Cid%3Apng%29%2CobjectType%3Adashboard%2CrelativeUrl%3A%27%2Fs%2Fnon_default_space%2Fapp%2Fdashboards%23%2Fview%2F3c9ee360-e7ee-11ea-a730-d58e9ea7581b%3F_g%3D%28filters%3A%21%21%28%29%2CrefreshInterval%3A%28pause%3A%21%21t%2Cvalue%3A0%29%2Ctime%3A%28from%3A%21%272019-06-10T03%3A17%3A28.800Z%21%27%2Cto%3A%21%272019-07-14T19%3A25%3A06.385Z%21%27%29%29%26_a%3D%28description%3A%21%27%21%27%2Cfilters%3A%21%21%28%29%2CfullScreenMode%3A%21%21f%2Coptions%3A%28hidePanelTitles%3A%21%21f%2CuseMargins%3A%21%21t%29%2Cquery%3A%28language%3Akuery%2Cquery%3A%21%27%21%27%29%2CtimeRestore%3A%21%21t%2Ctitle%3A%21%27Ecom%2520Dashboard%2520Non%2520Default%2520Space%21%27%2CviewMode%3Aview%29%27%2Ctitle%3A%27Ecom%20Dashboard%20Non%20Default%20Space%27%29` ); @@ -64,7 +64,8 @@ export default function ({ getService }: FtrProviderContext) { expect(reportCompleted).to.not.be(null); }); - it('should complete a job of PDF export of a dashboard in non-default space', async () => { + // FLAKY: https://github.com/elastic/kibana/issues/76551 + it.skip('should complete a job of PDF export of a dashboard in non-default space', async () => { const downloadPath = await reportingAPI.postJob( `/s/non_default_space/api/reporting/generate/printablePdf?jobParams=%28browserTimezone%3AUTC%2Clayout%3A%28dimensions%3A%28height%3A512%2Cwidth%3A2402%29%2Cid%3Apreserve_layout%29%2CobjectType%3Adashboard%2CrelativeUrls%3A%21%28%27%2Fs%2Fnon_default_space%2Fapp%2Fdashboards%23%2Fview%2F3c9ee360-e7ee-11ea-a730-d58e9ea7581b%3F_g%3D%28filters%3A%21%21%28%29%2CrefreshInterval%3A%28pause%3A%21%21t%2Cvalue%3A0%29%2Ctime%3A%28from%3A%21%272019-06-10T03%3A17%3A28.800Z%21%27%2Cto%3A%21%272019-07-14T19%3A25%3A06.385Z%21%27%29%29%26_a%3D%28description%3A%21%27%21%27%2Cfilters%3A%21%21%28%29%2CfullScreenMode%3A%21%21f%2Coptions%3A%28hidePanelTitles%3A%21%21f%2CuseMargins%3A%21%21t%29%2Cquery%3A%28language%3Akuery%2Cquery%3A%21%27%21%27%29%2CtimeRestore%3A%21%21t%2Ctitle%3A%21%27Ecom%2520Dashboard%2520Non%2520Default%2520Space%21%27%2CviewMode%3Aview%29%27%29%2Ctitle%3A%27Ecom%20Dashboard%20Non%20Default%20Space%27%29` ); diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/usage.ts b/x-pack/test/reporting_api_integration/reporting_and_security/usage.ts index 49db8696c1134..aaf4dd3926411 100644 --- a/x-pack/test/reporting_api_integration/reporting_and_security/usage.ts +++ b/x-pack/test/reporting_api_integration/reporting_and_security/usage.ts @@ -21,8 +21,7 @@ export default function ({ getService }: FtrProviderContext) { const reportingAPI = getService('reportingAPI'); const usageAPI = getService('usageAPI'); - // FAILING: https://github.com/elastic/kibana/issues/76581 - describe.skip('Usage', () => { + describe('Usage', () => { before(async () => { await esArchiver.load(OSS_KIBANA_ARCHIVE_PATH); await esArchiver.load(OSS_DATA_ARCHIVE_PATH); @@ -116,7 +115,8 @@ export default function ({ getService }: FtrProviderContext) { }); }); - describe('from new jobs posted', () => { + // FAILING: https://github.com/elastic/kibana/issues/76581 + describe.skip('from new jobs posted', () => { it('should handle csv', async () => { await reportingAPI.expectAllJobsToFinishSuccessfully( await Promise.all([ diff --git a/x-pack/test/saml_api_integration/apis/security/saml_login.ts b/x-pack/test/saml_api_integration/apis/security/saml_login.ts index 501e1e5f2c203..2da7c92cd07b6 100644 --- a/x-pack/test/saml_api_integration/apis/security/saml_login.ts +++ b/x-pack/test/saml_api_integration/apis/security/saml_login.ts @@ -93,9 +93,9 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); expect(user.username).to.eql(username); - expect(user.authentication_realm).to.eql({ name: 'reserved', type: 'reserved' }); expect(user.authentication_provider).to.eql('basic'); expect(user.authentication_type).to.be('realm'); + // Do not assert on the `authentication_realm`, as the value differes for on-prem vs cloud }); describe('initiating handshake', () => { diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/index.ts b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/index.ts index 81ffc5eea9220..ed501b235a457 100644 --- a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/index.ts +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/index.ts @@ -12,7 +12,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { const supertest = getService('supertest'); describe('saved objects security and spaces enabled', function () { - this.tags('ciGroup5'); + this.tags('ciGroup8'); before(async () => { await createUsersAndRoles(es, supertest); diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts index c9385bf9cebf2..ebd5ff0afee77 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts @@ -6,7 +6,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -import { deleteMetadataStream } from '../../../security_solution_endpoint_api_int/apis/data_stream_helper'; + +import { + deleteMetadataCurrentStream, + deleteMetadataStream, +} from '../../../security_solution_endpoint_api_int/apis/data_stream_helper'; + export default ({ getPageObjects, getService }: FtrProviderContext) => { const pageObjects = getPageObjects(['common', 'endpoint', 'header', 'endpointPageUtils']); const esArchiver = getService('esArchiver'); @@ -23,6 +28,16 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { 'Version', 'Last Active', ], + [ + 'rezzani-7.example.com', + 'Error', + 'Default', + 'Failure', + 'windows 10.0', + '10.101.149.26, 2606:a000:ffc0:39:11ef:37b9:3371:578c', + '6.8.0', + 'Jan 24, 2020 @ 16:06:09.541', + ], [ 'cadmann-4.example.com', 'Error', @@ -43,16 +58,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { '6.0.0', 'Jan 24, 2020 @ 16:06:09.541', ], - [ - 'rezzani-7.example.com', - 'Error', - 'Default', - 'Failure', - 'windows 10.0', - '10.101.149.26, 2606:a000:ffc0:39:11ef:37b9:3371:578c', - '6.8.0', - 'Jan 24, 2020 @ 16:06:09.541', - ], ]; describe('endpoint list', function () { @@ -61,10 +66,13 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('when initially navigating to page', () => { before(async () => { + await deleteMetadataStream(getService); + await deleteMetadataCurrentStream(getService); await pageObjects.endpoint.navigateToEndpointList(); }); after(async () => { await deleteMetadataStream(getService); + await deleteMetadataCurrentStream(getService); }); it('finds no data in list and prompts onboarding to add policy', async () => { @@ -73,7 +81,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { it('finds data after load and polling', async () => { await esArchiver.load('endpoint/metadata/api_feature', { useCreate: true }); - await pageObjects.endpoint.waitForTableToHaveData('endpointListTable', 10000); + await pageObjects.endpoint.waitForTableToHaveData('endpointListTable', 120000); const tableData = await pageObjects.endpointPageUtils.tableData('endpointListTable'); expect(tableData).to.eql(expectedData); }); @@ -82,10 +90,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('when there is data,', () => { before(async () => { await esArchiver.load('endpoint/metadata/api_feature', { useCreate: true }); + await sleep(120000); await pageObjects.endpoint.navigateToEndpointList(); }); after(async () => { await deleteMetadataStream(getService); + await deleteMetadataCurrentStream(getService); }); it('finds page title', async () => { @@ -202,10 +212,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - describe('when there is no data,', () => { + describe.skip('when there is no data,', () => { before(async () => { // clear out the data and reload the page await deleteMetadataStream(getService); + await deleteMetadataCurrentStream(getService); await pageObjects.endpoint.navigateToEndpointList(); }); it('displays empty Policy Table page.', async () => { diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/data_stream_helper.ts b/x-pack/test/security_solution_endpoint_api_int/apis/data_stream_helper.ts index b16da16b3137f..be25f26532d9c 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/data_stream_helper.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/data_stream_helper.ts @@ -10,6 +10,7 @@ import { eventsIndexPattern, alertsIndexPattern, policyIndexPattern, + metadataCurrentIndexPattern, } from '../../../plugins/security_solution/common/endpoint/constants'; export async function deleteDataStream(getService: (serviceName: 'es') => Client, index: string) { @@ -25,10 +26,44 @@ export async function deleteDataStream(getService: (serviceName: 'es') => Client ); } +export async function deleteAllDocsFromIndex( + getService: (serviceName: 'es') => Client, + index: string +) { + const client = getService('es'); + await client.deleteByQuery( + { + body: { + query: { + match_all: {}, + }, + }, + index: `${index}`, + }, + { + ignore: [404], + } + ); +} + export async function deleteMetadataStream(getService: (serviceName: 'es') => Client) { await deleteDataStream(getService, metadataIndexPattern); } +export async function deleteMetadataCurrentStream(getService: (serviceName: 'es') => Client) { + await deleteDataStream(getService, metadataCurrentIndexPattern); +} + +export async function deleteAllDocsFromMetadataIndex(getService: (serviceName: 'es') => Client) { + await deleteAllDocsFromIndex(getService, metadataIndexPattern); +} + +export async function deleteAllDocsFromMetadataCurrentIndex( + getService: (serviceName: 'es') => Client +) { + await deleteAllDocsFromIndex(getService, metadataCurrentIndexPattern); +} + export async function deleteEventsStream(getService: (serviceName: 'es') => Client) { await deleteDataStream(getService, eventsIndexPattern); } diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts b/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts index 3afa9f397a2ea..2286320ed7a88 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts @@ -5,7 +5,12 @@ */ import expect from '@kbn/expect/expect.js'; import { FtrProviderContext } from '../ftr_provider_context'; -import { deleteMetadataStream } from './data_stream_helper'; +import { + deleteAllDocsFromMetadataCurrentIndex, + deleteMetadataCurrentStream, + deleteAllDocsFromMetadataIndex, + deleteMetadataStream, +} from './data_stream_helper'; /** * The number of host documents in the es archive. @@ -15,12 +20,14 @@ const numberOfHostsInFixture = 3; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const supertest = getService('supertest'); + describe('test metadata api', () => { describe('POST /api/endpoint/metadata when index is empty', () => { it('metadata api should return empty result when index is empty', async () => { - // the endpoint uses data streams and es archiver does not support deleting them at the moment so we need - // to do it manually await deleteMetadataStream(getService); + await deleteAllDocsFromMetadataIndex(getService); + await deleteMetadataCurrentStream(getService); + await deleteAllDocsFromMetadataCurrentIndex(getService); const { body } = await supertest .post('/api/endpoint/metadata') .set('kbn-xsrf', 'xxx') @@ -34,12 +41,19 @@ export default function ({ getService }: FtrProviderContext) { }); describe('POST /api/endpoint/metadata when index is not empty', () => { - before( - async () => await esArchiver.load('endpoint/metadata/api_feature', { useCreate: true }) - ); + before(async () => { + await esArchiver.load('endpoint/metadata/api_feature', { useCreate: true }); + // wait for transform + await new Promise((r) => setTimeout(r, 120000)); + }); // the endpoint uses data streams and es archiver does not support deleting them at the moment so we need // to do it manually - after(async () => await deleteMetadataStream(getService)); + after(async () => { + await deleteMetadataStream(getService); + await deleteAllDocsFromMetadataIndex(getService); + await deleteMetadataCurrentStream(getService); + await deleteAllDocsFromMetadataCurrentIndex(getService); + }); it('metadata api should return one entry for each host with default paging', async () => { const { body } = await supertest .post('/api/endpoint/metadata') @@ -121,7 +135,7 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'xxx') .send({ filters: { - kql: 'not host.ip:10.46.229.234', + kql: 'not HostDetails.host.ip:10.46.229.234', }, }) .expect(200); @@ -146,7 +160,7 @@ export default function ({ getService }: FtrProviderContext) { }, ], filters: { - kql: `not host.ip:${notIncludedIp}`, + kql: `not HostDetails.host.ip:${notIncludedIp}`, }, }) .expect(200); @@ -154,12 +168,14 @@ export default function ({ getService }: FtrProviderContext) { const resultIps: string[] = [].concat( ...body.hosts.map((hostInfo: Record) => hostInfo.metadata.host.ip) ); - expect(resultIps).to.eql([ - '10.192.213.130', - '10.70.28.129', - '10.101.149.26', - '2606:a000:ffc0:39:11ef:37b9:3371:578c', - ]); + expect(resultIps.sort()).to.eql( + [ + '10.192.213.130', + '10.70.28.129', + '10.101.149.26', + '2606:a000:ffc0:39:11ef:37b9:3371:578c', + ].sort() + ); expect(resultIps).not.include.eql(notIncludedIp); expect(body.hosts.length).to.eql(2); expect(body.request_page_size).to.eql(10); @@ -173,7 +189,7 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'xxx') .send({ filters: { - kql: `host.os.Ext.variant:${variantValue}`, + kql: `HostDetails.host.os.Ext.variant:${variantValue}`, }, }) .expect(200); @@ -194,7 +210,7 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'xxx') .send({ filters: { - kql: `host.ip:${targetEndpointIp}`, + kql: `HostDetails.host.ip:${targetEndpointIp}`, }, }) .expect(200); @@ -215,7 +231,7 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'xxx') .send({ filters: { - kql: `not Endpoint.policy.applied.status:success`, + kql: `not HostDetails.Endpoint.policy.applied.status:success`, }, }) .expect(200); @@ -236,7 +252,7 @@ export default function ({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'xxx') .send({ filters: { - kql: `elastic.agent.id:${targetElasticAgentId}`, + kql: `HostDetails.elastic.agent.id:${targetElasticAgentId}`, }, }) .expect(200); diff --git a/x-pack/test/ui_capabilities/security_only/tests/nav_links.ts b/x-pack/test/ui_capabilities/security_only/tests/nav_links.ts index d7a0dfa1cf80a..091bbccd6f87a 100644 --- a/x-pack/test/ui_capabilities/security_only/tests/nav_links.ts +++ b/x-pack/test/ui_capabilities/security_only/tests/nav_links.ts @@ -49,7 +49,13 @@ export default function navLinksTests({ getService }: FtrProviderContext) { expect(uiCapabilities.success).to.be(true); expect(uiCapabilities.value).to.have.property('navLinks'); expect(uiCapabilities.value!.navLinks).to.eql( - navLinksBuilder.except('ml', 'monitoring', 'appSearch', 'workplaceSearch') + navLinksBuilder.except( + 'ml', + 'monitoring', + 'enterpriseSearch', + 'appSearch', + 'workplaceSearch' + ) ); break; case 'foo_all': diff --git a/yarn.lock b/yarn.lock index 95066c9fa8cda..105c5e3cba5ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1144,10 +1144,10 @@ dependencies: "@elastic/apm-rum-core" "^5.6.0" -"@elastic/charts@21.0.1": - version "21.0.1" - resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-21.0.1.tgz#1e8be5303d0c7d53d7ccfcfa121ef68164ae200f" - integrity sha512-KMJE2JNwoy021Rvhgu1wiga0FVCa0u4NlFVUSR+h+G010KLarc+c9yUKBTG8v/nZ6ijBtuOLCjjU9OCWXYfxvA== +"@elastic/charts@21.1.2": + version "21.1.2" + resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-21.1.2.tgz#da7e9c1025bf730a738b6ac6d7024d97dd2b5aa2" + integrity sha512-Uri+Xolgii7/mRSarfXTfA6X2JC76ILIxTPO8RlYdI44gzprJfUO7Aw5s8vVQke3x6Cu39a+9B0s6TY4GAaApQ== dependencies: "@popperjs/core" "^2.4.0" chroma-js "^2.1.0" @@ -1168,9 +1168,6 @@ ts-debounce "^1.0.0" utility-types "^3.10.0" uuid "^3.3.2" - optionalDependencies: - redux-immutable-state-invariant "^2.1.0" - redux-logger "^3.0.6" "@elastic/elasticsearch@7.9.0-rc.1": version "7.9.0-rc.1" @@ -10394,11 +10391,6 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= -deep-diff@^0.3.5: - version "0.3.8" - resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84" - integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ= - deep-eql@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" @@ -12295,15 +12287,10 @@ eventemitter2@~0.4.13: resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" integrity sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas= -eventemitter3@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" - integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== - eventemitter3@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" - integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg== + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events@^1.0.2: version "1.1.1" @@ -15524,11 +15511,11 @@ http-proxy-middleware@0.19.1: micromatch "^3.1.10" http-proxy@^1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" - integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g== + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== dependencies: - eventemitter3 "^3.0.0" + eventemitter3 "^4.0.0" follow-redirects "^1.0.0" requires-port "^1.0.0" @@ -18207,10 +18194,10 @@ kdbush@^3.0.0: resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-3.0.0.tgz#f8484794d47004cc2d85ed3a79353dbe0abc2bf0" integrity sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew== -kea@2.2.0-rc.4: - version "2.2.0-rc.4" - resolved "https://registry.yarnpkg.com/kea/-/kea-2.2.0-rc.4.tgz#cc0376950530a6751f73387c4b25a39efa1faa77" - integrity sha512-pYuwaCiJkBvHZShi8kqhk8dC4DjeELdK51Lw7Pn0tNdJgZJDF6COhsUiF/yrh9d7woNYDxKfuxH+QWZFfo8PkA== +kea@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/kea/-/kea-2.2.0.tgz#1ba4a174a53880cca8002a67cf62b19b30d09702" + integrity sha512-IzgTC6SC89wTLfiBMPlduG4r4YanxONYK4werz8RMZxPvcYw4XEEK8xQJguwVYtLCEGm4x5YiLCubGqGfRcbEw== kew@~0.1.7: version "0.1.7" @@ -24455,21 +24442,6 @@ redux-devtools-extension@^2.13.8: resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz#37b982688626e5e4993ff87220c9bbb7cd2d96e1" integrity sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg== -redux-immutable-state-invariant@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/redux-immutable-state-invariant/-/redux-immutable-state-invariant-2.1.0.tgz#308fd3cc7415a0e7f11f51ec997b6379c7055ce1" - integrity sha512-3czbDKs35FwiBRsx/3KabUk5zSOoTXC+cgVofGkpBNv3jQcqIe5JrHcF5AmVt7B/4hyJ8MijBIpCJ8cife6yJg== - dependencies: - invariant "^2.1.0" - json-stringify-safe "^5.0.1" - -redux-logger@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf" - integrity sha1-91VZZvMJjzyIYExEnPC69XeCdL8= - dependencies: - deep-diff "^0.3.5" - redux-observable@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/redux-observable/-/redux-observable-1.2.0.tgz#ff51b6c6be2598e9b5e89fc36639186bb0e669c7"