diff --git a/.eslintrc.js b/.eslintrc.js index 40dd6a55a2a3f6..c64f03a8398e54 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -893,6 +893,8 @@ module.exports = { files: [ 'x-pack/plugins/security_solution/public/**/*.{js,mjs,ts,tsx}', 'x-pack/plugins/security_solution/common/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/timelines/public/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/timelines/common/**/*.{js,mjs,ts,tsx}', ], rules: { 'import/no-nodejs-modules': 'error', @@ -907,7 +909,10 @@ module.exports = { }, { // typescript only for front and back end - files: ['x-pack/plugins/security_solution/**/*.{ts,tsx}'], + files: [ + 'x-pack/plugins/security_solution/**/*.{ts,tsx}', + 'x-pack/plugins/timelines/**/*.{ts,tsx}', + ], rules: { '@typescript-eslint/no-this-alias': 'error', '@typescript-eslint/no-explicit-any': 'error', @@ -917,7 +922,10 @@ module.exports = { }, { // typescript and javascript for front and back end - files: ['x-pack/plugins/security_solution/**/*.{js,mjs,ts,tsx}'], + files: [ + 'x-pack/plugins/security_solution/**/*.{js,mjs,ts,tsx}', + 'x-pack/plugins/timelines/**/*.{js,mjs,ts,tsx}', + ], plugins: ['eslint-plugin-node', 'react'], env: { jest: true, diff --git a/docs/developer/getting-started/monorepo-packages.asciidoc b/docs/developer/getting-started/monorepo-packages.asciidoc index e8b950a696f55d..5d7ba22841aa16 100644 --- a/docs/developer/getting-started/monorepo-packages.asciidoc +++ b/docs/developer/getting-started/monorepo-packages.asciidoc @@ -86,6 +86,7 @@ yarn kbn watch-bazel - @kbn/logging - @kbn/mapbox-gl - @kbn/monaco +- @kbn/optimizer - @kbn/rule-data-utils - @kbn/securitysolution-es-utils - @kbn/securitysolution-hook-utils diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md index ae433e3db14c68..b10ad949c49443 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md @@ -106,6 +106,7 @@ readonly links: { }; readonly search: { readonly sessions: string; + readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md index b0800c7dfc65ea..c020f57faa8825 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md @@ -17,5 +17,5 @@ export interface DocLinksStart | --- | --- | --- | | [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) | string | | | [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) | string | | -| [links](./kibana-plugin-core-public.doclinksstart.links.md) | {
readonly canvas: {
readonly guide: string;
};
readonly dashboard: {
readonly guide: string;
readonly drilldowns: string;
readonly drilldownsTriggerPicker: string;
readonly urlDrilldownTemplateSyntax: string;
readonly urlDrilldownVariables: string;
};
readonly discover: Record<string, string>;
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly elasticsearchModule: string;
readonly startup: string;
readonly exportedFields: string;
};
readonly auditbeat: {
readonly base: string;
};
readonly metricbeat: {
readonly base: string;
readonly configure: string;
readonly httpEndpoint: string;
readonly install: string;
readonly start: string;
};
readonly enterpriseSearch: {
readonly base: string;
readonly appSearchBase: string;
readonly workplaceSearchBase: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly composite: string;
readonly composite_missing_bucket: string;
readonly date_histogram: string;
readonly date_range: string;
readonly date_format_pattern: string;
readonly filter: string;
readonly filters: string;
readonly geohash_grid: string;
readonly histogram: string;
readonly ip_range: string;
readonly range: string;
readonly significant_terms: string;
readonly terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
readonly min_bucket: string;
readonly sum_bucket: string;
readonly cardinality: string;
readonly count: string;
readonly cumulative_sum: string;
readonly derivative: string;
readonly geo_bounds: string;
readonly geo_centroid: string;
readonly max: string;
readonly median: string;
readonly min: string;
readonly moving_avg: string;
readonly percentile_ranks: string;
readonly serial_diff: string;
readonly std_dev: string;
readonly sum: string;
readonly top_hits: string;
};
readonly runtimeFields: {
readonly overview: string;
readonly mapping: string;
};
readonly scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessLangSpec: string;
readonly painlessSyntax: string;
readonly painlessWalkthrough: string;
readonly luceneExpressions: string;
};
readonly search: {
readonly sessions: string;
};
readonly indexPatterns: {
readonly introduction: string;
readonly fieldFormattersNumber: string;
readonly fieldFormattersString: string;
readonly runtimeFields: string;
};
readonly addData: string;
readonly kibana: string;
readonly upgradeAssistant: string;
readonly rollupJobs: string;
readonly elasticsearch: Record<string, string>;
readonly siem: {
readonly guide: string;
readonly gettingStarted: string;
};
readonly query: {
readonly eql: string;
readonly kueryQuerySyntax: string;
readonly luceneQuerySyntax: string;
readonly percolate: string;
readonly queryDsl: string;
};
readonly date: {
readonly dateMath: string;
readonly dateMathIndexNames: string;
};
readonly management: Record<string, string>;
readonly ml: Record<string, string>;
readonly transforms: Record<string, string>;
readonly visualize: Record<string, string>;
readonly apis: Readonly<{
bulkIndexAlias: string;
byteSizeUnits: string;
createAutoFollowPattern: string;
createFollower: string;
createIndex: string;
createSnapshotLifecyclePolicy: string;
createRoleMapping: string;
createRoleMappingTemplates: string;
createRollupJobsRequest: string;
createApiKey: string;
createPipeline: string;
createTransformRequest: string;
cronExpressions: string;
executeWatchActionModes: string;
indexExists: string;
openIndex: string;
putComponentTemplate: string;
painlessExecute: string;
painlessExecuteAPIContexts: string;
putComponentTemplateMetadata: string;
putSnapshotLifecyclePolicy: string;
putIndexTemplateV1: string;
putWatch: string;
simulatePipeline: string;
timeUnits: string;
updateTransform: string;
}>;
readonly observability: Record<string, string>;
readonly alerting: Record<string, string>;
readonly maps: Record<string, string>;
readonly monitoring: Record<string, string>;
readonly security: Readonly<{
apiKeyServiceSettings: string;
clusterPrivileges: string;
elasticsearchSettings: string;
elasticsearchEnableSecurity: string;
indicesPrivileges: string;
kibanaTLS: string;
kibanaPrivileges: string;
mappingRoles: string;
mappingRolesFieldRules: string;
runAsPrivilege: string;
}>;
readonly watcher: Record<string, string>;
readonly ccs: Record<string, string>;
readonly plugins: Record<string, string>;
readonly snapshotRestore: Record<string, string>;
readonly ingest: Record<string, string>;
readonly fleet: Readonly<{
guide: string;
fleetServer: string;
fleetServerAddFleetServer: string;
settings: string;
settingsFleetServerHostSettings: string;
troubleshooting: string;
elasticAgent: string;
datastreams: string;
datastreamsNamingScheme: string;
upgradeElasticAgent: string;
upgradeElasticAgent712lower: string;
}>;
} | | +| [links](./kibana-plugin-core-public.doclinksstart.links.md) | {
readonly canvas: {
readonly guide: string;
};
readonly dashboard: {
readonly guide: string;
readonly drilldowns: string;
readonly drilldownsTriggerPicker: string;
readonly urlDrilldownTemplateSyntax: string;
readonly urlDrilldownVariables: string;
};
readonly discover: Record<string, string>;
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly elasticsearchModule: string;
readonly startup: string;
readonly exportedFields: string;
};
readonly auditbeat: {
readonly base: string;
};
readonly metricbeat: {
readonly base: string;
readonly configure: string;
readonly httpEndpoint: string;
readonly install: string;
readonly start: string;
};
readonly enterpriseSearch: {
readonly base: string;
readonly appSearchBase: string;
readonly workplaceSearchBase: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly composite: string;
readonly composite_missing_bucket: string;
readonly date_histogram: string;
readonly date_range: string;
readonly date_format_pattern: string;
readonly filter: string;
readonly filters: string;
readonly geohash_grid: string;
readonly histogram: string;
readonly ip_range: string;
readonly range: string;
readonly significant_terms: string;
readonly terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
readonly min_bucket: string;
readonly sum_bucket: string;
readonly cardinality: string;
readonly count: string;
readonly cumulative_sum: string;
readonly derivative: string;
readonly geo_bounds: string;
readonly geo_centroid: string;
readonly max: string;
readonly median: string;
readonly min: string;
readonly moving_avg: string;
readonly percentile_ranks: string;
readonly serial_diff: string;
readonly std_dev: string;
readonly sum: string;
readonly top_hits: string;
};
readonly runtimeFields: {
readonly overview: string;
readonly mapping: string;
};
readonly scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessLangSpec: string;
readonly painlessSyntax: string;
readonly painlessWalkthrough: string;
readonly luceneExpressions: string;
};
readonly search: {
readonly sessions: string;
readonly sessionLimits: string;
};
readonly indexPatterns: {
readonly introduction: string;
readonly fieldFormattersNumber: string;
readonly fieldFormattersString: string;
readonly runtimeFields: string;
};
readonly addData: string;
readonly kibana: string;
readonly upgradeAssistant: string;
readonly elasticsearch: Record<string, string>;
readonly siem: {
readonly guide: string;
readonly gettingStarted: string;
};
readonly query: {
readonly eql: string;
readonly kueryQuerySyntax: string;
readonly luceneQuerySyntax: string;
readonly percolate: string;
readonly queryDsl: string;
};
readonly date: {
readonly dateMath: string;
readonly dateMathIndexNames: string;
};
readonly management: Record<string, string>;
readonly ml: Record<string, string>;
readonly transforms: Record<string, string>;
readonly visualize: Record<string, string>;
readonly apis: Readonly<{
bulkIndexAlias: string;
byteSizeUnits: string;
createAutoFollowPattern: string;
createFollower: string;
createIndex: string;
createSnapshotLifecyclePolicy: string;
createRoleMapping: string;
createRoleMappingTemplates: string;
createRollupJobsRequest: string;
createApiKey: string;
createPipeline: string;
createTransformRequest: string;
cronExpressions: string;
executeWatchActionModes: string;
indexExists: string;
openIndex: string;
putComponentTemplate: string;
painlessExecute: string;
painlessExecuteAPIContexts: string;
putComponentTemplateMetadata: string;
putSnapshotLifecyclePolicy: string;
putIndexTemplateV1: string;
putWatch: string;
simulatePipeline: string;
timeUnits: string;
updateTransform: string;
}>;
readonly observability: Record<string, string>;
readonly alerting: Record<string, string>;
readonly maps: Record<string, string>;
readonly monitoring: Record<string, string>;
readonly security: Readonly<{
apiKeyServiceSettings: string;
clusterPrivileges: string;
elasticsearchSettings: string;
elasticsearchEnableSecurity: string;
indicesPrivileges: string;
kibanaTLS: string;
kibanaPrivileges: string;
mappingRoles: string;
mappingRolesFieldRules: string;
runAsPrivilege: string;
}>;
readonly watcher: Record<string, string>;
readonly ccs: Record<string, string>;
readonly plugins: Record<string, string>;
readonly snapshotRestore: Record<string, string>;
readonly ingest: Record<string, string>;
} | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.isrestored.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.isrestored.md new file mode 100644 index 00000000000000..d649212ae05477 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.isrestored.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IKibanaSearchResponse](./kibana-plugin-plugins-data-public.ikibanasearchresponse.md) > [isRestored](./kibana-plugin-plugins-data-public.ikibanasearchresponse.isrestored.md) + +## IKibanaSearchResponse.isRestored property + +Indicates whether the results returned are from the async-search index + +Signature: + +```typescript +isRestored?: boolean; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md index 1d3e0c08dfc18d..c7046902dac72b 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md @@ -16,6 +16,7 @@ export interface IKibanaSearchResponse | --- | --- | --- | | [id](./kibana-plugin-plugins-data-public.ikibanasearchresponse.id.md) | string | Some responses may contain a unique id to identify the request this response came from. | | [isPartial](./kibana-plugin-plugins-data-public.ikibanasearchresponse.ispartial.md) | boolean | Indicates whether the results returned are complete or partial | +| [isRestored](./kibana-plugin-plugins-data-public.ikibanasearchresponse.isrestored.md) | boolean | Indicates whether the results returned are from the async-search index | | [isRunning](./kibana-plugin-plugins-data-public.ikibanasearchresponse.isrunning.md) | boolean | Indicates whether search is still in flight | | [loaded](./kibana-plugin-plugins-data-public.ikibanasearchresponse.loaded.md) | number | If relevant to the search strategy, return a loaded number that represents how progress is indicated. | | [rawResponse](./kibana-plugin-plugins-data-public.ikibanasearchresponse.rawresponse.md) | RawResponse | The raw response returned by the internal search method (usually the raw ES response) | 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 b1745b298e27e8..9816b884c46144 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 @@ -13,6 +13,7 @@ | [IndexPatternsFetcher](./kibana-plugin-plugins-data-server.indexpatternsfetcher.md) | | | [IndexPatternsService](./kibana-plugin-plugins-data-server.indexpatternsservice.md) | | | [IndexPatternsServiceProvider](./kibana-plugin-plugins-data-server.indexpatternsserviceprovider.md) | | +| [NoSearchIdInSessionError](./kibana-plugin-plugins-data-server.nosearchidinsessionerror.md) | | | [OptionedParamType](./kibana-plugin-plugins-data-server.optionedparamtype.md) | | | [Plugin](./kibana-plugin-plugins-data-server.plugin.md) | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.nosearchidinsessionerror._constructor_.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.nosearchidinsessionerror._constructor_.md new file mode 100644 index 00000000000000..e48a1c98f85785 --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.nosearchidinsessionerror._constructor_.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [NoSearchIdInSessionError](./kibana-plugin-plugins-data-server.nosearchidinsessionerror.md) > [(constructor)](./kibana-plugin-plugins-data-server.nosearchidinsessionerror._constructor_.md) + +## NoSearchIdInSessionError.(constructor) + +Constructs a new instance of the `NoSearchIdInSessionError` class + +Signature: + +```typescript +constructor(); +``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.nosearchidinsessionerror.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.nosearchidinsessionerror.md new file mode 100644 index 00000000000000..707739f845cd14 --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.nosearchidinsessionerror.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [NoSearchIdInSessionError](./kibana-plugin-plugins-data-server.nosearchidinsessionerror.md) + +## NoSearchIdInSessionError class + +Signature: + +```typescript +export declare class NoSearchIdInSessionError extends KbnError +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)()](./kibana-plugin-plugins-data-server.nosearchidinsessionerror._constructor_.md) | | Constructs a new instance of the NoSearchIdInSessionError class | + diff --git a/docs/user/dashboard/aggregation-reference.asciidoc b/docs/user/dashboard/aggregation-reference.asciidoc index cb5c484def3b9d..17bfc19c2e0c9d 100644 --- a/docs/user/dashboard/aggregation-reference.asciidoc +++ b/docs/user/dashboard/aggregation-reference.asciidoc @@ -12,91 +12,168 @@ This reference can help simplify the comparison if you need a specific feature. [options="header"] |=== -| Type | Aggregation-based | Lens | TSVB | Timelion | Vega +| Type | Lens | TSVB | Agg-based | Vega | Timelion | Table -^| X -^| X -^| X +| ✓ +| ✓ +| ✓ | | -| Table with summary row -^| X -^| X -| +| Bar, line, and area +| ✓ +| ✓ +| ✓ +| ✓ +| ✓ + +| Split chart/small multiples | +| ✓ +| ✓ +| ✓ | -| Bar, line, and area charts -^| X -^| X -^| X -^| X -^| X +| Pie and donut +| ✓ +| +| ✓ +| ✓ +| -| Percentage bar or area chart +| Sunburst +| ✓ | -^| X -^| X +| ✓ +| ✓ | -^| X -| Split bar, line, and area charts -^| X +| Treemap +| ✓ +| | +| ✓ | + +| Heat map +| ✓ +| ✓ +| ✓ +| ✓ | -^| X -| Pie and donut charts -^| X -^| X +| Gauge and Goal | +| ✓ +| ✓ +| ✓ | -^| X -| Sunburst chart -^| X -^| X +| Markdown +| +| ✓ | | | -| Heat map -^| X -^| X +| Metric +| ✓ +| ✓ +| ✓ +| ✓ +| + +| Tag cloud | | -^| X +| ✓ +| ✓ +| -| Gauge and Goal -^| X +|=== + +[float] +[[table-features]] +=== Table features + +[options="header"] +|=== + +| Type | Lens | TSVB | Agg-based + +| Summary row +| ✓ | -^| X +| ✓ + +| Pivot table +| ✓ | | -| Markdown +| Calculated column +| Formula +| ✓ +| Percent only + +| Color by value +| ✓ +| ✓ | + +|=== + +[float] +[[xy-features]] +=== Bar, line, area features + +[options="header"] +|=== + +| Type | Lens | TSVB | Agg-based | Vega | Timelion + +| Dense time series +| Customizable +| ✓ +| Customizable +| ✓ +| ✓ + +| Percentage mode +| ✓ +| ✓ +| ✓ +| ✓ | -^| X + +| Break downs +| 1 +| 1 +| 3 +| ∞ +| 1 + +| Custom color with break downs | +| Only for Filters +| ✓ +| ✓ | -| Metric -^| X -^| X -^| X +| Fit missing values +| ✓ | -^| X +| ✓ +| ✓ +| ✓ -| Tag cloud -^| X +| Synchronized tooltips +| +| ✓ | | | -^| X |=== @@ -111,67 +188,57 @@ For information about {es} bucket aggregations, refer to {ref}/search-aggregatio [options="header"] |=== -| Type | Agg-based | Markdown | Lens | TSVB +| Type | Lens | TSVB | Agg-based | Histogram -^| X -^| X -^| X +| ✓ | +| ✓ | Date histogram -^| X -^| X -^| X -^| X +| ✓ +| ✓ +| ✓ | Date range -^| X -^| X -| +| Use filters | +| ✓ | Filter -^| X -^| X | -^| X +| ✓ +| | Filters -^| X -^| X -^| X -^| X +| ✓ +| ✓ +| ✓ | GeoHash grid -^| X -^| X | | +| ✓ | IP range -^| X -^| X -| -| +| Use filters +| Use filters +| ✓ | Range -^| X -^| X -^| X -| +| ✓ +| Use filters +| ✓ | Terms -^| X -^| X -^| X -^| X +| ✓ +| ✓ +| ✓ | Significant terms -^| X -^| X | -^| X +| +| ✓ |=== @@ -186,67 +253,57 @@ For information about {es} metrics aggregations, refer to {ref}/search-aggregati [options="header"] |=== -| Type | Agg-based | Markdown | Lens | TSVB +| Type | Lens | TSVB | Agg-based | Metrics with filters +| ✓ | | -^| X -| - -| Average -^| X -^| X -^| X -^| X -| Sum -^| X -^| X -^| X -^| X +| Average, Sum, Max, Min +| ✓ +| ✓ +| ✓ | Unique count (Cardinality) -^| X -^| X -^| X -^| X - -| Max -^| X -^| X -^| X -^| X - -| Min -^| X -^| X -^| X -^| X - -| Percentiles -^| X -^| X -^| X -^| X +| ✓ +| ✓ +| ✓ + +| Percentiles and Median +| ✓ +| ✓ +| ✓ | Percentiles Rank -^| X -^| X -| -^| X +| +| ✓ +| ✓ + +| Standard deviation +| +| ✓ +| ✓ + +| Sum of squares +| +| ✓ +| | Top hit (Last value) -^| X -^| X -^| X -^| X +| ✓ +| ✓ +| ✓ | Value count | | +| ✓ + +| Variance +| +| ✓ | -^| X |=== @@ -261,61 +318,94 @@ For information about {es} pipeline aggregations, refer to {ref}/search-aggregat [options="header"] |=== -| Type | Agg-based | Markdown | Lens | TSVB +| Type | Lens | TSVB | Agg-based | Avg bucket -^| X -^| X -| -^| X +| <> +| ✓ +| ✓ | Derivative -^| X -^| X -^| X -^| X +| ✓ +| ✓ +| ✓ | Max bucket -^| X -^| X -| -^| X +| <> +| ✓ +| ✓ | Min bucket -^| X -^| X -| -^| X +| <> +| ✓ +| ✓ | Sum bucket -^| X -^| X -| -^| X +| <> +| ✓ +| ✓ | Moving average -^| X -^| X -^| X -^| X +| ✓ +| ✓ +| ✓ | Cumulative sum -^| X -^| X -^| X -^| X +| ✓ +| ✓ +| ✓ | Bucket script | | +| ✓ + +| Bucket selector +| | -^| X +| | Serial differencing -^| X -^| X | -^| X +| ✓ +| ✓ + +|=== + +[float] +[[custom-functions]] +=== Additional functions + +[options="header"] +|=== + +| Type | Lens | TSVB | Agg-based + +| Counter rate +| ✓ +| ✓ +| + +| <> +| Use <> +| ✓ +| + +| <> +| +| ✓ +| + +| <> +| +| ✓ +| + +| Static value +| +| ✓ +| + |=== @@ -329,41 +419,49 @@ build their advanced visualization. [options="header"] |=== -| Type | Agg-based | Lens | TSVB | Timelion | Vega +| Type | Lens | TSVB | Agg-based | Vega | Timelion -| Math on aggregated data +| Math +| ✓ +| ✓ | -^| X -^| X -^| X -^| X +| ✓ +| ✓ | Visualize two indices +| ✓ +| ✓ | -^| X -^| X -^| X -^| X +| ✓ +| ✓ | Math across indices | | | -^| X -^| X +| ✓ +| ✓ | Time shifts +| ✓ +| ✓ | -^| X -^| X -^| X -^| X +| ✓ +| ✓ | Fully custom {es} queries | | | +| ✓ | -^| X + +| Normalize by time +| ✓ +| ✓ +| +| +| + |=== diff --git a/docs/user/dashboard/lens.asciidoc b/docs/user/dashboard/lens.asciidoc index 4ecfcc92501228..2071f17ecff3d5 100644 --- a/docs/user/dashboard/lens.asciidoc +++ b/docs/user/dashboard/lens.asciidoc @@ -139,6 +139,42 @@ image::images/lens_drag_drop_3.gif[Using drag and drop to reorder] . Press Space bar to confirm, or to cancel, press Esc. +[float] +[[lens-formulas]] +==== Use formulas to perform math + +Formulas let you perform math on aggregated data in Lens by typing +math and quick functions. To access formulas, +click the *Formula* tab in the dimension editor. Access the complete +reference for formulas from the help menu. + +The most common formulas are dividing two values to produce a percent. +To display accurately, set *Value format* to *Percent*. + +Filter ratio:: + +Use `kql=''` to filter one set of documents and compare it to other documents within the same grouping. +For example, to see how the error rate changes over time: ++ +``` +count(kql='response.status_code > 400') / count() +``` + +Week over week:: Use `shift='1w'` to get the value of each grouping from +the previous week. Time shift should not be used with the *Top values* function. ++ +``` +percentile(system.network.in.bytes, percentile=99) / +percentile(system.network.in.bytes, percentile=99, shift='1w') +``` + +Percent of total:: Formulas can calculate `overall_sum` for all the groupings, +which lets you convert each grouping into a percent of total: ++ +``` +sum(products.base_price) / overall_sum(sum(products.base_price)) +``` + [float] [[lens-faq]] ==== Frequently asked questions diff --git a/package.json b/package.json index 36fa086657adff..26465133569cd9 100644 --- a/package.json +++ b/package.json @@ -149,6 +149,7 @@ "@kbn/securitysolution-list-api": "link:bazel-bin/packages/kbn-securitysolution-list-api", "@kbn/securitysolution-list-hooks": "link:bazel-bin/packages/kbn-securitysolution-list-hooks", "@kbn/securitysolution-list-utils": "link:bazel-bin/packages/kbn-securitysolution-list-utils", + "@kbn/securitysolution-t-grid": "link:bazel-bin/packages/kbn-securitysolution-t-grid", "@kbn/securitysolution-utils": "link:bazel-bin/packages/kbn-securitysolution-utils", "@kbn/server-http-tools": "link:bazel-bin/packages/kbn-server-http-tools", "@kbn/server-route-repository": "link:bazel-bin/packages/kbn-server-route-repository", @@ -217,6 +218,8 @@ "cytoscape-dagre": "^2.2.2", "d3": "3.5.17", "d3-array": "1.2.4", + "d3-cloud": "1.2.5", + "d3-interpolate": "^3.0.1", "d3-scale": "1.0.7", "d3-shape": "^1.1.0", "d3-time": "^1.1.0", @@ -462,7 +465,7 @@ "@kbn/eslint-import-resolver-kibana": "link:bazel-bin/packages/kbn-eslint-import-resolver-kibana", "@kbn/eslint-plugin-eslint": "link:bazel-bin/packages/kbn-eslint-plugin-eslint", "@kbn/expect": "link:bazel-bin/packages/kbn-expect", - "@kbn/optimizer": "link:packages/kbn-optimizer", + "@kbn/optimizer": "link:bazel-bin/packages/kbn-optimizer", "@kbn/plugin-generator": "link:bazel-bin/packages/kbn-plugin-generator", "@kbn/plugin-helpers": "link:packages/kbn-plugin-helpers", "@kbn/pm": "link:packages/kbn-pm", @@ -511,6 +514,7 @@ "@types/cytoscape": "^3.14.0", "@types/d3": "^3.5.43", "@types/d3-array": "^1.2.7", + "@types/d3-interpolate": "^2.0.0", "@types/d3-scale": "^2.1.1", "@types/d3-shape": "^1.3.1", "@types/d3-time": "^1.0.10", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index b1c3f580c6baf8..d9e2f0e1f99854 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -3,7 +3,7 @@ filegroup( name = "build", srcs = [ - "//packages/elastic-datemath:build", + "//packages/elastic-datemath:build", "//packages/elastic-eslint-config-kibana:build", "//packages/elastic-safer-lodash-set:build", "//packages/kbn-ace:build", @@ -29,6 +29,7 @@ filegroup( "//packages/kbn-logging:build", "//packages/kbn-mapbox-gl:build", "//packages/kbn-monaco:build", + "//packages/kbn-optimizer:build", "//packages/kbn-plugin-generator:build", "//packages/kbn-rule-data-utils:build", "//packages/kbn-securitysolution-list-constants:build", @@ -41,6 +42,7 @@ filegroup( "//packages/kbn-securitysolution-list-utils:build", "//packages/kbn-securitysolution-utils:build", "//packages/kbn-securitysolution-es-utils:build", + "//packages/kbn-securitysolution-t-grid:build", "//packages/kbn-securitysolution-hook-utils:build", "//packages/kbn-server-http-tools:build", "//packages/kbn-server-route-repository:build", diff --git a/packages/kbn-cli-dev-mode/package.json b/packages/kbn-cli-dev-mode/package.json index dd491de55c075d..cf6fcfd88a26da 100644 --- a/packages/kbn-cli-dev-mode/package.json +++ b/packages/kbn-cli-dev-mode/package.json @@ -12,8 +12,5 @@ }, "kibana": { "devOnly": true - }, - "dependencies": { - "@kbn/optimizer": "link:../kbn-optimizer" } } \ No newline at end of file diff --git a/packages/kbn-optimizer/BUILD.bazel b/packages/kbn-optimizer/BUILD.bazel new file mode 100644 index 00000000000000..3809c2b33d5009 --- /dev/null +++ b/packages/kbn-optimizer/BUILD.bazel @@ -0,0 +1,120 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") + +PKG_BASE_NAME = "kbn-optimizer" +PKG_REQUIRE_NAME = "@kbn/optimizer" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + ], + exclude = [ + "**/*.test.*", + "**/__fixtures__/**", + "**/__snapshots__/**", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "limits.yml", + "package.json", + "postcss.config.js", + "README.md" +] + +SRC_DEPS = [ + "//packages/kbn-config", + "//packages/kbn-dev-utils", + "//packages/kbn-std", + "//packages/kbn-ui-shared-deps", + "//packages/kbn-utils", + "@npm//chalk", + "@npm//clean-webpack-plugin", + "@npm//compression-webpack-plugin", + "@npm//cpy", + "@npm//del", + "@npm//execa", + "@npm//jest-diff", + "@npm//json-stable-stringify", + "@npm//lmdb-store", + "@npm//loader-utils", + "@npm//node-sass", + "@npm//normalize-path", + "@npm//pirates", + "@npm//resize-observer-polyfill", + "@npm//rxjs", + "@npm//source-map-support", + "@npm//watchpack", + "@npm//webpack", + "@npm//webpack-merge", + "@npm//webpack-sources", + "@npm//zlib" +] + +TYPES_DEPS = [ + "@npm//@types/compression-webpack-plugin", + "@npm//@types/jest", + "@npm//@types/json-stable-stringify", + "@npm//@types/loader-utils", + "@npm//@types/node", + "@npm//@types/normalize-path", + "@npm//@types/source-map-support", + "@npm//@types/watchpack", + "@npm//@types/webpack", + "@npm//@types/webpack-merge", + "@npm//@types/webpack-sources", +] + +DEPS = SRC_DEPS + TYPES_DEPS + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + ], +) + +ts_project( + name = "tsc", + args = ['--pretty'], + srcs = SRCS, + deps = DEPS, + declaration = True, + declaration_map = True, + incremental = True, + out_dir = "target", + source_map = True, + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_BASE_NAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = DEPS + [":tsc"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [ + ":%s" % PKG_BASE_NAME, + ] +) + +filegroup( + name = "build", + srcs = [ + ":npm_module", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index f9127e4629f43e..c6960621359c78 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -67,7 +67,7 @@ pageLoadAssetSize: searchprofiler: 67080 security: 95864 securityOss: 30806 - securitySolution: 76000 + securitySolution: 217673 share: 99061 snapshotRestore: 79032 spaces: 57868 @@ -107,7 +107,7 @@ pageLoadAssetSize: dataVisualizer: 27530 banners: 17946 mapsEms: 26072 - timelines: 28613 + timelines: 230410 screenshotMode: 17856 visTypePie: 35583 cases: 144442 diff --git a/packages/kbn-optimizer/package.json b/packages/kbn-optimizer/package.json index a6c8284ad15f64..d23512f7c418d6 100644 --- a/packages/kbn-optimizer/package.json +++ b/packages/kbn-optimizer/package.json @@ -4,10 +4,5 @@ "private": true, "license": "SSPL-1.0 OR Elastic License 2.0", "main": "./target/index.js", - "types": "./target/index.d.ts", - "scripts": { - "build": "../../node_modules/.bin/tsc", - "kbn:bootstrap": "yarn build", - "kbn:watch": "yarn build --watch" - } + "types": "./target/index.d.ts" } \ No newline at end of file diff --git a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap index c175979f0e820e..1f1e33d3dda7c8 100644 --- a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap +++ b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap @@ -123,7 +123,7 @@ exports[`prepares assets for distribution: metrics.json 1`] = ` \\"group\\": \\"page load bundle size\\", \\"id\\": \\"foo\\", \\"value\\": 4627, - \\"limitConfigPath\\": \\"packages/kbn-optimizer/limits.yml\\" + \\"limitConfigPath\\": \\"node_modules/@kbn/optimizer/limits.yml\\" }, { \\"group\\": \\"async chunks size\\", diff --git a/packages/kbn-optimizer/src/worker/bundle_metrics_plugin.ts b/packages/kbn-optimizer/src/worker/bundle_metrics_plugin.ts index 92875d3f69e465..d9e1bee22557bf 100644 --- a/packages/kbn-optimizer/src/worker/bundle_metrics_plugin.ts +++ b/packages/kbn-optimizer/src/worker/bundle_metrics_plugin.ts @@ -79,7 +79,7 @@ export class BundleMetricsPlugin { id: bundle.id, value: entry.size, limit: bundle.pageLoadAssetSizeLimit, - limitConfigPath: `packages/kbn-optimizer/limits.yml`, + limitConfigPath: `node_modules/@kbn/optimizer/limits.yml`, }, { group: `async chunks size`, diff --git a/packages/kbn-optimizer/tsconfig.json b/packages/kbn-optimizer/tsconfig.json index f2d508cf14a55e..76beaf7689fd41 100644 --- a/packages/kbn-optimizer/tsconfig.json +++ b/packages/kbn-optimizer/tsconfig.json @@ -1,10 +1,11 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "incremental": false, + "incremental": true, "outDir": "./target", "declaration": true, "declarationMap": true, + "rootDir": "./src", "sourceMap": true, "sourceRoot": "../../../../packages/kbn-optimizer/src" }, diff --git a/packages/kbn-plugin-helpers/package.json b/packages/kbn-plugin-helpers/package.json index 2d642d9ede13bc..36a37075191a37 100644 --- a/packages/kbn-plugin-helpers/package.json +++ b/packages/kbn-plugin-helpers/package.json @@ -15,8 +15,5 @@ "scripts": { "kbn:bootstrap": "rm -rf target && ../../node_modules/.bin/tsc", "kbn:watch": "../../node_modules/.bin/tsc --watch" - }, - "dependencies": { - "@kbn/optimizer": "link:../kbn-optimizer" } } \ No newline at end of file diff --git a/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts b/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts index f75f0dcebf4f67..1909bcb1bcc2e6 100644 --- a/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts +++ b/packages/kbn-securitysolution-io-ts-list-types/src/typescript_types/index.ts @@ -42,6 +42,7 @@ export interface UseExceptionListsProps { notifications: NotificationsStart; pagination?: Pagination; showTrustedApps: boolean; + showEventFilters: boolean; } export interface UseExceptionListProps { diff --git a/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts b/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts index a9a93aa8df49a6..0bd4c6c705668d 100644 --- a/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts +++ b/packages/kbn-securitysolution-list-hooks/src/use_exception_lists/index.ts @@ -28,6 +28,7 @@ export type ReturnExceptionLists = [boolean, ExceptionListSchema[], Pagination, * @param namespaceTypes spaces to be searched * @param notifications kibana service for displaying toasters * @param showTrustedApps boolean - include/exclude trusted app lists + * @param showEventFilters boolean - include/exclude event filters lists * @param pagination * */ @@ -43,6 +44,7 @@ export const useExceptionLists = ({ namespaceTypes, notifications, showTrustedApps = false, + showEventFilters = false, }: UseExceptionListsProps): ReturnExceptionLists => { const [exceptionLists, setExceptionLists] = useState([]); const [paginationInfo, setPagination] = useState(pagination); @@ -51,8 +53,9 @@ export const useExceptionLists = ({ const namespaceTypesAsString = useMemo(() => namespaceTypes.join(','), [namespaceTypes]); const filters = useMemo( - (): string => getFilters(filterOptions, namespaceTypes, showTrustedApps), - [namespaceTypes, filterOptions, showTrustedApps] + (): string => + getFilters({ filters: filterOptions, namespaceTypes, showTrustedApps, showEventFilters }), + [namespaceTypes, filterOptions, showTrustedApps, showEventFilters] ); useEffect(() => { diff --git a/packages/kbn-securitysolution-list-utils/src/get_event_filters_filter/index.test.ts b/packages/kbn-securitysolution-list-utils/src/get_event_filters_filter/index.test.ts new file mode 100644 index 00000000000000..934a9cbff56a64 --- /dev/null +++ b/packages/kbn-securitysolution-list-utils/src/get_event_filters_filter/index.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { getEventFiltersFilter } from '.'; + +describe('getEventFiltersFilter', () => { + test('it returns filter to search for "exception-list" namespace trusted apps', () => { + const filter = getEventFiltersFilter(true, ['exception-list']); + + expect(filter).toEqual('(exception-list.attributes.list_id: endpoint_event_filters*)'); + }); + + test('it returns filter to search for "exception-list" and "agnostic" namespace trusted apps', () => { + const filter = getEventFiltersFilter(true, ['exception-list', 'exception-list-agnostic']); + + expect(filter).toEqual( + '(exception-list.attributes.list_id: endpoint_event_filters* OR exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it returns filter to exclude "exception-list" namespace trusted apps', () => { + const filter = getEventFiltersFilter(false, ['exception-list']); + + expect(filter).toEqual('(not exception-list.attributes.list_id: endpoint_event_filters*)'); + }); + + test('it returns filter to exclude "exception-list" and "agnostic" namespace trusted apps', () => { + const filter = getEventFiltersFilter(false, ['exception-list', 'exception-list-agnostic']); + + expect(filter).toEqual( + '(not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' + ); + }); +}); diff --git a/packages/kbn-securitysolution-list-utils/src/get_event_filters_filter/index.ts b/packages/kbn-securitysolution-list-utils/src/get_event_filters_filter/index.ts new file mode 100644 index 00000000000000..7e55073228fcab --- /dev/null +++ b/packages/kbn-securitysolution-list-utils/src/get_event_filters_filter/index.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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ENDPOINT_EVENT_FILTERS_LIST_ID } from '@kbn/securitysolution-list-constants'; +import { SavedObjectType } from '../types'; + +export const getEventFiltersFilter = ( + showEventFilter: boolean, + namespaceTypes: SavedObjectType[] +): string => { + if (showEventFilter) { + const filters = namespaceTypes.map((namespace) => { + return `${namespace}.attributes.list_id: ${ENDPOINT_EVENT_FILTERS_LIST_ID}*`; + }); + return `(${filters.join(' OR ')})`; + } else { + const filters = namespaceTypes.map((namespace) => { + return `not ${namespace}.attributes.list_id: ${ENDPOINT_EVENT_FILTERS_LIST_ID}*`; + }); + return `(${filters.join(' AND ')})`; + } +}; diff --git a/packages/kbn-securitysolution-list-utils/src/get_filters/index.test.ts b/packages/kbn-securitysolution-list-utils/src/get_filters/index.test.ts index 327a29dc1b987a..bfaad52ee81472 100644 --- a/packages/kbn-securitysolution-list-utils/src/get_filters/index.test.ts +++ b/packages/kbn-securitysolution-list-utils/src/get_filters/index.test.ts @@ -11,106 +11,318 @@ import { getFilters } from '.'; describe('getFilters', () => { describe('single', () => { test('it properly formats when no filters passed and "showTrustedApps" is false', () => { - const filter = getFilters({}, ['single'], false); + const filter = getFilters({ + filters: {}, + namespaceTypes: ['single'], + showTrustedApps: false, + showEventFilters: false, + }); - expect(filter).toEqual('(not exception-list.attributes.list_id: endpoint_trusted_apps*)'); + expect(filter).toEqual( + '(not exception-list.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters*)' + ); }); test('it properly formats when no filters passed and "showTrustedApps" is true', () => { - const filter = getFilters({}, ['single'], true); + const filter = getFilters({ + filters: {}, + namespaceTypes: ['single'], + showTrustedApps: true, + showEventFilters: false, + }); - expect(filter).toEqual('(exception-list.attributes.list_id: endpoint_trusted_apps*)'); + expect(filter).toEqual( + '(exception-list.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters*)' + ); }); test('it properly formats when filters passed and "showTrustedApps" is false', () => { - const filter = getFilters({ created_by: 'moi', name: 'Sample' }, ['single'], false); + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['single'], + showTrustedApps: false, + showEventFilters: false, + }); expect(filter).toEqual( - '(exception-list.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample) AND (not exception-list.attributes.list_id: endpoint_trusted_apps*)' + '(exception-list.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample) AND (not exception-list.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters*)' ); }); test('it if filters passed and "showTrustedApps" is true', () => { - const filter = getFilters({ created_by: 'moi', name: 'Sample' }, ['single'], true); + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['single'], + showTrustedApps: true, + showEventFilters: false, + }); + + expect(filter).toEqual( + '(exception-list.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample) AND (exception-list.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it properly formats when no filters passed and "showEventFilters" is false', () => { + const filter = getFilters({ + filters: {}, + namespaceTypes: ['single'], + showTrustedApps: false, + showEventFilters: false, + }); + + expect(filter).toEqual( + '(not exception-list.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it properly formats when no filters passed and "showEventFilters" is true', () => { + const filter = getFilters({ + filters: {}, + namespaceTypes: ['single'], + showTrustedApps: false, + showEventFilters: true, + }); + + expect(filter).toEqual( + '(not exception-list.attributes.list_id: endpoint_trusted_apps*) AND (exception-list.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it properly formats when filters passed and "showEventFilters" is false', () => { + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['single'], + showTrustedApps: false, + showEventFilters: false, + }); + + expect(filter).toEqual( + '(exception-list.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample) AND (not exception-list.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it if filters passed and "showEventFilters" is true', () => { + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['single'], + showTrustedApps: false, + showEventFilters: true, + }); expect(filter).toEqual( - '(exception-list.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample) AND (exception-list.attributes.list_id: endpoint_trusted_apps*)' + '(exception-list.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample) AND (not exception-list.attributes.list_id: endpoint_trusted_apps*) AND (exception-list.attributes.list_id: endpoint_event_filters*)' ); }); }); describe('agnostic', () => { test('it properly formats when no filters passed and "showTrustedApps" is false', () => { - const filter = getFilters({}, ['agnostic'], false); + const filter = getFilters({ + filters: {}, + namespaceTypes: ['agnostic'], + showTrustedApps: false, + showEventFilters: false, + }); expect(filter).toEqual( - '(not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)' + '(not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' ); }); test('it properly formats when no filters passed and "showTrustedApps" is true', () => { - const filter = getFilters({}, ['agnostic'], true); + const filter = getFilters({ + filters: {}, + namespaceTypes: ['agnostic'], + showTrustedApps: true, + showEventFilters: false, + }); expect(filter).toEqual( - '(exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)' + '(exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' ); }); test('it properly formats when filters passed and "showTrustedApps" is false', () => { - const filter = getFilters({ created_by: 'moi', name: 'Sample' }, ['agnostic'], false); + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['agnostic'], + showTrustedApps: false, + showEventFilters: false, + }); expect(filter).toEqual( - '(exception-list-agnostic.attributes.created_by:moi) AND (exception-list-agnostic.attributes.name.text:Sample) AND (not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)' + '(exception-list-agnostic.attributes.created_by:moi) AND (exception-list-agnostic.attributes.name.text:Sample) AND (not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' ); }); test('it if filters passed and "showTrustedApps" is true', () => { - const filter = getFilters({ created_by: 'moi', name: 'Sample' }, ['agnostic'], true); + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['agnostic'], + showTrustedApps: true, + showEventFilters: false, + }); + + expect(filter).toEqual( + '(exception-list-agnostic.attributes.created_by:moi) AND (exception-list-agnostic.attributes.name.text:Sample) AND (exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it properly formats when no filters passed and "showEventFilters" is false', () => { + const filter = getFilters({ + filters: {}, + namespaceTypes: ['agnostic'], + showTrustedApps: false, + showEventFilters: false, + }); + + expect(filter).toEqual( + '(not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it properly formats when no filters passed and "showEventFilters" is true', () => { + const filter = getFilters({ + filters: {}, + namespaceTypes: ['agnostic'], + showTrustedApps: false, + showEventFilters: true, + }); + + expect(filter).toEqual( + '(not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it properly formats when filters passed and "showEventFilters" is false', () => { + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['agnostic'], + showTrustedApps: false, + showEventFilters: false, + }); + + expect(filter).toEqual( + '(exception-list-agnostic.attributes.created_by:moi) AND (exception-list-agnostic.attributes.name.text:Sample) AND (not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it if filters passed and "showEventFilters" is true', () => { + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['agnostic'], + showTrustedApps: false, + showEventFilters: true, + }); expect(filter).toEqual( - '(exception-list-agnostic.attributes.created_by:moi) AND (exception-list-agnostic.attributes.name.text:Sample) AND (exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)' + '(exception-list-agnostic.attributes.created_by:moi) AND (exception-list-agnostic.attributes.name.text:Sample) AND (not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' ); }); }); describe('single, agnostic', () => { test('it properly formats when no filters passed and "showTrustedApps" is false', () => { - const filter = getFilters({}, ['single', 'agnostic'], false); + const filter = getFilters({ + filters: {}, + namespaceTypes: ['single', 'agnostic'], + showTrustedApps: false, + showEventFilters: false, + }); expect(filter).toEqual( - '(not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)' + '(not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' ); }); test('it properly formats when no filters passed and "showTrustedApps" is true', () => { - const filter = getFilters({}, ['single', 'agnostic'], true); + const filter = getFilters({ + filters: {}, + namespaceTypes: ['single', 'agnostic'], + showTrustedApps: true, + showEventFilters: false, + }); expect(filter).toEqual( - '(exception-list.attributes.list_id: endpoint_trusted_apps* OR exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)' + '(exception-list.attributes.list_id: endpoint_trusted_apps* OR exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' ); }); test('it properly formats when filters passed and "showTrustedApps" is false', () => { - const filter = getFilters( - { created_by: 'moi', name: 'Sample' }, - ['single', 'agnostic'], - false - ); + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['single', 'agnostic'], + showTrustedApps: false, + showEventFilters: false, + }); expect(filter).toEqual( - '(exception-list.attributes.created_by:moi OR exception-list-agnostic.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample OR exception-list-agnostic.attributes.name.text:Sample) AND (not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)' + '(exception-list.attributes.created_by:moi OR exception-list-agnostic.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample OR exception-list-agnostic.attributes.name.text:Sample) AND (not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' ); }); test('it properly formats when filters passed and "showTrustedApps" is true', () => { - const filter = getFilters( - { created_by: 'moi', name: 'Sample' }, - ['single', 'agnostic'], - true + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['single', 'agnostic'], + showTrustedApps: true, + showEventFilters: false, + }); + + expect(filter).toEqual( + '(exception-list.attributes.created_by:moi OR exception-list-agnostic.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample OR exception-list-agnostic.attributes.name.text:Sample) AND (exception-list.attributes.list_id: endpoint_trusted_apps* OR exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it properly formats when no filters passed and "showEventFilters" is false', () => { + const filter = getFilters({ + filters: {}, + namespaceTypes: ['single', 'agnostic'], + showTrustedApps: false, + showEventFilters: false, + }); + + expect(filter).toEqual( + '(not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it properly formats when no filters passed and "showEventFilters" is true', () => { + const filter = getFilters({ + filters: {}, + namespaceTypes: ['single', 'agnostic'], + showTrustedApps: false, + showEventFilters: true, + }); + + expect(filter).toEqual( + '(not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (exception-list.attributes.list_id: endpoint_event_filters* OR exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' + ); + }); + + test('it properly formats when filters passed and "showEventFilters" is false', () => { + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['single', 'agnostic'], + showTrustedApps: false, + showEventFilters: false, + }); + + expect(filter).toEqual( + '(exception-list.attributes.created_by:moi OR exception-list-agnostic.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample OR exception-list-agnostic.attributes.name.text:Sample) AND (not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' ); + }); + + test('it properly formats when filters passed and "showEventFilters" is true', () => { + const filter = getFilters({ + filters: { created_by: 'moi', name: 'Sample' }, + namespaceTypes: ['single', 'agnostic'], + showTrustedApps: false, + showEventFilters: true, + }); expect(filter).toEqual( - '(exception-list.attributes.created_by:moi OR exception-list-agnostic.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample OR exception-list-agnostic.attributes.name.text:Sample) AND (exception-list.attributes.list_id: endpoint_trusted_apps* OR exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)' + '(exception-list.attributes.created_by:moi OR exception-list-agnostic.attributes.created_by:moi) AND (exception-list.attributes.name.text:Sample OR exception-list-agnostic.attributes.name.text:Sample) AND (not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (exception-list.attributes.list_id: endpoint_event_filters* OR exception-list-agnostic.attributes.list_id: endpoint_event_filters*)' ); }); }); diff --git a/packages/kbn-securitysolution-list-utils/src/get_filters/index.ts b/packages/kbn-securitysolution-list-utils/src/get_filters/index.ts index c9dd6ccae484c2..238ae5541343cf 100644 --- a/packages/kbn-securitysolution-list-utils/src/get_filters/index.ts +++ b/packages/kbn-securitysolution-list-utils/src/get_filters/index.ts @@ -10,14 +10,26 @@ import { ExceptionListFilter, NamespaceType } from '@kbn/securitysolution-io-ts- import { getGeneralFilters } from '../get_general_filters'; import { getSavedObjectTypes } from '../get_saved_object_types'; import { getTrustedAppsFilter } from '../get_trusted_apps_filter'; +import { getEventFiltersFilter } from '../get_event_filters_filter'; -export const getFilters = ( - filters: ExceptionListFilter, - namespaceTypes: NamespaceType[], - showTrustedApps: boolean -): string => { +export interface GetFiltersParams { + filters: ExceptionListFilter; + namespaceTypes: NamespaceType[]; + showTrustedApps: boolean; + showEventFilters: boolean; +} + +export const getFilters = ({ + filters, + namespaceTypes, + showTrustedApps, + showEventFilters, +}: GetFiltersParams): string => { const namespaces = getSavedObjectTypes({ namespaceType: namespaceTypes }); const generalFilters = getGeneralFilters(filters, namespaces); const trustedAppsFilter = getTrustedAppsFilter(showTrustedApps, namespaces); - return [generalFilters, trustedAppsFilter].filter((filter) => filter.trim() !== '').join(' AND '); + const eventFiltersFilter = getEventFiltersFilter(showEventFilters, namespaces); + return [generalFilters, trustedAppsFilter, eventFiltersFilter] + .filter((filter) => filter.trim() !== '') + .join(' AND '); }; diff --git a/packages/kbn-securitysolution-t-grid/BUILD.bazel b/packages/kbn-securitysolution-t-grid/BUILD.bazel new file mode 100644 index 00000000000000..5cf1081bdd32e9 --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/BUILD.bazel @@ -0,0 +1,125 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") + +PKG_BASE_NAME = "kbn-securitysolution-t-grid" + +PKG_REQUIRE_NAME = "@kbn/securitysolution-t-grid" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + ], + exclude = [ + "**/*.test.*", + "**/*.mock.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "react/package.json", + "package.json", + "README.md", +] + +SRC_DEPS = [ + "//packages/kbn-babel-preset", + "//packages/kbn-dev-utils", + "//packages/kbn-i18n", + "@npm//@babel/core", + "@npm//babel-loader", + "@npm//enzyme", + "@npm//jest", + "@npm//lodash", + "@npm//react", + "@npm//react-beautiful-dnd", + "@npm//tslib", +] + +TYPES_DEPS = [ + "@npm//typescript", + "@npm//@types/enzyme", + "@npm//@types/jest", + "@npm//@types/lodash", + "@npm//@types/node", + "@npm//@types/react", + "@npm//@types/react-beautiful-dnd", +] + +DEPS = SRC_DEPS + TYPES_DEPS + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + ], +) + +ts_config( + name = "tsconfig_browser", + src = "tsconfig.browser.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.browser.json", + ], +) + +ts_project( + name = "tsc", + args = ["--pretty"], + srcs = SRCS, + deps = DEPS, + declaration = True, + declaration_dir = "target_types", + declaration_map = True, + incremental = True, + out_dir = "target_node", + root_dir = "src", + source_map = True, + tsconfig = ":tsconfig", +) + +ts_project( + name = "tsc_browser", + args = ['--pretty'], + srcs = SRCS, + deps = DEPS, + allow_js = True, + declaration = False, + incremental = True, + out_dir = "target_web", + source_map = True, + root_dir = "src", + tsconfig = ":tsconfig_browser", +) + +js_library( + name = PKG_BASE_NAME, + package_name = PKG_REQUIRE_NAME, + srcs = NPM_MODULE_EXTRA_FILES, + visibility = ["//visibility:public"], + deps = [":tsc", ":tsc_browser"] + DEPS, +) + +pkg_npm( + name = "npm_module", + deps = [ + ":%s" % PKG_BASE_NAME, + ], +) + +filegroup( + name = "build", + srcs = [ + ":npm_module", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-securitysolution-t-grid/README.md b/packages/kbn-securitysolution-t-grid/README.md new file mode 100644 index 00000000000000..a49669c81689a2 --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/README.md @@ -0,0 +1,3 @@ +# kbn-securitysolution-t-grid + +We do not want to create circular dependencies between security_solution and timelines plugins. Therefore , we will use this packages to share components between these two plugins. diff --git a/packages/kbn-securitysolution-t-grid/babel.config.js b/packages/kbn-securitysolution-t-grid/babel.config.js new file mode 100644 index 00000000000000..b4a118df51af51 --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/babel.config.js @@ -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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + env: { + web: { + presets: ['@kbn/babel-preset/webpack_preset'], + }, + node: { + presets: ['@kbn/babel-preset/node_preset'], + }, + }, + ignore: ['**/*.test.ts', '**/*.test.tsx'], +}; diff --git a/packages/kbn-securitysolution-t-grid/jest.config.js b/packages/kbn-securitysolution-t-grid/jest.config.js new file mode 100644 index 00000000000000..21e7d2d71b61a1 --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../..', + roots: ['/packages/kbn-securitysolution-t-grid'], +}; diff --git a/packages/kbn-securitysolution-t-grid/package.json b/packages/kbn-securitysolution-t-grid/package.json new file mode 100644 index 00000000000000..68d3a8c71e7cac --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/package.json @@ -0,0 +1,10 @@ +{ + "name": "@kbn/securitysolution-t-grid", + "version": "1.0.0", + "description": "security solution t-grid packages will allow sharing components between timelines and security_solution plugin until we transfer all functionality to timelines plugin", + "license": "SSPL-1.0 OR Elastic License 2.0", + "browser": "./target_web/browser.js", + "main": "./target_node/index.js", + "types": "./target_types/index.d.ts", + "private": true +} diff --git a/packages/kbn-securitysolution-t-grid/react/package.json b/packages/kbn-securitysolution-t-grid/react/package.json new file mode 100644 index 00000000000000..c29ddd45f084d8 --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/react/package.json @@ -0,0 +1,5 @@ +{ + "browser": "../target_web/react", + "main": "../target_node/react", + "types": "../target_types/react/index.d.ts" +} \ No newline at end of file diff --git a/packages/kbn-securitysolution-t-grid/src/constants/index.ts b/packages/kbn-securitysolution-t-grid/src/constants/index.ts new file mode 100644 index 00000000000000..c03c0093d98392 --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/src/constants/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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export const HIGHLIGHTED_DROP_TARGET_CLASS_NAME = 'highlighted-drop-target'; +export const EMPTY_PROVIDERS_GROUP_CLASS_NAME = 'empty-providers-group'; + +/** The draggable will move this many pixels via the keyboard when the arrow key is pressed */ +export const KEYBOARD_DRAG_OFFSET = 20; + +export const DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME = 'draggable-keyboard-wrapper'; + +export const ROW_RENDERER_CLASS_NAME = 'row-renderer'; + +export const NOTES_CONTAINER_CLASS_NAME = 'notes-container'; + +export const NOTE_CONTENT_CLASS_NAME = 'note-content'; + +/** This class is added to the document body while dragging */ +export const IS_DRAGGING_CLASS_NAME = 'is-dragging'; + +export const HOVER_ACTIONS_ALWAYS_SHOW_CLASS_NAME = 'hover-actions-always-show'; diff --git a/packages/kbn-securitysolution-t-grid/src/index.ts b/packages/kbn-securitysolution-t-grid/src/index.ts new file mode 100644 index 00000000000000..0c2e9a7dbea8bf --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/src/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export * from './constants'; +export * from './utils'; +export * from './mock'; diff --git a/packages/kbn-securitysolution-t-grid/src/mock/index.ts b/packages/kbn-securitysolution-t-grid/src/mock/index.ts new file mode 100644 index 00000000000000..dc1b63dfc33b03 --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/src/mock/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export * from './mock_event_details'; diff --git a/x-pack/plugins/security_solution/common/utils/mock_event_details.ts b/packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts similarity index 97% rename from x-pack/plugins/security_solution/common/utils/mock_event_details.ts rename to packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts index 7dc257ebb3feff..167fc9dd17a2ac 100644 --- a/x-pack/plugins/security_solution/common/utils/mock_event_details.ts +++ b/packages/kbn-securitysolution-t-grid/src/mock/mock_event_details.ts @@ -1,8 +1,9 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. */ export const eventHit = { diff --git a/packages/kbn-securitysolution-t-grid/src/utils/api/index.ts b/packages/kbn-securitysolution-t-grid/src/utils/api/index.ts new file mode 100644 index 00000000000000..34e448419693bb --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/src/utils/api/index.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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { has } from 'lodash/fp'; + +export interface AppError extends Error { + body: { + message: string; + }; +} + +export interface KibanaError extends AppError { + body: { + message: string; + statusCode: number; + }; +} + +export interface SecurityAppError extends AppError { + body: { + message: string; + status_code: number; + }; +} + +export const isKibanaError = (error: unknown): error is KibanaError => + has('message', error) && has('body.message', error) && has('body.statusCode', error); + +export const isSecurityAppError = (error: unknown): error is SecurityAppError => + has('message', error) && has('body.message', error) && has('body.status_code', error); + +export const isAppError = (error: unknown): error is AppError => + isKibanaError(error) || isSecurityAppError(error); + +export const isNotFoundError = (error: unknown) => + (isKibanaError(error) && error.body.statusCode === 404) || + (isSecurityAppError(error) && error.body.status_code === 404); diff --git a/packages/kbn-securitysolution-t-grid/src/utils/drag_and_drop/index.ts b/packages/kbn-securitysolution-t-grid/src/utils/drag_and_drop/index.ts new file mode 100644 index 00000000000000..91b2e88d973589 --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/src/utils/drag_and_drop/index.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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { DropResult } from 'react-beautiful-dnd'; + +export const draggableIdPrefix = 'draggableId'; + +export const droppableIdPrefix = 'droppableId'; + +export const draggableContentPrefix = `${draggableIdPrefix}.content.`; + +export const draggableTimelineProvidersPrefix = `${draggableIdPrefix}.timelineProviders.`; + +export const draggableFieldPrefix = `${draggableIdPrefix}.field.`; + +export const droppableContentPrefix = `${droppableIdPrefix}.content.`; + +export const droppableFieldPrefix = `${droppableIdPrefix}.field.`; + +export const droppableTimelineProvidersPrefix = `${droppableIdPrefix}.timelineProviders.`; + +export const droppableTimelineColumnsPrefix = `${droppableIdPrefix}.timelineColumns.`; + +export const droppableTimelineFlyoutBottomBarPrefix = `${droppableIdPrefix}.flyoutButton.`; + +export const getDraggableId = (dataProviderId: string): string => + `${draggableContentPrefix}${dataProviderId}`; + +export const getDraggableFieldId = ({ + contextId, + fieldId, +}: { + contextId: string; + fieldId: string; +}): string => `${draggableFieldPrefix}${escapeContextId(contextId)}.${escapeFieldId(fieldId)}`; + +export const getTimelineProviderDroppableId = ({ + groupIndex, + timelineId, +}: { + groupIndex: number; + timelineId: string; +}): string => `${droppableTimelineProvidersPrefix}${timelineId}.group.${groupIndex}`; + +export const getTimelineProviderDraggableId = ({ + dataProviderId, + groupIndex, + timelineId, +}: { + dataProviderId: string; + groupIndex: number; + timelineId: string; +}): string => + `${draggableTimelineProvidersPrefix}${timelineId}.group.${groupIndex}.${dataProviderId}`; + +export const getDroppableId = (visualizationPlaceholderId: string): string => + `${droppableContentPrefix}${visualizationPlaceholderId}`; + +export const sourceIsContent = (result: DropResult): boolean => + result.source.droppableId.startsWith(droppableContentPrefix); + +export const sourceAndDestinationAreSameTimelineProviders = (result: DropResult): boolean => { + const regex = /^droppableId\.timelineProviders\.(\S+)\./; + const sourceMatches = result.source.droppableId.match(regex) || []; + const destinationMatches = + (result.destination && result.destination.droppableId.match(regex)) || []; + + return ( + sourceMatches.length >= 2 && + destinationMatches.length >= 2 && + sourceMatches[1] === destinationMatches[1] + ); +}; + +export const draggableIsContent = (result: DropResult | { draggableId: string }): boolean => + result.draggableId.startsWith(draggableContentPrefix); + +export const draggableIsField = (result: DropResult | { draggableId: string }): boolean => + result.draggableId.startsWith(draggableFieldPrefix); + +export const reasonIsDrop = (result: DropResult): boolean => result.reason === 'DROP'; + +export const destinationIsTimelineProviders = (result: DropResult): boolean => + result.destination != null && + result.destination.droppableId.startsWith(droppableTimelineProvidersPrefix); + +export const destinationIsTimelineColumns = (result: DropResult): boolean => + result.destination != null && + result.destination.droppableId.startsWith(droppableTimelineColumnsPrefix); + +export const destinationIsTimelineButton = (result: DropResult): boolean => + result.destination != null && + result.destination.droppableId.startsWith(droppableTimelineFlyoutBottomBarPrefix); + +export const getProviderIdFromDraggable = (result: DropResult): string => + result.draggableId.substring(result.draggableId.lastIndexOf('.') + 1); + +export const getFieldIdFromDraggable = (result: DropResult): string => + unEscapeFieldId(result.draggableId.substring(result.draggableId.lastIndexOf('.') + 1)); + +export const escapeDataProviderId = (path: string) => path.replace(/\./g, '_'); + +export const escapeContextId = (path: string) => path.replace(/\./g, '_'); + +export const escapeFieldId = (path: string) => path.replace(/\./g, '!!!DOT!!!'); + +export const unEscapeFieldId = (path: string) => path.replace(/!!!DOT!!!/g, '.'); + +export const providerWasDroppedOnTimeline = (result: DropResult): boolean => + reasonIsDrop(result) && + draggableIsContent(result) && + sourceIsContent(result) && + destinationIsTimelineProviders(result); + +export const userIsReArrangingProviders = (result: DropResult): boolean => + reasonIsDrop(result) && sourceAndDestinationAreSameTimelineProviders(result); + +export const fieldWasDroppedOnTimelineColumns = (result: DropResult): boolean => + reasonIsDrop(result) && draggableIsField(result) && destinationIsTimelineColumns(result); + +/** + * Prevents fields from being dragged or dropped to any area other than column + * header drop zone in the timeline + */ +export const DRAG_TYPE_FIELD = 'drag-type-field'; + +/** This class is added to the document body while timeline field dragging */ +export const IS_TIMELINE_FIELD_DRAGGING_CLASS_NAME = 'is-timeline-field-dragging'; diff --git a/packages/kbn-securitysolution-t-grid/src/utils/index.ts b/packages/kbn-securitysolution-t-grid/src/utils/index.ts new file mode 100644 index 00000000000000..39629a990c539c --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/src/utils/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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export * from './api'; +export * from './drag_and_drop'; diff --git a/packages/kbn-securitysolution-t-grid/tsconfig.browser.json b/packages/kbn-securitysolution-t-grid/tsconfig.browser.json new file mode 100644 index 00000000000000..a5183ba4fd4576 --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/tsconfig.browser.json @@ -0,0 +1,23 @@ +{ + "extends": "../../tsconfig.browser.json", + "compilerOptions": { + "allowJs": true, + "incremental": true, + "outDir": "./target_web", + "declaration": false, + "isolatedModules": true, + "sourceMap": true, + "sourceRoot": "../../../../../packages/kbn-securitysolution-t-grid/src", + "types": [ + "jest", + "node" + ], + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + ], + "exclude": [ + "**/__fixtures__/**/*" + ] +} diff --git a/packages/kbn-securitysolution-t-grid/tsconfig.json b/packages/kbn-securitysolution-t-grid/tsconfig.json new file mode 100644 index 00000000000000..8cda578edede4c --- /dev/null +++ b/packages/kbn-securitysolution-t-grid/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "incremental": true, + "outDir": "target", + "rootDir": "src", + "sourceMap": true, + "sourceRoot": "../../../../packages/kbn-securitysolution-t-grid/src", + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/kbn-test/jest-preset.js b/packages/kbn-test/jest-preset.js index 225f93d4878238..5baff607704c78 100644 --- a/packages/kbn-test/jest-preset.js +++ b/packages/kbn-test/jest-preset.js @@ -94,7 +94,7 @@ module.exports = { transformIgnorePatterns: [ // ignore all node_modules except monaco-editor and react-monaco-editor which requires babel transforms to handle dynamic import() // since ESM modules are not natively supported in Jest yet (https://github.com/facebook/jest/issues/4842) - '[/\\\\]node_modules(?![\\/\\\\](monaco-editor|react-monaco-editor))[/\\\\].+\\.js$', + '[/\\\\]node_modules(?![\\/\\\\](monaco-editor|react-monaco-editor|d3-interpolate|d3-color))[/\\\\].+\\.js$', 'packages/kbn-pm/dist/index.js', ], diff --git a/packages/kbn-test/package.json b/packages/kbn-test/package.json index 275d9fac73c58d..aaff513f1591f2 100644 --- a/packages/kbn-test/package.json +++ b/packages/kbn-test/package.json @@ -12,8 +12,5 @@ }, "kibana": { "devOnly": true - }, - "dependencies": { - "@kbn/optimizer": "link:../kbn-optimizer" } } \ No newline at end of file diff --git a/packages/kbn-test/src/jest/setup/babel_polyfill.js b/packages/kbn-test/src/jest/setup/babel_polyfill.js index d112e4d4fcb393..7dda4cceec65cd 100644 --- a/packages/kbn-test/src/jest/setup/babel_polyfill.js +++ b/packages/kbn-test/src/jest/setup/babel_polyfill.js @@ -9,4 +9,4 @@ // Note: In theory importing the polyfill should not be needed, as Babel should // include the necessary polyfills when using `@babel/preset-env`, but for some // reason it did not work. See https://github.com/elastic/kibana/issues/14506 -import '@kbn/optimizer/src/node/polyfill'; +import '@kbn/optimizer/target/node/polyfill'; diff --git a/src/core/public/chrome/chrome_service.test.ts b/src/core/public/chrome/chrome_service.test.ts index 0264c8a1acf754..92f5a854f6b00f 100644 --- a/src/core/public/chrome/chrome_service.test.ts +++ b/src/core/public/chrome/chrome_service.test.ts @@ -53,8 +53,21 @@ function defaultStartDeps(availableApps?: App[]) { return deps; } +function defaultStartTestOptions({ + browserSupportsCsp = true, + kibanaVersion = 'version', +}: { + browserSupportsCsp?: boolean; + kibanaVersion?: string; +}): any { + return { + browserSupportsCsp, + kibanaVersion, + }; +} + async function start({ - options = { browserSupportsCsp: true }, + options = defaultStartTestOptions({}), cspConfigMock = { warnLegacyBrowsers: true }, startDeps = defaultStartDeps(), }: { options?: any; cspConfigMock?: any; startDeps?: ReturnType } = {}) { @@ -82,7 +95,9 @@ afterAll(() => { describe('start', () => { it('adds legacy browser warning if browserSupportsCsp is disabled and warnLegacyBrowsers is enabled', async () => { - const { startDeps } = await start({ options: { browserSupportsCsp: false } }); + const { startDeps } = await start({ + options: { browserSupportsCsp: false, kibanaVersion: '7.0.0' }, + }); expect(startDeps.notifications.toasts.addWarning.mock.calls).toMatchInlineSnapshot(` Array [ @@ -95,6 +110,41 @@ describe('start', () => { `); }); + it('adds the kibana versioned class to the document body', async () => { + const { chrome, service } = await start({ + options: { browserSupportsCsp: false, kibanaVersion: '1.2.3' }, + }); + const promise = chrome.getBodyClasses$().pipe(toArray()).toPromise(); + service.stop(); + await expect(promise).resolves.toMatchInlineSnapshot(` + Array [ + Array [ + "kbnBody", + "kbnBody--noHeaderBanner", + "kbnBody--chromeHidden", + "kbnVersion-1-2-3", + ], + ] + `); + }); + it('strips off "snapshot" from the kibana version if present', async () => { + const { chrome, service } = await start({ + options: { browserSupportsCsp: false, kibanaVersion: '8.0.0-SnAPshot' }, + }); + const promise = chrome.getBodyClasses$().pipe(toArray()).toPromise(); + service.stop(); + await expect(promise).resolves.toMatchInlineSnapshot(` + Array [ + Array [ + "kbnBody", + "kbnBody--noHeaderBanner", + "kbnBody--chromeHidden", + "kbnVersion-8-0-0", + ], + ] + `); + }); + it('does not add legacy browser warning if browser supports CSP', async () => { const { startDeps } = await start(); diff --git a/src/core/public/chrome/chrome_service.tsx b/src/core/public/chrome/chrome_service.tsx index 5ed447edde75a0..f1381c52ce7793 100644 --- a/src/core/public/chrome/chrome_service.tsx +++ b/src/core/public/chrome/chrome_service.tsx @@ -37,9 +37,11 @@ import { export type { ChromeNavControls, ChromeRecentlyAccessed, ChromeDocTitle }; const IS_LOCKED_KEY = 'core.chrome.isLocked'; +const SNAPSHOT_REGEX = /-snapshot/i; interface ConstructorParams { browserSupportsCsp: boolean; + kibanaVersion: string; } interface StartDeps { @@ -116,6 +118,16 @@ export class ChromeService { const helpSupportUrl$ = new BehaviorSubject(KIBANA_ASK_ELASTIC_LINK); const isNavDrawerLocked$ = new BehaviorSubject(localStorage.getItem(IS_LOCKED_KEY) === 'true'); + const getKbnVersionClass = () => { + // we assume that the version is valid and has the form 'X.X.X' + // strip out `SNAPSHOT` and reformat to 'X-X-X' + const formattedVersionClass = this.params.kibanaVersion + .replace(SNAPSHOT_REGEX, '') + .split('.') + .join('-'); + return `kbnVersion-${formattedVersionClass}`; + }; + const headerBanner$ = new BehaviorSubject(undefined); const bodyClasses$ = combineLatest([headerBanner$, this.isVisible$!]).pipe( map(([headerBanner, isVisible]) => { @@ -123,6 +135,7 @@ export class ChromeService { 'kbnBody', headerBanner ? 'kbnBody--hasHeaderBanner' : 'kbnBody--noHeaderBanner', isVisible ? 'kbnBody--chromeVisible' : 'kbnBody--chromeHidden', + getKbnVersionClass(), ]; }) ); diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index 1c4e78f0a5c2ef..8ead0f50785bdc 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -46,6 +46,7 @@ const defaultCoreSystemParams = { csp: { warnLegacyBrowsers: true, }, + version: 'version', } as any, }; @@ -91,12 +92,12 @@ describe('constructor', () => { }); }); - it('passes browserSupportsCsp to ChromeService', () => { + it('passes browserSupportsCsp and coreContext to ChromeService', () => { createCoreSystem(); - expect(ChromeServiceConstructor).toHaveBeenCalledTimes(1); expect(ChromeServiceConstructor).toHaveBeenCalledWith({ - browserSupportsCsp: expect.any(Boolean), + browserSupportsCsp: true, + kibanaVersion: 'version', }); }); diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index f0ea1e62fc33f8..9a28bf45df9273 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -5,7 +5,6 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - import { CoreId } from '../server'; import { PackageInfo, EnvironmentMode } from '../server/types'; import { CoreSetup, CoreStart } from '.'; @@ -98,6 +97,7 @@ export class CoreSystem { this.injectedMetadata = new InjectedMetadataService({ injectedMetadata, }); + this.coreContext = { coreId: Symbol('core'), env: injectedMetadata.env }; this.fatalErrors = new FatalErrorsService(rootDomElement, () => { // Stop Core before rendering any fatal errors into the DOM @@ -109,14 +109,16 @@ export class CoreSystem { this.savedObjects = new SavedObjectsService(); this.uiSettings = new UiSettingsService(); this.overlay = new OverlayService(); - this.chrome = new ChromeService({ browserSupportsCsp }); + this.chrome = new ChromeService({ + browserSupportsCsp, + kibanaVersion: injectedMetadata.version, + }); this.docLinks = new DocLinksService(); this.rendering = new RenderingService(); this.application = new ApplicationService(); this.integrations = new IntegrationsService(); this.deprecations = new DeprecationsService(); - this.coreContext = { coreId: Symbol('core'), env: injectedMetadata.env }; this.plugins = new PluginsService(this.coreContext, injectedMetadata.uiPlugins); this.coreApp = new CoreApp(this.coreContext); } diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index 8c52d09f821595..502b22a6f8e89c 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -204,6 +204,7 @@ export class DocLinksService { }, search: { sessions: `${KIBANA_DOCS}search-sessions.html`, + sessionLimits: `${KIBANA_DOCS}search-sessions.html#_limitations`, }, date: { dateMath: `${ELASTICSEARCH_DOCS}common-options.html#date-math`, @@ -523,6 +524,7 @@ export interface DocLinksStart { }; readonly search: { readonly sessions: string; + readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 27569935bcc65f..ca95b253f9cdbb 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -585,6 +585,7 @@ export interface DocLinksStart { }; readonly search: { readonly sessions: string; + readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; @@ -1631,6 +1632,6 @@ export interface UserProvidedValues { // Warnings were encountered during analysis: // -// src/core/public/core_system.ts:166:21 - (ae-forgotten-export) The symbol "InternalApplicationStart" needs to be exported by the entry point index.d.ts +// src/core/public/core_system.ts:168:21 - (ae-forgotten-export) The symbol "InternalApplicationStart" needs to be exported by the entry point index.d.ts ``` diff --git a/src/core/public/rendering/_base.scss b/src/core/public/rendering/_base.scss index 4bd6afe90d3429..92ba28ff70887e 100644 --- a/src/core/public/rendering/_base.scss +++ b/src/core/public/rendering/_base.scss @@ -38,6 +38,7 @@ @mixin kbnAffordForHeader($headerHeight) { @include euiHeaderAffordForFixed($headerHeight); + #securitySolutionStickyKQL, #app-fixed-viewport { top: $headerHeight; } diff --git a/src/dev/build/tasks/bin/scripts/kibana-encryption-keys.bat b/src/dev/build/tasks/bin/scripts/kibana-encryption-keys.bat new file mode 100755 index 00000000000000..9221af3142e613 --- /dev/null +++ b/src/dev/build/tasks/bin/scripts/kibana-encryption-keys.bat @@ -0,0 +1,35 @@ +@echo off + +SETLOCAL ENABLEDELAYEDEXPANSION + +set SCRIPT_DIR=%~dp0 +for %%I in ("%SCRIPT_DIR%..") do set DIR=%%~dpfI + +set NODE=%DIR%\node\node.exe + +If Not Exist "%NODE%" ( + Echo unable to find usable node.js executable. + Exit /B 1 +) + +set CONFIG_DIR=%KBN_PATH_CONF% +If [%KBN_PATH_CONF%] == [] ( + set "CONFIG_DIR=%DIR%\config" +) + +IF EXIST "%CONFIG_DIR%\node.options" ( + for /F "usebackq eol=# tokens=*" %%i in ("%CONFIG_DIR%\node.options") do ( + If [!NODE_OPTIONS!] == [] ( + set "NODE_OPTIONS=%%i" + ) Else ( + set "NODE_OPTIONS=!NODE_OPTIONS! %%i" + ) + ) +) + +TITLE Kibana Encryption Keys +"%NODE%" "%DIR%\src\cli_encryption_keys\dist" %* + +:finally + +ENDLOCAL diff --git a/src/dev/typescript/projects.ts b/src/dev/typescript/projects.ts index 050743114f657d..f372cf052d3683 100644 --- a/src/dev/typescript/projects.ts +++ b/src/dev/typescript/projects.ts @@ -22,6 +22,9 @@ export const PROJECTS = [ new Project(resolve(REPO_ROOT, 'x-pack/plugins/security_solution/cypress/tsconfig.json'), { name: 'security_solution/cypress', }), + new Project(resolve(REPO_ROOT, 'x-pack/plugins/osquery/cypress/tsconfig.json'), { + name: 'osquery/cypress', + }), new Project(resolve(REPO_ROOT, 'x-pack/plugins/apm/e2e/tsconfig.json'), { name: 'apm/cypress', disableTypeCheck: true, diff --git a/src/plugins/data/common/search/aggs/utils/parse_time_shift.ts b/src/plugins/data/common/search/aggs/utils/parse_time_shift.ts index 4d8ee0f8891732..91379ea054de3b 100644 --- a/src/plugins/data/common/search/aggs/utils/parse_time_shift.ts +++ b/src/plugins/data/common/search/aggs/utils/parse_time_shift.ts @@ -20,7 +20,7 @@ export const parseTimeShift = (val: string): moment.Duration | 'previous' | 'inv if (trimmedVal === 'previous') { return 'previous'; } - const [, amount, unit] = trimmedVal.match(/^(\d+)(\w)$/) || []; + const [, amount, unit] = trimmedVal.match(/^(\d+)\s*(\w)$/) || []; const parsedAmount = Number(amount); if (Number.isNaN(parsedAmount) || !allowedUnits.includes(unit as AllowedUnit)) { return 'invalid'; diff --git a/src/plugins/data/common/search/types.ts b/src/plugins/data/common/search/types.ts index d1890ec97df4e1..c5cf3f9f09e6c7 100644 --- a/src/plugins/data/common/search/types.ts +++ b/src/plugins/data/common/search/types.ts @@ -65,6 +65,11 @@ export interface IKibanaSearchResponse { */ isPartial?: boolean; + /** + * Indicates whether the results returned are from the async-search index + */ + isRestored?: boolean; + /** * The raw response returned by the internal search method (usually the raw ES response) */ diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 4d9c69b137a3e0..7a5f323e51459a 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1351,6 +1351,7 @@ export interface IKibanaSearchRequest { export interface IKibanaSearchResponse { id?: string; isPartial?: boolean; + isRestored?: boolean; isRunning?: boolean; loaded?: number; rawResponse: RawResponse; diff --git a/src/plugins/data/public/search/errors/index.ts b/src/plugins/data/public/search/errors/index.ts index 82c9e04b797983..fcdea8dec1c2eb 100644 --- a/src/plugins/data/public/search/errors/index.ts +++ b/src/plugins/data/public/search/errors/index.ts @@ -12,3 +12,4 @@ export * from './timeout_error'; export * from './utils'; export * from './types'; export * from './http_error'; +export * from './search_session_incomplete_warning'; diff --git a/src/plugins/data/public/search/errors/search_session_incomplete_warning.tsx b/src/plugins/data/public/search/errors/search_session_incomplete_warning.tsx new file mode 100644 index 00000000000000..c5c5c37f31cf87 --- /dev/null +++ b/src/plugins/data/public/search/errors/search_session_incomplete_warning.tsx @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; +import { CoreStart } from 'kibana/public'; +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; + +export const SearchSessionIncompleteWarning = (docLinks: CoreStart['docLinks']) => ( + <> + + It needs more time to fully render. You can wait here or come back to it later. + + + + + + + +); diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts index fe66d4b6e99370..155638250a2a4c 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts @@ -29,6 +29,12 @@ jest.mock('./utils', () => ({ }), })); +jest.mock('../errors/search_session_incomplete_warning', () => ({ + SearchSessionIncompleteWarning: jest.fn(), +})); + +import { SearchSessionIncompleteWarning } from '../errors/search_session_incomplete_warning'; + let searchInterceptor: SearchInterceptor; let mockCoreSetup: MockedKeys; let bfetchSetup: jest.Mocked; @@ -508,6 +514,7 @@ describe('SearchInterceptor', () => { } : null ); + sessionServiceMock.isRestore.mockReturnValue(!!opts?.isRestore); fetchMock.mockResolvedValue({ result: 200 }); }; @@ -562,6 +569,92 @@ describe('SearchInterceptor', () => { (sessionService as jest.Mocked).getSearchOptions ).toHaveBeenCalledWith(sessionId); }); + + test('should not show warning if a search is available during restore', async () => { + setup({ + isRestore: true, + isStored: true, + sessionId: '123', + }); + + const responses = [ + { + time: 10, + value: { + isPartial: false, + isRunning: false, + isRestored: true, + id: 1, + rawResponse: { + took: 1, + }, + }, + }, + ]; + mockFetchImplementation(responses); + + const response = searchInterceptor.search( + {}, + { + sessionId: '123', + } + ); + response.subscribe({ next, error, complete }); + + await timeTravel(10); + + expect(SearchSessionIncompleteWarning).toBeCalledTimes(0); + }); + + test('should show warning once if a search is not available during restore', async () => { + setup({ + isRestore: true, + isStored: true, + sessionId: '123', + }); + + const responses = [ + { + time: 10, + value: { + isPartial: false, + isRunning: false, + isRestored: false, + id: 1, + rawResponse: { + took: 1, + }, + }, + }, + ]; + mockFetchImplementation(responses); + + searchInterceptor + .search( + {}, + { + sessionId: '123', + } + ) + .subscribe({ next, error, complete }); + + await timeTravel(10); + + expect(SearchSessionIncompleteWarning).toBeCalledTimes(1); + + searchInterceptor + .search( + {}, + { + sessionId: '123', + } + ) + .subscribe({ next, error, complete }); + + await timeTravel(10); + + expect(SearchSessionIncompleteWarning).toBeCalledTimes(1); + }); }); describe('Session tracking', () => { diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts index 57b156a9b3c00a..e0e1df65101c7d 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts @@ -43,6 +43,7 @@ import { PainlessError, SearchTimeoutError, TimeoutErrorMode, + SearchSessionIncompleteWarning, } from '../errors'; import { toMountPoint } from '../../../../kibana_react/public'; import { AbortError, KibanaServerError } from '../../../../kibana_utils/public'; @@ -82,6 +83,7 @@ export class SearchInterceptor { * @internal */ private application!: CoreStart['application']; + private docLinks!: CoreStart['docLinks']; private batchedFetch!: BatchedFunc< { request: IKibanaSearchRequest; options: ISearchOptionsSerializable }, IKibanaSearchResponse @@ -95,6 +97,7 @@ export class SearchInterceptor { this.deps.startServices.then(([coreStart]) => { this.application = coreStart.application; + this.docLinks = coreStart.docLinks; }); this.batchedFetch = deps.bfetch.batchedFunction({ @@ -345,6 +348,11 @@ export class SearchInterceptor { this.handleSearchError(e, searchOptions, searchAbortController.isTimeout()) ); }), + tap((response) => { + if (this.deps.session.isRestore() && response.isRestored === false) { + this.showRestoreWarning(this.deps.session.getSessionId()); + } + }), finalize(() => { this.pendingCount$.next(this.pendingCount$.getValue() - 1); if (untrackSearch && this.deps.session.isCurrentSession(sessionId)) { @@ -371,6 +379,25 @@ export class SearchInterceptor { } ); + private showRestoreWarningToast = (sessionId?: string) => { + this.deps.toasts.addWarning( + { + title: 'Your search session is still running', + text: toMountPoint(SearchSessionIncompleteWarning(this.docLinks)), + }, + { + toastLifeTimeMs: 60000, + } + ); + }; + + private showRestoreWarning = memoize( + this.showRestoreWarningToast, + (_: SearchTimeoutError, sessionId: string) => { + return sessionId; + } + ); + /** * Show one error notification per session. * @internal diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index 0764f4f441e425..dd60951e6d2285 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -238,6 +238,7 @@ export { DataRequestHandlerContext, AsyncSearchResponse, AsyncSearchStatusResponse, + NoSearchIdInSessionError, } from './search'; // Search namespace diff --git a/src/plugins/data/server/search/errors/no_search_id_in_session.ts b/src/plugins/data/server/search/errors/no_search_id_in_session.ts new file mode 100644 index 00000000000000..b291df1cee5ba7 --- /dev/null +++ b/src/plugins/data/server/search/errors/no_search_id_in_session.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { KbnError } from '../../../../kibana_utils/common'; + +export class NoSearchIdInSessionError extends KbnError { + constructor() { + super('No search ID in this session matching the given search request'); + } +} diff --git a/src/plugins/data/server/search/index.ts b/src/plugins/data/server/search/index.ts index 812f3171aef99f..b9affe96ea2ddd 100644 --- a/src/plugins/data/server/search/index.ts +++ b/src/plugins/data/server/search/index.ts @@ -13,3 +13,4 @@ export * from './strategies/eql_search'; export { usageProvider, SearchUsage, searchUsageObserver } from './collectors'; export * from './aggs'; export * from './session'; +export * from './errors/no_search_id_in_session'; diff --git a/src/plugins/data/server/search/search_service.test.ts b/src/plugins/data/server/search/search_service.test.ts index 52ee8e60a5b26a..314cb2c3acbf87 100644 --- a/src/plugins/data/server/search/search_service.test.ts +++ b/src/plugins/data/server/search/search_service.test.ts @@ -25,6 +25,7 @@ import { ISearchSessionService, ISearchStart, ISearchStrategy, + NoSearchIdInSessionError, } from '.'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { expressionsPluginMock } from '../../../expressions/public/mocks'; @@ -175,6 +176,22 @@ describe('Search service', () => { expect(request).toStrictEqual({ ...searchRequest, id: 'my_id' }); }); + it('searches even if id is not found in session during restore', async () => { + const searchRequest = { params: {} }; + const options = { sessionId, isStored: true, isRestore: true }; + + mockSessionClient.getId = jest.fn().mockImplementation(() => { + throw new NoSearchIdInSessionError(); + }); + + const res = await mockScopedClient.search(searchRequest, options).toPromise(); + + const [request, callOptions] = mockStrategy.search.mock.calls[0]; + expect(callOptions).toBe(options); + expect(request).toStrictEqual({ ...searchRequest }); + expect(res.isRestored).toBe(false); + }); + it('does not fail if `trackId` throws', async () => { const searchRequest = { params: {} }; const options = { sessionId, isStored: false, isRestore: false }; diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index a651d7b3bf105e..00dffefa5e3a6e 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -19,7 +19,7 @@ import { SharedGlobalConfig, StartServicesAccessor, } from 'src/core/server'; -import { first, switchMap, tap } from 'rxjs/operators'; +import { first, map, switchMap, tap, withLatestFrom } from 'rxjs/operators'; import { BfetchServerSetup } from 'src/plugins/bfetch/server'; import { ExpressionsServerSetup } from 'src/plugins/expressions/server'; import type { @@ -80,6 +80,7 @@ import { registerBsearchRoute } from './routes/bsearch'; import { getKibanaContext } from './expressions/kibana_context'; import { enhancedEsSearchStrategyProvider } from './strategies/ese_search'; import { eqlSearchStrategyProvider } from './strategies/eql_search'; +import { NoSearchIdInSessionError } from './errors/no_search_id_in_session'; type StrategyMap = Record>; @@ -287,24 +288,48 @@ export class SearchService implements Plugin { options.strategy ); - const getSearchRequest = async () => - !options.sessionId || !options.isRestore || request.id - ? request - : { + const getSearchRequest = async () => { + if (!options.sessionId || !options.isRestore || request.id) { + return request; + } else { + try { + const id = await deps.searchSessionsClient.getId(request, options); + this.logger.debug(`Found search session id for request ${id}`); + return { ...request, - id: await deps.searchSessionsClient.getId(request, options), + id, }; + } catch (e) { + if (e instanceof NoSearchIdInSessionError) { + this.logger.debug('Ignoring missing search ID'); + return request; + } else { + throw e; + } + } + } + }; - return from(getSearchRequest()).pipe( + const searchRequest$ = from(getSearchRequest()); + const search$ = searchRequest$.pipe( switchMap((searchRequest) => strategy.search(searchRequest, options, deps)), - tap((response) => { - if (!options.sessionId || !response.id || options.isRestore) return; + withLatestFrom(searchRequest$), + tap(([response, requestWithId]) => { + if (!options.sessionId || !response.id || (options.isRestore && requestWithId.id)) return; // intentionally swallow tracking error, as it shouldn't fail the search deps.searchSessionsClient.trackId(request, response.id, options).catch((trackErr) => { this.logger.error(trackErr); }); + }), + map(([response, requestWithId]) => { + return { + ...response, + isRestored: !!requestWithId.id, + }; }) ); + + return search$; } catch (e) { return throwError(e); } diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index c2b533bc42dc6f..768c44d3e3e950 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -1205,6 +1205,14 @@ export enum METRIC_TYPES { TOP_HITS = "top_hits" } +// Warning: (ae-forgotten-export) The symbol "KbnError" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "NoSearchIdInSessionError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class NoSearchIdInSessionError extends KbnError { + constructor(); +} + // Warning: (ae-missing-release-tag) "OptionedParamType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1537,18 +1545,18 @@ export function usageProvider(core: CoreSetup_2): SearchUsage; // src/plugins/data/server/index.ts:101:26 - (ae-forgotten-export) The symbol "HistogramFormat" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index.ts:128:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index.ts:128:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:244:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:244:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:246:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:247:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:256:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:257:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:258:1 - (ae-forgotten-export) The symbol "IpAddress" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:262:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:263:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:267:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:270:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:271:1 - (ae-forgotten-export) The symbol "calcAutoIntervalLessThan" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:245:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:245:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:247:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:248:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:257:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:258:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:259:1 - (ae-forgotten-export) The symbol "IpAddress" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:263:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:264:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:268:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:271:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:272:1 - (ae-forgotten-export) The symbol "calcAutoIntervalLessThan" needs to be exported by the entry point index.d.ts // src/plugins/data/server/plugin.ts:81:74 - (ae-forgotten-export) The symbol "DataEnhancements" needs to be exported by the entry point index.d.ts // src/plugins/data/server/search/types.ts:115:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.test.tsx b/src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.test.tsx new file mode 100644 index 00000000000000..8c32942740a768 --- /dev/null +++ b/src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.test.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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import React from 'react'; +import { EuiSelectable } from '@elastic/eui'; +import { ShallowWrapper } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import { shallowWithIntl } from '@kbn/test/jest'; +import { ChangeIndexPattern } from './change_indexpattern'; +import { indexPatternMock } from '../../../../../__mocks__/index_pattern'; +import { indexPatternWithTimefieldMock } from '../../../../../__mocks__/index_pattern_with_timefield'; +import { IndexPatternRef } from './types'; + +function getProps() { + return { + indexPatternId: indexPatternMock.id, + indexPatternRefs: [ + indexPatternMock as IndexPatternRef, + indexPatternWithTimefieldMock as IndexPatternRef, + ], + onChangeIndexPattern: jest.fn(), + trigger: { + label: indexPatternMock.title, + title: indexPatternMock.title, + 'data-test-subj': 'indexPattern-switch-link', + }, + }; +} + +function getIndexPatternPickerList(instance: ShallowWrapper) { + return instance.find(EuiSelectable).first(); +} + +function getIndexPatternPickerOptions(instance: ShallowWrapper) { + return getIndexPatternPickerList(instance).prop('options'); +} + +export function selectIndexPatternPickerOption(instance: ShallowWrapper, selectedLabel: string) { + const options: Array<{ label: string; checked?: 'on' | 'off' }> = getIndexPatternPickerOptions( + instance + ).map((option: { label: string }) => + option.label === selectedLabel + ? { ...option, checked: 'on' } + : { ...option, checked: undefined } + ); + return getIndexPatternPickerList(instance).prop('onChange')!(options); +} + +describe('ChangeIndexPattern', () => { + test('switching index pattern to the same index pattern does not trigger onChangeIndexPattern', async () => { + const props = getProps(); + const comp = shallowWithIntl(); + await act(async () => { + selectIndexPatternPickerOption(comp, indexPatternMock.title); + }); + expect(props.onChangeIndexPattern).toHaveBeenCalledTimes(0); + }); + test('switching index pattern to a different index pattern triggers onChangeIndexPattern', async () => { + const props = getProps(); + const comp = shallowWithIntl(); + await act(async () => { + selectIndexPatternPickerOption(comp, indexPatternWithTimefieldMock.title); + }); + expect(props.onChangeIndexPattern).toHaveBeenCalledTimes(1); + expect(props.onChangeIndexPattern).toHaveBeenCalledWith(indexPatternWithTimefieldMock.id); + }); +}); diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.tsx b/src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.tsx index d5076e4daa9904..5f2f35e2419dd7 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.tsx +++ b/src/plugins/discover/public/application/apps/main/components/sidebar/change_indexpattern.tsx @@ -26,17 +26,17 @@ export type ChangeIndexPatternTriggerProps = EuiButtonProps & { // TODO: refactor to shared component with ../../../../../../../../x-pack/legacy/plugins/lens/public/indexpattern_plugin/change_indexpattern export function ChangeIndexPattern({ - indexPatternRefs, indexPatternId, + indexPatternRefs, onChangeIndexPattern, - trigger, selectableProps, + trigger, }: { - trigger: ChangeIndexPatternTriggerProps; + indexPatternId?: string; indexPatternRefs: IndexPatternRef[]; onChangeIndexPattern: (newId: string) => void; - indexPatternId?: string; selectableProps?: EuiSelectableProps<{ value: string }>; + trigger: ChangeIndexPatternTriggerProps; }) { const [isPopoverOpen, setPopoverIsOpen] = useState(false); @@ -86,7 +86,9 @@ export function ChangeIndexPattern({ const choice = (choices.find(({ checked }) => checked) as unknown) as { value: string; }; - onChangeIndexPattern(choice.value); + if (choice.value !== indexPatternId) { + onChangeIndexPattern(choice.value); + } setPopoverIsOpen(false); }} searchProps={{ diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index fbe853ec6deb5b..3840df4353faf8 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -17,4 +17,6 @@ export function plugin(initializerContext: PluginInitializerContext) { export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './saved_searches'; export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable'; export { loadSharingDataHelpers } from './shared'; + export { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState } from './url_generator'; +export { DiscoverAppLocator, DiscoverAppLocatorParams } from './locator'; diff --git a/src/plugins/discover/public/locator.test.ts b/src/plugins/discover/public/locator.test.ts new file mode 100644 index 00000000000000..edbb0663d4aa37 --- /dev/null +++ b/src/plugins/discover/public/locator.test.ts @@ -0,0 +1,270 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { hashedItemStore, getStatesFromKbnUrl } from '../../kibana_utils/public'; +import { mockStorage } from '../../kibana_utils/public/storage/hashed_item_store/mock'; +import { FilterStateStore } from '../../data/common'; +import { DiscoverAppLocatorDefinition } from './locator'; +import { SerializableState } from 'src/plugins/kibana_utils/common'; + +const indexPatternId: string = 'c367b774-a4c2-11ea-bb37-0242ac130002'; +const savedSearchId: string = '571aaf70-4c88-11e8-b3d7-01146121b73d'; + +interface SetupParams { + useHash?: boolean; +} + +const setup = async ({ useHash = false }: SetupParams = {}) => { + const locator = new DiscoverAppLocatorDefinition({ + useHash, + }); + + return { + locator, + }; +}; + +beforeEach(() => { + // @ts-expect-error + hashedItemStore.storage = mockStorage; +}); + +describe('Discover url generator', () => { + test('can create a link to Discover with no state and no saved search', async () => { + const { locator } = await setup(); + const { app, path } = await locator.getLocation({}); + const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']); + + expect(app).toBe('discover'); + expect(_a).toEqual({}); + expect(_g).toEqual({}); + }); + + test('can create a link to a saved search in Discover', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ savedSearchId }); + const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']); + + expect(path.startsWith(`#/view/${savedSearchId}`)).toBe(true); + expect(_a).toEqual({}); + expect(_g).toEqual({}); + }); + + test('can specify specific index pattern', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ + indexPatternId, + }); + const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']); + + expect(_a).toEqual({ + index: indexPatternId, + }); + expect(_g).toEqual({}); + }); + + test('can specify specific time range', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ + timeRange: { to: 'now', from: 'now-15m', mode: 'relative' }, + }); + const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']); + + expect(_a).toEqual({}); + expect(_g).toEqual({ + time: { + from: 'now-15m', + mode: 'relative', + to: 'now', + }, + }); + }); + + test('can specify query', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ + query: { + language: 'kuery', + query: 'foo', + }, + }); + const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']); + + expect(_a).toEqual({ + query: { + language: 'kuery', + query: 'foo', + }, + }); + expect(_g).toEqual({}); + }); + + test('can specify local and global filters', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ + filters: [ + { + meta: { + alias: 'foo', + disabled: false, + negate: false, + }, + $state: { + store: FilterStateStore.APP_STATE, + }, + }, + { + meta: { + alias: 'bar', + disabled: false, + negate: false, + }, + $state: { + store: FilterStateStore.GLOBAL_STATE, + }, + }, + ], + }); + const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']); + + expect(_a).toEqual({ + filters: [ + { + $state: { + store: 'appState', + }, + meta: { + alias: 'foo', + disabled: false, + negate: false, + }, + }, + ], + }); + expect(_g).toEqual({ + filters: [ + { + $state: { + store: 'globalState', + }, + meta: { + alias: 'bar', + disabled: false, + negate: false, + }, + }, + ], + }); + }); + + test('can set refresh interval', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ + refreshInterval: { + pause: false, + value: 666, + }, + }); + const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']); + + expect(_a).toEqual({}); + expect(_g).toEqual({ + refreshInterval: { + pause: false, + value: 666, + }, + }); + }); + + test('can set time range', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ + timeRange: { + from: 'now-3h', + to: 'now', + }, + }); + const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']); + + expect(_a).toEqual({}); + expect(_g).toEqual({ + time: { + from: 'now-3h', + to: 'now', + }, + }); + }); + + test('can specify a search session id', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ + searchSessionId: '__test__', + }); + + expect(path).toMatchInlineSnapshot(`"#/?_g=()&_a=()&searchSessionId=__test__"`); + expect(path).toContain('__test__'); + }); + + test('can specify columns, interval, sort and savedQuery', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ + columns: ['_source'], + interval: 'auto', + sort: [['timestamp, asc']] as string[][] & SerializableState, + savedQuery: '__savedQueryId__', + }); + + expect(path).toMatchInlineSnapshot( + `"#/?_g=()&_a=(columns:!(_source),interval:auto,savedQuery:__savedQueryId__,sort:!(!('timestamp,%20asc')))"` + ); + }); + + describe('useHash property', () => { + describe('when default useHash is set to false', () => { + test('when using default, sets index pattern ID in the generated URL', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ + indexPatternId, + }); + + expect(path.indexOf(indexPatternId) > -1).toBe(true); + }); + + test('when enabling useHash, does not set index pattern ID in the generated URL', async () => { + const { locator } = await setup(); + const { path } = await locator.getLocation({ + useHash: true, + indexPatternId, + }); + + expect(path.indexOf(indexPatternId) > -1).toBe(false); + }); + }); + + describe('when default useHash is set to true', () => { + test('when using default, does not set index pattern ID in the generated URL', async () => { + const { locator } = await setup({ useHash: true }); + const { path } = await locator.getLocation({ + indexPatternId, + }); + + expect(path.indexOf(indexPatternId) > -1).toBe(false); + }); + + test('when disabling useHash, sets index pattern ID in the generated URL', async () => { + const { locator } = await setup({ useHash: true }); + const { path } = await locator.getLocation({ + useHash: false, + indexPatternId, + }); + + expect(path.indexOf(indexPatternId) > -1).toBe(true); + }); + }); + }); +}); diff --git a/src/plugins/discover/public/locator.ts b/src/plugins/discover/public/locator.ts new file mode 100644 index 00000000000000..fff89903bc4653 --- /dev/null +++ b/src/plugins/discover/public/locator.ts @@ -0,0 +1,146 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { TimeRange, Filter, Query, QueryState, RefreshInterval } from '../../data/public'; +import type { LocatorDefinition, LocatorPublic } from '../../share/public'; +import { esFilters } from '../../data/public'; +import { setStateToKbnUrl } from '../../kibana_utils/public'; + +export const DISCOVER_APP_LOCATOR = 'DISCOVER_APP_LOCATOR'; + +export interface DiscoverAppLocatorParams extends SerializableState { + /** + * Optionally set saved search ID. + */ + savedSearchId?: string; + + /** + * Optionally set index pattern ID. + */ + indexPatternId?: string; + + /** + * Optionally set the time range in the time picker. + */ + timeRange?: TimeRange; + + /** + * Optionally set the refresh interval. + */ + refreshInterval?: RefreshInterval & SerializableState; + + /** + * Optionally apply filters. + */ + filters?: Filter[]; + + /** + * Optionally set a query. + */ + query?: Query; + + /** + * If not given, will use the uiSettings configuration for `storeInSessionStorage`. useHash determines + * whether to hash the data in the url to avoid url length issues. + */ + useHash?: boolean; + + /** + * Background search session id + */ + searchSessionId?: string; + + /** + * Columns displayed in the table + */ + columns?: string[]; + + /** + * Used interval of the histogram + */ + interval?: string; + + /** + * Array of the used sorting [[field,direction],...] + */ + sort?: string[][] & SerializableState; + + /** + * id of the used saved query + */ + savedQuery?: string; +} + +export type DiscoverAppLocator = LocatorPublic; + +export interface DiscoverAppLocatorDependencies { + useHash: boolean; +} + +export class DiscoverAppLocatorDefinition implements LocatorDefinition { + public readonly id = DISCOVER_APP_LOCATOR; + + constructor(protected readonly deps: DiscoverAppLocatorDependencies) {} + + public readonly getLocation = async (params: DiscoverAppLocatorParams) => { + const { + useHash = this.deps.useHash, + filters, + indexPatternId, + query, + refreshInterval, + savedSearchId, + timeRange, + searchSessionId, + columns, + savedQuery, + sort, + interval, + } = params; + const savedSearchPath = savedSearchId ? `view/${encodeURIComponent(savedSearchId)}` : ''; + const appState: { + query?: Query; + filters?: Filter[]; + index?: string; + columns?: string[]; + interval?: string; + sort?: string[][]; + savedQuery?: string; + } = {}; + const queryState: QueryState = {}; + + if (query) appState.query = query; + if (filters && filters.length) + appState.filters = filters?.filter((f) => !esFilters.isFilterPinned(f)); + if (indexPatternId) appState.index = indexPatternId; + if (columns) appState.columns = columns; + if (savedQuery) appState.savedQuery = savedQuery; + if (sort) appState.sort = sort; + if (interval) appState.interval = interval; + + if (timeRange) queryState.time = timeRange; + if (filters && filters.length) + queryState.filters = filters?.filter((f) => esFilters.isFilterPinned(f)); + if (refreshInterval) queryState.refreshInterval = refreshInterval; + + let path = `#/${savedSearchPath}`; + path = setStateToKbnUrl('_g', queryState, { useHash }, path); + path = setStateToKbnUrl('_a', appState, { useHash }, path); + + if (searchSessionId) { + path = `${path}&searchSessionId=${searchSessionId}`; + } + + return { + app: 'discover', + path, + state: {}, + }; + }; +} diff --git a/src/plugins/discover/public/mocks.ts b/src/plugins/discover/public/mocks.ts index 0f57c5c0fa1381..53160df472a3c7 100644 --- a/src/plugins/discover/public/mocks.ts +++ b/src/plugins/discover/public/mocks.ts @@ -16,6 +16,12 @@ const createSetupContract = (): Setup => { docViews: { addDocView: jest.fn(), }, + locator: { + getLocation: jest.fn(), + getUrl: jest.fn(), + useUrl: jest.fn(), + navigate: jest.fn(), + }, }; return setupContract; }; @@ -26,6 +32,12 @@ const createStartContract = (): Start => { urlGenerator: ({ createUrl: jest.fn(), } as unknown) as DiscoverStart['urlGenerator'], + locator: { + getLocation: jest.fn(), + getUrl: jest.fn(), + useUrl: jest.fn(), + navigate: jest.fn(), + }, }; return startContract; }; diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 7b4e7bb67c00ec..ec89f7516e92d1 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -59,6 +59,7 @@ import { DiscoverUrlGenerator, SEARCH_SESSION_ID_QUERY_PARAM, } from './url_generator'; +import { DiscoverAppLocatorDefinition, DiscoverAppLocator } from './locator'; import { SearchEmbeddableFactory } from './application/embeddable'; import { UsageCollectionSetup } from '../../usage_collection/public'; import { replaceUrlHashQuery } from '../../kibana_utils/public/'; @@ -83,17 +84,68 @@ export interface DiscoverSetup { */ addDocView(docViewRaw: DocViewInput | DocViewInputFn): void; }; + + /** + * `share` plugin URL locator for Discover app. Use it to generate links into + * Discover application, for example, navigate: + * + * ```ts + * await plugins.discover.locator.navigate({ + * savedSearchId: '571aaf70-4c88-11e8-b3d7-01146121b73d', + * indexPatternId: 'c367b774-a4c2-11ea-bb37-0242ac130002', + * timeRange: { + * to: 'now', + * from: 'now-15m', + * mode: 'relative', + * }, + * }); + * ``` + * + * Generate a location: + * + * ```ts + * const location = await plugins.discover.locator.getLocation({ + * savedSearchId: '571aaf70-4c88-11e8-b3d7-01146121b73d', + * indexPatternId: 'c367b774-a4c2-11ea-bb37-0242ac130002', + * timeRange: { + * to: 'now', + * from: 'now-15m', + * mode: 'relative', + * }, + * }); + * ``` + */ + readonly locator: undefined | DiscoverAppLocator; } export interface DiscoverStart { savedSearchLoader: SavedObjectLoader; /** - * `share` plugin URL generator for Discover app. Use it to generate links into - * Discover application, example: + * @deprecated Use URL locator instead. URL generaotr will be removed. + */ + readonly urlGenerator: undefined | UrlGeneratorContract<'DISCOVER_APP_URL_GENERATOR'>; + + /** + * `share` plugin URL locator for Discover app. Use it to generate links into + * Discover application, for example, navigate: + * + * ```ts + * await plugins.discover.locator.navigate({ + * savedSearchId: '571aaf70-4c88-11e8-b3d7-01146121b73d', + * indexPatternId: 'c367b774-a4c2-11ea-bb37-0242ac130002', + * timeRange: { + * to: 'now', + * from: 'now-15m', + * mode: 'relative', + * }, + * }); + * ``` + * + * Generate a location: * * ```ts - * const url = await plugins.discover.urlGenerator.createUrl({ + * const location = await plugins.discover.locator.getLocation({ * savedSearchId: '571aaf70-4c88-11e8-b3d7-01146121b73d', * indexPatternId: 'c367b774-a4c2-11ea-bb37-0242ac130002', * timeRange: { @@ -104,7 +156,7 @@ export interface DiscoverStart { * }); * ``` */ - readonly urlGenerator: undefined | UrlGeneratorContract<'DISCOVER_APP_URL_GENERATOR'>; + readonly locator: undefined | DiscoverAppLocator; } /** @@ -156,7 +208,12 @@ export class DiscoverPlugin private stopUrlTracking: (() => void) | undefined = undefined; private servicesInitialized: boolean = false; private innerAngularInitialized: boolean = false; + + /** + * @deprecated + */ private urlGenerator?: DiscoverStart['urlGenerator']; + private locator?: DiscoverAppLocator; /** * why are those functions public? they are needed for some mocha tests @@ -179,6 +236,15 @@ export class DiscoverPlugin }) ); } + + if (plugins.share) { + this.locator = plugins.share.url.locators.create( + new DiscoverAppLocatorDefinition({ + useHash: core.uiSettings.get('state:storeInSessionStorage'), + }) + ); + } + this.docViewsRegistry = new DocViewsRegistry(); setDocViewsRegistry(this.docViewsRegistry); this.docViewsRegistry.addDocView({ @@ -323,6 +389,7 @@ export class DiscoverPlugin docViews: { addDocView: this.docViewsRegistry.addDocView.bind(this.docViewsRegistry), }, + locator: this.locator, }; } @@ -367,6 +434,7 @@ export class DiscoverPlugin return { urlGenerator: this.urlGenerator, + locator: this.locator, savedSearchLoader: createSavedSearchesLoader({ savedObjectsClient: core.savedObjects.client, savedObjects: plugins.savedObjects, diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/authorization/components/page_error.tsx b/src/plugins/es_ui_shared/__packages_do_not_import__/authorization/components/page_error.tsx index 0a27b4098681b6..732aa35b052370 100644 --- a/src/plugins/es_ui_shared/__packages_do_not_import__/authorization/components/page_error.tsx +++ b/src/plugins/es_ui_shared/__packages_do_not_import__/authorization/components/page_error.tsx @@ -13,7 +13,7 @@ import { Error } from '../types'; interface Props { title: React.ReactNode; - error: Error; + error?: Error; actions?: JSX.Element; isCentered?: boolean; } @@ -32,30 +32,30 @@ export const PageError: React.FunctionComponent = ({ isCentered, ...rest }) => { - const { - error: errorString, - cause, // wrapEsError() on the server adds a "cause" array - message, - } = error; + const errorString = error?.error; + const cause = error?.cause; // wrapEsError() on the server adds a "cause" array + const message = error?.message; const errorContent = ( {title}} body={ - <> - {cause ? message || errorString :

{message || errorString}

} - {cause && ( - <> - -
    - {cause.map((causeMsg, i) => ( -
  • {causeMsg}
  • - ))} -
- - )} - + error && ( + <> + {cause ? message || errorString :

{message || errorString}

} + {cause && ( + <> + +
    + {cause.map((causeMsg, i) => ( +
  • {causeMsg}
  • + ))} +
+ + )} + + ) } iconType="alert" actions={actions} diff --git a/src/plugins/es_ui_shared/public/components/page_loading/index.ts b/src/plugins/es_ui_shared/public/components/page_loading/index.ts new file mode 100644 index 00000000000000..3e7b93bb4e7c31 --- /dev/null +++ b/src/plugins/es_ui_shared/public/components/page_loading/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { PageLoading } from './page_loading'; diff --git a/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx b/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx new file mode 100644 index 00000000000000..2fb99208e58ac0 --- /dev/null +++ b/src/plugins/es_ui_shared/public/components/page_loading/page_loading.tsx @@ -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 + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { EuiEmptyPrompt, EuiLoadingSpinner, EuiText, EuiPageContent } from '@elastic/eui'; + +export const PageLoading: React.FunctionComponent = ({ children }) => { + return ( + + } + body={{children}} + data-test-subj="sectionLoading" + /> + + ); +}; diff --git a/src/plugins/es_ui_shared/public/index.ts b/src/plugins/es_ui_shared/public/index.ts index 7b9013c043a0e1..ef2e2daa254689 100644 --- a/src/plugins/es_ui_shared/public/index.ts +++ b/src/plugins/es_ui_shared/public/index.ts @@ -17,6 +17,7 @@ import * as XJson from './xjson'; export { JsonEditor, OnJsonEditorUpdateHandler, JsonEditorState } from './components/json_editor'; +export { PageLoading } from './components/page_loading'; export { SectionLoading } from './components/section_loading'; export { Frequency, CronEditor } from './components/cron_editor'; diff --git a/src/plugins/share/public/index.ts b/src/plugins/share/public/index.ts index 8f5356f6a22012..5ee3156534c5ef 100644 --- a/src/plugins/share/public/index.ts +++ b/src/plugins/share/public/index.ts @@ -7,7 +7,8 @@ */ export { CSV_QUOTE_VALUES_SETTING, CSV_SEPARATOR_SETTING } from '../common/constants'; -export { LocatorDefinition } from '../common/url_service'; + +export { LocatorDefinition, LocatorPublic, KibanaLocation } from '../common/url_service'; export { UrlGeneratorStateMapping } from './url_generators/url_generator_definition'; diff --git a/src/plugins/vis_default_editor/public/components/sidebar/controls.tsx b/src/plugins/vis_default_editor/public/components/sidebar/controls.tsx index a24673a4c12455..e757b5fe8f61dd 100644 --- a/src/plugins/vis_default_editor/public/components/sidebar/controls.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/controls.tsx @@ -7,7 +7,14 @@ */ import React, { useCallback, useState } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiButton, EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiButtonEmpty, + EuiToolTip, + EuiIconTip, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import useDebounce from 'react-use/lib/useDebounce'; @@ -84,19 +91,32 @@ function DefaultEditorControls({ ) : ( - - - + + + + + + + + + + )} diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.tsx b/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.tsx index 7d42eb3f40ac57..610b4a91cfd14b 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/field_select.tsx @@ -128,7 +128,7 @@ export function FieldSelect({ selectedOptions = [{ label: value!, id: 'INVALID_FIELD' }]; } } else { - if (value && !selectedOptions.length) { + if (value && fields[fieldsSelector] && !selectedOptions.length) { onChange([]); } } diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/reorder.js b/src/plugins/vis_type_timeseries/public/application/components/lib/reorder.ts similarity index 85% rename from src/plugins/vis_type_timeseries/public/application/components/lib/reorder.js rename to src/plugins/vis_type_timeseries/public/application/components/lib/reorder.ts index 15c21e19af2a5c..a026b5bb2051e6 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/lib/reorder.js +++ b/src/plugins/vis_type_timeseries/public/application/components/lib/reorder.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -export const reorder = (list, startIndex, endIndex) => { +export const reorder = (list: unknown[], startIndex: number, endIndex: number) => { const result = Array.from(list); const [removed] = result.splice(startIndex, 1); result.splice(endIndex, 0, removed); diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.test.ts similarity index 100% rename from src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.test.js rename to src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.test.ts diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.js b/src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.ts similarity index 77% rename from src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.js rename to src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.ts index 458866f2098a0d..2862fe933bfb75 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.js +++ b/src/plugins/vis_type_timeseries/public/application/components/lib/replace_vars.ts @@ -6,20 +6,30 @@ * Side Public License, v 1. */ -import _ from 'lodash'; -import handlebars from 'handlebars/dist/handlebars'; -import { emptyLabel } from '../../../../common/empty_label'; +import handlebars from 'handlebars'; import { i18n } from '@kbn/i18n'; +import { emptyLabel } from '../../../../common/empty_label'; + +type CompileOptions = Parameters[1]; -export function replaceVars(str, args = {}, vars = {}) { +export function replaceVars( + str: string, + args: Record = {}, + vars: Record = {}, + compileOptions: Partial = {} +) { try { - // we need add '[]' for emptyLabel because this value contains special characters. (https://handlebarsjs.com/guide/expressions.html#literal-segments) + /** we need add '[]' for emptyLabel because this value contains special characters. + * @see (https://handlebarsjs.com/guide/expressions.html#literal-segments) **/ const template = handlebars.compile(str.split(emptyLabel).join(`[${emptyLabel}]`), { strict: true, knownHelpersOnly: true, + ...compileOptions, + }); + const string = template({ + ...vars, + args, }); - - const string = template(_.assign({}, vars, { args })); return string; } catch (e) { diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js b/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js index 70529be78567d0..c1d82a182e509b 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js +++ b/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.js @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import handlebars from 'handlebars/dist/handlebars'; import { isNumber } from 'lodash'; +import handlebars from 'handlebars'; import { isEmptyValue, DISPLAY_EMPTY_VALUE } from '../../../../common/last_value_utils'; import { inputFormats, outputFormats, isDuration } from '../lib/durations'; import { getFieldFormats } from '../../../services'; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js index 8e59e8e1bb628a..097b0a7b5e3327 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js @@ -51,7 +51,9 @@ class TimeseriesVisualization extends Component { }; applyDocTo = (template) => (doc) => { - const vars = replaceVars(template, null, doc); + const vars = replaceVars(template, null, doc, { + noEscape: true, + }); if (vars instanceof Error) { this.showToastNotification = vars.error.caused_by; diff --git a/test/functional/apps/discover/_data_grid_doc_navigation.ts b/test/functional/apps/discover/_data_grid_doc_navigation.ts index e3e8a20b693f85..cf5532aa6d7625 100644 --- a/test/functional/apps/discover/_data_grid_doc_navigation.ts +++ b/test/functional/apps/discover/_data_grid_doc_navigation.ts @@ -41,8 +41,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await rowActions[0].click(); }); - const hasDocHit = await testSubjects.exists('doc-hit'); - expect(hasDocHit).to.be(true); + await retry.waitFor('hit loaded', async () => { + const hasDocHit = await testSubjects.exists('doc-hit'); + return !!hasDocHit; + }); }); // no longer relevant as null field won't be returned in the Fields API response diff --git a/test/functional/apps/discover/_discover.ts b/test/functional/apps/discover/_discover.ts index dce6bfba9cd99c..c68db8cbd797bd 100644 --- a/test/functional/apps/discover/_discover.ts +++ b/test/functional/apps/discover/_discover.ts @@ -181,8 +181,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/89550 - describe.skip('query #2, which has an empty time range', () => { + describe('query #2, which has an empty time range', () => { const fromTime = 'Jun 11, 1999 @ 09:22:11.000'; const toTime = 'Jun 12, 1999 @ 11:21:04.000'; @@ -193,8 +192,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should show "no results"', async () => { - const isVisible = await PageObjects.discover.hasNoResults(); - expect(isVisible).to.be(true); + await retry.waitFor('no results screen is displayed', async function () { + const isVisible = await PageObjects.discover.hasNoResults(); + return isVisible === true; + }); }); it('should suggest a new time range is picked', async () => { diff --git a/test/functional/apps/discover/_doc_navigation.ts b/test/functional/apps/discover/_doc_navigation.ts index 771dac4d40a64f..8d156cb305586b 100644 --- a/test/functional/apps/discover/_doc_navigation.ts +++ b/test/functional/apps/discover/_doc_navigation.ts @@ -51,8 +51,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await rowActions[1].click(); }); - const hasDocHit = await testSubjects.exists('doc-hit'); - expect(hasDocHit).to.be(true); + await retry.waitFor('hit loaded', async () => { + const hasDocHit = await testSubjects.exists('doc-hit'); + return !!hasDocHit; + }); }); // no longer relevant as null field won't be returned in the Fields API response diff --git a/test/functional/apps/discover/_huge_fields.ts b/test/functional/apps/discover/_huge_fields.ts index c7fe0a94b6019b..24b10e1df04956 100644 --- a/test/functional/apps/discover/_huge_fields.ts +++ b/test/functional/apps/discover/_huge_fields.ts @@ -15,21 +15,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const testSubjects = getService('testSubjects'); - // FLAKY: https://github.com/elastic/kibana/issues/96113 - describe.skip('test large number of fields in sidebar', function () { + describe('test large number of fields in sidebar', function () { before(async function () { + await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/huge_fields'); await security.testUser.setRoles(['kibana_admin', 'test_testhuge_reader'], false); - await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/large_fields'); - await PageObjects.settings.navigateTo(); await kibanaServer.uiSettings.update({ 'timepicker:timeDefaults': `{ "from": "2016-10-05T00:00:00", "to": "2016-10-06T00:00:00"}`, }); - await PageObjects.settings.createIndexPattern('*huge*', 'date', true); await PageObjects.common.navigateToApp('discover'); }); it('test_huge data should have expected number of fields', async function () { - await PageObjects.discover.selectIndexPattern('*huge*'); + await PageObjects.discover.selectIndexPattern('testhuge*'); // initially this field should not be rendered const fieldExistsBeforeScrolling = await testSubjects.exists('field-myvar1050'); expect(fieldExistsBeforeScrolling).to.be(false); @@ -41,8 +38,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await security.testUser.restoreDefaults(); - await esArchiver.unload('test/functional/fixtures/es_archiver/large_fields'); - await kibanaServer.uiSettings.replace({}); + await esArchiver.unload('test/functional/fixtures/es_archiver/huge_fields'); + await kibanaServer.uiSettings.unset('timepicker:timeDefaults'); }); }); } diff --git a/test/functional/fixtures/es_archiver/huge_fields/data.json.gz b/test/functional/fixtures/es_archiver/huge_fields/data.json.gz new file mode 100644 index 00000000000000..1ce42c64c53a34 Binary files /dev/null and b/test/functional/fixtures/es_archiver/huge_fields/data.json.gz differ diff --git a/test/functional/fixtures/es_archiver/huge_fields/mappings.json b/test/functional/fixtures/es_archiver/huge_fields/mappings.json new file mode 100644 index 00000000000000..49a677a42f2ba6 --- /dev/null +++ b/test/functional/fixtures/es_archiver/huge_fields/mappings.json @@ -0,0 +1,24 @@ +{ + "type": "index", + "value": { + "index": "testhuge", + "mappings": { + "properties": { + "date": { + "type": "date" + } + } + }, + "settings": { + "index": { + "mapping": { + "total_fields": { + "limit": "50000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "5" + } + } + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index c91f7b768a5c4e..f6df8fcbb64064 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -70,7 +70,6 @@ { "path": "./src/plugins/visualize/tsconfig.json" }, { "path": "./src/plugins/index_pattern_management/tsconfig.json" }, { "path": "./src/plugins/index_pattern_field_editor/tsconfig.json" }, - { "path": "./x-pack/plugins/actions/tsconfig.json" }, { "path": "./x-pack/plugins/alerting/tsconfig.json" }, { "path": "./x-pack/plugins/apm/tsconfig.json" }, diff --git a/tsconfig.refs.json b/tsconfig.refs.json index 3baf5c323ef81e..e08b50cc055c1c 100644 --- a/tsconfig.refs.json +++ b/tsconfig.refs.json @@ -105,6 +105,7 @@ { "path": "./x-pack/plugins/stack_alerts/tsconfig.json" }, { "path": "./x-pack/plugins/task_manager/tsconfig.json" }, { "path": "./x-pack/plugins/telemetry_collection_xpack/tsconfig.json" }, + { "path": "./x-pack/plugins/timelines/tsconfig.json" }, { "path": "./x-pack/plugins/transform/tsconfig.json" }, { "path": "./x-pack/plugins/translations/tsconfig.json" }, { "path": "./x-pack/plugins/triggers_actions_ui/tsconfig.json" }, diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.stories.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.stories.tsx new file mode 100644 index 00000000000000..8cc16dd801c25d --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.stories.tsx @@ -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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { ComponentType } from 'react'; +import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public'; +import { + ApmPluginContext, + ApmPluginContextValue, +} from '../../../../context/apm_plugin/apm_plugin_context'; +import { EuiThemeProvider } from '../../../../../../../../src/plugins/kibana_react/common'; +import { ErrorDistribution } from './'; + +export default { + title: 'app/ErrorGroupDetails/Distribution', + component: ErrorDistribution, + decorators: [ + (Story: ComponentType) => { + const apmPluginContextMock = ({ + observabilityRuleTypeRegistry: { getFormatter: () => undefined }, + } as unknown) as ApmPluginContextValue; + + const kibanaContextServices = { + uiSettings: { get: () => {} }, + }; + + return ( + + + + + + + + ); + }, + ], +}; + +export function Example() { + const distribution = { + noHits: false, + bucketSize: 62350, + buckets: [ + { key: 1624279912350, count: 6 }, + { key: 1624279974700, count: 1 }, + { key: 1624280037050, count: 2 }, + { key: 1624280099400, count: 3 }, + { key: 1624280161750, count: 13 }, + { key: 1624280224100, count: 1 }, + { key: 1624280286450, count: 2 }, + { key: 1624280348800, count: 0 }, + { key: 1624280411150, count: 4 }, + { key: 1624280473500, count: 4 }, + { key: 1624280535850, count: 1 }, + { key: 1624280598200, count: 4 }, + { key: 1624280660550, count: 0 }, + { key: 1624280722900, count: 2 }, + { key: 1624280785250, count: 3 }, + { key: 1624280847600, count: 0 }, + ], + }; + + return ; +} + +export function EmptyState() { + return ( + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx index 643653c24aeb3a..e53aaf97cdf757 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx @@ -67,6 +67,7 @@ export function ErrorDistribution({ distribution, title }: Props) { const xFormatter = niceTimeFormatter([xMin, xMax]); const { observabilityRuleTypeRegistry } = useApmPluginContext(); + const { alerts } = useApmServiceContext(); const { getFormatter } = observabilityRuleTypeRegistry; const [selectedAlertId, setSelectedAlertId] = useState( @@ -84,7 +85,7 @@ export function ErrorDistribution({ distribution, title }: Props) { }; return ( -
+ <> {title} @@ -124,7 +125,7 @@ export function ErrorDistribution({ distribution, title }: Props) { alerts: alerts?.filter( (alert) => alert[RULE_ID]?.[0] === AlertType.ErrorCount ), - chartStartTime: buckets[0].x0, + chartStartTime: buckets[0]?.x0, getFormatter, selectedAlertId, setSelectedAlertId, @@ -143,6 +144,6 @@ export function ErrorDistribution({ distribution, title }: Props) {
- + ); } diff --git a/x-pack/plugins/cases/public/components/panel/index.tsx b/x-pack/plugins/cases/public/components/panel/index.tsx index 652d22409cb0c3..802fd4c7f44a60 100644 --- a/x-pack/plugins/cases/public/components/panel/index.tsx +++ b/x-pack/plugins/cases/public/components/panel/index.tsx @@ -25,7 +25,7 @@ import { EuiPanel } from '@elastic/eui'; * Ref: https://www.styled-components.com/docs/faqs#why-am-i-getting-html-attribute-warnings * Ref: https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html */ -export const Panel = styled(({ loading, ...props }) => )` +export const Panel = styled(({ loading, ...props }) => )` position: relative; ${({ loading }) => loading && diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.test.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.test.tsx index 86f5564a17d528..59da0f0f4d17e5 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.test.tsx +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.test.tsx @@ -27,6 +27,7 @@ describe('Background Search Session management status labels', () => { id: 'wtywp9u2802hahgp-gsla', restoreUrl: '/app/great-app-url/#45', reloadUrl: '/app/great-app-url/#45', + numSearches: 1, appId: 'security', status: SearchSessionStatus.IN_PROGRESS, created: '2020-12-02T00:19:32Z', diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/table.test.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/table.test.tsx index 42ff270ed44a06..6dfe3a5153670b 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/table.test.tsx +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/table/table.test.tsx @@ -70,6 +70,7 @@ describe('Background Search Session Management Table', () => { status: SearchSessionStatus.IN_PROGRESS, created: '2020-12-02T00:19:32Z', expires: '2020-12-07T00:19:32Z', + idMapping: {}, }, }, ], @@ -95,10 +96,12 @@ describe('Background Search Session Management Table', () => { ); }); - expect(table.find('thead th').map((node) => node.text())).toMatchInlineSnapshot(` + expect(table.find('thead th .euiTableCellContent__text').map((node) => node.text())) + .toMatchInlineSnapshot(` Array [ "App", "Name", + "# Searches", "Status", "Created", "Expiration", @@ -130,6 +133,7 @@ describe('Background Search Session Management Table', () => { Array [ "App", "Namevery background search ", + "# Searches0", "StatusExpired", "Created2 Dec, 2020, 00:19:32", "Expiration--", diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts index 3857b08ad0a3ae..cc79f8002a98c4 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts @@ -52,6 +52,7 @@ describe('Search Sessions Management API', () => { status: 'complete', initialState: {}, restoreState: {}, + idMapping: [], }, }, ], @@ -78,6 +79,7 @@ describe('Search Sessions Management API', () => { "id": "hello-pizza-123", "initialState": Object {}, "name": "Veggie", + "numSearches": 0, "reloadUrl": "hello-cool-undefined-url", "restoreState": Object {}, "restoreUrl": "hello-cool-undefined-url", @@ -100,6 +102,7 @@ describe('Search Sessions Management API', () => { expires: moment().subtract(3, 'days'), initialState: {}, restoreState: {}, + idMapping: {}, }, }, ], diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts index 3710dfa16e76b8..0369dc4a839b51 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts @@ -90,6 +90,7 @@ const mapToUISession = (urls: UrlGeneratorsStart, config: SessionsConfigSchema) urlGeneratorId, initialState, restoreState, + idMapping, } = savedObject.attributes; const status = getUIStatus(savedObject.attributes); @@ -113,6 +114,7 @@ const mapToUISession = (urls: UrlGeneratorsStart, config: SessionsConfigSchema) reloadUrl, initialState, restoreState, + numSearches: Object.keys(idMapping).length, }; }; diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.test.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.test.tsx index 4b68e0c9e2afd0..fc4e67360ea4aa 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.test.tsx +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.test.tsx @@ -70,6 +70,7 @@ describe('Search Sessions Management table column factory', () => { reloadUrl: '/app/great-app-url', restoreUrl: '/app/great-app-url/#42', appId: 'discovery', + numSearches: 3, status: SearchSessionStatus.IN_PROGRESS, created: '2020-12-02T00:19:32Z', expires: '2020-12-07T00:19:32Z', @@ -95,6 +96,12 @@ describe('Search Sessions Management table column factory', () => { "sortable": true, "width": "20%", }, + Object { + "field": "numSearches", + "name": "# Searches", + "render": [Function], + "sortable": true, + }, Object { "field": "status", "name": "Status", @@ -146,10 +153,29 @@ describe('Search Sessions Management table column factory', () => { }); }); + // Num of searches column + describe('num of searches', () => { + test('renders', () => { + const [, , numOfSearches] = getColumns( + mockCoreStart, + mockPluginsSetup, + api, + mockConfig, + tz, + handleAction + ) as Array>; + + const numOfSearchesLine = mount( + numOfSearches.render!(mockSession.numSearches, mockSession) as ReactElement + ); + expect(numOfSearchesLine.text()).toMatchInlineSnapshot(`"3"`); + }); + }); + // Status column describe('status', () => { test('render in_progress', () => { - const [, , status] = getColumns( + const [, , , status] = getColumns( mockCoreStart, mockPluginsSetup, api, @@ -165,7 +191,7 @@ describe('Search Sessions Management table column factory', () => { }); test('error handling', () => { - const [, , status] = getColumns( + const [, , , status] = getColumns( mockCoreStart, mockPluginsSetup, api, @@ -188,7 +214,7 @@ describe('Search Sessions Management table column factory', () => { test('render using Browser timezone', () => { tz = 'Browser'; - const [, , , createdDateCol] = getColumns( + const [, , , , createdDateCol] = getColumns( mockCoreStart, mockPluginsSetup, api, @@ -205,7 +231,7 @@ describe('Search Sessions Management table column factory', () => { test('render using AK timezone', () => { tz = 'US/Alaska'; - const [, , , createdDateCol] = getColumns( + const [, , , , createdDateCol] = getColumns( mockCoreStart, mockPluginsSetup, api, @@ -220,7 +246,7 @@ describe('Search Sessions Management table column factory', () => { }); test('error handling', () => { - const [, , , createdDateCol] = getColumns( + const [, , , , createdDateCol] = getColumns( mockCoreStart, mockPluginsSetup, api, diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.tsx index 1805ef52b85f1d..d8d2fa0aeac59c 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.tsx +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.tsx @@ -120,6 +120,20 @@ export const getColumns = ( }, }, + // # Searches + { + field: 'numSearches', + name: i18n.translate('xpack.data.mgmt.searchSessions.table.numSearches', { + defaultMessage: '# Searches', + }), + sortable: true, + render: (numSearches: UISession['numSearches'], session) => ( + + {numSearches} + + ), + }, + // Session status { field: 'status', diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts index d0d5ee9fb17dd3..6a8ace8dbdc79a 100644 --- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts +++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts @@ -34,6 +34,7 @@ export interface UISession { created: string; expires: string | null; status: UISearchSessionState; + numSearches: number; actions?: ACTION[]; reloadUrl: string; restoreUrl: string; diff --git a/x-pack/plugins/data_enhanced/server/search/session/session_service.ts b/x-pack/plugins/data_enhanced/server/search/session/session_service.ts index 138f42549a0944..81a12f607935d2 100644 --- a/x-pack/plugins/data_enhanced/server/search/session/session_service.ts +++ b/x-pack/plugins/data_enhanced/server/search/session/session_service.ts @@ -24,7 +24,11 @@ import { ENHANCED_ES_SEARCH_STRATEGY, SEARCH_SESSION_TYPE, } from '../../../../../../src/plugins/data/common'; -import { esKuery, ISearchSessionService } from '../../../../../../src/plugins/data/server'; +import { + esKuery, + ISearchSessionService, + NoSearchIdInSessionError, +} from '../../../../../../src/plugins/data/server'; import { AuthenticatedUser, SecurityPluginSetup } from '../../../../security/server'; import { TaskManagerSetupContract, @@ -436,7 +440,7 @@ export class SearchSessionService const requestHash = createRequestHash(searchRequest.params); if (!session.attributes.idMapping.hasOwnProperty(requestHash)) { this.logger.error(`getId | ${sessionId} | ${requestHash} not found`); - throw new Error('No search ID in this session matching the given search request'); + throw new NoSearchIdInSessionError(); } this.logger.debug(`getId | ${sessionId} | ${requestHash}`); diff --git a/x-pack/plugins/discover_enhanced/kibana.json b/x-pack/plugins/discover_enhanced/kibana.json index 01a3624d3e3201..da95a0f21a0204 100644 --- a/x-pack/plugins/discover_enhanced/kibana.json +++ b/x-pack/plugins/discover_enhanced/kibana.json @@ -7,5 +7,5 @@ "requiredPlugins": ["uiActions", "embeddable", "discover"], "optionalPlugins": ["share", "kibanaLegacy", "usageCollection"], "configPath": ["xpack", "discoverEnhanced"], - "requiredBundles": ["kibanaUtils", "data", "share"] + "requiredBundles": ["kibanaUtils", "data"] } diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts index 023db127ca6336..44ea53fe0b8706 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts @@ -11,13 +11,13 @@ import { ViewMode, IEmbeddable } from '../../../../../../src/plugins/embeddable/ import { StartServicesGetter } from '../../../../../../src/plugins/kibana_utils/public'; import { KibanaLegacyStart } from '../../../../../../src/plugins/kibana_legacy/public'; import { CoreStart } from '../../../../../../src/core/public'; -import { KibanaURL } from '../../../../../../src/plugins/share/public'; +import { KibanaLocation } from '../../../../../../src/plugins/share/public'; import * as shared from './shared'; export const ACTION_EXPLORE_DATA = 'ACTION_EXPLORE_DATA'; export interface PluginDeps { - discover: Pick; + discover: Pick; kibanaLegacy?: { dashboardConfig: { getHideWriteControls: KibanaLegacyStart['dashboardConfig']['getHideWriteControls']; @@ -26,7 +26,7 @@ export interface PluginDeps { } export interface CoreDeps { - application: Pick; + application: Pick; } export interface Params { @@ -43,7 +43,7 @@ export abstract class AbstractExploreDataAction; + protected abstract getLocation(context: Context): Promise; public async isCompatible({ embeddable }: Context): Promise { if (!embeddable) return false; @@ -52,7 +52,7 @@ export abstract class AbstractExploreDataAction { - type UrlGenerator = UrlGeneratorContract<'DISCOVER_APP_URL_GENERATOR'>; - const core = coreMock.createStart(); - - const urlGenerator: UrlGenerator = ({ - createUrl: jest.fn(() => Promise.resolve('/xyz/app/discover/foo#bar')), - } as unknown) as UrlGenerator; + const locator: DiscoverAppLocator = { + getLocation: jest.fn(() => + Promise.resolve({ + app: 'discover', + path: '/foo#bar', + state: {}, + }) + ), + navigate: jest.fn(async () => {}), + getUrl: jest.fn(), + useUrl: jest.fn(), + }; const plugins: PluginDeps = { discover: { - urlGenerator, + locator, }, kibanaLegacy: { dashboardConfig: { @@ -95,7 +101,7 @@ const setup = ( embeddable, } as ExploreDataChartActionContext; - return { core, plugins, urlGenerator, params, action, input, output, embeddable, context }; + return { core, plugins, locator, params, action, input, output, embeddable, context }; }; describe('"Explore underlying data" panel action', () => { @@ -132,7 +138,7 @@ describe('"Explore underlying data" panel action', () => { test('returns false when URL generator is not present', async () => { const { action, plugins, context } = setup(); - (plugins.discover as any).urlGenerator = undefined; + (plugins.discover as any).locator = undefined; const isCompatible = await action.isCompatible(context); @@ -205,23 +211,15 @@ describe('"Explore underlying data" panel action', () => { }); describe('getHref()', () => { - test('returns URL path generated by URL generator', async () => { - const { action, context } = setup(); - - const href = await action.getHref(context); - - expect(href).toBe('/xyz/app/discover/foo#bar'); - }); - test('calls URL generator with right arguments', async () => { - const { action, urlGenerator, context } = setup(); + const { action, locator, context } = setup(); - expect(urlGenerator.createUrl).toHaveBeenCalledTimes(0); + expect(locator.getLocation).toHaveBeenCalledTimes(0); await action.getHref(context); - expect(urlGenerator.createUrl).toHaveBeenCalledTimes(1); - expect(urlGenerator.createUrl).toHaveBeenCalledWith({ + expect(locator.getLocation).toHaveBeenCalledTimes(1); + expect(locator.getLocation).toHaveBeenCalledWith({ filters: [], indexPatternId: 'index-ptr-foo', timeRange: undefined, @@ -260,11 +258,11 @@ describe('"Explore underlying data" panel action', () => { }, ]; - const { action, context, urlGenerator } = setup({ filters, timeFieldName }); + const { action, context, locator } = setup({ filters, timeFieldName }); await action.getHref(context); - expect(urlGenerator.createUrl).toHaveBeenCalledWith({ + expect(locator.getLocation).toHaveBeenCalledWith({ filters: [ { meta: { diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts index 32264ee1deceb8..7b59a4e51d0428 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts @@ -7,7 +7,7 @@ import { Action } from '../../../../../../src/plugins/ui_actions/public'; import { - DiscoverUrlGeneratorState, + DiscoverAppLocatorParams, SearchInput, } from '../../../../../../src/plugins/discover/public'; import { @@ -15,7 +15,7 @@ import { esFilters, } from '../../../../../../src/plugins/data/public'; import { IEmbeddable } from '../../../../../../src/plugins/embeddable/public'; -import { KibanaURL } from '../../../../../../src/plugins/share/public'; +import { KibanaLocation } from '../../../../../../src/plugins/share/public'; import * as shared from './shared'; import { AbstractExploreDataAction } from './abstract_explore_data_action'; @@ -43,14 +43,14 @@ export class ExploreDataChartAction return super.isCompatible(context); } - protected readonly getUrl = async ( + protected readonly getLocation = async ( context: ExploreDataChartActionContext - ): Promise => { + ): Promise => { const { plugins } = this.params.start(); - const { urlGenerator } = plugins.discover; + const { locator } = plugins.discover; - if (!urlGenerator) { - throw new Error('Discover URL generator not available.'); + if (!locator) { + throw new Error('Discover URL locator not available.'); } const { embeddable } = context; @@ -59,23 +59,23 @@ export class ExploreDataChartAction context.timeFieldName ); - const state: DiscoverUrlGeneratorState = { + const params: DiscoverAppLocatorParams = { filters, timeRange, }; if (embeddable) { - state.indexPatternId = shared.getIndexPatterns(embeddable)[0] || undefined; + params.indexPatternId = shared.getIndexPatterns(embeddable)[0] || undefined; const input = embeddable.getInput() as Readonly; - if (input.timeRange && !state.timeRange) state.timeRange = input.timeRange; - if (input.query) state.query = input.query; - if (input.filters) state.filters = [...input.filters, ...(state.filters || [])]; + if (input.timeRange && !params.timeRange) params.timeRange = input.timeRange; + if (input.query) params.query = input.query; + if (input.filters) params.filters = [...input.filters, ...(params.filters || [])]; } - const path = await urlGenerator.createUrl(state); + const location = await locator.getLocation(params); - return new KibanaURL(path); + return location; }; } diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts index 842c7d6b339b4b..5bdac602ec271d 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts @@ -8,13 +8,13 @@ import { ExploreDataContextMenuAction } from './explore_data_context_menu_action'; import { Params, PluginDeps } from './abstract_explore_data_action'; import { coreMock } from '../../../../../../src/core/public/mocks'; -import { UrlGeneratorContract } from '../../../../../../src/plugins/share/public'; import { i18n } from '@kbn/i18n'; import { VisualizeEmbeddableContract, VISUALIZE_EMBEDDABLE_TYPE, } from '../../../../../../src/plugins/visualizations/public'; import { ViewMode } from '../../../../../../src/plugins/embeddable/public'; +import { DiscoverAppLocator } from '../../../../../../src/plugins/discover/public'; const i18nTranslateSpy = (i18n.translate as unknown) as jest.SpyInstance; @@ -29,17 +29,23 @@ afterEach(() => { }); const setup = ({ dashboardOnlyMode = false }: { dashboardOnlyMode?: boolean } = {}) => { - type UrlGenerator = UrlGeneratorContract<'DISCOVER_APP_URL_GENERATOR'>; - const core = coreMock.createStart(); - - const urlGenerator: UrlGenerator = ({ - createUrl: jest.fn(() => Promise.resolve('/xyz/app/discover/foo#bar')), - } as unknown) as UrlGenerator; + const locator: DiscoverAppLocator = { + getLocation: jest.fn(() => + Promise.resolve({ + app: 'discover', + path: '/foo#bar', + state: {}, + }) + ), + navigate: jest.fn(async () => {}), + getUrl: jest.fn(), + useUrl: jest.fn(), + }; const plugins: PluginDeps = { discover: { - urlGenerator, + locator, }, kibanaLegacy: { dashboardConfig: { @@ -79,7 +85,7 @@ const setup = ({ dashboardOnlyMode = false }: { dashboardOnlyMode?: boolean } = embeddable, }; - return { core, plugins, urlGenerator, params, action, input, output, embeddable, context }; + return { core, plugins, locator, params, action, input, output, embeddable, context }; }; describe('"Explore underlying data" panel action', () => { @@ -116,7 +122,7 @@ describe('"Explore underlying data" panel action', () => { test('returns false when URL generator is not present', async () => { const { action, plugins, context } = setup(); - (plugins.discover as any).urlGenerator = undefined; + (plugins.discover as any).locator = undefined; const isCompatible = await action.isCompatible(context); @@ -189,23 +195,15 @@ describe('"Explore underlying data" panel action', () => { }); describe('getHref()', () => { - test('returns URL path generated by URL generator', async () => { - const { action, context } = setup(); - - const href = await action.getHref(context); - - expect(href).toBe('/xyz/app/discover/foo#bar'); - }); - test('calls URL generator with right arguments', async () => { - const { action, urlGenerator, context } = setup(); + const { action, locator, context } = setup(); - expect(urlGenerator.createUrl).toHaveBeenCalledTimes(0); + expect(locator.getLocation).toHaveBeenCalledTimes(0); await action.getHref(context); - expect(urlGenerator.createUrl).toHaveBeenCalledTimes(1); - expect(urlGenerator.createUrl).toHaveBeenCalledWith({ + expect(locator.getLocation).toHaveBeenCalledTimes(1); + expect(locator.getLocation).toHaveBeenCalledWith({ indexPatternId: 'index-ptr-foo', }); }); diff --git a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts index 99a2afd239645f..88c093a299cb98 100644 --- a/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts +++ b/x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts @@ -12,8 +12,8 @@ import { IEmbeddable, } from '../../../../../../src/plugins/embeddable/public'; import { Query, Filter, TimeRange } from '../../../../../../src/plugins/data/public'; -import { DiscoverUrlGeneratorState } from '../../../../../../src/plugins/discover/public'; -import { KibanaURL } from '../../../../../../src/plugins/share/public'; +import { DiscoverAppLocatorParams } from '../../../../../../src/plugins/discover/public'; +import { KibanaLocation } from '../../../../../../src/plugins/share/public'; import * as shared from './shared'; import { AbstractExploreDataAction } from './abstract_explore_data_action'; @@ -40,29 +40,31 @@ export class ExploreDataContextMenuAction public readonly order = 200; - protected readonly getUrl = async (context: EmbeddableQueryContext): Promise => { + protected readonly getLocation = async ( + context: EmbeddableQueryContext + ): Promise => { const { plugins } = this.params.start(); - const { urlGenerator } = plugins.discover; + const { locator } = plugins.discover; - if (!urlGenerator) { - throw new Error('Discover URL generator not available.'); + if (!locator) { + throw new Error('Discover URL locator not available.'); } const { embeddable } = context; - const state: DiscoverUrlGeneratorState = {}; + const params: DiscoverAppLocatorParams = {}; if (embeddable) { - state.indexPatternId = shared.getIndexPatterns(embeddable)[0] || undefined; + params.indexPatternId = shared.getIndexPatterns(embeddable)[0] || undefined; const input = embeddable.getInput(); - if (input.timeRange && !state.timeRange) state.timeRange = input.timeRange; - if (input.query) state.query = input.query; - if (input.filters) state.filters = [...input.filters, ...(state.filters || [])]; + if (input.timeRange && !params.timeRange) params.timeRange = input.timeRange; + if (input.query) params.query = input.query; + if (input.filters) params.filters = [...input.filters, ...(params.filters || [])]; } - const path = await urlGenerator.createUrl(state); + const location = await locator.getLocation(params); - return new KibanaURL(path); + return location; }; } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx index 1b5a8084f5b594..d5bb525cfd3328 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/api_logs_table.tsx @@ -26,6 +26,8 @@ import { ApiLogsLogic } from '../index'; import { ApiLog } from '../types'; import { getStatusColor } from '../utils'; +import { EmptyState } from './'; + import './api_logs_table.scss'; interface Props { @@ -108,6 +110,7 @@ export const ApiLogsTable: React.FC = ({ hasPagination }) => { items={apiLogs} responsive loading={dataLoading} + noItemsMessage={} {...paginationProps} /> ); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.test.tsx index 3ad22ceac5840d..19f45ced5dc5dc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.test.tsx @@ -19,7 +19,7 @@ describe('EmptyState', () => { .find(EuiEmptyPrompt) .dive(); - expect(wrapper.find('h2').text()).toEqual('Perform your first API call'); + expect(wrapper.find('h2').text()).toEqual('No API events in the last 24 hours'); expect(wrapper.find(EuiButton).prop('href')).toEqual( expect.stringContaining('/api-reference.html') ); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx index 3f6f44adefc71d..76bd0cba1731f8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/api_logs/components/empty_state.tsx @@ -18,14 +18,14 @@ export const EmptyState: React.FC = () => ( title={

{i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.emptyTitle', { - defaultMessage: 'Perform your first API call', + defaultMessage: 'No API events in the last 24 hours', })}

} body={

{i18n.translate('xpack.enterpriseSearch.appSearch.engine.apiLogs.emptyDescription', { - defaultMessage: "Check back after you've performed some API calls.", + defaultMessage: 'Logs will update in real-time when an API request occurs.', })}

} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_landing.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_landing.tsx index a2993b4d86d5a1..91a0a7c5edcc0f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_landing.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_landing.tsx @@ -7,29 +7,25 @@ import React from 'react'; -import { - EuiButton, - EuiLink, - EuiPageHeader, - EuiPanel, - EuiSpacer, - EuiText, - EuiTitle, -} from '@elastic/eui'; +import { EuiButton, EuiLink, EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { getAppSearchUrl } from '../../../shared/enterprise_search_url'; import { DOCS_PREFIX, ENGINE_CRAWLER_PATH } from '../../routes'; -import { generateEnginePath } from '../engine'; +import { generateEnginePath, getEngineBreadcrumbs } from '../engine'; +import { AppSearchPageTemplate } from '../layout'; import './crawler_landing.scss'; import { CRAWLER_TITLE } from '.'; export const CrawlerLanding: React.FC = () => ( -
- - - + +

@@ -81,5 +77,5 @@ export const CrawlerLanding: React.FC = () => (

-
+ ); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx index affc2fd08e34c8..3804ecfe7c67db 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx @@ -7,14 +7,12 @@ import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; import '../../../__mocks__/shallow_useeffect.mock'; +import '../../__mocks__/engine_logic.mock'; import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; -import { Loading } from '../../../shared/loading'; -import { rerender } from '../../../test_helpers'; - import { DomainsTable } from './components/domains_table'; import { CrawlerOverview } from './crawler_overview'; @@ -50,11 +48,4 @@ describe('CrawlerOverview', () => { // TODO test for empty state after it is built in a future PR }); - - it('shows a loading state when data is loading', () => { - setMockValues({ dataLoading: true }); - rerender(wrapper); - - expect(wrapper.find(Loading)).toHaveLength(1); - }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx index 14906378692ed9..9e484df35e7a20 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx @@ -9,10 +9,8 @@ import React, { useEffect } from 'react'; import { useActions, useValues } from 'kea'; -import { EuiPageHeader } from '@elastic/eui'; - -import { FlashMessages } from '../../../shared/flash_messages'; -import { Loading } from '../../../shared/loading'; +import { getEngineBreadcrumbs } from '../engine'; +import { AppSearchPageTemplate } from '../layout'; import { DomainsTable } from './components/domains_table'; import { CRAWLER_TITLE } from './constants'; @@ -27,15 +25,13 @@ export const CrawlerOverview: React.FC = () => { fetchCrawlerData(); }, []); - if (dataLoading) { - return ; - } - return ( - <> - - + - + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.test.tsx index c11c6563330104..587ba61ce27e91 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.test.tsx @@ -5,9 +5,6 @@ * 2.0. */ -import { setMockValues } from '../../../__mocks__/kea_logic'; -import { mockEngineValues } from '../../__mocks__'; - import React from 'react'; import { Switch } from 'react-router-dom'; @@ -22,7 +19,6 @@ describe('CrawlerRouter', () => { beforeEach(() => { jest.clearAllMocks(); - setMockValues({ ...mockEngineValues }); }); afterEach(() => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.tsx index 926c45b4379377..a0145cf76908a0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_router.tsx @@ -8,11 +8,6 @@ import React from 'react'; import { Route, Switch } from 'react-router-dom'; -import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; - -import { getEngineBreadcrumbs } from '../engine'; - -import { CRAWLER_TITLE } from './constants'; import { CrawlerLanding } from './crawler_landing'; import { CrawlerOverview } from './crawler_overview'; @@ -20,7 +15,6 @@ export const CrawlerRouter: React.FC = () => { return ( - {process.env.NODE_ENV === 'development' ? : } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/constants.ts index 37c1e9a7a1a2e6..c490910184a693 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/constants.ts @@ -18,7 +18,7 @@ export const CURATIONS_OVERVIEW_TITLE = i18n.translate( ); export const CREATE_NEW_CURATION_TITLE = i18n.translate( 'xpack.enterpriseSearch.appSearch.engine.curations.create.title', - { defaultMessage: 'Create new curation' } + { defaultMessage: 'Create a curation' } ); export const MANAGE_CURATION_TITLE = i18n.translate( 'xpack.enterpriseSearch.appSearch.engine.curations.manage.title', diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.test.tsx index 937acfd84ce83d..2efe1f2ffe86fc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.test.tsx @@ -8,16 +8,13 @@ import '../../../../__mocks__/shallow_useeffect.mock'; import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; import { mockUseParams } from '../../../../__mocks__/react_router'; +import '../../../__mocks__/engine_logic.mock'; import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; -import { EuiPageHeader } from '@elastic/eui'; - -import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome'; -import { Loading } from '../../../../shared/loading'; -import { rerender } from '../../../../test_helpers'; +import { rerender, getPageTitle, getPageHeaderActions } from '../../../../test_helpers'; jest.mock('./curation_logic', () => ({ CurationLogic: jest.fn() })); import { CurationLogic } from './curation_logic'; @@ -27,9 +24,6 @@ import { AddResultFlyout } from './results'; import { Curation } from './'; describe('Curation', () => { - const props = { - curationsBreadcrumb: ['Engines', 'some-engine', 'Curations'], - }; const values = { dataLoading: false, queries: ['query A', 'query B'], @@ -47,39 +41,34 @@ describe('Curation', () => { }); it('renders', () => { - const wrapper = shallow(); + const wrapper = shallow(); - expect(wrapper.find(EuiPageHeader).prop('pageTitle')).toEqual('Manage curation'); - expect(wrapper.find(SetPageChrome).prop('trail')).toEqual([ - ...props.curationsBreadcrumb, + expect(getPageTitle(wrapper)).toEqual('Manage curation'); + expect(wrapper.prop('pageChrome')).toEqual([ + 'Engines', + 'some-engine', + 'Curations', 'query A, query B', ]); }); - it('renders a loading component on page load', () => { - setMockValues({ ...values, dataLoading: true }); - const wrapper = shallow(); - - expect(wrapper.find(Loading)).toHaveLength(1); - }); - it('renders the add result flyout when open', () => { setMockValues({ ...values, isFlyoutOpen: true }); - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.find(AddResultFlyout)).toHaveLength(1); }); it('initializes CurationLogic with a curationId prop from URL param', () => { mockUseParams.mockReturnValueOnce({ curationId: 'hello-world' }); - shallow(); + shallow(); expect(CurationLogic).toHaveBeenCalledWith({ curationId: 'hello-world' }); }); it('calls loadCuration on page load & whenever the curationId URL param changes', () => { mockUseParams.mockReturnValueOnce({ curationId: 'cur-123456789' }); - const wrapper = shallow(); + const wrapper = shallow(); expect(actions.loadCuration).toHaveBeenCalledTimes(1); mockUseParams.mockReturnValueOnce({ curationId: 'cur-987654321' }); @@ -92,9 +81,8 @@ describe('Curation', () => { let confirmSpy: jest.SpyInstance; beforeAll(() => { - const wrapper = shallow(); - const headerActions = wrapper.find(EuiPageHeader).prop('rightSideItems'); - restoreDefaultsButton = shallow(headerActions![0] as React.ReactElement); + const wrapper = shallow(); + restoreDefaultsButton = getPageHeaderActions(wrapper).childAt(0); confirmSpy = jest.spyOn(window, 'confirm'); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.tsx index ffa9fd8422a1bc..2a01c0db049ab1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/curation.tsx @@ -10,26 +10,19 @@ import { useParams } from 'react-router-dom'; import { useValues, useActions } from 'kea'; -import { EuiPageHeader, EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui'; - -import { FlashMessages } from '../../../../shared/flash_messages'; -import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome'; -import { BreadcrumbTrail } from '../../../../shared/kibana_chrome/generate_breadcrumbs'; -import { Loading } from '../../../../shared/loading'; +import { EuiSpacer, EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui'; import { RESTORE_DEFAULTS_BUTTON_LABEL } from '../../../constants'; +import { AppSearchPageTemplate } from '../../layout'; import { MANAGE_CURATION_TITLE, RESTORE_CONFIRMATION } from '../constants'; +import { getCurationsBreadcrumbs } from '../utils'; import { CurationLogic } from './curation_logic'; import { PromotedDocuments, OrganicDocuments, HiddenDocuments } from './documents'; import { ActiveQuerySelect, ManageQueriesModal } from './queries'; import { AddResultLogic, AddResultFlyout } from './results'; -interface Props { - curationsBreadcrumb: BreadcrumbTrail; -} - -export const Curation: React.FC = ({ curationsBreadcrumb }) => { +export const Curation: React.FC = () => { const { curationId } = useParams() as { curationId: string }; const { loadCuration, resetCuration } = useActions(CurationLogic({ curationId })); const { dataLoading, queries } = useValues(CurationLogic({ curationId })); @@ -39,14 +32,12 @@ export const Curation: React.FC = ({ curationsBreadcrumb }) => { loadCuration(); }, [curationId]); - if (dataLoading) return ; - return ( - <> - - { @@ -55,10 +46,10 @@ export const Curation: React.FC = ({ curationsBreadcrumb }) => { > {RESTORE_DEFAULTS_BUTTON_LABEL} , - ]} - responsive={false} - /> - + ], + }} + isLoading={dataLoading} + > @@ -69,7 +60,6 @@ export const Curation: React.FC = ({ curationsBreadcrumb }) => { - @@ -78,6 +68,6 @@ export const Curation: React.FC = ({ curationsBreadcrumb }) => { {isFlyoutOpen && } - + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/hidden_documents.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/hidden_documents.tsx index f2bc416b00341d..8cb06f32d9e4ef 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/hidden_documents.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/documents/hidden_documents.tsx @@ -80,7 +80,7 @@ export const HiddenDocuments: React.FC = () => {

{i18n.translate( 'xpack.enterpriseSearch.appSearch.engine.curations.hiddenDocuments.emptyTitle', - { defaultMessage: 'No documents are being hidden for this query' } + { defaultMessage: "You haven't hidden any documents yet" } )}

} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx index 9598212d3e0c98..a241edb8020a4c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx @@ -19,6 +19,6 @@ describe('CurationsRouter', () => { const wrapper = shallow(); expect(wrapper.find(Switch)).toHaveLength(1); - expect(wrapper.find(Route)).toHaveLength(4); + expect(wrapper.find(Route)).toHaveLength(3); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx index 28ce311b438875..40f2d07ab61ab6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx @@ -8,38 +8,26 @@ import React from 'react'; import { Route, Switch } from 'react-router-dom'; -import { APP_SEARCH_PLUGIN } from '../../../../../common/constants'; -import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; -import { NotFound } from '../../../shared/not_found'; import { ENGINE_CURATIONS_PATH, ENGINE_CURATIONS_NEW_PATH, ENGINE_CURATION_PATH, } from '../../routes'; -import { getEngineBreadcrumbs } from '../engine'; -import { CURATIONS_TITLE, CREATE_NEW_CURATION_TITLE } from './constants'; import { Curation } from './curation'; import { Curations, CurationCreation } from './views'; export const CurationsRouter: React.FC = () => { - const CURATIONS_BREADCRUMB = getEngineBreadcrumbs([CURATIONS_TITLE]); - return ( - - - - - - + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/utils.test.ts index 51618ed4e37419..02641b09255e53 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/utils.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/utils.test.ts @@ -5,7 +5,21 @@ * 2.0. */ -import { convertToDate, addDocument, removeDocument } from './utils'; +import '../../__mocks__/engine_logic.mock'; + +import { getCurationsBreadcrumbs, convertToDate, addDocument, removeDocument } from './utils'; + +describe('getCurationsBreadcrumbs', () => { + it('generates curation-prefixed breadcrumbs', () => { + expect(getCurationsBreadcrumbs()).toEqual(['Engines', 'some-engine', 'Curations']); + expect(getCurationsBreadcrumbs(['Some page'])).toEqual([ + 'Engines', + 'some-engine', + 'Curations', + 'Some page', + ]); + }); +}); describe('convertToDate', () => { it('converts the English-only server timestamps to a parseable Date', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/utils.ts index 8af2636128304b..978b63885fbdd3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/utils.ts @@ -5,6 +5,14 @@ * 2.0. */ +import { BreadcrumbTrail } from '../../../shared/kibana_chrome/generate_breadcrumbs'; +import { getEngineBreadcrumbs } from '../engine'; + +import { CURATIONS_TITLE } from './constants'; + +export const getCurationsBreadcrumbs = (breadcrumbs: BreadcrumbTrail = []) => + getEngineBreadcrumbs([CURATIONS_TITLE, ...breadcrumbs]); + // The server API feels us an English datestring, but we want to convert // it to an actual Date() instance so that we can localize date formats. export const convertToDate = (serverDateString: string): Date => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.test.tsx index ad306dfc730802..33aab9943cc832 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.test.tsx @@ -6,6 +6,7 @@ */ import { setMockActions } from '../../../../__mocks__/kea_logic'; +import '../../../__mocks__/engine_logic.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.tsx index 32d46775a2125e..9aa1759cec5c07 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_creation.tsx @@ -9,10 +9,10 @@ import React from 'react'; import { useActions } from 'kea'; -import { EuiPageHeader, EuiPageContent, EuiTitle, EuiText, EuiSpacer } from '@elastic/eui'; +import { EuiPanel, EuiTitle, EuiText, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FlashMessages } from '../../../../shared/flash_messages'; +import { AppSearchPageTemplate } from '../../layout'; import { MultiInputRows } from '../../multi_input_rows'; import { @@ -21,15 +21,17 @@ import { QUERY_INPUTS_PLACEHOLDER, } from '../constants'; import { CurationsLogic } from '../index'; +import { getCurationsBreadcrumbs } from '../utils'; export const CurationCreation: React.FC = () => { const { createCuration } = useActions(CurationsLogic); return ( - <> - - - + +

{i18n.translate( @@ -56,7 +58,7 @@ export const CurationCreation: React.FC = () => { inputPlaceholder={QUERY_INPUTS_PLACEHOLDER} onSubmit={(queries) => createCuration(queries)} /> - - + + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx index bcc402d6eea273..85827d53741793 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx @@ -6,17 +6,16 @@ */ import { mockKibanaValues, setMockActions, setMockValues } from '../../../../__mocks__/kea_logic'; +import '../../../../__mocks__/react_router'; import '../../../__mocks__/engine_logic.mock'; import React from 'react'; import { shallow, ReactWrapper } from 'enzyme'; -import { EuiPageHeader, EuiBasicTable } from '@elastic/eui'; +import { EuiBasicTable } from '@elastic/eui'; -import { Loading } from '../../../../shared/loading'; -import { mountWithIntl } from '../../../../test_helpers'; -import { EmptyState } from '../components'; +import { mountWithIntl, getPageTitle } from '../../../../test_helpers'; import { Curations, CurationsTable } from './curations'; @@ -61,32 +60,34 @@ describe('Curations', () => { it('renders', () => { const wrapper = shallow(); - expect(wrapper.find(EuiPageHeader).prop('pageTitle')).toEqual('Curated results'); + expect(getPageTitle(wrapper)).toEqual('Curated results'); expect(wrapper.find(CurationsTable)).toHaveLength(1); }); - it('renders a loading component on page load', () => { - setMockValues({ ...values, dataLoading: true, curations: [] }); - const wrapper = shallow(); + describe('loading state', () => { + it('renders a full-page loading state on initial page load', () => { + setMockValues({ ...values, dataLoading: true, curations: [] }); + const wrapper = shallow(); + + expect(wrapper.prop('isLoading')).toEqual(true); + }); + + it('does not re-render a full-page loading state after initial page load (uses component-level loading state instead)', () => { + setMockValues({ ...values, dataLoading: true, curations: [{}] }); + const wrapper = shallow(); - expect(wrapper.find(Loading)).toHaveLength(1); + expect(wrapper.prop('isLoading')).toEqual(false); + }); }); it('calls loadCurations on page load', () => { + setMockValues({ ...values, myRole: {} }); // Required for AppSearchPageTemplate to load mountWithIntl(); expect(actions.loadCurations).toHaveBeenCalledTimes(1); }); describe('CurationsTable', () => { - it('renders an empty state', () => { - setMockValues({ ...values, curations: [] }); - const table = shallow().find(EuiBasicTable); - const noItemsMessage = table.prop('noItemsMessage') as React.ReactElement; - - expect(noItemsMessage.type).toEqual(EmptyState); - }); - it('passes loading prop based on dataLoading', () => { setMockValues({ ...values, dataLoading: true }); const wrapper = shallow(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx index 80de9aba772585..12497ab52baf6e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx @@ -9,25 +9,24 @@ import React, { useEffect } from 'react'; import { useValues, useActions } from 'kea'; -import { EuiBasicTable, EuiBasicTableColumn, EuiPageContent, EuiPageHeader } from '@elastic/eui'; +import { EuiBasicTable, EuiBasicTableColumn, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { EDIT_BUTTON_LABEL, DELETE_BUTTON_LABEL } from '../../../../shared/constants'; -import { FlashMessages } from '../../../../shared/flash_messages'; import { KibanaLogic } from '../../../../shared/kibana'; -import { Loading } from '../../../../shared/loading'; import { EuiButtonTo, EuiLinkTo } from '../../../../shared/react_router_helpers'; import { convertMetaToPagination, handlePageChange } from '../../../../shared/table_pagination'; import { ENGINE_CURATIONS_NEW_PATH, ENGINE_CURATION_PATH } from '../../../routes'; import { FormattedDateTime } from '../../../utils/formatted_date_time'; import { generateEnginePath } from '../../engine'; +import { AppSearchPageTemplate } from '../../layout'; import { EmptyState } from '../components'; import { CURATIONS_OVERVIEW_TITLE, CREATE_NEW_CURATION_TITLE } from '../constants'; import { CurationsLogic } from '../curations_logic'; import { Curation } from '../types'; -import { convertToDate } from '../utils'; +import { getCurationsBreadcrumbs, convertToDate } from '../utils'; export const Curations: React.FC = () => { const { dataLoading, curations, meta } = useValues(CurationsLogic); @@ -37,23 +36,29 @@ export const Curations: React.FC = () => { loadCurations(); }, [meta.page.current]); - if (dataLoading && !curations.length) return ; - return ( - <> - + {CREATE_NEW_CURATION_TITLE} , - ]} - /> - - + ], + }} + isLoading={dataLoading && !curations.length} + isEmptyState={!curations.length} + emptyState={} + > + - - + + ); }; @@ -139,7 +144,6 @@ export const CurationsTable: React.FC = () => { responsive hasActions loading={dataLoading} - noItemsMessage={} pagination={{ ...convertMetaToPagination(meta), hidePerPageOptions: true, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx index 91a21847107a95..0f42483f44e0c1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx @@ -13,9 +13,7 @@ import { useValues, useActions } from 'kea'; import { i18n } from '@kbn/i18n'; import { setQueuedErrorMessage } from '../../../shared/flash_messages'; -import { Layout } from '../../../shared/layout'; import { AppLogic } from '../../app_logic'; -import { AppSearchNav } from '../../index'; import { ENGINE_PATH, @@ -114,6 +112,36 @@ export const EngineRouter: React.FC = () => { )} + {canViewMetaEngineSourceEngines && ( + + + + )} + {canViewEngineCrawler && ( + + + + )} + {canManageEngineRelevanceTuning && ( + + + + )} + {canManageEngineSynonyms && ( + + + + )} + {canManageEngineCurations && ( + + + + )} + {canManageEngineResultSettings && ( + + + + )} {canManageEngineSearchUi && ( @@ -124,39 +152,6 @@ export const EngineRouter: React.FC = () => { )} - {/* TODO: Remove layout once page template migration is over */} - }> - {canManageEngineCurations && ( - - - - )} - {canManageEngineRelevanceTuning && ( - - - - )} - {canManageEngineSynonyms && ( - - - - )} - {canManageEngineResultSettings && ( - - - - )} - {canViewMetaEngineSourceEngines && ( - - - - )} - {canViewEngineCrawler && ( - - - - )} - ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx index e6a14d7b5cd725..df29010bd682ff 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/empty_state.tsx @@ -7,42 +7,40 @@ import React from 'react'; -import { EuiButton, EuiEmptyPrompt, EuiPanel } from '@elastic/eui'; +import { EuiButton, EuiEmptyPrompt } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DOCS_PREFIX } from '../../../routes'; export const EmptyState: React.FC = () => ( - - - {i18n.translate('xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.title', { - defaultMessage: 'Add documents to tune relevance', - })} -

+ + {i18n.translate('xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.title', { + defaultMessage: 'Add documents to tune relevance', + })} + + } + body={i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.description', + { + defaultMessage: + 'A schema will be automatically created for you after you index some documents.', } - body={i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.description', - { - defaultMessage: - 'A schema will be automatically created for you after you index some documents.', - } - )} - actions={ - - {i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.buttonLabel', - { defaultMessage: 'Read the relevance tuning guide' } - )} - - } - /> -
+ )} + actions={ + + {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.buttonLabel', + { defaultMessage: 'Read the relevance tuning guide' } + )} + + } + /> ); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.test.tsx index 092740ac5d3cc6..48b536a954ed59 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.test.tsx @@ -13,14 +13,14 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { EuiEmptyPrompt } from '@elastic/eui'; - -import { Loading } from '../../../shared/loading'; import { UnsavedChangesPrompt } from '../../../shared/unsaved_changes_prompt'; +import { getPageHeaderActions } from '../../../test_helpers'; -import { EmptyState } from './components'; import { RelevanceTuning } from './relevance_tuning'; + +import { RelevanceTuningCallouts } from './relevance_tuning_callouts'; import { RelevanceTuningForm } from './relevance_tuning_form'; +import { RelevanceTuningPreview } from './relevance_tuning_preview'; describe('RelevanceTuning', () => { const values = { @@ -50,9 +50,9 @@ describe('RelevanceTuning', () => { it('renders', () => { const wrapper = subject(); + expect(wrapper.find(RelevanceTuningCallouts).exists()).toBe(true); expect(wrapper.find(RelevanceTuningForm).exists()).toBe(true); - expect(wrapper.find(Loading).exists()).toBe(false); - expect(wrapper.find(EmptyState).exists()).toBe(false); + expect(wrapper.find(RelevanceTuningPreview).exists()).toBe(true); }); it('initializes relevance tuning data', () => { @@ -60,33 +60,38 @@ describe('RelevanceTuning', () => { expect(actions.initializeRelevanceTuning).toHaveBeenCalled(); }); - it('will render an empty message when the engine has no schema', () => { + it('will prevent user from leaving the page if there are unsaved changes', () => { setMockValues({ ...values, - engineHasSchemaFields: false, + unsavedChanges: true, }); - const wrapper = subject(); - expect(wrapper.find(EmptyState).dive().find(EuiEmptyPrompt).exists()).toBe(true); - expect(wrapper.find(Loading).exists()).toBe(false); - expect(wrapper.find(RelevanceTuningForm).exists()).toBe(false); + expect(subject().find(UnsavedChangesPrompt).prop('hasUnsavedChanges')).toBe(true); }); - it('will show a loading message if data is loading', () => { - setMockValues({ - ...values, - dataLoading: true, + describe('header actions', () => { + it('renders a Save button that will save the current changes', () => { + const buttons = getPageHeaderActions(subject()); + expect(buttons.children().length).toBe(2); + const saveButton = buttons.find('[data-test-subj="SaveRelevanceTuning"]'); + saveButton.simulate('click'); + expect(actions.updateSearchSettings).toHaveBeenCalled(); }); - const wrapper = subject(); - expect(wrapper.find(Loading).exists()).toBe(true); - expect(wrapper.find(EmptyState).exists()).toBe(false); - expect(wrapper.find(RelevanceTuningForm).exists()).toBe(false); - }); - it('will prevent user from leaving the page if there are unsaved changes', () => { - setMockValues({ - ...values, - unsavedChanges: true, + it('renders a Reset button that will remove all weights and boosts', () => { + const buttons = getPageHeaderActions(subject()); + expect(buttons.children().length).toBe(2); + const resetButton = buttons.find('[data-test-subj="ResetRelevanceTuning"]'); + resetButton.simulate('click'); + expect(actions.resetSearchSettings).toHaveBeenCalled(); + }); + + it('will not render buttons if the engine has no schema', () => { + setMockValues({ + ...values, + engineHasSchemaFields: false, + }); + const buttons = getPageHeaderActions(subject()); + expect(buttons.children().length).toBe(0); }); - expect(subject().find(UnsavedChangesPrompt).prop('hasUnsavedChanges')).toBe(true); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.tsx index b98541a9638901..2e87d6836199bd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.tsx @@ -9,43 +9,77 @@ import React, { useEffect } from 'react'; import { useActions, useValues } from 'kea'; -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; -import { Loading } from '../../../shared/loading'; +import { SAVE_BUTTON_LABEL } from '../../../shared/constants'; import { UnsavedChangesPrompt } from '../../../shared/unsaved_changes_prompt'; +import { RESTORE_DEFAULTS_BUTTON_LABEL } from '../../constants'; +import { getEngineBreadcrumbs } from '../engine'; +import { AppSearchPageTemplate } from '../layout'; import { EmptyState } from './components'; +import { RELEVANCE_TUNING_TITLE } from './constants'; +import { RelevanceTuningCallouts } from './relevance_tuning_callouts'; import { RelevanceTuningForm } from './relevance_tuning_form'; -import { RelevanceTuningLayout } from './relevance_tuning_layout'; import { RelevanceTuningPreview } from './relevance_tuning_preview'; import { RelevanceTuningLogic } from '.'; export const RelevanceTuning: React.FC = () => { const { dataLoading, engineHasSchemaFields, unsavedChanges } = useValues(RelevanceTuningLogic); - const { initializeRelevanceTuning } = useActions(RelevanceTuningLogic); + const { initializeRelevanceTuning, resetSearchSettings, updateSearchSettings } = useActions( + RelevanceTuningLogic + ); useEffect(() => { initializeRelevanceTuning(); }, []); - if (dataLoading) return ; - return ( - + + {SAVE_BUTTON_LABEL} + , + + {RESTORE_DEFAULTS_BUTTON_LABEL} + , + ] + : [], + }} + isLoading={dataLoading} + isEmptyState={!engineHasSchemaFields} + emptyState={} + > - {engineHasSchemaFields ? ( - - - - - - - - - ) : ( - - )} - + + + + + + + + + + +
); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_form.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_form.tsx index 5cbd291f85debf..c35cd280c7a058 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_form.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_form/relevance_tuning_form.tsx @@ -42,7 +42,7 @@ export const RelevanceTuningForm: React.FC = () => { return (
- +

{i18n.translate( diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_layout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_layout.test.tsx deleted file mode 100644 index 20b1a16879234e..00000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_layout.test.tsx +++ /dev/null @@ -1,64 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; -import '../../__mocks__/engine_logic.mock'; - -import React from 'react'; - -import { shallow, ShallowWrapper } from 'enzyme'; - -import { EuiPageHeader } from '@elastic/eui'; - -import { RelevanceTuningLayout } from './relevance_tuning_layout'; - -describe('RelevanceTuningLayout', () => { - const values = { - engineHasSchemaFields: true, - schemaFieldsWithConflicts: [], - }; - - const actions = { - updateSearchSettings: jest.fn(), - resetSearchSettings: jest.fn(), - }; - - beforeEach(() => { - jest.clearAllMocks(); - setMockValues(values); - setMockActions(actions); - }); - - const subject = () => shallow(); - const findButtons = (wrapper: ShallowWrapper) => - wrapper.find(EuiPageHeader).prop('rightSideItems') as React.ReactElement[]; - - it('renders a Save button that will save the current changes', () => { - const buttons = findButtons(subject()); - expect(buttons.length).toBe(2); - const saveButton = shallow(buttons[0]); - saveButton.simulate('click'); - expect(actions.updateSearchSettings).toHaveBeenCalled(); - }); - - it('renders a Reset button that will remove all weights and boosts', () => { - const buttons = findButtons(subject()); - expect(buttons.length).toBe(2); - const resetButton = shallow(buttons[1]); - resetButton.simulate('click'); - expect(actions.resetSearchSettings).toHaveBeenCalled(); - }); - - it('will not render buttons if the engine has no schema', () => { - setMockValues({ - ...values, - engineHasSchemaFields: false, - }); - const buttons = findButtons(subject()); - expect(buttons.length).toBe(0); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_layout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_layout.tsx deleted file mode 100644 index 4fa694300a7795..00000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_layout.tsx +++ /dev/null @@ -1,73 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { useActions, useValues } from 'kea'; - -import { EuiPageHeader, EuiButton } from '@elastic/eui'; - -import { i18n } from '@kbn/i18n'; - -import { SAVE_BUTTON_LABEL } from '../../../shared/constants'; -import { FlashMessages } from '../../../shared/flash_messages'; -import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; -import { RESTORE_DEFAULTS_BUTTON_LABEL } from '../../constants'; -import { getEngineBreadcrumbs } from '../engine'; - -import { RELEVANCE_TUNING_TITLE } from './constants'; -import { RelevanceTuningCallouts } from './relevance_tuning_callouts'; -import { RelevanceTuningLogic } from './relevance_tuning_logic'; - -export const RelevanceTuningLayout: React.FC = ({ children }) => { - const { resetSearchSettings, updateSearchSettings } = useActions(RelevanceTuningLogic); - const { engineHasSchemaFields } = useValues(RelevanceTuningLogic); - - const pageHeader = () => ( - - {SAVE_BUTTON_LABEL} - , - - {RESTORE_DEFAULTS_BUTTON_LABEL} - , - ] - : [] - } - /> - ); - - return ( - <> - - {pageHeader()} - - - {children} - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.tsx index 911e97de5b53f5..4f3b20b419e802 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.tsx @@ -21,6 +21,7 @@ import { RelevanceTuningLogic } from '.'; const emptyCallout = ( ( - - - {i18n.translate('xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.title', { - defaultMessage: 'Add documents to adjust settings', - })} -

+ + {i18n.translate('xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.title', { + defaultMessage: 'Add documents to adjust settings', + })} + + } + body={i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.description', + { + defaultMessage: + 'A schema will be automatically created for you after you index some documents.', } - body={i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.description', - { - defaultMessage: - 'A schema will be automatically created for you after you index some documents.', - } - )} - actions={ - - {i18n.translate( - 'xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.buttonLabel', - { defaultMessage: 'Read the result settings guide' } - )} - - } - /> - + )} + actions={ + + {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.buttonLabel', + { defaultMessage: 'Read the result settings guide' } + )} + + } + /> ); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.test.tsx index ec521b4959535c..440acaf136ddac 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.test.tsx @@ -13,11 +13,9 @@ import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; -import { EuiPageHeader } from '@elastic/eui'; - import { UnsavedChangesPrompt } from '../../../shared/unsaved_changes_prompt'; +import { getPageHeaderActions } from '../../../test_helpers'; -import { EmptyState } from './components'; import { ResultSettings } from './result_settings'; import { ResultSettingsTable } from './result_settings_table'; import { SampleResponse } from './sample_response'; @@ -46,8 +44,6 @@ describe('ResultSettings', () => { }); const subject = () => shallow(); - const findButtons = (wrapper: ShallowWrapper) => - wrapper.find(EuiPageHeader).prop('rightSideItems') as React.ReactElement[]; it('renders', () => { const wrapper = subject(); @@ -60,19 +56,10 @@ describe('ResultSettings', () => { expect(actions.initializeResultSettingsData).toHaveBeenCalled(); }); - it('renders a loading screen if data has not loaded yet', () => { - setMockValues({ - dataLoading: true, - }); - const wrapper = subject(); - expect(wrapper.find(ResultSettingsTable).exists()).toBe(false); - expect(wrapper.find(SampleResponse).exists()).toBe(false); - }); - it('renders a "save" button that will save the current changes', () => { - const buttons = findButtons(subject()); - expect(buttons.length).toBe(3); - const saveButton = shallow(buttons[0]); + const buttons = getPageHeaderActions(subject()); + expect(buttons.children().length).toBe(3); + const saveButton = buttons.find('[data-test-subj="SaveResultSettings"]'); saveButton.simulate('click'); expect(actions.saveResultSettings).toHaveBeenCalled(); }); @@ -82,8 +69,8 @@ describe('ResultSettings', () => { ...values, stagedUpdates: false, }); - const buttons = findButtons(subject()); - const saveButton = shallow(buttons[0]); + const buttons = getPageHeaderActions(subject()); + const saveButton = buttons.find('[data-test-subj="SaveResultSettings"]'); expect(saveButton.prop('disabled')).toBe(true); }); @@ -93,15 +80,15 @@ describe('ResultSettings', () => { stagedUpdates: true, resultFieldsEmpty: true, }); - const buttons = findButtons(subject()); - const saveButton = shallow(buttons[0]); + const buttons = getPageHeaderActions(subject()); + const saveButton = buttons.find('[data-test-subj="SaveResultSettings"]'); expect(saveButton.prop('disabled')).toBe(true); }); it('renders a "restore defaults" button that will reset all values to their defaults', () => { - const buttons = findButtons(subject()); - expect(buttons.length).toBe(3); - const resetButton = shallow(buttons[1]); + const buttons = getPageHeaderActions(subject()); + expect(buttons.children().length).toBe(3); + const resetButton = buttons.find('[data-test-subj="ResetResultSettings"]'); resetButton.simulate('click'); expect(actions.confirmResetAllFields).toHaveBeenCalled(); }); @@ -111,15 +98,15 @@ describe('ResultSettings', () => { ...values, resultFieldsAtDefaultSettings: true, }); - const buttons = findButtons(subject()); - const resetButton = shallow(buttons[1]); + const buttons = getPageHeaderActions(subject()); + const resetButton = buttons.find('[data-test-subj="ResetResultSettings"]'); expect(resetButton.prop('disabled')).toBe(true); }); it('renders a "clear" button that will remove all selected options', () => { - const buttons = findButtons(subject()); - expect(buttons.length).toBe(3); - const clearButton = shallow(buttons[2]); + const buttons = getPageHeaderActions(subject()); + expect(buttons.children().length).toBe(3); + const clearButton = buttons.find('[data-test-subj="ClearResultSettings"]'); clearButton.simulate('click'); expect(actions.clearAllFields).toHaveBeenCalled(); }); @@ -143,17 +130,12 @@ describe('ResultSettings', () => { }); it('will not render action buttons', () => { - const buttons = findButtons(wrapper); - expect(buttons.length).toBe(0); - }); - - it('will not render the main page content', () => { - expect(wrapper.find(ResultSettingsTable).exists()).toBe(false); - expect(wrapper.find(SampleResponse).exists()).toBe(false); + const buttons = getPageHeaderActions(wrapper); + expect(buttons.children().length).toBe(0); }); it('will render an empty state', () => { - expect(wrapper.find(EmptyState).exists()).toBe(true); + expect(wrapper.prop('isEmptyState')).toBe(true); }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.tsx index 45cb9ea1cfcb4c..c315927433a0a9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_settings/result_settings.tsx @@ -9,17 +9,15 @@ import React, { useEffect } from 'react'; import { useActions, useValues } from 'kea'; -import { EuiPageHeader, EuiFlexGroup, EuiFlexItem, EuiButton, EuiButtonEmpty } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiButton, EuiButtonEmpty } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { SAVE_BUTTON_LABEL } from '../../../shared/constants'; -import { FlashMessages } from '../../../shared/flash_messages'; -import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; -import { Loading } from '../../../shared/loading'; import { UnsavedChangesPrompt } from '../../../shared/unsaved_changes_prompt'; import { RESTORE_DEFAULTS_BUTTON_LABEL } from '../../constants'; import { getEngineBreadcrumbs } from '../engine'; +import { AppSearchPageTemplate } from '../layout'; import { EmptyState } from './components'; import { RESULT_SETTINGS_TITLE } from './constants'; @@ -57,59 +55,56 @@ export const ResultSettings: React.FC = () => { initializeResultSettingsData(); }, []); - if (dataLoading) return ; const hasSchema = Object.keys(schema).length > 0; return ( - <> - - - - {SAVE_BUTTON_LABEL} - , - - {RESTORE_DEFAULTS_BUTTON_LABEL} - , - - {CLEAR_BUTTON_LABEL} - , - ] - : [] - } - /> - - {hasSchema ? ( - - - - - - - - - ) : ( - - )} - + ), + rightSideItems: hasSchema + ? [ + + {SAVE_BUTTON_LABEL} + , + + {RESTORE_DEFAULTS_BUTTON_LABEL} + , + + {CLEAR_BUTTON_LABEL} + , + ] + : [], + }} + isLoading={dataLoading} + isEmptyState={!hasSchema} + emptyState={} + > + + + + + + + + + + + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_button.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_button.tsx index 004217d88987bd..3076e14d6329b5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_button.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/components/add_source_engines_button.tsx @@ -18,7 +18,7 @@ export const AddSourceEnginesButton: React.FC = () => { const { openModal } = useActions(SourceEnginesLogic); return ( - + {ADD_SOURCE_ENGINES_BUTTON_LABEL} ); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.test.tsx index 9d2fe653150c33..e2398209e630d0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.test.tsx @@ -11,11 +11,9 @@ import '../../__mocks__/engine_logic.mock'; import React from 'react'; -import { shallow, ShallowWrapper } from 'enzyme'; +import { shallow } from 'enzyme'; -import { EuiPageHeader } from '@elastic/eui'; - -import { Loading } from '../../../shared/loading'; +import { getPageHeaderActions } from '../../../test_helpers'; import { AddSourceEnginesButton, AddSourceEnginesModal, SourceEnginesTable } from './components'; @@ -61,20 +59,10 @@ describe('SourceEngines', () => { expect(wrapper.find(AddSourceEnginesModal)).toHaveLength(1); }); - it('renders a loading component before data has loaded', () => { - setMockValues({ ...MOCK_VALUES, dataLoading: true }); - const wrapper = shallow(); - - expect(wrapper.find(Loading)).toHaveLength(1); - }); - describe('page actions', () => { - const getPageHeader = (wrapper: ShallowWrapper) => - wrapper.find(EuiPageHeader).dive().children().dive(); - it('contains a button to add source engines', () => { const wrapper = shallow(); - expect(getPageHeader(wrapper).find(AddSourceEnginesButton)).toHaveLength(1); + expect(getPageHeaderActions(wrapper).find(AddSourceEnginesButton)).toHaveLength(1); }); it('hides the add source engines button if the user does not have permissions', () => { @@ -86,7 +74,7 @@ describe('SourceEngines', () => { }); const wrapper = shallow(); - expect(getPageHeader(wrapper).find(AddSourceEnginesButton)).toHaveLength(0); + expect(getPageHeaderActions(wrapper).find(AddSourceEnginesButton)).toHaveLength(0); }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.tsx index 190c44c9190204..d2476faf4f3f50 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/source_engines/source_engines.tsx @@ -9,13 +9,11 @@ import React, { useEffect } from 'react'; import { useActions, useValues } from 'kea'; -import { EuiPageHeader, EuiPageContent } from '@elastic/eui'; +import { EuiPanel } from '@elastic/eui'; -import { FlashMessages } from '../../../shared/flash_messages'; -import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; -import { Loading } from '../../../shared/loading'; import { AppLogic } from '../../app_logic'; import { getEngineBreadcrumbs } from '../engine'; +import { AppSearchPageTemplate } from '../layout'; import { AddSourceEnginesButton, AddSourceEnginesModal, SourceEnginesTable } from './components'; import { SOURCE_ENGINES_TITLE } from './i18n'; @@ -33,20 +31,19 @@ export const SourceEngines: React.FC = () => { fetchSourceEngines(); }, []); - if (dataLoading) return ; - return ( - <> - - ] : []} - /> - - + ] : [], + }} + isLoading={dataLoading} + > + {isModalOpen && } - - + + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.test.tsx index f1382bb5972b21..a43f170e5822f8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.test.tsx @@ -11,7 +11,7 @@ import { shallow } from 'enzyme'; import { EuiEmptyPrompt, EuiButton } from '@elastic/eui'; -import { EmptyState } from './'; +import { EmptyState, SynonymModal } from './'; describe('EmptyState', () => { it('renders', () => { @@ -24,4 +24,10 @@ describe('EmptyState', () => { expect.stringContaining('/synonyms-guide.html') ); }); + + it('renders the add synonym modal', () => { + const wrapper = shallow(); + + expect(wrapper.find(SynonymModal)).toHaveLength(1); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx index 2eb6643bda5032..f856a5c035f811 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/components/empty_state.tsx @@ -7,16 +7,16 @@ import React from 'react'; -import { EuiPanel, EuiEmptyPrompt, EuiButton } from '@elastic/eui'; +import { EuiEmptyPrompt, EuiButton } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DOCS_PREFIX } from '../../../routes'; -import { SynonymIcon } from './'; +import { SynonymModal, SynonymIcon } from './'; export const EmptyState: React.FC = () => { return ( - + <> { } /> - + + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.test.tsx index c8f65c4bdbc6c4..64ac3066b51a51 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.test.tsx @@ -13,12 +13,11 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { EuiPageHeader, EuiButton, EuiPagination } from '@elastic/eui'; +import { EuiButton, EuiPagination } from '@elastic/eui'; -import { Loading } from '../../../shared/loading'; -import { rerender } from '../../../test_helpers'; +import { rerender, getPageHeaderActions } from '../../../test_helpers'; -import { SynonymCard, SynonymModal, EmptyState } from './components'; +import { SynonymCard, SynonymModal } from './components'; import { Synonyms } from './'; @@ -53,21 +52,9 @@ describe('Synonyms', () => { }); it('renders a create action button', () => { - const wrapper = shallow() - .find(EuiPageHeader) - .dive() - .children() - .dive(); - - wrapper.find(EuiButton).simulate('click'); - expect(actions.openModal).toHaveBeenCalled(); - }); - - it('renders an empty state if no synonyms exist', () => { - setMockValues({ ...values, synonymSets: [] }); const wrapper = shallow(); - - expect(wrapper.find(EmptyState)).toHaveLength(1); + getPageHeaderActions(wrapper).find(EuiButton).simulate('click'); + expect(actions.openModal).toHaveBeenCalled(); }); describe('loading', () => { @@ -75,14 +62,14 @@ describe('Synonyms', () => { setMockValues({ ...values, synonymSets: [], dataLoading: true }); const wrapper = shallow(); - expect(wrapper.find(Loading)).toHaveLength(1); + expect(wrapper.prop('isLoading')).toEqual(true); }); it('does not render a full loading state after initial page load', () => { setMockValues({ ...values, synonymSets: [MOCK_SYNONYM_SET], dataLoading: true }); const wrapper = shallow(); - expect(wrapper.find(Loading)).toHaveLength(0); + expect(wrapper.prop('isLoading')).toEqual(false); }); }); @@ -108,7 +95,7 @@ describe('Synonyms', () => { const wrapper = shallow(); expect(actions.onPaginate).not.toHaveBeenCalled(); - expect(wrapper.find(EmptyState)).toHaveLength(1); + expect(wrapper.prop('isEmptyState')).toEqual(true); }); it('handles off-by-one shenanigans between EuiPagination and our API', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.tsx index d3ba53819f7de2..4a68bc381f7641 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/synonyms/synonyms.tsx @@ -9,21 +9,11 @@ import React, { useEffect } from 'react'; import { useValues, useActions } from 'kea'; -import { - EuiPageHeader, - EuiButton, - EuiPageContentBody, - EuiSpacer, - EuiFlexGrid, - EuiFlexItem, - EuiPagination, -} from '@elastic/eui'; +import { EuiButton, EuiSpacer, EuiFlexGrid, EuiFlexItem, EuiPagination } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FlashMessages } from '../../../shared/flash_messages'; -import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; -import { Loading } from '../../../shared/loading'; import { getEngineBreadcrumbs } from '../engine'; +import { AppSearchPageTemplate } from '../layout'; import { SynonymCard, SynonymModal, EmptyState } from './components'; import { SYNONYMS_TITLE } from './constants'; @@ -46,46 +36,45 @@ export const Synonyms: React.FC = () => { } }, [synonymSets]); - if (dataLoading && !hasSynonyms) return ; - return ( - <> - - openModal(null)}> + openModal(null)}> {i18n.translate( 'xpack.enterpriseSearch.appSearch.engine.synonyms.createSynonymSetButtonLabel', { defaultMessage: 'Create a synonym set' } )} , - ]} + ], + }} + isLoading={dataLoading && !hasSynonyms} + isEmptyState={!hasSynonyms} + emptyState={} + > + + {synonymSets.map(({ id, synonyms }) => ( + + + + ))} + + + onPaginate(pageIndex + 1)} /> - - - - {hasSynonyms ? ( - <> - - {synonymSets.map(({ id, synonyms }) => ( - - - - ))} - - - onPaginate(pageIndex + 1)} - /> - - ) : ( - - )} - - - + + ); }; diff --git a/x-pack/plugins/fleet/server/services/hosts_utils.test.ts b/x-pack/plugins/fleet/common/services/hosts_utils.test.ts similarity index 100% rename from x-pack/plugins/fleet/server/services/hosts_utils.test.ts rename to x-pack/plugins/fleet/common/services/hosts_utils.test.ts diff --git a/x-pack/plugins/fleet/server/services/hosts_utils.ts b/x-pack/plugins/fleet/common/services/hosts_utils.ts similarity index 100% rename from x-pack/plugins/fleet/server/services/hosts_utils.ts rename to x-pack/plugins/fleet/common/services/hosts_utils.ts diff --git a/x-pack/plugins/fleet/common/services/index.ts b/x-pack/plugins/fleet/common/services/index.ts index 86361ae1633995..a6f4cd319b9701 100644 --- a/x-pack/plugins/fleet/common/services/index.ts +++ b/x-pack/plugins/fleet/common/services/index.ts @@ -30,3 +30,5 @@ export { validationHasErrors, countValidationErrors, } from './validate_package_policy'; + +export { normalizeHostsForAgents } from './hosts_utils'; diff --git a/x-pack/plugins/fleet/common/types/models/epm.ts b/x-pack/plugins/fleet/common/types/models/epm.ts index aece6580831960..c4441fb6e0d95b 100644 --- a/x-pack/plugins/fleet/common/types/models/epm.ts +++ b/x-pack/plugins/fleet/common/types/models/epm.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { estypes } from '@elastic/elasticsearch'; // Follow pattern from https://github.com/elastic/kibana/pull/52447 // TODO: Update when https://github.com/elastic/kibana/issues/53021 is closed import type { SavedObject, SavedObjectAttributes, SavedObjectReference } from 'src/core/public'; @@ -299,8 +300,8 @@ export interface RegistryDataStream { } export interface RegistryElasticsearch { - 'index_template.settings'?: object; - 'index_template.mappings'?: object; + 'index_template.settings'?: estypes.IndicesIndexSettings; + 'index_template.mappings'?: estypes.MappingTypeMapping; } export interface RegistryDataStreamPermissions { @@ -425,7 +426,7 @@ export interface IndexTemplate { _meta: object; } -export interface TemplateRef { +export interface IndexTemplateEntry { templateName: string; indexTemplate: IndexTemplate; } diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/settings.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/settings.tsx index 995423ea91f968..9e8d200344b01d 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/settings.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/settings.tsx @@ -233,7 +233,7 @@ export const SettingsPage: React.FC = memo(({ packageInfo }: Props) => { , diff --git a/x-pack/plugins/fleet/public/components/settings_flyout/index.tsx b/x-pack/plugins/fleet/public/components/settings_flyout/index.tsx index d748e655bd5062..9bc1bc977b7861 100644 --- a/x-pack/plugins/fleet/public/components/settings_flyout/index.tsx +++ b/x-pack/plugins/fleet/public/components/settings_flyout/index.tsx @@ -38,7 +38,7 @@ import { useGetOutputs, sendPutOutput, } from '../../hooks'; -import { isDiffPathProtocol } from '../../../common'; +import { isDiffPathProtocol, normalizeHostsForAgents } from '../../../common'; import { SettingsConfirmModal } from './confirm_modal'; import type { SettingsConfirmModalProps } from './confirm_modal'; @@ -53,8 +53,20 @@ interface Props { onClose: () => void; } -function isSameArrayValue(arrayA: string[] = [], arrayB: string[] = []) { - return arrayA.length === arrayB.length && arrayA.every((val, index) => val === arrayB[index]); +function normalizeHosts(hostsInput: string[]) { + return hostsInput.map((host) => { + try { + return normalizeHostsForAgents(host); + } catch (err) { + return host; + } + }); +} + +function isSameArrayValueWithNormalizedHosts(arrayA: string[] = [], arrayB: string[] = []) { + const hostsA = normalizeHosts(arrayA); + const hostsB = normalizeHosts(arrayB); + return hostsA.length === hostsB.length && hostsA.every((val, index) => val === hostsB[index]); } function useSettingsForm(outputId: string | undefined, onSuccess: () => void) { @@ -234,8 +246,11 @@ export const SettingFlyout: React.FunctionComponent = ({ onClose }) => { return false; } return ( - !isSameArrayValue(settings.fleet_server_hosts, inputs.fleetServerHosts.value) || - !isSameArrayValue(output.hosts, inputs.elasticsearchUrl.value) || + !isSameArrayValueWithNormalizedHosts( + settings.fleet_server_hosts, + inputs.fleetServerHosts.value + ) || + !isSameArrayValueWithNormalizedHosts(output.hosts, inputs.elasticsearchUrl.value) || (output.config_yaml || '') !== inputs.additionalYamlConfig.value ); }, [settings, inputs, output]); @@ -246,32 +261,37 @@ export const SettingFlyout: React.FunctionComponent = ({ onClose }) => { } const tmpChanges: SettingsConfirmModalProps['changes'] = []; - if (!isSameArrayValue(output.hosts, inputs.elasticsearchUrl.value)) { + if (!isSameArrayValueWithNormalizedHosts(output.hosts, inputs.elasticsearchUrl.value)) { tmpChanges.push( { type: 'elasticsearch', direction: 'removed', - urls: output.hosts || [], + urls: normalizeHosts(output.hosts || []), }, { type: 'elasticsearch', direction: 'added', - urls: inputs.elasticsearchUrl.value, + urls: normalizeHosts(inputs.elasticsearchUrl.value), } ); } - if (!isSameArrayValue(settings.fleet_server_hosts, inputs.fleetServerHosts.value)) { + if ( + !isSameArrayValueWithNormalizedHosts( + settings.fleet_server_hosts, + inputs.fleetServerHosts.value + ) + ) { tmpChanges.push( { type: 'fleet_server', direction: 'removed', - urls: settings.fleet_server_hosts, + urls: normalizeHosts(settings.fleet_server_hosts || []), }, { type: 'fleet_server', direction: 'added', - urls: inputs.fleetServerHosts.value, + urls: normalizeHosts(inputs.fleetServerHosts.value), } ); } @@ -300,7 +320,7 @@ export const SettingFlyout: React.FunctionComponent = ({ onClose }) => { helpText={ = ({ onClose }) => { defaultMessage: 'Elasticsearch hosts', })} helpText={i18n.translate('xpack.fleet.settings.elasticsearchUrlsHelpTect', { - defaultMessage: 'Specify the Elasticsearch URLs where agents send data.', + defaultMessage: + 'Specify the Elasticsearch URLs where agents send data. Elasticsearch uses port 9200 by default.', })} /> diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts index d202dab54f5bdc..db1fba1eedccde 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts @@ -11,7 +11,7 @@ import type { ElasticsearchClient, SavedObjectsClientContract } from 'src/core/s import { ElasticsearchAssetType } from '../../../../types'; import type { RegistryDataStream, - TemplateRef, + IndexTemplateEntry, RegistryElasticsearch, InstallablePackage, } from '../../../../types'; @@ -19,7 +19,7 @@ import { loadFieldsFromYaml, processFields } from '../../fields/field'; import type { Field } from '../../fields/field'; import { getPipelineNameForInstallation } from '../ingest_pipeline/install'; import { getAsset, getPathParts } from '../../archive'; -import { removeAssetsFromInstalledEsByType, saveInstalledEsRefs } from '../../packages/install'; +import { removeAssetTypesFromInstalledEs, saveInstalledEsRefs } from '../../packages/install'; import { generateMappings, @@ -34,7 +34,7 @@ export const installTemplates = async ( esClient: ElasticsearchClient, paths: string[], savedObjectsClient: SavedObjectsClientContract -): Promise => { +): Promise => { // install any pre-built index template assets, // atm, this is only the base package's global index templates // Install component templates first, as they are used by the index templates @@ -42,44 +42,36 @@ export const installTemplates = async ( await installPreBuiltTemplates(paths, esClient); // remove package installation's references to index templates - await removeAssetsFromInstalledEsByType( - savedObjectsClient, - installablePackage.name, - ElasticsearchAssetType.indexTemplate - ); + await removeAssetTypesFromInstalledEs(savedObjectsClient, installablePackage.name, [ + ElasticsearchAssetType.indexTemplate, + ElasticsearchAssetType.componentTemplate, + ]); // build templates per data stream from yml files const dataStreams = installablePackage.data_streams; if (!dataStreams) return []; + + const installedTemplatesNested = await Promise.all( + dataStreams.map((dataStream) => + installTemplateForDataStream({ + pkg: installablePackage, + esClient, + dataStream, + }) + ) + ); + const installedTemplates = installedTemplatesNested.flat(); + // get template refs to save - const installedTemplateRefs = dataStreams.map((dataStream) => ({ - id: generateTemplateName(dataStream), - type: ElasticsearchAssetType.indexTemplate, - })); + const installedIndexTemplateRefs = getAllTemplateRefs(installedTemplates); // add package installation's references to index templates - await saveInstalledEsRefs(savedObjectsClient, installablePackage.name, installedTemplateRefs); - - if (dataStreams) { - const installTemplatePromises = dataStreams.reduce>>( - (acc, dataStream) => { - acc.push( - installTemplateForDataStream({ - pkg: installablePackage, - esClient, - dataStream, - }) - ); - return acc; - }, - [] - ); - - const res = await Promise.all(installTemplatePromises); - const installedTemplates = res.flat(); + await saveInstalledEsRefs( + savedObjectsClient, + installablePackage.name, + installedIndexTemplateRefs + ); - return installedTemplates; - } - return []; + return installedTemplates; }; const installPreBuiltTemplates = async (paths: string[], esClient: ElasticsearchClient) => { @@ -160,7 +152,7 @@ export async function installTemplateForDataStream({ pkg: InstallablePackage; esClient: ElasticsearchClient; dataStream: RegistryDataStream; -}): Promise { +}): Promise { const fields = await loadFieldsFromYaml(pkg, dataStream.path); return installTemplate({ esClient, @@ -171,84 +163,118 @@ export async function installTemplateForDataStream({ }); } +interface TemplateMapEntry { + _meta: { package: { name: string } }; + template: + | { + mappings: NonNullable; + } + | { + settings: NonNullable | object; + }; +} +type TemplateMap = Record; function putComponentTemplate( - body: object | undefined, - name: string, - esClient: ElasticsearchClient -): { clusterPromise: Promise; name: string } | undefined { - if (body) { - const esClientParams = { - name, - body, - }; - - return { - // @ts-expect-error body expected to be ClusterPutComponentTemplateRequest - clusterPromise: esClient.cluster.putComponentTemplate(esClientParams, { ignore: [404] }), - name, - }; + esClient: ElasticsearchClient, + params: { + body: TemplateMapEntry; + name: string; + create?: boolean; } +): { clusterPromise: Promise; name: string } { + const { name, body, create = false } = params; + return { + clusterPromise: esClient.cluster.putComponentTemplate( + // @ts-expect-error body is missing required key `settings`. TemplateMapEntry has settings *or* mappings + { name, body, create }, + { ignore: [404] } + ), + name, + }; } -function buildComponentTemplates(registryElasticsearch: RegistryElasticsearch | undefined) { - let mappingsTemplate; - let settingsTemplate; +const mappingsSuffix = '@mappings'; +const settingsSuffix = '@settings'; +const userSettingsSuffix = '@custom'; +type TemplateBaseName = string; +type UserSettingsTemplateName = `${TemplateBaseName}${typeof userSettingsSuffix}`; + +const isUserSettingsTemplate = (name: string): name is UserSettingsTemplateName => + name.endsWith(userSettingsSuffix); + +function buildComponentTemplates(params: { + templateName: string; + registryElasticsearch: RegistryElasticsearch | undefined; + packageName: string; +}) { + const { templateName, registryElasticsearch, packageName } = params; + const mappingsTemplateName = `${templateName}${mappingsSuffix}`; + const settingsTemplateName = `${templateName}${settingsSuffix}`; + const userSettingsTemplateName = `${templateName}${userSettingsSuffix}`; + + const templatesMap: TemplateMap = {}; + const _meta = { package: { name: packageName } }; if (registryElasticsearch && registryElasticsearch['index_template.mappings']) { - mappingsTemplate = { + templatesMap[mappingsTemplateName] = { template: { - mappings: { - ...registryElasticsearch['index_template.mappings'], - }, + mappings: registryElasticsearch['index_template.mappings'], }, + _meta, }; } if (registryElasticsearch && registryElasticsearch['index_template.settings']) { - settingsTemplate = { + templatesMap[settingsTemplateName] = { template: { settings: registryElasticsearch['index_template.settings'], }, + _meta, }; } - return { settingsTemplate, mappingsTemplate }; -} -async function installDataStreamComponentTemplates( - templateName: string, - registryElasticsearch: RegistryElasticsearch | undefined, - esClient: ElasticsearchClient -) { - const templates: string[] = []; - const componentPromises: Array> = []; + // return empty/stub template + templatesMap[userSettingsTemplateName] = { + template: { + settings: {}, + }, + _meta, + }; - const compTemplates = buildComponentTemplates(registryElasticsearch); + return templatesMap; +} - const mappings = putComponentTemplate( - compTemplates.mappingsTemplate, - `${templateName}-mappings`, - esClient - ); +async function installDataStreamComponentTemplates(params: { + templateName: string; + registryElasticsearch: RegistryElasticsearch | undefined; + esClient: ElasticsearchClient; + packageName: string; +}) { + const { templateName, registryElasticsearch, esClient, packageName } = params; + const templates = buildComponentTemplates({ templateName, registryElasticsearch, packageName }); + const templateNames = Object.keys(templates); + const templateEntries = Object.entries(templates); - const settings = putComponentTemplate( - compTemplates.settingsTemplate, - `${templateName}-settings`, - esClient + // TODO: Check return values for errors + await Promise.all( + templateEntries.map(async ([name, body]) => { + if (isUserSettingsTemplate(name)) { + // look for existing user_settings template + const result = await esClient.cluster.getComponentTemplate({ name }, { ignore: [404] }); + const hasUserSettingsTemplate = result.body.component_templates?.length === 1; + if (!hasUserSettingsTemplate) { + // only add if one isn't already present + const { clusterPromise } = putComponentTemplate(esClient, { body, name, create: true }); + return clusterPromise; + } + } else { + const { clusterPromise } = putComponentTemplate(esClient, { body, name }); + return clusterPromise; + } + }) ); - if (mappings) { - templates.push(mappings.name); - componentPromises.push(mappings.clusterPromise); - } - - if (settings) { - templates.push(settings.name); - componentPromises.push(settings.clusterPromise); - } - - // TODO: Check return values for errors - await Promise.all(componentPromises); - return templates; + return templateNames; } export async function installTemplate({ @@ -263,7 +289,7 @@ export async function installTemplate({ dataStream: RegistryDataStream; packageVersion: string; packageName: string; -}): Promise { +}): Promise { const validFields = processFields(fields); const mappings = generateMappings(validFields); const templateName = generateTemplateName(dataStream); @@ -310,11 +336,12 @@ export async function installTemplate({ await esClient.indices.putIndexTemplate(updateIndexTemplateParams, { ignore: [404] }); } - const composedOfTemplates = await installDataStreamComponentTemplates( + const composedOfTemplates = await installDataStreamComponentTemplates({ templateName, - dataStream.elasticsearch, - esClient - ); + registryElasticsearch: dataStream.elasticsearch, + esClient, + packageName, + }); const template = getTemplate({ type: dataStream.type, @@ -342,3 +369,21 @@ export async function installTemplate({ indexTemplate: template, }; } + +export function getAllTemplateRefs(installedTemplates: IndexTemplateEntry[]) { + return installedTemplates.flatMap((installedTemplate) => { + const indexTemplates = [ + { + id: installedTemplate.templateName, + type: ElasticsearchAssetType.indexTemplate, + }, + ]; + const componentTemplates = installedTemplate.indexTemplate.composed_of.map( + (componentTemplateId) => ({ + id: componentTemplateId, + type: ElasticsearchAssetType.componentTemplate, + }) + ); + return indexTemplates.concat(componentTemplates); + }); +} diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts index 07d0df021c827b..158996cc574d7a 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts @@ -10,7 +10,7 @@ import type { ElasticsearchClient } from 'kibana/server'; import type { Field, Fields } from '../../fields/field'; import type { RegistryDataStream, - TemplateRef, + IndexTemplateEntry, IndexTemplate, IndexTemplateMappings, } from '../../../../types'; @@ -456,7 +456,7 @@ function getBaseTemplate( export const updateCurrentWriteIndices = async ( esClient: ElasticsearchClient, - templates: TemplateRef[] + templates: IndexTemplateEntry[] ): Promise => { if (!templates.length) return; @@ -471,7 +471,7 @@ function isCurrentDataStream(item: CurrentDataStream[] | undefined): item is Cur const queryDataStreamsFromTemplates = async ( esClient: ElasticsearchClient, - templates: TemplateRef[] + templates: IndexTemplateEntry[] ): Promise => { const dataStreamPromises = templates.map((template) => { return getDataStreams(esClient, template); @@ -482,7 +482,7 @@ const queryDataStreamsFromTemplates = async ( const getDataStreams = async ( esClient: ElasticsearchClient, - template: TemplateRef + template: IndexTemplateEntry ): Promise => { const { templateName, indexTemplate } = template; const { body } = await esClient.indices.getDataStream({ name: `${templateName}-*` }); diff --git a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts index 65d71ac5fdc179..1bbbb1bb9b6a24 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts @@ -10,10 +10,10 @@ import type { ElasticsearchClient, SavedObject, SavedObjectsClientContract } fro import { MAX_TIME_COMPLETE_INSTALL, ASSETS_SAVED_OBJECT_TYPE } from '../../../../common'; import type { InstallablePackage, InstallSource, PackageAssetReference } from '../../../../common'; import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../constants'; -import { ElasticsearchAssetType } from '../../../types'; import type { AssetReference, Installation, InstallType } from '../../../types'; import { installTemplates } from '../elasticsearch/template/install'; import { installPipelines, deletePreviousPipelines } from '../elasticsearch/ingest_pipeline/'; +import { getAllTemplateRefs } from '../elasticsearch/template/install'; import { installILMPolicy } from '../elasticsearch/ilm/install'; import { installKibanaAssets, getKibanaAssets } from '../kibana/assets/install'; import { updateCurrentWriteIndices } from '../elasticsearch/template/template'; @@ -170,10 +170,7 @@ export async function _installPackage({ installedPkg.attributes.install_version ); } - const installedTemplateRefs = installedTemplates.map((template) => ({ - id: template.templateName, - type: ElasticsearchAssetType.indexTemplate, - })); + const installedTemplateRefs = getAllTemplateRefs(installedTemplates); // make sure the assets are installed (or didn't error) if (installKibanaAssetsError) throw installKibanaAssetsError; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index c6fd9a8f763ab4..e00526cbb4ec46 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -257,8 +257,7 @@ async function installPackageFromRegistry({ const { paths, packageInfo } = await Registry.getRegistryPackage(pkgName, pkgVersion); // try installing the package, if there was an error, call error handler and rethrow - // TODO: without the ts-ignore, TS complains about the type of the value of the returned InstallResult.status - // @ts-ignore + // @ts-expect-error status is string instead of InstallResult.status 'installed' | 'already_installed' return _installPackage({ savedObjectsClient, esClient, @@ -334,8 +333,7 @@ async function installPackageByUpload({ version: packageInfo.version, packageInfo, }); - // TODO: without the ts-ignore, TS complains about the type of the value of the returned InstallResult.status - // @ts-ignore + // @ts-expect-error status is string instead of InstallResult.status 'installed' | 'already_installed' return _installPackage({ savedObjectsClient, esClient, @@ -484,17 +482,17 @@ export const saveInstalledEsRefs = async ( return installedAssets; }; -export const removeAssetsFromInstalledEsByType = async ( +export const removeAssetTypesFromInstalledEs = async ( savedObjectsClient: SavedObjectsClientContract, pkgName: string, - assetType: AssetType + assetTypes: AssetType[] ) => { const installedPkg = await getInstallationObject({ savedObjectsClient, pkgName }); const installedAssets = installedPkg?.attributes.installed_es; if (!installedAssets?.length) return; - const installedAssetsToSave = installedAssets?.filter(({ id, type }) => { - return type !== assetType; - }); + const installedAssetsToSave = installedAssets?.filter( + (asset) => !assetTypes.includes(asset.type) + ); return savedObjectsClient.update(PACKAGES_SAVED_OBJECT_TYPE, pkgName, { installed_es: installedAssetsToSave, diff --git a/x-pack/plugins/fleet/server/services/epm/packages/remove.ts b/x-pack/plugins/fleet/server/services/epm/packages/remove.ts index 706f1bbbaaf35b..70167d1156a667 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/remove.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/remove.ts @@ -89,13 +89,18 @@ function deleteKibanaAssets( }); } -function deleteESAssets(installedObjects: EsAssetReference[], esClient: ElasticsearchClient) { +function deleteESAssets( + installedObjects: EsAssetReference[], + esClient: ElasticsearchClient +): Array> { return installedObjects.map(async ({ id, type }) => { const assetType = type as AssetType; if (assetType === ElasticsearchAssetType.ingestPipeline) { return deletePipeline(esClient, id); } else if (assetType === ElasticsearchAssetType.indexTemplate) { - return deleteTemplate(esClient, id); + return deleteIndexTemplate(esClient, id); + } else if (assetType === ElasticsearchAssetType.componentTemplate) { + return deleteComponentTemplate(esClient, id); } else if (assetType === ElasticsearchAssetType.transform) { return deleteTransforms(esClient, [id]); } else if (assetType === ElasticsearchAssetType.dataStreamIlmPolicy) { @@ -111,13 +116,30 @@ async function deleteAssets( ) { const logger = appContextService.getLogger(); - const deletePromises: Array> = [ - ...deleteESAssets(installedEs, esClient), - ...deleteKibanaAssets(installedKibana, savedObjectsClient), - ]; + // must delete index templates first, or component templates which reference them cannot be deleted + // separate the assets into Index Templates and other assets + type Tuple = [EsAssetReference[], EsAssetReference[]]; + const [indexTemplates, otherAssets] = installedEs.reduce( + ([indexAssetTypes, otherAssetTypes], asset) => { + if (asset.type === ElasticsearchAssetType.indexTemplate) { + indexAssetTypes.push(asset); + } else { + otherAssetTypes.push(asset); + } + + return [indexAssetTypes, otherAssetTypes]; + }, + [[], []] + ); try { - await Promise.all(deletePromises); + // must delete index templates first + await Promise.all(deleteESAssets(indexTemplates, esClient)); + // then the other asset types + await Promise.all([ + ...deleteESAssets(otherAssets, esClient), + ...deleteKibanaAssets(installedKibana, savedObjectsClient), + ]); } catch (err) { // in the rollback case, partial installs are likely, so missing assets are not an error if (!savedObjectsClient.errors.isNotFoundError(err)) { @@ -126,13 +148,24 @@ async function deleteAssets( } } -async function deleteTemplate(esClient: ElasticsearchClient, name: string): Promise { +async function deleteIndexTemplate(esClient: ElasticsearchClient, name: string): Promise { // '*' shouldn't ever appear here, but it still would delete all templates if (name && name !== '*') { try { await esClient.indices.deleteIndexTemplate({ name }, { ignore: [404] }); } catch { - throw new Error(`error deleting template ${name}`); + throw new Error(`error deleting index template ${name}`); + } + } +} + +async function deleteComponentTemplate(esClient: ElasticsearchClient, name: string): Promise { + // '*' shouldn't ever appear here, but it still would delete all templates + if (name && name !== '*') { + try { + await esClient.cluster.deleteComponentTemplate({ name }, { ignore: [404] }); + } catch (error) { + throw new Error(`error deleting component template ${name}`); } } } diff --git a/x-pack/plugins/fleet/server/services/output.ts b/x-pack/plugins/fleet/server/services/output.ts index 0c7b086f78fdf8..8c6bc7eca04010 100644 --- a/x-pack/plugins/fleet/server/services/output.ts +++ b/x-pack/plugins/fleet/server/services/output.ts @@ -9,10 +9,9 @@ import type { SavedObjectsClientContract } from 'src/core/server'; import type { NewOutput, Output, OutputSOAttributes } from '../types'; import { DEFAULT_OUTPUT, OUTPUT_SAVED_OBJECT_TYPE } from '../constants'; -import { decodeCloudId } from '../../common'; +import { decodeCloudId, normalizeHostsForAgents } from '../../common'; import { appContextService } from './app_context'; -import { normalizeHostsForAgents } from './hosts_utils'; const SAVED_OBJECT_TYPE = OUTPUT_SAVED_OBJECT_TYPE; diff --git a/x-pack/plugins/fleet/server/services/settings.ts b/x-pack/plugins/fleet/server/services/settings.ts index 226fbb29467c2f..26d581f32d9a23 100644 --- a/x-pack/plugins/fleet/server/services/settings.ts +++ b/x-pack/plugins/fleet/server/services/settings.ts @@ -8,11 +8,14 @@ import Boom from '@hapi/boom'; import type { SavedObjectsClientContract } from 'kibana/server'; -import { decodeCloudId, GLOBAL_SETTINGS_SAVED_OBJECT_TYPE } from '../../common'; +import { + decodeCloudId, + GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, + normalizeHostsForAgents, +} from '../../common'; import type { SettingsSOAttributes, Settings, BaseSettings } from '../../common'; import { appContextService } from './app_context'; -import { normalizeHostsForAgents } from './hosts_utils'; export async function getSettings(soClient: SavedObjectsClientContract): Promise { const res = await soClient.find({ diff --git a/x-pack/plugins/fleet/server/types/index.tsx b/x-pack/plugins/fleet/server/types/index.tsx index 8927676976457a..0c08a09e76f4ea 100644 --- a/x-pack/plugins/fleet/server/types/index.tsx +++ b/x-pack/plugins/fleet/server/types/index.tsx @@ -63,7 +63,7 @@ export { IndexTemplate, RegistrySearchResults, RegistrySearchResult, - TemplateRef, + IndexTemplateEntry, IndexTemplateMappings, Settings, SettingsSOAttributes, diff --git a/x-pack/plugins/index_management/__jest__/components/index_table.test.js b/x-pack/plugins/index_management/__jest__/components/index_table.test.js index 4ac94319d47119..463d0b30cad08d 100644 --- a/x-pack/plugins/index_management/__jest__/components/index_table.test.js +++ b/x-pack/plugins/index_management/__jest__/components/index_table.test.js @@ -6,9 +6,12 @@ */ import React from 'react'; +import { Provider } from 'react-redux'; +import { MemoryRouter } from 'react-router-dom'; import axios from 'axios'; +import sinon from 'sinon'; +import { findTestSubject } from '@elastic/eui/lib/test'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; -import { MemoryRouter } from 'react-router-dom'; /** * The below import is required to avoid a console error warn from brace package @@ -18,9 +21,9 @@ import { MemoryRouter } from 'react-router-dom'; */ import { mountWithIntl, stubWebWorker } from '@kbn/test/jest'; // eslint-disable-line no-unused-vars +import { BASE_PATH, API_BASE_PATH } from '../../common/constants'; import { AppWithoutRouter } from '../../public/application/app'; import { AppContextProvider } from '../../public/application/app_context'; -import { Provider } from 'react-redux'; import { loadIndicesSuccess } from '../../public/application/store/actions'; import { breadcrumbService } from '../../public/application/services/breadcrumbs'; import { UiMetricService } from '../../public/application/services/ui_metric'; @@ -29,10 +32,7 @@ import { httpService } from '../../public/application/services/http'; import { setUiMetricService } from '../../public/application/services/api'; import { indexManagementStore } from '../../public/application/store'; import { setExtensionsService } from '../../public/application/store/selectors/extension_service'; -import { BASE_PATH, API_BASE_PATH } from '../../common/constants'; import { ExtensionsService } from '../../public/services'; -import sinon from 'sinon'; -import { findTestSubject } from '@elastic/eui/lib/test'; /* eslint-disable @kbn/eslint/no-restricted-paths */ import { notificationServiceMock } from '../../../../../src/core/public/notifications/notifications_service.mock'; @@ -40,9 +40,9 @@ import { notificationServiceMock } from '../../../../../src/core/public/notifica const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); let server = null; - let store = null; const indices = []; + for (let i = 0; i < 105; i++) { const baseFake = { health: i % 2 === 0 ? 'green' : 'yellow', @@ -63,8 +63,12 @@ for (let i = 0; i < 105; i++) { name: `.admin${i}`, }); } + let component = null; +// Resolve outstanding API requests. See https://www.benmvp.com/blog/asynchronous-testing-with-enzyme-react-jest/ +const runAllPromises = () => new Promise(setImmediate); + const status = (rendered, row = 0) => { rendered.update(); return findTestSubject(rendered, 'indexTableCell-status') @@ -76,39 +80,54 @@ const status = (rendered, row = 0) => { const snapshot = (rendered) => { expect(rendered).toMatchSnapshot(); }; + const openMenuAndClickButton = (rendered, rowIndex, buttonIndex) => { + // Select a row. const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); checkboxes.at(rowIndex).simulate('change', { target: { checked: true } }); rendered.update(); + + // Click the bulk actions button to open the context menu. const actionButton = findTestSubject(rendered, 'indexActionsContextMenuButton'); actionButton.simulate('click'); rendered.update(); + + // Click an action in the context menu. const contextMenuButtons = findTestSubject(rendered, 'indexTableContextMenuButton'); contextMenuButtons.at(buttonIndex).simulate('click'); + rendered.update(); }; -const testEditor = (buttonIndex, rowIndex = 0) => { - const rendered = mountWithIntl(component); + +const testEditor = (rendered, buttonIndex, rowIndex = 0) => { openMenuAndClickButton(rendered, rowIndex, buttonIndex); rendered.update(); snapshot(findTestSubject(rendered, 'detailPanelTabSelected').text()); }; -const testAction = (buttonIndex, done, rowIndex = 0) => { - const rendered = mountWithIntl(component); - let count = 0; + +const testAction = (rendered, buttonIndex, rowIndex = 0) => { + // This is leaking some implementation details about how Redux works. Not sure exactly what's going on + // but it looks like we're aware of how many Redux actions are dispatched in response to user interaction, + // so we "time" our assertion based on how many Redux actions we observe. This is brittle because it + // depends upon how our UI is architected, which will affect how many actions are dispatched. + // Expect this to break when we rearchitect the UI. + let dispatchedActionsCount = 0; store.subscribe(() => { - if (count > 1) { + if (dispatchedActionsCount === 1) { + // Take snapshot of final state. snapshot(status(rendered, rowIndex)); - done(); } - count++; + dispatchedActionsCount++; }); - expect.assertions(2); + openMenuAndClickButton(rendered, rowIndex, buttonIndex); + // take snapshot of initial state. snapshot(status(rendered, rowIndex)); }; + const names = (rendered) => { return findTestSubject(rendered, 'indexTableIndexNameLink'); }; + const namesText = (rendered) => { return names(rendered).map((button) => button.text()); }; @@ -142,23 +161,28 @@ describe('index table', () => { ); + store.dispatch(loadIndicesSuccess({ indices })); server = sinon.fakeServer.create(); + server.respondWith(`${API_BASE_PATH}/indices`, [ 200, { 'Content-Type': 'application/json' }, JSON.stringify(indices), ]); + server.respondWith([ 200, { 'Content-Type': 'application/json' }, JSON.stringify({ acknowledged: true }), ]); + server.respondWith(`${API_BASE_PATH}/indices/reload`, [ 200, { 'Content-Type': 'application/json' }, JSON.stringify(indices), ]); + server.respondImmediately = true; }); afterEach(() => { @@ -168,83 +192,124 @@ describe('index table', () => { server.restore(); }); - test('should change pages when a pagination link is clicked on', () => { + test('should change pages when a pagination link is clicked on', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + snapshot(namesText(rendered)); + const pagingButtons = rendered.find('.euiPaginationButton'); pagingButtons.at(2).simulate('click'); - rendered.update(); snapshot(namesText(rendered)); }); - test('should show more when per page value is increased', () => { + + test('should show more when per page value is increased', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const perPageButton = rendered.find('EuiTablePagination EuiPopover').find('button'); perPageButton.simulate('click'); rendered.update(); + const fiftyButton = rendered.find('.euiContextMenuItem').at(1); fiftyButton.simulate('click'); rendered.update(); expect(namesText(rendered).length).toBe(50); }); - test('should show the Actions menu button only when at least one row is selected', () => { + + test('should show the Actions menu button only when at least one row is selected', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + let button = findTestSubject(rendered, 'indexTableContextMenuButton'); expect(button.length).toEqual(0); + const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); checkboxes.at(0).simulate('change', { target: { checked: true } }); rendered.update(); button = findTestSubject(rendered, 'indexActionsContextMenuButton'); expect(button.length).toEqual(1); }); - test('should update the Actions menu button text when more than one row is selected', () => { + + test('should update the Actions menu button text when more than one row is selected', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + let button = findTestSubject(rendered, 'indexTableContextMenuButton'); expect(button.length).toEqual(0); + const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); checkboxes.at(0).simulate('change', { target: { checked: true } }); rendered.update(); button = findTestSubject(rendered, 'indexActionsContextMenuButton'); expect(button.text()).toEqual('Manage index'); + checkboxes.at(1).simulate('change', { target: { checked: true } }); rendered.update(); button = findTestSubject(rendered, 'indexActionsContextMenuButton'); expect(button.text()).toEqual('Manage 2 indices'); }); - test('should show system indices only when the switch is turned on', () => { + + test('should show system indices only when the switch is turned on', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + snapshot(rendered.find('.euiPagination li').map((item) => item.text())); const switchControl = rendered.find('.euiSwitch__button'); switchControl.simulate('click'); snapshot(rendered.find('.euiPagination li').map((item) => item.text())); }); - test('should filter based on content of search input', () => { + + test('should filter based on content of search input', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const searchInput = rendered.find('.euiFieldSearch').first(); searchInput.instance().value = 'testy0'; searchInput.simulate('keyup', { key: 'Enter', keyCode: 13, which: 13 }); rendered.update(); snapshot(namesText(rendered)); }); - test('should sort when header is clicked', () => { + + test('should sort when header is clicked', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const nameHeader = findTestSubject(rendered, 'indexTableHeaderCell-name').find('button'); nameHeader.simulate('click'); rendered.update(); snapshot(namesText(rendered)); + nameHeader.simulate('click'); rendered.update(); snapshot(namesText(rendered)); }); - test('should open the index detail slideout when the index name is clicked', () => { + + test('should open the index detail slideout when the index name is clicked', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + expect(findTestSubject(rendered, 'indexDetailFlyout').length).toBe(0); + const indexNameLink = names(rendered).at(0); indexNameLink.simulate('click'); rendered.update(); expect(findTestSubject(rendered, 'indexDetailFlyout').length).toBe(1); }); - test('should show the right context menu options when one index is selected and open', () => { + + test('should show the right context menu options when one index is selected and open', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); checkboxes.at(0).simulate('change', { target: { checked: true } }); rendered.update(); @@ -253,8 +318,12 @@ describe('index table', () => { rendered.update(); snapshot(findTestSubject(rendered, 'indexTableContextMenuButton').map((span) => span.text())); }); - test('should show the right context menu options when one index is selected and closed', () => { + + test('should show the right context menu options when one index is selected and closed', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); checkboxes.at(1).simulate('change', { target: { checked: true } }); rendered.update(); @@ -263,8 +332,12 @@ describe('index table', () => { rendered.update(); snapshot(findTestSubject(rendered, 'indexTableContextMenuButton').map((span) => span.text())); }); - test('should show the right context menu options when one open and one closed index is selected', () => { + + test('should show the right context menu options when one open and one closed index is selected', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); checkboxes.at(0).simulate('change', { target: { checked: true } }); checkboxes.at(1).simulate('change', { target: { checked: true } }); @@ -274,8 +347,12 @@ describe('index table', () => { rendered.update(); snapshot(findTestSubject(rendered, 'indexTableContextMenuButton').map((span) => span.text())); }); - test('should show the right context menu options when more than one open index is selected', () => { + + test('should show the right context menu options when more than one open index is selected', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); checkboxes.at(0).simulate('change', { target: { checked: true } }); checkboxes.at(2).simulate('change', { target: { checked: true } }); @@ -285,8 +362,12 @@ describe('index table', () => { rendered.update(); snapshot(findTestSubject(rendered, 'indexTableContextMenuButton').map((span) => span.text())); }); - test('should show the right context menu options when more than one closed index is selected', () => { + + test('should show the right context menu options when more than one closed index is selected', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const checkboxes = findTestSubject(rendered, 'indexTableRowCheckbox'); checkboxes.at(1).simulate('change', { target: { checked: true } }); checkboxes.at(3).simulate('change', { target: { checked: true } }); @@ -296,37 +377,57 @@ describe('index table', () => { rendered.update(); snapshot(findTestSubject(rendered, 'indexTableContextMenuButton').map((span) => span.text())); }); - test('flush button works from context menu', (done) => { - testAction(8, done); + + test('flush button works from context menu', async () => { + const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + testAction(rendered, 8); }); - test('clear cache button works from context menu', (done) => { - testAction(7, done); + + test('clear cache button works from context menu', async () => { + const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + testAction(rendered, 7); }); - test('refresh button works from context menu', (done) => { - testAction(6, done); + + test('refresh button works from context menu', async () => { + const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + testAction(rendered, 6); }); - test('force merge button works from context menu', (done) => { + + test('force merge button works from context menu', async () => { const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const rowIndex = 0; openMenuAndClickButton(rendered, rowIndex, 5); snapshot(status(rendered, rowIndex)); expect(rendered.find('.euiModal').length).toBe(1); + let count = 0; store.subscribe(() => { - if (count > 1) { + if (count === 1) { snapshot(status(rendered, rowIndex)); expect(rendered.find('.euiModal').length).toBe(0); - done(); } count++; }); + const confirmButton = findTestSubject(rendered, 'confirmModalConfirmButton'); confirmButton.simulate('click'); snapshot(status(rendered, rowIndex)); }); - // Commenting the following 2 tests as it works in the browser (status changes to "closed" or "open") but the - // snapshot say the contrary. Need to be investigated. - test('close index button works from context menu', (done) => { + + test('close index button works from context menu', async () => { + const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const modifiedIndices = indices.map((index) => { return { ...index, @@ -339,32 +440,56 @@ describe('index table', () => { { 'Content-Type': 'application/json' }, JSON.stringify(modifiedIndices), ]); - testAction(4, done); + + testAction(rendered, 4); }); - test('open index button works from context menu', (done) => { + + test('open index button works from context menu', async () => { + const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + const modifiedIndices = indices.map((index) => { return { ...index, status: index.name === 'testy1' ? 'open' : index.status, }; }); + server.respondWith(`${API_BASE_PATH}/indices/reload`, [ 200, { 'Content-Type': 'application/json' }, JSON.stringify(modifiedIndices), ]); - testAction(3, done, 1); + + testAction(rendered, 3, 1); }); - test('show settings button works from context menu', () => { - testEditor(0); + + test('show settings button works from context menu', async () => { + const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + testEditor(rendered, 0); }); - test('show mappings button works from context menu', () => { - testEditor(1); + + test('show mappings button works from context menu', async () => { + const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + testEditor(rendered, 1); }); - test('show stats button works from context menu', () => { - testEditor(2); + + test('show stats button works from context menu', async () => { + const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + testEditor(rendered, 2); }); - test('edit index button works from context menu', () => { - testEditor(3); + + test('edit index button works from context menu', async () => { + const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + testEditor(rendered, 3); }); }); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts index 8c8f7e57899254..dee15f2ae3a45d 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_list.test.ts @@ -165,8 +165,10 @@ describe('', () => { const { exists, find } = testBed; expect(exists('componentTemplatesLoadError')).toBe(true); + // The text here looks weird because the child elements' text values (title and description) + // are concatenated when we retrive the error element's text value. expect(find('componentTemplatesLoadError').text()).toContain( - 'Unable to load component templates. Try again.' + 'Error loading component templatesInternal server error' ); }); }); 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 2bb240e6b6ae18..77668f7d550720 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 @@ -13,8 +13,13 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { ScopedHistory } from 'kibana/public'; import { EuiLink, EuiText, EuiSpacer } from '@elastic/eui'; -import { attemptToURIDecode } from '../../../../shared_imports'; -import { SectionLoading, ComponentTemplateDeserialized, GlobalFlyout } from '../shared_imports'; +import { + APP_WRAPPER_CLASS, + PageLoading, + PageError, + attemptToURIDecode, +} from '../../../../shared_imports'; +import { ComponentTemplateDeserialized, GlobalFlyout } from '../shared_imports'; import { UIM_COMPONENT_TEMPLATE_LIST_LOAD } from '../constants'; import { useComponentTemplatesContext } from '../component_templates_context'; import { @@ -24,7 +29,6 @@ import { } from '../component_template_details'; import { EmptyPrompt } from './empty_prompt'; import { ComponentTable } from './table'; -import { LoadError } from './error'; import { ComponentTemplatesDeleteModal } from './delete_modal'; interface Props { @@ -138,18 +142,20 @@ export const ComponentTemplateList: React.FunctionComponent = ({ } }, [componentTemplateName, removeContentFromGlobalFlyout]); - let content: React.ReactNode; - if (isLoading) { - content = ( - + return ( + - + ); - } else if (data?.length) { + } + + let content: React.ReactNode; + + if (data?.length) { content = ( <> @@ -183,11 +189,22 @@ export const ComponentTemplateList: React.FunctionComponent = ({ } else if (data && data.length === 0) { content = ; } else if (error) { - content = ; + content = ( + + } + error={error} + data-test-subj="componentTemplatesLoadError" + /> + ); } return ( -
+
{content} {/* delete modal */} diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/error.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/error.tsx deleted file mode 100644 index 9fd0031fe87786..00000000000000 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/error.tsx +++ /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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { FunctionComponent } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiLink, EuiCallOut } from '@elastic/eui'; - -export interface Props { - onReloadClick: () => void; -} - -export const LoadError: FunctionComponent = ({ onReloadClick }) => { - return ( - - - - ), - }} - /> - } - /> - ); -}; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx index a0f6dc4b59fe7f..eecb56768df9a5 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/with_privileges.tsx @@ -9,10 +9,10 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React, { FunctionComponent } from 'react'; import { - SectionError, + PageLoading, + PageError, useAuthorizationContext, WithPrivileges, - SectionLoading, NotAuthorizedSection, } from '../shared_imports'; import { APP_CLUSTER_REQUIRED_PRIVILEGES } from '../constants'; @@ -26,7 +26,7 @@ export const ComponentTemplatesWithPrivileges: FunctionComponent = ({ if (apiError) { return ( - { if (isLoading) { return ( - + - + ); } diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx index b87b043c924a60..d19c500c3622ae 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx @@ -10,7 +10,7 @@ import { RouteComponentProps } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { SectionLoading, attemptToURIDecode } from '../../shared_imports'; +import { PageLoading, attemptToURIDecode } from '../../shared_imports'; import { useComponentTemplatesContext } from '../../component_templates_context'; import { ComponentTemplateCreate } from '../component_template_create'; @@ -30,7 +30,8 @@ export const ComponentTemplateClone: FunctionComponent { if (error && !isLoading) { - toasts.addError(error, { + // Toasts expects a generic Error object, which is typed as having a required name property. + toasts.addError({ ...error, name: '' } as Error, { title: i18n.translate('xpack.idxMgmt.componentTemplateClone.loadComponentTemplateTitle', { defaultMessage: `Error loading component template '{sourceComponentTemplateName}'.`, values: { sourceComponentTemplateName }, @@ -42,12 +43,12 @@ export const ComponentTemplateClone: FunctionComponent + - + ); } else { // We still show the create form (unpopulated) even if we were not able to load the diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_create/component_template_create.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_create/component_template_create.tsx index 5163c75bdbadda..8fe2c193daa0c1 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_create/component_template_create.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_create/component_template_create.tsx @@ -8,7 +8,7 @@ import React, { useState, useEffect } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiPageBody, EuiPageContent, EuiSpacer, EuiTitle } from '@elastic/eui'; +import { EuiPageContentBody, EuiSpacer, EuiPageHeader } from '@elastic/eui'; import { ComponentTemplateDeserialized } from '../../shared_imports'; import { useComponentTemplatesContext } from '../../component_templates_context'; @@ -59,27 +59,28 @@ export const ComponentTemplateCreate: React.FunctionComponent - - -

+ + -

-
- - - - -
- + + } + bottomBorder + /> + + + + + ); }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx index 809fac980069f4..6ac831b5daccea 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx @@ -8,13 +8,15 @@ import React, { useState, useEffect } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiPageBody, EuiPageContent, EuiTitle, EuiSpacer, EuiCallOut } from '@elastic/eui'; +import { EuiPageContentBody, EuiPageHeader, EuiSpacer } from '@elastic/eui'; import { useComponentTemplatesContext } from '../../component_templates_context'; import { ComponentTemplateDeserialized, - SectionLoading, + PageLoading, + PageError, attemptToURIDecode, + Error, } from '../../shared_imports'; import { ComponentTemplateForm } from '../component_template_form'; @@ -65,64 +67,57 @@ export const ComponentTemplateEdit: React.FunctionComponent + return ( + - - ); - } else if (error) { - content = ( - <> - - } - color="danger" - iconType="alert" - data-test-subj="loadComponentTemplateError" - > -
{error.message}
-
- - +
); - } else if (componentTemplate) { - content = ( - + } + error={error as Error} + data-test-subj="loadComponentTemplateError" /> ); } return ( - - - -

+ + -

-
- - {content} -
-
+ + } + bottomBorder + /> + + + + + ); }; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts b/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts index 75c68e71996b85..6bf6d204fd9a51 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/lib/api.ts @@ -10,7 +10,6 @@ import { ComponentTemplateListItem, ComponentTemplateDeserialized, ComponentTemplateSerialized, - Error, } from '../shared_imports'; import { UIM_COMPONENT_TEMPLATE_DELETE_MANY, @@ -26,7 +25,7 @@ export const getApi = ( trackMetric: (type: UiCounterMetricType, eventName: string) => void ) => { function useLoadComponentTemplates() { - return useRequest({ + return useRequest({ path: `${apiBasePath}/component_templates`, method: 'get', }); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/lib/request.ts b/x-pack/plugins/index_management/public/application/components/component_templates/lib/request.ts index 64b2e6b47e5d95..a7056e27b5cad4 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/lib/request.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/lib/request.ts @@ -14,6 +14,7 @@ import { SendRequestResponse, sendRequest as _sendRequest, useRequest as _useRequest, + Error, } from '../shared_imports'; export type UseRequestHook = ( diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/shared_imports.ts b/x-pack/plugins/index_management/public/application/components/component_templates/shared_imports.ts index afc7aed874387e..15528f5b4e8e5b 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/shared_imports.ts +++ b/x-pack/plugins/index_management/public/application/components/component_templates/shared_imports.ts @@ -12,10 +12,12 @@ export { SendRequestResponse, sendRequest, useRequest, - SectionLoading, WithPrivileges, AuthorizationProvider, SectionError, + SectionLoading, + PageLoading, + PageError, Error, useAuthorizationContext, NotAuthorizedSection, diff --git a/x-pack/plugins/index_management/public/application/components/index.ts b/x-pack/plugins/index_management/public/application/components/index.ts index f5c58e5b45ebd2..eeba6e16b543c5 100644 --- a/x-pack/plugins/index_management/public/application/components/index.ts +++ b/x-pack/plugins/index_management/public/application/components/index.ts @@ -6,9 +6,7 @@ */ export { SectionError, Error } from './section_error'; -export { SectionLoading } from './section_loading'; export { NoMatch } from './no_match'; -export { PageErrorForbidden } from './page_error'; export { TemplateDeleteModal } from './template_delete_modal'; export { TemplateForm } from './template_form'; export { DataHealth } from './data_health'; diff --git a/x-pack/plugins/index_management/public/application/components/page_error/page_error_forbidden.tsx b/x-pack/plugins/index_management/public/application/components/page_error/page_error_forbidden.tsx deleted file mode 100644 index e22b180881ed59..00000000000000 --- a/x-pack/plugins/index_management/public/application/components/page_error/page_error_forbidden.tsx +++ /dev/null @@ -1,30 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { EuiEmptyPrompt, EuiPageContent } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; - -export function PageErrorForbidden() { - return ( - - - - - } - /> - - ); -} diff --git a/x-pack/plugins/index_management/public/application/components/section_loading.tsx b/x-pack/plugins/index_management/public/application/components/section_loading.tsx deleted file mode 100644 index 3c31744dee398c..00000000000000 --- a/x-pack/plugins/index_management/public/application/components/section_loading.tsx +++ /dev/null @@ -1,24 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -import { EuiEmptyPrompt, EuiLoadingSpinner, EuiText } from '@elastic/eui'; - -interface Props { - children: React.ReactNode; -} - -export const SectionLoading: React.FunctionComponent = ({ children }) => { - return ( - } - body={{children}} - data-test-subj="sectionLoading" - /> - ); -}; diff --git a/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx b/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx index 54160141827d0a..4ccd77d275a94d 100644 --- a/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx @@ -8,7 +8,7 @@ import React, { useState, useCallback, useRef } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiSpacer, EuiButton } from '@elastic/eui'; +import { EuiSpacer, EuiButton, EuiPageHeader } from '@elastic/eui'; import { ScopedHistory } from 'kibana/public'; import { TemplateDeserialized } from '../../../../common'; @@ -292,7 +292,7 @@ export const TemplateForm = ({ return ( <> {/* Form header */} - {title} + {title}} bottomBorder /> diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx index a9258c6a3b10be..3d5f56c08f8e18 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx @@ -24,8 +24,8 @@ import { EuiTitle, } from '@elastic/eui'; -import { reactRouterNavigate } from '../../../../../shared_imports'; -import { SectionLoading, SectionError, Error, DataHealth } from '../../../../components'; +import { SectionLoading, reactRouterNavigate } from '../../../../../shared_imports'; +import { SectionError, Error, DataHealth } from '../../../../components'; import { useLoadDataStream } from '../../../../services/api'; import { DeleteDataStreamConfirmationModal } from '../delete_data_stream_confirmation_modal'; import { humanizeTimeStamp } from '../humanize_time_stamp'; 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 131dc2662bc1c7..7bd7c163837d8e 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 @@ -16,18 +16,22 @@ import { EuiText, EuiIconTip, EuiSpacer, + EuiPageContent, EuiEmptyPrompt, EuiLink, } from '@elastic/eui'; import { ScopedHistory } from 'kibana/public'; import { + PageLoading, + PageError, + Error, reactRouterNavigate, extractQueryParams, attemptToURIDecode, + APP_WRAPPER_CLASS, } from '../../../../shared_imports'; import { useAppContext } from '../../../app_context'; -import { SectionError, SectionLoading, Error } from '../../../components'; import { useLoadDataStreams } from '../../../services/api'; import { documentationService } from '../../../services/documentation'; import { Section } from '../home'; @@ -166,16 +170,16 @@ export const DataStreamList: React.FunctionComponent + - + ); } else if (error) { content = ( - ); - } else if (Array.isArray(dataStreams) && dataStreams.length > 0) { - activateHiddenFilter(isSelectedDataStreamHidden(dataStreams, decodedDataStreamName)); + } else { + activateHiddenFilter(isSelectedDataStreamHidden(dataStreams!, decodedDataStreamName)); content = ( - <> + {renderHeader()} @@ -270,12 +274,12 @@ export const DataStreamList: React.FunctionComponent - + ); } return ( -
+
{content} {/* diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.tsx b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.tsx index ac46b5dbd256be..fc68ca33e95361 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.tsx @@ -8,12 +8,13 @@ import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; +import { APP_WRAPPER_CLASS } from '../../../../shared_imports'; import { DetailPanel } from './detail_panel'; import { IndexTable } from './index_table'; export const IndexList: React.FunctionComponent = ({ history }) => { return ( -
+
diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js index f488290692e7ef..0a407927e34666 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js @@ -19,7 +19,7 @@ import { EuiCheckbox, EuiFlexGroup, EuiFlexItem, - EuiLoadingSpinner, + EuiPageContent, EuiScreenReaderOnly, EuiSpacer, EuiSearchBar, @@ -37,13 +37,18 @@ import { } from '@elastic/eui'; import { UIM_SHOW_DETAILS_CLICK } from '../../../../../../common/constants'; -import { reactRouterNavigate, attemptToURIDecode } from '../../../../../shared_imports'; +import { + PageLoading, + PageError, + reactRouterNavigate, + attemptToURIDecode, +} from '../../../../../shared_imports'; import { REFRESH_RATE_INDEX_LIST } from '../../../../constants'; import { getDataStreamDetailsLink } from '../../../../services/routing'; import { documentationService } from '../../../../services/documentation'; import { AppContextConsumer } from '../../../../app_context'; import { renderBadges } from '../../../../lib/render_badges'; -import { NoMatch, PageErrorForbidden, DataHealth } from '../../../../components'; +import { NoMatch, DataHealth } from '../../../../components'; import { IndexActionsContextMenu } from '../index_actions_context_menu'; const HEADERS = { @@ -332,42 +337,6 @@ export class IndexTable extends Component { }); } - renderError() { - const { indicesError } = this.props; - - const data = indicesError.body ? indicesError.body : indicesError; - - const { error: errorString, cause, message } = data; - - return ( - - - } - color="danger" - iconType="alert" - > -
{message || errorString}
- {cause && ( - - -
    - {cause.map((message, i) => ( -
  • {message}
  • - ))} -
-
- )} -
- -
- ); - } - renderBanners(extensionsService) { const { allIndices = [], filterChanged } = this.props; return extensionsService.banners.map((bannerExtension, i) => { @@ -470,37 +439,71 @@ export class IndexTable extends Component { } = this.props; const { includeHiddenIndices } = this.readURLParams(); + const hasContent = !indicesLoading && !indicesError; - let emptyState; + if (!hasContent) { + const renderNoContent = () => { + if (indicesLoading) { + return ( + + + + ); + } + + if (indicesError) { + if (indicesError.status === 403) { + return ( + + } + /> + ); + } - if (indicesLoading) { - emptyState = ( - - - - - - ); - } + return ( + + } + error={indicesError.body} + /> + ); + } + }; - if (!indicesLoading && !indicesError) { - emptyState = ; + return ( + + {renderNoContent()} + + ); } const { selectedIndicesMap } = this.state; const atLeastOneItemSelected = Object.keys(selectedIndicesMap).length > 0; - if (indicesError && indicesError.status === 403) { - return ; - } - return ( {({ services }) => { const { extensionsService } = services; return ( - + @@ -557,8 +560,6 @@ export class IndexTable extends Component { {this.renderBanners(extensionsService)} - {indicesError && this.renderError()} - {atLeastOneItemSelected ? ( @@ -665,13 +666,13 @@ export class IndexTable extends Component {
) : ( - emptyState + )} {indices.length > 0 ? this.renderPager() : null} - + ); }} 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 e61362efb8c99a..1a82cb3bfbdd15 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 @@ -33,8 +33,8 @@ import { UIM_TEMPLATE_DETAIL_PANEL_ALIASES_TAB, UIM_TEMPLATE_DETAIL_PANEL_PREVIEW_TAB, } from '../../../../../../common/constants'; -import { UseRequestResponse } from '../../../../../shared_imports'; -import { TemplateDeleteModal, SectionLoading, SectionError, Error } from '../../../../components'; +import { SectionLoading, UseRequestResponse } from '../../../../../shared_imports'; +import { TemplateDeleteModal, SectionError, Error } from '../../../../components'; import { useLoadIndexTemplate } from '../../../../services/api'; import { useServices } from '../../../../app_context'; import { TabAliases, TabMappings, TabSettings } from '../../../../components/shared'; 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 b8b5a8e3c7d1a4..57f18134be5d69 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 @@ -5,7 +5,7 @@ * 2.0. */ -import React, { Fragment, useState, useEffect, useMemo } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; @@ -24,13 +24,14 @@ import { import { UIM_TEMPLATE_LIST_LOAD } from '../../../../../common/constants'; import { TemplateListItem } from '../../../../../common'; -import { attemptToURIDecode } from '../../../../shared_imports'; import { - SectionError, - SectionLoading, - Error, - LegacyIndexTemplatesDeprecation, -} from '../../../components'; + APP_WRAPPER_CLASS, + PageLoading, + PageError, + attemptToURIDecode, + reactRouterNavigate, +} from '../../../../shared_imports'; +import { LegacyIndexTemplatesDeprecation } from '../../../components'; import { useLoadIndexTemplates } from '../../../services/api'; import { documentationService } from '../../../services/documentation'; import { useServices } from '../../../app_context'; @@ -130,7 +131,8 @@ export const TemplateList: React.FunctionComponent ( - + // flex-grow: 0 is needed here because the parent element is a flex column and the header would otherwise expand. + ); - const renderContent = () => { - if (isLoading) { - return ( - + // Track this component mounted. + useEffect(() => { + uiMetricService.trackMetric(METRIC_TYPE.LOADED, UIM_TEMPLATE_LIST_LOAD); + }, [uiMetricService]); + + let content; + + if (isLoading) { + content = ( + + + + ); + } else if (error) { + content = ( + - - ); - } else if (error) { - return ( - + ); + } else if (!hasTemplates) { + content = ( + - } - error={error as Error} - /> - ); - } else if (!hasTemplates) { - return ( - + + } + body={ + <> +

- - } - data-test-subj="emptyPrompt" - /> - ); - } else { - return ( - - {/* Header */} - {renderHeader()} +

+ + } + actions={ + + + + } + data-test-subj="emptyPrompt" + /> + ); + } else { + content = ( + <> + {/* Header */} + {renderHeader()} - {/* Composable index templates table */} - {renderTemplatesTable()} + {/* Composable index templates table */} + {renderTemplatesTable()} - {/* Legacy index templates table. We discourage their adoption if the user isn't already using them. */} - {filteredTemplates.legacyTemplates.length > 0 && renderLegacyTemplatesTable()} - - ); - } - }; + {/* Legacy index templates table. We discourage their adoption if the user isn't already using them. */} + {filteredTemplates.legacyTemplates.length > 0 && renderLegacyTemplatesTable()} - // Track component loaded - useEffect(() => { - uiMetricService.trackMetric(METRIC_TYPE.LOADED, UIM_TEMPLATE_LIST_LOAD); - }, [uiMetricService]); + {isTemplateDetailsVisible && ( + + )} + + ); + } return ( -
- {renderContent()} - - {isTemplateDetailsVisible && ( - - )} +
+ {content}
); }; diff --git a/x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx b/x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx index 36bff298e345ba..32c84bc3b15f12 100644 --- a/x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx +++ b/x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx @@ -8,11 +8,12 @@ import React, { useEffect, useState } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiPageBody, EuiPageContent, EuiTitle } from '@elastic/eui'; +import { EuiPageContentBody } from '@elastic/eui'; import { ScopedHistory } from 'kibana/public'; +import { PageLoading, PageError, Error } from '../../../shared_imports'; import { TemplateDeserialized } from '../../../../common'; -import { TemplateForm, SectionLoading, SectionError, Error } from '../../components'; +import { TemplateForm } from '../../components'; import { breadcrumbService } from '../../services/breadcrumbs'; import { getTemplateDetailsLink } from '../../services/routing'; import { saveTemplate, useLoadIndexTemplate } from '../../services/api'; @@ -62,24 +63,22 @@ export const TemplateClone: React.FunctionComponent { breadcrumbService.setBreadcrumbs('templateClone'); }, []); if (isLoading) { - content = ( - + return ( + - + ); } else if (templateToCloneError) { - content = ( - ); - } else if (templateToClone) { - const templateData = { - ...templateToClone, - name: `${decodedTemplateName}-copy`, - } as TemplateDeserialized; + } + + const templateData = { + ...templateToClone, + name: `${decodedTemplateName}-copy`, + } as TemplateDeserialized; - content = ( + return ( + -

- -

- + } defaultValue={templateData} onSave={onSave} @@ -117,12 +114,6 @@ export const TemplateClone: React.FunctionComponent - ); - } - - return ( - - {content} - +
); }; diff --git a/x-pack/plugins/index_management/public/application/sections/template_create/template_create.tsx b/x-pack/plugins/index_management/public/application/sections/template_create/template_create.tsx index 310807aeef38fd..6eba112b11939a 100644 --- a/x-pack/plugins/index_management/public/application/sections/template_create/template_create.tsx +++ b/x-pack/plugins/index_management/public/application/sections/template_create/template_create.tsx @@ -8,7 +8,7 @@ import React, { useEffect, useState } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiPageBody, EuiPageContent, EuiTitle } from '@elastic/eui'; +import { EuiPageContentBody } from '@elastic/eui'; import { useLocation } from 'react-router-dom'; import { parse } from 'query-string'; import { ScopedHistory } from 'kibana/public'; @@ -52,34 +52,28 @@ export const TemplateCreate: React.FunctionComponent = ({ h }, []); return ( - - - -

- {isLegacy ? ( - - ) : ( - - )} -

- - } - onSave={onSave} - isSaving={isSaving} - saveError={saveError} - clearSaveError={clearSaveError} - isLegacy={isLegacy} - history={history as ScopedHistory} - /> -
-
+ + + ) : ( + + ) + } + onSave={onSave} + isSaving={isSaving} + saveError={saveError} + clearSaveError={clearSaveError} + isLegacy={isLegacy} + history={history as ScopedHistory} + /> + ); }; diff --git a/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx b/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx index f4ffe97931a240..ff6909d4666f80 100644 --- a/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx +++ b/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx @@ -7,16 +7,17 @@ import React, { useEffect, useState, Fragment } from 'react'; import { RouteComponentProps } from 'react-router-dom'; +import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiPageBody, EuiPageContent, EuiTitle, EuiSpacer, EuiCallOut } from '@elastic/eui'; +import { EuiPageContentBody, EuiSpacer, EuiCallOut } from '@elastic/eui'; import { ScopedHistory } from 'kibana/public'; import { TemplateDeserialized } from '../../../../common'; -import { attemptToURIDecode } from '../../../shared_imports'; +import { PageError, PageLoading, attemptToURIDecode, Error } from '../../../shared_imports'; import { breadcrumbService } from '../../services/breadcrumbs'; import { useLoadIndexTemplate, updateTemplate } from '../../services/api'; import { getTemplateDetailsLink } from '../../services/routing'; -import { SectionLoading, SectionError, TemplateForm, Error } from '../../components'; +import { TemplateForm } from '../../components'; import { getIsLegacyFromQueryParams } from '../../lib/index_templates'; interface MatchParams { @@ -62,27 +63,27 @@ export const TemplateEdit: React.FunctionComponent + return ( + - + ); } else if (error) { - content = ( - } - error={error as Error} + error={error} data-test-subj="sectionError" /> ); @@ -91,80 +92,75 @@ export const TemplateEdit: React.FunctionComponent } - color="danger" - iconType="alert" + error={ + { + message: i18n.translate( + 'xpack.idxMgmt.templateEdit.managedTemplateWarningDescription', + { + defaultMessage: 'Managed templates are critical for internal operations.', + } + ), + } as Error + } data-test-subj="systemTemplateEditCallout" - > - - + /> ); - } else { - content = ( + } + } + + return ( + + {isSystemTemplate && ( - {isSystemTemplate && ( - - - } - color="danger" - iconType="alert" - data-test-subj="systemTemplateEditCallout" - > - - - - - )} - -

- -

- + } - defaultValue={template} - onSave={onSave} - isSaving={isSaving} - saveError={saveError} - clearSaveError={clearSaveError} - isEditing={true} - isLegacy={isLegacy} - history={history as ScopedHistory} - /> + color="danger" + iconType="alert" + data-test-subj="systemTemplateEditCallout" + > + + +
- ); - } - } + )} - return ( - - {content} - + + } + defaultValue={template!} + onSave={onSave} + isSaving={isSaving} + saveError={saveError} + clearSaveError={clearSaveError} + isEditing={true} + isLegacy={isLegacy} + history={history as ScopedHistory} + /> +
); }; diff --git a/x-pack/plugins/index_management/public/application/services/use_request.ts b/x-pack/plugins/index_management/public/application/services/use_request.ts index f4d34264395621..3b1d5cf22452df 100644 --- a/x-pack/plugins/index_management/public/application/services/use_request.ts +++ b/x-pack/plugins/index_management/public/application/services/use_request.ts @@ -11,6 +11,7 @@ import { UseRequestConfig, sendRequest as _sendRequest, useRequest as _useRequest, + Error, } from '../../shared_imports'; import { httpService } from './http'; @@ -19,6 +20,6 @@ export const sendRequest = (config: SendRequestConfig): Promise(config: UseRequestConfig) => { - return _useRequest(httpService.httpClient, config); +export const useRequest = (config: UseRequestConfig) => { + return _useRequest(httpService.httpClient, config); }; diff --git a/x-pack/plugins/index_management/public/shared_imports.ts b/x-pack/plugins/index_management/public/shared_imports.ts index eddac8e4b8a86a..fa27b22e502fa5 100644 --- a/x-pack/plugins/index_management/public/shared_imports.ts +++ b/x-pack/plugins/index_management/public/shared_imports.ts @@ -5,6 +5,8 @@ * 2.0. */ +export { APP_WRAPPER_CLASS } from '../../../../src/core/public'; + export { SendRequestConfig, SendRequestResponse, @@ -16,6 +18,10 @@ export { extractQueryParams, GlobalFlyout, attemptToURIDecode, + PageLoading, + PageError, + Error, + SectionLoading, } from '../../../../src/plugins/es_ui_shared/public'; export { diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts index bd000186d91c40..231a2764d27106 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts @@ -17,28 +17,40 @@ import { getCloudManagedTemplatePrefix } from '../../../lib/get_managed_template import { RouteDependencies } from '../../../types'; import { addBasePath } from '../index'; -export function registerGetAllRoute({ router }: RouteDependencies) { +export function registerGetAllRoute({ router, lib: { isEsError } }: RouteDependencies) { router.get({ path: addBasePath('/index_templates'), validate: false }, async (ctx, req, res) => { const { callAsCurrentUser } = ctx.dataManagement!.client; - const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(callAsCurrentUser); - const legacyTemplatesEs = await callAsCurrentUser('indices.getTemplate'); - const { index_templates: templatesEs } = await callAsCurrentUser( - 'dataManagement.getComposableIndexTemplates' - ); - - const legacyTemplates = deserializeLegacyTemplateList( - legacyTemplatesEs, - cloudManagedTemplatePrefix - ); - const templates = deserializeTemplateList(templatesEs, cloudManagedTemplatePrefix); - - const body = { - templates, - legacyTemplates, - }; - - return res.ok({ body }); + try { + const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(callAsCurrentUser); + + const legacyTemplatesEs = await callAsCurrentUser('indices.getTemplate'); + const { index_templates: templatesEs } = await callAsCurrentUser( + 'dataManagement.getComposableIndexTemplates' + ); + + const legacyTemplates = deserializeLegacyTemplateList( + legacyTemplatesEs, + cloudManagedTemplatePrefix + ); + const templates = deserializeTemplateList(templatesEs, cloudManagedTemplatePrefix); + + const body = { + templates, + legacyTemplates, + }; + + return res.ok({ body }); + } catch (error) { + if (isEsError(error)) { + return res.customError({ + statusCode: error.statusCode, + body: error, + }); + } + // Case: default + throw error; + } }); } diff --git a/x-pack/plugins/ingest_pipelines/public/index.ts b/x-pack/plugins/ingest_pipelines/public/index.ts index 8948a3e8d56bef..d120f60ef8a2d1 100644 --- a/x-pack/plugins/ingest_pipelines/public/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/index.ts @@ -10,10 +10,3 @@ import { IngestPipelinesPlugin } from './plugin'; export function plugin() { return new IngestPipelinesPlugin(); } - -export { - INGEST_PIPELINES_APP_ULR_GENERATOR, - IngestPipelinesUrlGenerator, - IngestPipelinesUrlGeneratorState, - INGEST_PIPELINES_PAGES, -} from './url_generator'; diff --git a/x-pack/plugins/ingest_pipelines/public/locator.test.ts b/x-pack/plugins/ingest_pipelines/public/locator.test.ts new file mode 100644 index 00000000000000..0b1246b2bed59f --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/locator.test.ts @@ -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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ManagementAppLocatorDefinition } from 'src/plugins/management/common/locator'; +import { IngestPipelinesLocatorDefinition, INGEST_PIPELINES_PAGES } from './locator'; + +describe('Ingest pipeline locator', () => { + const setup = () => { + const managementDefinition = new ManagementAppLocatorDefinition(); + const definition = new IngestPipelinesLocatorDefinition({ + managementAppLocator: { + getLocation: (params) => managementDefinition.getLocation(params), + getUrl: async () => { + throw new Error('not implemented'); + }, + navigate: async () => { + throw new Error('not implemented'); + }, + useUrl: () => '', + }, + }); + return { definition }; + }; + + describe('Pipelines List', () => { + it('generates relative url for list without pipelineId', async () => { + const { definition } = setup(); + const location = await definition.getLocation({ + page: INGEST_PIPELINES_PAGES.LIST, + }); + + expect(location).toMatchObject({ + app: 'management', + path: '/ingest/ingest_pipelines', + }); + }); + + it('generates relative url for list with a pipelineId', async () => { + const { definition } = setup(); + const location = await definition.getLocation({ + page: INGEST_PIPELINES_PAGES.LIST, + pipelineId: 'pipeline_name', + }); + + expect(location).toMatchObject({ + app: 'management', + path: '/ingest/ingest_pipelines/?pipeline=pipeline_name', + }); + }); + }); + + describe('Pipeline Edit', () => { + it('generates relative url for pipeline edit', async () => { + const { definition } = setup(); + const location = await definition.getLocation({ + page: INGEST_PIPELINES_PAGES.EDIT, + pipelineId: 'pipeline_name', + }); + + expect(location).toMatchObject({ + app: 'management', + path: '/ingest/ingest_pipelines/edit/pipeline_name', + }); + }); + }); + + describe('Pipeline Clone', () => { + it('generates relative url for pipeline clone', async () => { + const { definition } = setup(); + const location = await definition.getLocation({ + page: INGEST_PIPELINES_PAGES.CLONE, + pipelineId: 'pipeline_name', + }); + + expect(location).toMatchObject({ + app: 'management', + path: '/ingest/ingest_pipelines/create/pipeline_name', + }); + }); + }); + + describe('Pipeline Create', () => { + it('generates relative url for pipeline create', async () => { + const { definition } = setup(); + const location = await definition.getLocation({ + page: INGEST_PIPELINES_PAGES.CREATE, + pipelineId: 'pipeline_name', + }); + + expect(location).toMatchObject({ + app: 'management', + path: '/ingest/ingest_pipelines/create', + }); + }); + }); +}); diff --git a/x-pack/plugins/ingest_pipelines/public/locator.ts b/x-pack/plugins/ingest_pipelines/public/locator.ts new file mode 100644 index 00000000000000..d819011f14f470 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/locator.ts @@ -0,0 +1,102 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SerializableState } from 'src/plugins/kibana_utils/common'; +import { ManagementAppLocator } from 'src/plugins/management/common'; +import { + LocatorPublic, + LocatorDefinition, + KibanaLocation, +} from '../../../../src/plugins/share/public'; +import { + getClonePath, + getCreatePath, + getEditPath, + getListPath, +} from './application/services/navigation'; +import { PLUGIN_ID } from '../common/constants'; + +export enum INGEST_PIPELINES_PAGES { + LIST = 'pipelines_list', + EDIT = 'pipeline_edit', + CREATE = 'pipeline_create', + CLONE = 'pipeline_clone', +} + +interface IngestPipelinesBaseParams extends SerializableState { + pipelineId: string; +} +export interface IngestPipelinesListParams extends Partial { + page: INGEST_PIPELINES_PAGES.LIST; +} + +export interface IngestPipelinesEditParams extends IngestPipelinesBaseParams { + page: INGEST_PIPELINES_PAGES.EDIT; +} + +export interface IngestPipelinesCloneParams extends IngestPipelinesBaseParams { + page: INGEST_PIPELINES_PAGES.CLONE; +} + +export interface IngestPipelinesCreateParams extends IngestPipelinesBaseParams { + page: INGEST_PIPELINES_PAGES.CREATE; +} + +export type IngestPipelinesParams = + | IngestPipelinesListParams + | IngestPipelinesEditParams + | IngestPipelinesCloneParams + | IngestPipelinesCreateParams; + +export type IngestPipelinesLocator = LocatorPublic; + +export const INGEST_PIPELINES_APP_LOCATOR = 'INGEST_PIPELINES_APP_LOCATOR'; + +export interface IngestPipelinesLocatorDependencies { + managementAppLocator: ManagementAppLocator; +} + +export class IngestPipelinesLocatorDefinition implements LocatorDefinition { + public readonly id = INGEST_PIPELINES_APP_LOCATOR; + + constructor(protected readonly deps: IngestPipelinesLocatorDependencies) {} + + public readonly getLocation = async (params: IngestPipelinesParams): Promise => { + const location = await this.deps.managementAppLocator.getLocation({ + sectionId: 'ingest', + appId: PLUGIN_ID, + }); + + let path: string = ''; + + switch (params.page) { + case INGEST_PIPELINES_PAGES.EDIT: + path = getEditPath({ + pipelineName: params.pipelineId, + }); + break; + case INGEST_PIPELINES_PAGES.CREATE: + path = getCreatePath(); + break; + case INGEST_PIPELINES_PAGES.LIST: + path = getListPath({ + inspectedPipelineName: params.pipelineId, + }); + break; + case INGEST_PIPELINES_PAGES.CLONE: + path = getClonePath({ + clonedPipelineName: params.pipelineId, + }); + break; + } + + return { + ...location, + path: path === '/' ? location.path : location.path + path, + }; + }; +} diff --git a/x-pack/plugins/ingest_pipelines/public/plugin.ts b/x-pack/plugins/ingest_pipelines/public/plugin.ts index 4a138a12d6819f..b4eb33162a1f4c 100644 --- a/x-pack/plugins/ingest_pipelines/public/plugin.ts +++ b/x-pack/plugins/ingest_pipelines/public/plugin.ts @@ -11,7 +11,7 @@ import { CoreSetup, Plugin } from 'src/core/public'; import { PLUGIN_ID } from '../common/constants'; import { uiMetricService, apiService } from './application/services'; import { SetupDependencies, StartDependencies } from './types'; -import { registerUrlGenerator } from './url_generator'; +import { IngestPipelinesLocatorDefinition } from './locator'; export class IngestPipelinesPlugin implements Plugin { @@ -50,7 +50,11 @@ export class IngestPipelinesPlugin }, }); - registerUrlGenerator(coreSetup, management, share); + share.url.locators.create( + new IngestPipelinesLocatorDefinition({ + managementAppLocator: management.locator, + }) + ); } public start() {} diff --git a/x-pack/plugins/ingest_pipelines/public/url_generator.test.ts b/x-pack/plugins/ingest_pipelines/public/url_generator.test.ts deleted file mode 100644 index dc45f9bc39088e..00000000000000 --- a/x-pack/plugins/ingest_pipelines/public/url_generator.test.ts +++ /dev/null @@ -1,108 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { IngestPipelinesUrlGenerator, INGEST_PIPELINES_PAGES } from './url_generator'; - -describe('IngestPipelinesUrlGenerator', () => { - const getAppBasePath = (absolute: boolean = false) => { - if (absolute) { - return Promise.resolve('http://localhost/app/test_app'); - } - return Promise.resolve('/app/test_app'); - }; - const urlGenerator = new IngestPipelinesUrlGenerator(getAppBasePath); - - describe('Pipelines List', () => { - it('generates relative url for list without pipelineId', async () => { - const url = await urlGenerator.createUrl({ - page: INGEST_PIPELINES_PAGES.LIST, - }); - expect(url).toBe('/app/test_app/'); - }); - - it('generates absolute url for list without pipelineId', async () => { - const url = await urlGenerator.createUrl({ - page: INGEST_PIPELINES_PAGES.LIST, - absolute: true, - }); - expect(url).toBe('http://localhost/app/test_app/'); - }); - it('generates relative url for list with a pipelineId', async () => { - const url = await urlGenerator.createUrl({ - page: INGEST_PIPELINES_PAGES.LIST, - pipelineId: 'pipeline_name', - }); - expect(url).toBe('/app/test_app/?pipeline=pipeline_name'); - }); - - it('generates absolute url for list with a pipelineId', async () => { - const url = await urlGenerator.createUrl({ - page: INGEST_PIPELINES_PAGES.LIST, - pipelineId: 'pipeline_name', - absolute: true, - }); - expect(url).toBe('http://localhost/app/test_app/?pipeline=pipeline_name'); - }); - }); - - describe('Pipeline Edit', () => { - it('generates relative url for pipeline edit', async () => { - const url = await urlGenerator.createUrl({ - page: INGEST_PIPELINES_PAGES.EDIT, - pipelineId: 'pipeline_name', - }); - expect(url).toBe('/app/test_app/edit/pipeline_name'); - }); - - it('generates absolute url for pipeline edit', async () => { - const url = await urlGenerator.createUrl({ - page: INGEST_PIPELINES_PAGES.EDIT, - pipelineId: 'pipeline_name', - absolute: true, - }); - expect(url).toBe('http://localhost/app/test_app/edit/pipeline_name'); - }); - }); - - describe('Pipeline Clone', () => { - it('generates relative url for pipeline clone', async () => { - const url = await urlGenerator.createUrl({ - page: INGEST_PIPELINES_PAGES.CLONE, - pipelineId: 'pipeline_name', - }); - expect(url).toBe('/app/test_app/create/pipeline_name'); - }); - - it('generates absolute url for pipeline clone', async () => { - const url = await urlGenerator.createUrl({ - page: INGEST_PIPELINES_PAGES.CLONE, - pipelineId: 'pipeline_name', - absolute: true, - }); - expect(url).toBe('http://localhost/app/test_app/create/pipeline_name'); - }); - }); - - describe('Pipeline Create', () => { - it('generates relative url for pipeline create', async () => { - const url = await urlGenerator.createUrl({ - page: INGEST_PIPELINES_PAGES.CREATE, - pipelineId: 'pipeline_name', - }); - expect(url).toBe('/app/test_app/create'); - }); - - it('generates absolute url for pipeline create', async () => { - const url = await urlGenerator.createUrl({ - page: INGEST_PIPELINES_PAGES.CREATE, - pipelineId: 'pipeline_name', - absolute: true, - }); - expect(url).toBe('http://localhost/app/test_app/create'); - }); - }); -}); diff --git a/x-pack/plugins/ingest_pipelines/public/url_generator.ts b/x-pack/plugins/ingest_pipelines/public/url_generator.ts deleted file mode 100644 index d9a77addcd5fd8..00000000000000 --- a/x-pack/plugins/ingest_pipelines/public/url_generator.ts +++ /dev/null @@ -1,99 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { CoreSetup } from 'src/core/public'; -import { MANAGEMENT_APP_ID } from '../../../../src/plugins/management/public'; -import { UrlGeneratorsDefinition } from '../../../../src/plugins/share/public'; -import { - getClonePath, - getCreatePath, - getEditPath, - getListPath, -} from './application/services/navigation'; -import { SetupDependencies } from './types'; -import { PLUGIN_ID } from '../common/constants'; - -export const INGEST_PIPELINES_APP_ULR_GENERATOR = 'INGEST_PIPELINES_APP_URL_GENERATOR'; - -export enum INGEST_PIPELINES_PAGES { - LIST = 'pipelines_list', - EDIT = 'pipeline_edit', - CREATE = 'pipeline_create', - CLONE = 'pipeline_clone', -} - -interface UrlGeneratorState { - pipelineId: string; - absolute?: boolean; -} -export interface PipelinesListUrlGeneratorState extends Partial { - page: INGEST_PIPELINES_PAGES.LIST; -} - -export interface PipelineEditUrlGeneratorState extends UrlGeneratorState { - page: INGEST_PIPELINES_PAGES.EDIT; -} - -export interface PipelineCloneUrlGeneratorState extends UrlGeneratorState { - page: INGEST_PIPELINES_PAGES.CLONE; -} - -export interface PipelineCreateUrlGeneratorState extends UrlGeneratorState { - page: INGEST_PIPELINES_PAGES.CREATE; -} - -export type IngestPipelinesUrlGeneratorState = - | PipelinesListUrlGeneratorState - | PipelineEditUrlGeneratorState - | PipelineCloneUrlGeneratorState - | PipelineCreateUrlGeneratorState; - -export class IngestPipelinesUrlGenerator - implements UrlGeneratorsDefinition { - constructor(private readonly getAppBasePath: (absolute: boolean) => Promise) {} - - public readonly id = INGEST_PIPELINES_APP_ULR_GENERATOR; - - public readonly createUrl = async (state: IngestPipelinesUrlGeneratorState): Promise => { - switch (state.page) { - case INGEST_PIPELINES_PAGES.EDIT: { - return `${await this.getAppBasePath(!!state.absolute)}${getEditPath({ - pipelineName: state.pipelineId, - })}`; - } - case INGEST_PIPELINES_PAGES.CREATE: { - return `${await this.getAppBasePath(!!state.absolute)}${getCreatePath()}`; - } - case INGEST_PIPELINES_PAGES.LIST: { - return `${await this.getAppBasePath(!!state.absolute)}${getListPath({ - inspectedPipelineName: state.pipelineId, - })}`; - } - case INGEST_PIPELINES_PAGES.CLONE: { - return `${await this.getAppBasePath(!!state.absolute)}${getClonePath({ - clonedPipelineName: state.pipelineId, - })}`; - } - } - }; -} - -export const registerUrlGenerator = ( - coreSetup: CoreSetup, - management: SetupDependencies['management'], - share: SetupDependencies['share'] -) => { - const getAppBasePath = async (absolute = false) => { - const [coreStart] = await coreSetup.getStartServices(); - return coreStart.application.getUrlForApp(MANAGEMENT_APP_ID, { - path: management.sections.section.ingest.getApp(PLUGIN_ID)!.basePath, - absolute: !!absolute, - }); - }; - - share.urlGenerators.registerUrlGenerator(new IngestPipelinesUrlGenerator(getAppBasePath)); -}; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx index 52488cb32ae837..0e2ba5ce8ad59f 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx @@ -1370,6 +1370,57 @@ describe('editor_frame', () => { }) ); }); + + it('should avoid completely to compute suggestion when in fullscreen mode', async () => { + const props = { + ...getDefaultProps(), + initialContext: { + indexPatternId: '1', + fieldName: 'test', + }, + visualizationMap: { + testVis: mockVisualization, + }, + datasourceMap: { + testDatasource: mockDatasource, + testDatasource2: mockDatasource2, + }, + + ExpressionRenderer: expressionRendererMock, + }; + + const { instance: el } = await mountWithProvider( + , + props.plugins.data + ); + instance = el; + + expect( + instance.find(FrameLayout).prop('suggestionsPanel') as ReactElement + ).not.toBeUndefined(); + + await act(async () => { + (instance.find(FrameLayout).prop('dataPanel') as ReactElement)!.props.dispatch({ + type: 'TOGGLE_FULLSCREEN', + }); + }); + + instance.update(); + + expect(instance.find(FrameLayout).prop('suggestionsPanel') as ReactElement).toBe(false); + + await act(async () => { + (instance.find(FrameLayout).prop('dataPanel') as ReactElement)!.props.dispatch({ + type: 'TOGGLE_FULLSCREEN', + }); + }); + + instance.update(); + + expect( + instance.find(FrameLayout).prop('suggestionsPanel') as ReactElement + ).not.toBeUndefined(); + }); }); describe('passing state back to the caller', () => { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx index cc65bb126d2d9e..bd96682f427fa6 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx @@ -452,7 +452,8 @@ export function EditorFrame(props: EditorFrameProps) { ) } suggestionsPanel={ - allLoaded && ( + allLoaded && + !state.isFullscreenDatasource && ( { const parsedValue = parseTimeShift(value); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts index 03b9d6c07709c5..87116f71919b56 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts @@ -7,11 +7,12 @@ import { i18n } from '@kbn/i18n'; import type { ExpressionFunctionAST } from '@kbn/interpreter/common'; +import memoizeOne from 'memoize-one'; import type { TimeScaleUnit } from '../../../time_scale'; import type { IndexPattern, IndexPatternLayer } from '../../../types'; import { adjustTimeScaleLabelSuffix } from '../../time_scale_utils'; import type { ReferenceBasedIndexPatternColumn } from '../column_types'; -import { isColumnValidAsReference } from '../../layer_helpers'; +import { getManagedColumnsFrom, isColumnValidAsReference } from '../../layer_helpers'; import { operationDefinitionMap } from '..'; export const buildLabelFunction = (ofName: (name?: string) => string) => ( @@ -45,6 +46,23 @@ export function checkForDateHistogram(layer: IndexPatternLayer, name: string) { ]; } +const getFullyManagedColumnIds = memoizeOne((layer: IndexPatternLayer) => { + const managedColumnIds = new Set(); + Object.entries(layer.columns).forEach(([id, column]) => { + if ( + 'references' in column && + operationDefinitionMap[column.operationType].input === 'managedReference' + ) { + managedColumnIds.add(id); + const managedColumns = getManagedColumnsFrom(id, layer.columns); + managedColumns.map(([managedId]) => { + managedColumnIds.add(managedId); + }); + } + }); + return managedColumnIds; +}); + export function checkReferences(layer: IndexPatternLayer, columnId: string) { const column = layer.columns[columnId] as ReferenceBasedIndexPatternColumn; @@ -72,7 +90,8 @@ export function checkReferences(layer: IndexPatternLayer, columnId: string) { column: referenceColumn, }); - if (!isValid) { + // do not enforce column validity if current column is part of managed subtree + if (!isValid && !getFullyManagedColumnIds(layer).has(columnId)) { errors.push( i18n.translate('xpack.lens.indexPattern.invalidReferenceConfiguration', { defaultMessage: 'Dimension "{dimensionLabel}" is configured incorrectly', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.test.tsx index e6aa29ea4d763e..279e76b8395484 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.test.tsx @@ -413,13 +413,13 @@ describe('formula', () => { ).newLayer ).toEqual({ ...layer, - columnOrder: ['col1X0', 'col1X1', 'col1'], + columnOrder: ['col1X0', 'col1'], columns: { ...layer.columns, col1: { ...currentColumn, label: 'average(bytes)', - references: ['col1X1'], + references: ['col1X0'], params: { ...currentColumn.params, formula: 'average(bytes)', @@ -436,18 +436,6 @@ describe('formula', () => { sourceField: 'bytes', timeScale: false, }, - col1X1: { - customLabel: true, - dataType: 'number', - isBucketed: false, - label: 'Part of average(bytes)', - operationType: 'math', - params: { - tinymathAst: 'col1X0', - }, - references: ['col1X0'], - scale: 'ratio', - }, }, }); }); @@ -568,8 +556,8 @@ describe('formula', () => { ).locations ).toEqual({ col1X0: { min: 15, max: 29 }, - col1X2: { min: 0, max: 41 }, - col1X3: { min: 42, max: 50 }, + col1X1: { min: 0, max: 41 }, + col1X2: { min: 42, max: 50 }, }); }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/parse.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/parse.ts index 8b726d06f46023..cb1d0dc143efcf 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/parse.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/parse.ts @@ -123,17 +123,20 @@ function extractColumns( if (nodeOperation.input === 'fullReference') { const [referencedOp] = functions; const consumedParam = parseNode(referencedOp); + const hasActualMathContent = typeof consumedParam !== 'string'; - const subNodeVariables = consumedParam ? findVariables(consumedParam) : []; - const mathColumn = mathOperation.buildColumn({ - layer, - indexPattern, - }); - mathColumn.references = subNodeVariables.map(({ value }) => value); - mathColumn.params.tinymathAst = consumedParam!; - columns.push({ column: mathColumn }); - mathColumn.customLabel = true; - mathColumn.label = label; + if (hasActualMathContent) { + const subNodeVariables = consumedParam ? findVariables(consumedParam) : []; + const mathColumn = mathOperation.buildColumn({ + layer, + indexPattern, + }); + mathColumn.references = subNodeVariables.map(({ value }) => value); + mathColumn.params.tinymathAst = consumedParam!; + columns.push({ column: mathColumn }); + mathColumn.customLabel = true; + mathColumn.label = label; + } const mappedParams = getOperationParams(nodeOperation, namedArguments || []); const newCol = (nodeOperation as OperationDefinition< @@ -143,7 +146,11 @@ function extractColumns( { layer, indexPattern, - referenceIds: [getManagedId(idPrefix, columns.length - 1)], + referenceIds: [ + hasActualMathContent + ? getManagedId(idPrefix, columns.length - 1) + : (consumedParam as string), + ], }, mappedParams ); @@ -160,16 +167,19 @@ function extractColumns( if (root === undefined) { return []; } - const variables = findVariables(root); - const mathColumn = mathOperation.buildColumn({ - layer, - indexPattern, - }); - mathColumn.references = variables.map(({ value }) => value); - mathColumn.params.tinymathAst = root!; - mathColumn.customLabel = true; - mathColumn.label = label; - columns.push({ column: mathColumn }); + const topLevelMath = typeof root !== 'string'; + if (topLevelMath) { + const variables = findVariables(root); + const mathColumn = mathOperation.buildColumn({ + layer, + indexPattern, + }); + mathColumn.references = variables.map(({ value }) => value); + mathColumn.params.tinymathAst = root!; + mathColumn.customLabel = true; + mathColumn.label = label; + columns.push({ column: mathColumn }); + } return columns; } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx index 7551b88039182b..a458a1edcfa16d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx @@ -424,25 +424,9 @@ export const termsOperation: OperationDefinition - {i18n.translate('xpack.lens.indexPattern.terms.orderDirection', { - defaultMessage: 'Rank direction', - })}{' '} - - - } + label={i18n.translate('xpack.lens.indexPattern.terms.orderDirection', { + defaultMessage: 'Rank direction', + })} display="columnCompressed" fullWidth > @@ -513,7 +497,10 @@ export const termsOperation: OperationDefinition diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx index 3b557461546caf..f326f3e3ed5f69 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx @@ -60,7 +60,7 @@ describe('terms', () => { size: 3, orderDirection: 'asc', }, - sourceField: 'category', + sourceField: 'source', }, col2: { label: 'Count', @@ -88,7 +88,7 @@ describe('terms', () => { expect.objectContaining({ arguments: expect.objectContaining({ orderBy: ['_key'], - field: ['category'], + field: ['source'], size: [3], otherBucket: [true], }), @@ -770,6 +770,34 @@ describe('terms', () => { expect(select.prop('disabled')).toEqual(false); }); + it('should disable missing bucket setting if field is not a string', () => { + const updateLayerSpy = jest.fn(); + const instance = shallow( + + ); + + const select = instance + .find('[data-test-subj="indexPattern-terms-missing-bucket"]') + .find(EuiSwitch); + + expect(select.prop('disabled')).toEqual(true); + }); + it('should update state when clicking other bucket toggle', () => { const updateLayerSpy = jest.fn(); const instance = shallow( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts index 387a61ff792640..7de1318cbac612 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts @@ -25,6 +25,7 @@ import { documentField } from '../document_field'; import { getFieldByNameFactory } from '../pure_helpers'; import { generateId } from '../../id_generator'; import { createMockedFullReference, createMockedManagedReference } from './mocks'; +import { TinymathAST } from 'packages/kbn-tinymath'; jest.mock('../operations'); jest.mock('../../id_generator'); @@ -105,28 +106,34 @@ describe('state_helpers', () => { const source = { dataType: 'number' as const, isBucketed: false, - label: 'moving_average(sum(bytes), window=5)', + label: '5 + moving_average(sum(bytes), window=5)', operationType: 'formula' as const, params: { - formula: 'moving_average(sum(bytes), window=5)', + formula: '5 + moving_average(sum(bytes), window=5)', isFormulaBroken: false, }, - references: ['formulaX1'], + references: ['formulaX2'], }; const math = { customLabel: true, dataType: 'number' as const, isBucketed: false, - label: 'Part of moving_average(sum(bytes), window=5)', operationType: 'math' as const, - params: { tinymathAst: 'formulaX2' }, - references: ['formulaX2'], + label: 'Part of 5 + moving_average(sum(bytes), window=5)', + references: ['formulaX1'], + params: { + tinymathAst: { + type: 'function', + name: 'add', + args: [5, 'formulaX1'], + } as TinymathAST, + }, }; const sum = { customLabel: true, dataType: 'number' as const, isBucketed: false, - label: 'Part of moving_average(sum(bytes), window=5)', + label: 'Part of 5 + moving_average(sum(bytes), window=5)', operationType: 'sum' as const, scale: 'ratio' as const, sourceField: 'bytes', @@ -135,7 +142,7 @@ describe('state_helpers', () => { customLabel: true, dataType: 'number' as const, isBucketed: false, - label: 'Part of moving_average(sum(bytes), window=5)', + label: 'Part of 5 + moving_average(sum(bytes), window=5)', operationType: 'moving_average' as const, params: { window: 5 }, references: ['formulaX0'], @@ -148,14 +155,8 @@ describe('state_helpers', () => { columns: { source, formulaX0: sum, - formulaX1: math, - formulaX2: movingAvg, - formulaX3: { - ...math, - label: 'Part of moving_average(sum(bytes), window=5)', - references: ['formulaX2'], - params: { tinymathAst: 'formulaX2' }, - }, + formulaX1: movingAvg, + formulaX2: math, }, }, targetId: 'copy', @@ -171,40 +172,34 @@ describe('state_helpers', () => { 'formulaX0', 'formulaX1', 'formulaX2', - 'formulaX3', 'copyX0', 'copyX1', 'copyX2', - 'copyX3', 'copy', ], columns: { source, formulaX0: sum, - formulaX1: math, - formulaX2: movingAvg, - formulaX3: { - ...math, - references: ['formulaX2'], - params: { tinymathAst: 'formulaX2' }, - }, - copy: expect.objectContaining({ ...source, references: ['copyX3'] }), + formulaX1: movingAvg, + formulaX2: math, + copy: expect.objectContaining({ ...source, references: ['copyX2'] }), copyX0: expect.objectContaining({ ...sum, }), copyX1: expect.objectContaining({ - ...math, + ...movingAvg, references: ['copyX0'], - params: { tinymathAst: 'copyX0' }, }), copyX2: expect.objectContaining({ - ...movingAvg, - references: ['copyX1'], - }), - copyX3: expect.objectContaining({ ...math, - references: ['copyX2'], - params: { tinymathAst: 'copyX2' }, + references: ['copyX1'], + params: { + tinymathAst: expect.objectContaining({ + type: 'function', + name: 'add', + args: [5, 'copyX1'], + } as TinymathAST), + }, }), }, }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx index 14ba6b9189e6bd..a1bc643c3bd932 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx @@ -23,67 +23,67 @@ import { FramePublicAPI } from '../types'; export const timeShiftOptions = [ { label: i18n.translate('xpack.lens.indexPattern.timeShift.hour', { - defaultMessage: '1 hour (1h)', + defaultMessage: '1 hour ago (1h)', }), value: '1h', }, { label: i18n.translate('xpack.lens.indexPattern.timeShift.3hours', { - defaultMessage: '3 hours (3h)', + defaultMessage: '3 hours ago (3h)', }), value: '3h', }, { label: i18n.translate('xpack.lens.indexPattern.timeShift.6hours', { - defaultMessage: '6 hours (6h)', + defaultMessage: '6 hours ago (6h)', }), value: '6h', }, { label: i18n.translate('xpack.lens.indexPattern.timeShift.12hours', { - defaultMessage: '12 hours (12h)', + defaultMessage: '12 hours ago (12h)', }), value: '12h', }, { label: i18n.translate('xpack.lens.indexPattern.timeShift.day', { - defaultMessage: '1 day (1d)', + defaultMessage: '1 day ago (1d)', }), value: '1d', }, { label: i18n.translate('xpack.lens.indexPattern.timeShift.week', { - defaultMessage: '1 week (1w)', + defaultMessage: '1 week ago (1w)', }), value: '1w', }, { label: i18n.translate('xpack.lens.indexPattern.timeShift.month', { - defaultMessage: '1 month (1M)', + defaultMessage: '1 month ago (1M)', }), value: '1M', }, { label: i18n.translate('xpack.lens.indexPattern.timeShift.3months', { - defaultMessage: '3 months (3M)', + defaultMessage: '3 months ago (3M)', }), value: '3M', }, { label: i18n.translate('xpack.lens.indexPattern.timeShift.6months', { - defaultMessage: '6 months (6M)', + defaultMessage: '6 months ago (6M)', }), value: '6M', }, { label: i18n.translate('xpack.lens.indexPattern.timeShift.year', { - defaultMessage: '1 year (1y)', + defaultMessage: '1 year ago (1y)', }), value: '1y', }, { label: i18n.translate('xpack.lens.indexPattern.timeShift.previous', { - defaultMessage: 'Previous', + defaultMessage: 'Previous time range', }), value: 'previous', }, diff --git a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts index bdcb4224eed9c5..4987de321c556c 100644 --- a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts +++ b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_lists.test.ts @@ -48,6 +48,7 @@ describe('useExceptionLists', () => { perPage: 20, total: 0, }, + showEventFilters: false, showTrustedApps: false, }) ); @@ -83,6 +84,7 @@ describe('useExceptionLists', () => { perPage: 20, total: 0, }, + showEventFilters: false, showTrustedApps: false, }) ); @@ -122,6 +124,7 @@ describe('useExceptionLists', () => { perPage: 20, total: 0, }, + showEventFilters: false, showTrustedApps: true, }) ); @@ -132,7 +135,7 @@ describe('useExceptionLists', () => { expect(spyOnfetchExceptionLists).toHaveBeenCalledWith({ filters: - '(exception-list.attributes.list_id: endpoint_trusted_apps* OR exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)', + '(exception-list.attributes.list_id: endpoint_trusted_apps* OR exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)', http: mockKibanaHttpService, namespaceTypes: 'single,agnostic', pagination: { page: 1, perPage: 20 }, @@ -157,6 +160,7 @@ describe('useExceptionLists', () => { perPage: 20, total: 0, }, + showEventFilters: false, showTrustedApps: false, }) ); @@ -167,7 +171,79 @@ describe('useExceptionLists', () => { expect(spyOnfetchExceptionLists).toHaveBeenCalledWith({ filters: - '(not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)', + '(not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)', + http: mockKibanaHttpService, + namespaceTypes: 'single,agnostic', + pagination: { page: 1, perPage: 20 }, + signal: new AbortController().signal, + }); + }); + }); + + test('fetches event filters lists if "showEventFilters" is true', async () => { + const spyOnfetchExceptionLists = jest.spyOn(api, 'fetchExceptionLists'); + + await act(async () => { + const { waitForNextUpdate } = renderHook(() => + useExceptionLists({ + errorMessage: 'Uh oh', + filterOptions: {}, + http: mockKibanaHttpService, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + showEventFilters: true, + showTrustedApps: false, + }) + ); + // NOTE: First `waitForNextUpdate` is initialization + // Second call applies the params + await waitForNextUpdate(); + await waitForNextUpdate(); + + expect(spyOnfetchExceptionLists).toHaveBeenCalledWith({ + filters: + '(not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (exception-list.attributes.list_id: endpoint_event_filters* OR exception-list-agnostic.attributes.list_id: endpoint_event_filters*)', + http: mockKibanaHttpService, + namespaceTypes: 'single,agnostic', + pagination: { page: 1, perPage: 20 }, + signal: new AbortController().signal, + }); + }); + }); + + test('does not fetch event filters lists if "showEventFilters" is false', async () => { + const spyOnfetchExceptionLists = jest.spyOn(api, 'fetchExceptionLists'); + + await act(async () => { + const { waitForNextUpdate } = renderHook(() => + useExceptionLists({ + errorMessage: 'Uh oh', + filterOptions: {}, + http: mockKibanaHttpService, + namespaceTypes: ['single', 'agnostic'], + notifications: mockKibanaNotificationsService, + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + showEventFilters: false, + showTrustedApps: false, + }) + ); + // NOTE: First `waitForNextUpdate` is initialization + // Second call applies the params + await waitForNextUpdate(); + await waitForNextUpdate(); + + expect(spyOnfetchExceptionLists).toHaveBeenCalledWith({ + filters: + '(not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)', http: mockKibanaHttpService, namespaceTypes: 'single,agnostic', pagination: { page: 1, perPage: 20 }, @@ -195,6 +271,7 @@ describe('useExceptionLists', () => { perPage: 20, total: 0, }, + showEventFilters: false, showTrustedApps: false, }) ); @@ -205,7 +282,7 @@ describe('useExceptionLists', () => { expect(spyOnfetchExceptionLists).toHaveBeenCalledWith({ filters: - '(exception-list.attributes.created_by:Moi OR exception-list-agnostic.attributes.created_by:Moi) AND (exception-list.attributes.name.text:Sample Endpoint OR exception-list-agnostic.attributes.name.text:Sample Endpoint) AND (not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*)', + '(exception-list.attributes.created_by:Moi OR exception-list-agnostic.attributes.created_by:Moi) AND (exception-list.attributes.name.text:Sample Endpoint OR exception-list-agnostic.attributes.name.text:Sample Endpoint) AND (not exception-list.attributes.list_id: endpoint_trusted_apps* AND not exception-list-agnostic.attributes.list_id: endpoint_trusted_apps*) AND (not exception-list.attributes.list_id: endpoint_event_filters* AND not exception-list-agnostic.attributes.list_id: endpoint_event_filters*)', http: mockKibanaHttpService, namespaceTypes: 'single,agnostic', pagination: { page: 1, perPage: 20 }, @@ -228,6 +305,7 @@ describe('useExceptionLists', () => { namespaceTypes, notifications, pagination, + showEventFilters, showTrustedApps, }) => useExceptionLists({ @@ -237,6 +315,7 @@ describe('useExceptionLists', () => { namespaceTypes, notifications, pagination, + showEventFilters, showTrustedApps, }), { @@ -251,6 +330,7 @@ describe('useExceptionLists', () => { perPage: 20, total: 0, }, + showEventFilters: false, showTrustedApps: false, }, } @@ -271,6 +351,7 @@ describe('useExceptionLists', () => { perPage: 20, total: 0, }, + showEventFilters: false, showTrustedApps: false, }); // NOTE: Only need one call here because hook already initilaized @@ -298,6 +379,7 @@ describe('useExceptionLists', () => { perPage: 20, total: 0, }, + showEventFilters: false, showTrustedApps: false, }) ); @@ -336,6 +418,7 @@ describe('useExceptionLists', () => { perPage: 20, total: 0, }, + showEventFilters: false, showTrustedApps: false, }) ); diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index 37a8e8063c4ed1..fa065e701184e9 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -58,15 +58,14 @@ export const KBN_IS_CENTROID_FEATURE = '__kbn_is_centroid_feature__'; export const MVT_TOKEN_PARAM_NAME = 'token'; -const MAP_BASE_URL = `/${MAPS_APP_PATH}/${MAP_PATH}`; export function getNewMapPath() { - return MAP_BASE_URL; + return `/${MAPS_APP_PATH}/${MAP_PATH}`; } -export function getExistingMapPath(id: string) { - return `${MAP_BASE_URL}/${id}`; +export function getFullPath(id: string | undefined) { + return `/${MAPS_APP_PATH}${getEditPath(id)}`; } -export function getEditPath(id: string) { - return `/${MAP_PATH}/${id}`; +export function getEditPath(id: string | undefined) { + return id ? `/${MAP_PATH}/${id}` : `/${MAP_PATH}`; } export enum LAYER_TYPE { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_circle.ts b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_circle.ts index f0df797582bef7..998329a78bfbbd 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_circle.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_circle.ts @@ -11,7 +11,11 @@ import turfDistance from '@turf/distance'; // @ts-expect-error import turfCircle from '@turf/circle'; -import { Position } from 'geojson'; +import { Feature, GeoJSON, Position } from 'geojson'; + +const DRAW_CIRCLE_RADIUS = 'draw-circle-radius'; + +export const DRAW_CIRCLE_RADIUS_MB_FILTER = ['==', 'meta', DRAW_CIRCLE_RADIUS]; export interface DrawCircleProperties { center: Position; @@ -22,10 +26,12 @@ type DrawCircleState = { circle: { properties: Omit & { center: Position | null; + edge: Position | null; + radiusKm: number; }; id: string | number; incomingCoords: (coords: unknown[]) => void; - toGeoJSON: () => unknown; + toGeoJSON: () => GeoJSON; }; }; @@ -43,6 +49,7 @@ export const DrawCircle = { type: 'Feature', properties: { center: null, + edge: null, radiusKm: 0, }, geometry: { @@ -96,6 +103,7 @@ export const DrawCircle = { } const mouseLocation = [e.lngLat.lng, e.lngLat.lat]; + state.circle.properties.edge = mouseLocation; state.circle.properties.radiusKm = turfDistance(state.circle.properties.center, mouseLocation); const newCircleFeature = turfCircle( state.circle.properties.center, @@ -124,15 +132,53 @@ export const DrawCircle = { this.changeMode('simple_select', {}, { silent: true }); } }, - toDisplayFeatures( - state: DrawCircleState, - geojson: { properties: { active: string } }, - display: (geojson: unknown) => unknown - ) { - if (state.circle.properties.center) { - geojson.properties.active = 'true'; - return display(geojson); + toDisplayFeatures(state: DrawCircleState, geojson: Feature, display: (geojson: Feature) => void) { + if (!state.circle.properties.center || !state.circle.properties.edge) { + return null; + } + + geojson.properties!.active = 'true'; + + let radiusLabel = ''; + if (state.circle.properties.radiusKm <= 1) { + radiusLabel = `${Math.round(state.circle.properties.radiusKm * 1000)} m`; + } else if (state.circle.properties.radiusKm <= 10) { + radiusLabel = `${state.circle.properties.radiusKm.toFixed(1)} km`; + } else { + radiusLabel = `${Math.round(state.circle.properties.radiusKm)} km`; } + + // display radius label, requires custom 'symbol' style with DRAW_CIRCLE_RADIUS_MB_FILTER filter + display({ + type: 'Feature', + properties: { + meta: DRAW_CIRCLE_RADIUS, + parent: state.circle.id, + radiusLabel, + active: 'false', + }, + geometry: { + type: 'Point', + coordinates: state.circle.properties.edge, + }, + }); + + // display line from center vertex to edge + display({ + type: 'Feature', + properties: { + meta: 'draw-circle-radius-line', + parent: state.circle.id, + active: 'true', + }, + geometry: { + type: 'LineString', + coordinates: [state.circle.properties.center, state.circle.properties.edge], + }, + }); + + // display circle + display(geojson); }, onTrash(state: DrawCircleState) { // @ts-ignore diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx index 879bd85dd6019d..5d9cb59bbe522f 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/draw_control/draw_control.tsx @@ -14,9 +14,11 @@ import DrawRectangle from 'mapbox-gl-draw-rectangle-mode'; import type { Map as MbMap } from '@kbn/mapbox-gl'; import { Feature } from 'geojson'; import { DRAW_SHAPE } from '../../../../common/constants'; -import { DrawCircle } from './draw_circle'; +import { DrawCircle, DRAW_CIRCLE_RADIUS_MB_FILTER } from './draw_circle'; import { DrawTooltip } from './draw_tooltip'; +const GL_DRAW_RADIUS_LABEL_LAYER_ID = 'gl-draw-radius-label'; + const mbModeEquivalencies = new Map([ ['simple_select', DRAW_SHAPE.SIMPLE_SELECT], ['draw_rectangle', DRAW_SHAPE.BOUNDS], @@ -94,6 +96,7 @@ export class DrawControl extends Component { this.props.mbMap.getCanvas().style.cursor = ''; this.props.mbMap.off('draw.modechange', this._onModeChange); this.props.mbMap.off('draw.create', this._onDraw); + this.props.mbMap.removeLayer(GL_DRAW_RADIUS_LABEL_LAYER_ID); this.props.mbMap.removeControl(this._mbDrawControl); this._mbDrawControlAdded = false; } @@ -105,6 +108,25 @@ export class DrawControl extends Component { if (!this._mbDrawControlAdded) { this.props.mbMap.addControl(this._mbDrawControl); + this.props.mbMap.addLayer({ + id: GL_DRAW_RADIUS_LABEL_LAYER_ID, + type: 'symbol', + source: 'mapbox-gl-draw-hot', + filter: DRAW_CIRCLE_RADIUS_MB_FILTER, + layout: { + 'text-anchor': 'right', + 'text-field': '{radiusLabel}', + 'text-size': 16, + 'text-offset': [-1, 0], + 'text-ignore-placement': true, + 'text-allow-overlap': true, + }, + paint: { + 'text-color': '#fbb03b', + 'text-halo-color': 'rgba(255, 255, 255, 1)', + 'text-halo-width': 2, + }, + }); this._mbDrawControlAdded = true; this.props.mbMap.getCanvas().style.cursor = 'crosshair'; this.props.mbMap.on('draw.modechange', this._onModeChange); diff --git a/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx b/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx index 5a477754683e68..509cece671dd6d 100644 --- a/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx +++ b/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx @@ -54,9 +54,9 @@ import { } from '../selectors/map_selectors'; import { APP_ID, - getExistingMapPath, + getEditPath, + getFullPath, MAP_SAVED_OBJECT_TYPE, - MAP_PATH, RawValue, } from '../../common/constants'; import { RenderToolTipContent } from '../classes/tooltips/tooltip_property'; @@ -180,13 +180,13 @@ export class MapEmbeddable : ''; const input = this.getInput(); const title = input.hidePanelTitles ? '' : input.title || savedMapTitle; - const savedObjectId = (input as MapByReferenceInput).savedObjectId; + const savedObjectId = 'savedObjectId' in input ? input.savedObjectId : undefined; this.updateOutput({ ...this.getOutput(), defaultTitle: savedMapTitle, title, - editPath: `/${MAP_PATH}/${savedObjectId}`, - editUrl: getHttp().basePath.prepend(getExistingMapPath(savedObjectId)), + editPath: getEditPath(savedObjectId), + editUrl: getHttp().basePath.prepend(getFullPath(savedObjectId)), indexPatterns: await this._getIndexPatterns(), }); } diff --git a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx index 0dfff5a2c221ed..92459ed28ab91e 100644 --- a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx @@ -44,7 +44,7 @@ import { getTopNavConfig } from '../top_nav_config'; import { MapQuery } from '../../../../common/descriptor_types'; import { goToSpecifiedPath } from '../../../render_app'; import { MapSavedObjectAttributes } from '../../../../common/map_saved_object_type'; -import { getExistingMapPath, APP_ID } from '../../../../common/constants'; +import { getFullPath, APP_ID } from '../../../../common/constants'; import { getInitialQuery, getInitialRefreshConfig, @@ -356,7 +356,7 @@ export class MapApp extends React.Component { const savedObjectId = this.props.savedMap.getSavedObjectId(); if (savedObjectId) { getCoreChrome().recentlyAccessed.add( - getExistingMapPath(savedObjectId), + getFullPath(savedObjectId), this.props.savedMap.getTitle(), savedObjectId ); diff --git a/x-pack/plugins/maps/public/routes/map_page/url_state/app_sync.ts b/x-pack/plugins/maps/public/routes/map_page/url_state/app_sync.ts index 268e5fa600b464..f05836dff2bd98 100644 --- a/x-pack/plugins/maps/public/routes/map_page/url_state/app_sync.ts +++ b/x-pack/plugins/maps/public/routes/map_page/url_state/app_sync.ts @@ -60,7 +60,9 @@ export function startAppStateSyncing(appStateManager: AppStateManager) { stateContainer.set(initialAppState); // set current url to whatever is in app state container - kbnUrlStateStorage.set('_a', initialAppState); + kbnUrlStateStorage.set('_a', initialAppState, { + replace: true, + }); // finally start syncing state containers with url startSyncingAppStateWithUrl(); diff --git a/x-pack/plugins/maps/server/plugin.ts b/x-pack/plugins/maps/server/plugin.ts index c7532979320378..b8676559a4e2b1 100644 --- a/x-pack/plugins/maps/server/plugin.ts +++ b/x-pack/plugins/maps/server/plugin.ts @@ -22,7 +22,7 @@ import { getFlightsSavedObjects } from './sample_data/flights_saved_objects.js'; // @ts-ignore import { getWebLogsSavedObjects } from './sample_data/web_logs_saved_objects.js'; import { registerMapsUsageCollector } from './maps_telemetry/collectors/register'; -import { APP_ID, APP_ICON, MAP_SAVED_OBJECT_TYPE, getExistingMapPath } from '../common/constants'; +import { APP_ID, APP_ICON, MAP_SAVED_OBJECT_TYPE, getFullPath } from '../common/constants'; import { mapSavedObjects, mapsTelemetrySavedObjects } from './saved_objects'; import { MapsXPackConfig } from '../config'; // @ts-ignore @@ -77,7 +77,7 @@ export class MapsPlugin implements Plugin { home.sampleData.addAppLinksToSampleDataset('ecommerce', [ { - path: getExistingMapPath('2c9c1f60-1909-11e9-919b-ffe5949a18d2'), + path: getFullPath('2c9c1f60-1909-11e9-919b-ffe5949a18d2'), label: sampleDataLinkLabel, icon: APP_ICON, }, @@ -99,7 +99,7 @@ export class MapsPlugin implements Plugin { home.sampleData.addAppLinksToSampleDataset('flights', [ { - path: getExistingMapPath('5dd88580-1906-11e9-919b-ffe5949a18d2'), + path: getFullPath('5dd88580-1906-11e9-919b-ffe5949a18d2'), label: sampleDataLinkLabel, icon: APP_ICON, }, @@ -120,7 +120,7 @@ export class MapsPlugin implements Plugin { home.sampleData.addSavedObjectsToSampleDataset('logs', getWebLogsSavedObjects()); home.sampleData.addAppLinksToSampleDataset('logs', [ { - path: getExistingMapPath('de71f4f0-1902-11e9-919b-ffe5949a18d2'), + path: getFullPath('de71f4f0-1902-11e9-919b-ffe5949a18d2'), label: sampleDataLinkLabel, icon: APP_ICON, }, diff --git a/x-pack/plugins/maps/server/saved_objects/map.ts b/x-pack/plugins/maps/server/saved_objects/map.ts index 78f70e27b2b7bf..24effd651a31b0 100644 --- a/x-pack/plugins/maps/server/saved_objects/map.ts +++ b/x-pack/plugins/maps/server/saved_objects/map.ts @@ -6,7 +6,7 @@ */ import { SavedObjectsType } from 'src/core/server'; -import { APP_ICON, getExistingMapPath } from '../../common/constants'; +import { APP_ICON, getFullPath } from '../../common/constants'; // @ts-ignore import { savedObjectMigrations } from './saved_object_migrations'; @@ -34,7 +34,7 @@ export const mapSavedObjects: SavedObjectsType = { }, getInAppUrl(obj) { return { - path: getExistingMapPath(obj.id), + path: getFullPath(obj.id), uiCapabilitiesPath: 'maps.show', }; }, diff --git a/x-pack/plugins/ml/common/types/results.ts b/x-pack/plugins/ml/common/types/results.ts index fa40cefcaed48d..74d32864385889 100644 --- a/x-pack/plugins/ml/common/types/results.ts +++ b/x-pack/plugins/ml/common/types/results.ts @@ -6,6 +6,7 @@ */ import { estypes } from '@elastic/elasticsearch'; +import { LineAnnotationDatum, RectAnnotationDatum } from '@elastic/charts'; export interface GetStoppedPartitionResult { jobs: string[] | Record; @@ -13,6 +14,9 @@ export interface GetStoppedPartitionResult { export interface GetDatafeedResultsChartDataResult { bucketResults: number[][]; datafeedResults: number[][]; + annotationResultsRect: RectAnnotationDatum[]; + annotationResultsLine: LineAnnotationDatum[]; + modelSnapshotResultsLine: LineAnnotationDatum[]; } export interface DatafeedResultsChartDataParams { diff --git a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js index afed7e79ff757f..b68e64a5d9f6ae 100644 --- a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js +++ b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js @@ -494,13 +494,13 @@ class AnnotationsTableUI extends Component { render: (annotation) => { const viewDataFeedText = ( ); const viewDataFeedTooltipAriaLabelText = i18n.translate( - 'xpack.ml.annotationsTable.viewDatafeedTooltipAriaLabel', - { defaultMessage: 'View datafeed' } + 'xpack.ml.annotationsTable.datafeedChartTooltipAriaLabel', + { defaultMessage: 'Datafeed chart' } ); return ( ) : null} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/expanded_row.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/expanded_row.tsx index 88ffaa0da7fdcd..93be45bbdaf978 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/expanded_row.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/models_management/expanded_row.tsx @@ -114,10 +114,7 @@ export const ExpandedRow: FC = ({ item }) => { } const { - services: { - share, - application: { navigateToUrl }, - }, + services: { share }, } = useMlKibana(); const tabs = [ @@ -402,17 +399,16 @@ export const ExpandedRow: FC = ({ item }) => { { - const ingestPipelinesAppUrlGenerator = share.urlGenerators.getUrlGenerator( - 'INGEST_PIPELINES_APP_URL_GENERATOR' - ); - await navigateToUrl( - await ingestPipelinesAppUrlGenerator.createUrl({ - page: 'pipeline_edit', - pipelineId: pipelineName, - absolute: true, - }) + onClick={() => { + const locator = share.url.locators.get( + 'INGEST_PIPELINES_APP_LOCATOR' ); + if (!locator) return; + locator.navigate({ + page: 'pipeline_edit', + pipelineId: pipelineName, + absolute: true, + }); }} > void; + onClose: () => void; +} + +function setLineAnnotationHeader(lineDatum: LineAnnotationDatum) { + lineDatum.header = dateFormatter(lineDatum.dataValue); + return lineDatum; } export const DatafeedModal: FC = ({ jobId, end, onClose }) => { @@ -68,11 +83,17 @@ export const DatafeedModal: FC = ({ jobId, end, onClose }) = isInitialized: boolean; }>({ datafeedConfig: undefined, bucketSpan: undefined, isInitialized: false }); const [endDate, setEndDate] = useState(moment(end)); - const [interval, setInterval] = useState(); const [selectedTabId, setSelectedTabId] = useState(TAB_IDS.CHART); const [isLoadingChartData, setIsLoadingChartData] = useState(false); const [bucketData, setBucketData] = useState([]); + const [annotationData, setAnnotationData] = useState<{ + rect: RectAnnotationDatum[]; + line: LineAnnotationDatum[]; + }>({ rect: [], line: [] }); + const [modelSnapshotData, setModelSnapshotData] = useState([]); const [sourceData, setSourceData] = useState([]); + const [showAnnotations, setShowAnnotations] = useState(true); + const [showModelSnapshots, setShowModelSnapshots] = useState(true); const { results: { getDatafeedResultChartData }, @@ -102,25 +123,30 @@ export const DatafeedModal: FC = ({ jobId, end, onClose }) = const handleChange = (date: moment.Moment) => setEndDate(date); const handleEndDateChange = (direction: ChartDirectionType) => { - if (interval === undefined) return; + if (data.bucketSpan === undefined) return; const newEndDate = endDate.clone(); - const [count, type] = interval.split(' '); + const unitMatch = data.bucketSpan.match(/[d | h| m | s]/g)!; + const unit = unitMatch[0]; + const count = Number(data.bucketSpan.replace(/[^0-9]/g, '')); if (direction === CHART_DIRECTION.FORWARD) { - newEndDate.add(Number(count), type); + newEndDate.add(MAX_CHART_POINTS * count, unit); } else { - newEndDate.subtract(Number(count), type); + newEndDate.subtract(MAX_CHART_POINTS * count, unit); } setEndDate(newEndDate); }; const getChartData = useCallback(async () => { - if (interval === undefined) return; + if (data.bucketSpan === undefined) return; const endTimestamp = moment(endDate).valueOf(); - const [count, type] = interval.split(' '); - const startMoment = endDate.clone().subtract(Number(count), type); + const unitMatch = data.bucketSpan.match(/[d | h| m | s]/g)!; + const unit = unitMatch[0]; + const count = Number(data.bucketSpan.replace(/[^0-9]/g, '')); + // STARTTIME = ENDTIME - (BucketSpan * MAX_CHART_POINTS) + const startMoment = endDate.clone().subtract(MAX_CHART_POINTS * count, unit); const startTimestamp = moment(startMoment).valueOf(); try { @@ -128,6 +154,11 @@ export const DatafeedModal: FC = ({ jobId, end, onClose }) = setSourceData(chartData.datafeedResults); setBucketData(chartData.bucketResults); + setAnnotationData({ + rect: chartData.annotationResultsRect, + line: chartData.annotationResultsLine.map(setLineAnnotationHeader), + }); + setModelSnapshotData(chartData.modelSnapshotResultsLine.map(setLineAnnotationHeader)); } catch (error) { const title = i18n.translate('xpack.ml.jobsList.datafeedModal.errorToastTitle', { defaultMessage: 'Error fetching data', @@ -135,7 +166,7 @@ export const DatafeedModal: FC = ({ jobId, end, onClose }) = displayErrorToast(error, title); } setIsLoadingChartData(false); - }, [endDate, interval]); + }, [endDate, data.bucketSpan]); const getJobData = async () => { try { @@ -145,11 +176,6 @@ export const DatafeedModal: FC = ({ jobId, end, onClose }) = bucketSpan: job.analysis_config.bucket_span, isInitialized: true, }); - const intervalOptions = getIntervalOptions(job.analysis_config.bucket_span); - const initialInterval = intervalOptions.length - ? intervalOptions[intervalOptions.length - 1] - : undefined; - setInterval(initialInterval?.value || '72 hours'); } catch (error) { displayErrorToast(error); } @@ -161,20 +187,17 @@ export const DatafeedModal: FC = ({ jobId, end, onClose }) = useEffect( function loadChartData() { - if (interval !== undefined) { + if (data.bucketSpan !== undefined) { setIsLoadingChartData(true); getChartData(); } }, - [endDate, interval] + [endDate, data.bucketSpan] ); const { datafeedConfig, bucketSpan, isInitialized } = data; - - const intervalOptions = useMemo(() => { - if (bucketSpan === undefined) return []; - return getIntervalOptions(bucketSpan); - }, [bucketSpan]); + const checkboxIdAnnotation = useMemo(() => htmlIdGenerator()(), []); + const checkboxIdModelSnapshot = useMemo(() => htmlIdGenerator()(), []); return ( = ({ jobId, end, onClose }) = - + + + + } + /> + + + +

+ +

+
+
+
= ({ jobId, end, onClose }) = - - setInterval(e.target.value)} - aria-label={i18n.translate( - 'xpack.ml.jobsList.datafeedModal.intervalSelection', - { - defaultMessage: 'Datafeed modal chart interval selection', - } - )} - /> - = ({ jobId, end, onClose }) = isEnabled={datafeedConfig.state === DATAFEED_STATE.STOPPED} /> + + + + + + + } + checked={showAnnotations} + onChange={() => setShowAnnotations(!showAnnotations)} + /> + + + + + + } + checked={showModelSnapshots} + onChange={() => setShowModelSnapshots(!showModelSnapshots)} + /> + + + @@ -298,7 +362,65 @@ export const DatafeedModal: FC = ({ jobId, end, onClose }) = })} position={Position.Left} /> + {showModelSnapshots ? ( + } + markerPosition={Position.Top} + style={{ + line: { + strokeWidth: 3, + stroke: euiTheme.euiColorVis1, + opacity: 0.5, + }, + }} + /> + ) : null} + {showAnnotations ? ( + <> + } + markerPosition={Position.Top} + style={{ + line: { + strokeWidth: 3, + stroke: euiTheme.euiColorDangerText, + opacity: 0.5, + }, + }} + /> + + + ) : null} = ({ jobId, end, onClose }) = curve={CurveType.LINEAR} /> { - const unitMatch = bucketSpan.match(/[d | h| m | s]/g)!; - const unit = unitMatch[0]; - const count = Number(bucketSpan.replace(/[^0-9]/g, '')); - - const intervalOptions = []; - - if (['s', 'ms', 'micros', 'nanos'].includes(unit)) { - intervalOptions.push( - { - value: '1 hour', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.1hourOption', { - defaultMessage: '{count} hour', - values: { count: 1 }, - }), - }, - { - value: '2 hours', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.2hourOption', { - defaultMessage: '{count} hours', - values: { count: 2 }, - }), - } - ); - } - - if ((unit === 'm' && count <= 4) || unit === 'h') { - intervalOptions.push( - { - value: '3 hours', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.3hourOption', { - defaultMessage: '{count} hours', - values: { count: 3 }, - }), - }, - { - value: '8 hours', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.8hourOption', { - defaultMessage: '{count} hours', - values: { count: 8 }, - }), - }, - { - value: '12 hours', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.12hourOption', { - defaultMessage: '{count} hours', - values: { count: 12 }, - }), - }, - { - value: '24 hours', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.24hourOption', { - defaultMessage: '{count} hours', - values: { count: 24 }, - }), - } - ); - } - - if ((unit === 'm' && count >= 5 && count <= 15) || unit === 'h') { - intervalOptions.push( - { - value: '48 hours', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.48hourOption', { - defaultMessage: '{count} hours', - values: { count: 48 }, - }), - }, - { - value: '72 hours', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.72hourOption', { - defaultMessage: '{count} hours', - values: { count: 72 }, - }), - } - ); - } - - if ((unit === 'm' && count >= 10 && count <= 15) || unit === 'h' || unit === 'd') { - intervalOptions.push( - { - value: '5 days', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.5daysOption', { - defaultMessage: '{count} days', - values: { count: 5 }, - }), - }, - { - value: '7 days', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.7daysOption', { - defaultMessage: '{count} days', - values: { count: 7 }, - }), - } - ); - } - - if (unit === 'h' || unit === 'd') { - intervalOptions.push({ - value: '14 days', - text: i18n.translate('xpack.ml.jobsList.datafeedModal.14DaysOption', { - defaultMessage: '{count} days', - values: { count: 14 }, - }), - }); - } - - return intervalOptions; -}; diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_details.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_details.js index b514c8433daf48..d3856e6afa3982 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_details.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_details.js @@ -7,26 +7,29 @@ import PropTypes from 'prop-types'; import React, { Component, Fragment } from 'react'; - -import { EuiTabbedContent, EuiLoadingSpinner } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { EuiButtonIcon, EuiTabbedContent, EuiLoadingSpinner, EuiToolTip } from '@elastic/eui'; import { extractJobDetails } from './extract_job_details'; import { JsonPane } from './json_tab'; import { DatafeedPreviewPane } from './datafeed_preview_tab'; import { AnnotationsTable } from '../../../../components/annotations/annotations_table'; +import { DatafeedModal } from '../datafeed_modal'; import { AnnotationFlyout } from '../../../../components/annotations/annotation_flyout'; import { ModelSnapshotTable } from '../../../../components/model_snapshots'; import { ForecastsTable } from './forecasts_table'; import { JobDetailsPane } from './job_details_pane'; import { JobMessagesPane } from './job_messages_pane'; -import { i18n } from '@kbn/i18n'; import { withKibana } from '../../../../../../../../../src/plugins/kibana_react/public'; export class JobDetailsUI extends Component { constructor(props) { super(props); - this.state = {}; + this.state = { + datafeedModalVisible: false, + }; if (this.props.addYourself) { this.props.addYourself(props.jobId, (j) => this.updateJob(j)); } @@ -77,6 +80,30 @@ export class JobDetailsUI extends Component { alertRules, } = extractJobDetails(job, basePath, refreshJobList); + datafeed.titleAction = ( + + } + > + + this.setState({ + datafeedModalVisible: true, + }) + } + /> + + ); + const tabs = [ { id: 'job-settings', @@ -105,6 +132,32 @@ export class JobDetailsUI extends Component { /> ), }, + { + id: 'datafeed', + 'data-test-subj': 'mlJobListTab-datafeed', + name: i18n.translate('xpack.ml.jobsList.jobDetails.tabs.datafeedLabel', { + defaultMessage: 'Datafeed', + }), + content: ( + <> + + {this.props.jobId && this.state.datafeedModalVisible ? ( + { + this.setState({ + datafeedModalVisible: false, + }); + }} + end={job.data_counts.latest_bucket_timestamp} + jobId={this.props.jobId} + /> + ) : null} + + ), + }, { id: 'counts', 'data-test-subj': 'mlJobListTab-counts', @@ -137,21 +190,6 @@ export class JobDetailsUI extends Component { ]; if (showFullDetails && datafeed.items.length) { - // Datafeed should be at index 2 in tabs array for full details - tabs.splice(2, 0, { - id: 'datafeed', - 'data-test-subj': 'mlJobListTab-datafeed', - name: i18n.translate('xpack.ml.jobsList.jobDetails.tabs.datafeedLabel', { - defaultMessage: 'Datafeed', - }), - content: ( - - ), - }); - tabs.push( { id: 'datafeed-preview', diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_details_pane.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_details_pane.js index 49d9bcde490520..4046f4d5d80712 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_details_pane.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_details_pane.js @@ -9,6 +9,8 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { + EuiFlexGroup, + EuiFlexItem, EuiTitle, EuiTable, EuiTableBody, @@ -42,9 +44,14 @@ function Section({ section }) { return ( - -

{section.title}

-
+ + + +

{section.title}

+
+
+ {section.titleAction} +
diff --git a/x-pack/plugins/ml/public/application/services/ml_api_service/results.ts b/x-pack/plugins/ml/public/application/services/ml_api_service/results.ts index 19ba5aa304bf04..25ef36782207f1 100644 --- a/x-pack/plugins/ml/public/application/services/ml_api_service/results.ts +++ b/x-pack/plugins/ml/public/application/services/ml_api_service/results.ts @@ -6,7 +6,10 @@ */ // Service for obtaining data for the ML Results dashboards. -import { GetStoppedPartitionResult } from '../../../../common/types/results'; +import { + GetStoppedPartitionResult, + GetDatafeedResultsChartDataResult, +} from '../../../../common/types/results'; import { HttpService } from '../http_service'; import { basePath } from './index'; import { JobId } from '../../../../common/types/anomaly_detection_jobs'; @@ -148,7 +151,7 @@ export const resultsApiProvider = (httpService: HttpService) => ({ start, end, }); - return httpService.http({ + return httpService.http({ path: `${basePath()}/results/datafeed_results_chart`, method: 'POST', body, diff --git a/x-pack/plugins/ml/server/models/results_service/results_service.ts b/x-pack/plugins/ml/server/models/results_service/results_service.ts index 9413ee00184d20..81ee394b997044 100644 --- a/x-pack/plugins/ml/server/models/results_service/results_service.ts +++ b/x-pack/plugins/ml/server/models/results_service/results_service.ts @@ -27,6 +27,7 @@ import { import { MlJobsResponse } from '../../../common/types/job_service'; import type { MlClient } from '../../lib/ml_client'; import { datafeedsProvider } from '../job_service/datafeeds'; +import { annotationServiceProvider } from '../annotation_service'; // Service for carrying out Elasticsearch queries to obtain data for the // ML Results dashboards. @@ -620,13 +621,19 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust const finalResults: GetDatafeedResultsChartDataResult = { bucketResults: [], datafeedResults: [], + annotationResultsRect: [], + annotationResultsLine: [], + modelSnapshotResultsLine: [], }; const { getDatafeedByJobId } = datafeedsProvider(client!, mlClient); - const datafeedConfig = await getDatafeedByJobId(jobId); - const { body: jobsResponse } = await mlClient.getJobs({ job_id: jobId }); - if (jobsResponse.count === 0 || jobsResponse.jobs === undefined) { + const [datafeedConfig, { body: jobsResponse }] = await Promise.all([ + getDatafeedByJobId(jobId), + mlClient.getJobs({ job_id: jobId }), + ]); + + if (jobsResponse && (jobsResponse.count === 0 || jobsResponse.jobs === undefined)) { throw Boom.notFound(`Job with the id "${jobId}" not found`); } @@ -696,10 +703,25 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust ]) || []; } - const bucketResp = await mlClient.getBuckets({ - job_id: jobId, - body: { desc: true, start: String(start), end: String(end), page: { from: 0, size: 1000 } }, - }); + const { getAnnotations } = annotationServiceProvider(client!); + + const [bucketResp, annotationResp, { body: modelSnapshotsResp }] = await Promise.all([ + mlClient.getBuckets({ + job_id: jobId, + body: { desc: true, start: String(start), end: String(end), page: { from: 0, size: 1000 } }, + }), + getAnnotations({ + jobIds: [jobId], + earliestMs: start, + latestMs: end, + maxAnnotations: 1000, + }), + mlClient.getModelSnapshots({ + job_id: jobId, + start: String(start), + end: String(end), + }), + ]); const bucketResults = bucketResp?.body?.buckets ?? []; bucketResults.forEach((dataForTime) => { @@ -708,6 +730,36 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust finalResults.bucketResults.push([timestamp, eventCount]); }); + const annotationResults = annotationResp.annotations[jobId] || []; + annotationResults.forEach((annotation) => { + const timestamp = Number(annotation?.timestamp); + const endTimestamp = Number(annotation?.end_timestamp); + if (timestamp === endTimestamp) { + finalResults.annotationResultsLine.push({ + dataValue: timestamp, + details: annotation.annotation, + }); + } else { + finalResults.annotationResultsRect.push({ + coordinates: { + x0: timestamp, + x1: endTimestamp, + }, + details: annotation.annotation, + }); + } + }); + + const modelSnapshots = modelSnapshotsResp?.model_snapshots ?? []; + modelSnapshots.forEach((modelSnapshot) => { + const timestamp = Number(modelSnapshot?.timestamp); + + finalResults.modelSnapshotResultsLine.push({ + dataValue: timestamp, + details: modelSnapshot.description, + }); + }); + return finalResults; } diff --git a/x-pack/plugins/osquery/cypress/README.md b/x-pack/plugins/osquery/cypress/README.md new file mode 100644 index 00000000000000..0df311ebc0a05b --- /dev/null +++ b/x-pack/plugins/osquery/cypress/README.md @@ -0,0 +1,138 @@ +# Cypress Tests + +The `osquery/cypress` directory contains functional UI tests that execute using [Cypress](https://www.cypress.io/). + +## Running the tests + +There are currently three ways to run the tests, comprised of two execution modes and two target environments, which will be detailed below. + +### Execution modes + +#### Interactive mode + +When you run Cypress in interactive mode, an interactive runner is displayed that allows you to see commands as they execute while also viewing the application under test. For more information, please see [cypress documentation](https://docs.cypress.io/guides/core-concepts/test-runner.html#Overview). + +#### Headless mode + +A headless browser is a browser simulation program that does not have a user interface. These programs operate like any other browser, but do not display any UI. This is why meanwhile you are executing the tests on this mode you are not going to see the application under test. Just the output of the test is displayed on the terminal once the execution is finished. + +### Target environments + +#### FTR (CI) + +This is the configuration used by CI. It uses the FTR to spawn both a Kibana instance (http://localhost:5620) and an Elasticsearch instance (http://localhost:9220) with a preloaded minimum set of data (see preceding "Test data" section), and then executes cypress against this stack. You can find this configuration in `x-pack/test/security_solution_cypress` + +### Test Execution: Examples + +#### FTR + Headless (Chrome) + +Since this is how tests are run on CI, this will likely be the configuration you want to reproduce failures locally, etc. + +```shell +# bootstrap kibana from the project root +yarn kbn bootstrap + +# build the plugins/assets that cypress will execute against +node scripts/build_kibana_platform_plugins + +# launch the cypress test runner +cd x-pack/plugins/security_solution +yarn cypress:run-as-ci +``` +#### FTR + Interactive + +This is the preferred mode for developing new tests. + +```shell +# bootstrap kibana from the project root +yarn kbn bootstrap + +# build the plugins/assets that cypress will execute against +node scripts/build_kibana_platform_plugins + +# launch the cypress test runner +cd x-pack/plugins/security_solution +yarn cypress:open-as-ci +``` + +Note that you can select the browser you want to use on the top right side of the interactive runner. + +## Folder Structure + +### integration/ + +Cypress convention. Contains the specs that are going to be executed. + +### fixtures/ + +Cypress convention. Fixtures are used as external pieces of static data when we stub responses. + +### plugins/ + +Cypress convention. As a convenience, by default Cypress will automatically include the plugins file cypress/plugins/index.js before every single spec file it runs. + +### screens/ + +Contains the elements we want to interact with in our tests. + +Each file inside the screens folder represents a screen in our application. + +### tasks/ + +_Tasks_ are functions that may be reused across tests. + +Each file inside the tasks folder represents a screen of our application. + +## Test data + +The data the tests need: + +- Is generated on the fly using our application APIs (preferred way) +- Is ingested on the ELS instance using the `es_archive` utility + +### How to generate a new archive + +**Note:** As mentioned above, archives are only meant to contain external data, e.g. beats data. Due to the tendency for archived domain objects (rules, signals) to quickly become out of date, it is strongly suggested that you generate this data within the test, through interaction with either the UI or the API. + +We use es_archiver to manage the data that our Cypress tests need. + +1. Set up a clean instance of kibana and elasticsearch (if this is not possible, try to clean/minimize the data that you are going to archive). +2. With the kibana and elasticsearch instance up and running, create the data that you need for your test. +3. When you are sure that you have all the data you need run the following command from: `x-pack/plugins/security_solution` + +```sh +node ../../../scripts/es_archiver save --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url http://:@: +``` + +Example: + +```sh +node ../../../scripts/es_archiver save custom_rules ".kibana",".siem-signal*" --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url http://elastic:changeme@localhost:9220 +``` + +Note that the command will create the folder if it does not exist. + +## Development Best Practices + +### Clean up the state + +Remember to clean up the state of the test after its execution, typically with the `cleanKibana` function. Be mindful of failure scenarios, as well: if your test fails, will it leave the environment in a recoverable state? + +### Minimize the use of es_archive + +When possible, create all the data that you need for executing the tests using the application APIS or the UI. + +### Speed up test execution time + +Loading the web page takes a big amount of time, in order to minimize that impact, the following points should be +taken into consideration until another solution is implemented: + +- Group the tests that are similar in different contexts. +- For every context login only once, clean the state between tests if needed without re-loading the page. +- All tests in a spec file must be order-independent. + +Remember that minimizing the number of times the web page is loaded, we minimize as well the execution time. + +## Linting + +Optional linting rules for Cypress and linting setup can be found [here](https://github.com/cypress-io/eslint-plugin-cypress#usage) diff --git a/x-pack/plugins/osquery/cypress/cypress.json b/x-pack/plugins/osquery/cypress/cypress.json new file mode 100644 index 00000000000000..eb24616607ec3f --- /dev/null +++ b/x-pack/plugins/osquery/cypress/cypress.json @@ -0,0 +1,14 @@ +{ + "baseUrl": "http://localhost:5620", + "defaultCommandTimeout": 60000, + "execTimeout": 120000, + "pageLoadTimeout": 120000, + "nodeVersion": "system", + "retries": { + "runMode": 2 + }, + "trashAssetsBeforeRuns": false, + "video": false, + "viewportHeight": 900, + "viewportWidth": 1440 +} \ No newline at end of file diff --git a/x-pack/plugins/osquery/cypress/integration/osquery_manager.spec.ts b/x-pack/plugins/osquery/cypress/integration/osquery_manager.spec.ts new file mode 100644 index 00000000000000..0babfd2f10a8e6 --- /dev/null +++ b/x-pack/plugins/osquery/cypress/integration/osquery_manager.spec.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { HEADER } from '../screens/osquery'; +import { OSQUERY_NAVIGATION_LINK } from '../screens/navigation'; + +import { INTEGRATIONS, OSQUERY, openNavigationFlyout, navigateTo } from '../tasks/navigation'; +import { addIntegration } from '../tasks/integrations'; + +describe('Osquery Manager', () => { + before(() => { + navigateTo(INTEGRATIONS); + addIntegration('Osquery Manager'); + }); + + it('Displays Osquery on the navigation flyout once installed ', () => { + openNavigationFlyout(); + cy.get(OSQUERY_NAVIGATION_LINK).should('exist'); + }); + + it('Displays Live queries history title when navigating to Osquery', () => { + navigateTo(OSQUERY); + cy.get(HEADER).should('have.text', 'Live queries history'); + }); +}); diff --git a/x-pack/plugins/osquery/cypress/plugins/index.js b/x-pack/plugins/osquery/cypress/plugins/index.js new file mode 100644 index 00000000000000..7dbb69ced7016c --- /dev/null +++ b/x-pack/plugins/osquery/cypress/plugins/index.js @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +/** + * @type {Cypress.PluginConfig} + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +module.exports = (_on, _config) => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config +}; diff --git a/x-pack/plugins/osquery/cypress/screens/integrations.ts b/x-pack/plugins/osquery/cypress/screens/integrations.ts new file mode 100644 index 00000000000000..0b29e857f46ee4 --- /dev/null +++ b/x-pack/plugins/osquery/cypress/screens/integrations.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const ADD_POLICY_BTN = '[data-test-subj="addIntegrationPolicyButton"]'; +export const CREATE_PACKAGE_POLICY_SAVE_BTN = '[data-test-subj="createPackagePolicySaveButton"]'; +export const INTEGRATIONS_CARD = '.euiCard__titleAnchor'; diff --git a/x-pack/plugins/osquery/cypress/screens/navigation.ts b/x-pack/plugins/osquery/cypress/screens/navigation.ts new file mode 100644 index 00000000000000..7884cf347d7c09 --- /dev/null +++ b/x-pack/plugins/osquery/cypress/screens/navigation.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const TOGGLE_NAVIGATION_BTN = '[data-test-subj="toggleNavButton"]'; +export const OSQUERY_NAVIGATION_LINK = '[data-test-subj="collapsibleNavAppLink"] [title="Osquery"]'; diff --git a/x-pack/plugins/osquery/cypress/screens/osquery.ts b/x-pack/plugins/osquery/cypress/screens/osquery.ts new file mode 100644 index 00000000000000..bc387a57e9e3c5 --- /dev/null +++ b/x-pack/plugins/osquery/cypress/screens/osquery.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const HEADER = 'h1'; diff --git a/x-pack/plugins/osquery/cypress/support/commands.js b/x-pack/plugins/osquery/cypress/support/commands.js new file mode 100644 index 00000000000000..66f94350355712 --- /dev/null +++ b/x-pack/plugins/osquery/cypress/support/commands.js @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/x-pack/plugins/osquery/cypress/support/index.ts b/x-pack/plugins/osquery/cypress/support/index.ts new file mode 100644 index 00000000000000..72618c943f4d24 --- /dev/null +++ b/x-pack/plugins/osquery/cypress/support/index.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands'; + +// Alternatively you can use CommonJS syntax: +// require('./commands') +Cypress.on('uncaught:exception', () => { + return false; +}); diff --git a/x-pack/plugins/osquery/cypress/tasks/integrations.ts b/x-pack/plugins/osquery/cypress/tasks/integrations.ts new file mode 100644 index 00000000000000..f85ef56550af50 --- /dev/null +++ b/x-pack/plugins/osquery/cypress/tasks/integrations.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + ADD_POLICY_BTN, + CREATE_PACKAGE_POLICY_SAVE_BTN, + INTEGRATIONS_CARD, +} from '../screens/integrations'; + +export const addIntegration = (integration: string) => { + cy.get(INTEGRATIONS_CARD).contains(integration).click(); + cy.get(ADD_POLICY_BTN).click(); + cy.get(CREATE_PACKAGE_POLICY_SAVE_BTN).click(); + cy.get(CREATE_PACKAGE_POLICY_SAVE_BTN).should('not.exist'); + cy.reload(); +}; diff --git a/x-pack/plugins/osquery/cypress/tasks/navigation.ts b/x-pack/plugins/osquery/cypress/tasks/navigation.ts new file mode 100644 index 00000000000000..63d6b205b433bf --- /dev/null +++ b/x-pack/plugins/osquery/cypress/tasks/navigation.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TOGGLE_NAVIGATION_BTN } from '../screens/navigation'; + +export const INTEGRATIONS = 'app/integrations#/'; +export const OSQUERY = 'app/osquery/live_queries'; + +export const navigateTo = (page: string) => { + cy.visit(page); +}; + +export const openNavigationFlyout = () => { + cy.get(TOGGLE_NAVIGATION_BTN).click(); +}; diff --git a/x-pack/plugins/osquery/cypress/tsconfig.json b/x-pack/plugins/osquery/cypress/tsconfig.json new file mode 100644 index 00000000000000..467ea13fc48695 --- /dev/null +++ b/x-pack/plugins/osquery/cypress/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../../../tsconfig.base.json", + "exclude": [], + "include": [ + "./**/*" + ], + "compilerOptions": { + "tsBuildInfoFile": "../../../../build/tsbuildinfo/osquery/cypress", + "types": [ + "cypress", + "node" + ], + "resolveJsonModule": true, + }, + } diff --git a/x-pack/plugins/osquery/package.json b/x-pack/plugins/osquery/package.json new file mode 100644 index 00000000000000..5bbb95e556d6be --- /dev/null +++ b/x-pack/plugins/osquery/package.json @@ -0,0 +1,13 @@ +{ + "author": "Elastic", + "name": "osquery", + "version": "8.0.0", + "private": true, + "license": "Elastic-License", + "scripts": { + "cypress:open": "../../../node_modules/.bin/cypress open --config-file ./cypress/cypress.json", + "cypress:open-as-ci": "node ../../../scripts/functional_tests --config ../../test/osquery_cypress/visual_config.ts", + "cypress:run": "../../../node_modules/.bin/cypress run --config-file ./cypress/cypress.json", + "cypress:run-as-ci": "node ../../../scripts/functional_tests --config ../../test/osquery_cypress/cli_config.ts" + } +} diff --git a/x-pack/plugins/osquery/server/usage/fetchers.ts b/x-pack/plugins/osquery/server/usage/fetchers.ts index 6a4236b5adccd3..3d5f3592101fd2 100644 --- a/x-pack/plugins/osquery/server/usage/fetchers.ts +++ b/x-pack/plugins/osquery/server/usage/fetchers.ts @@ -56,6 +56,7 @@ export async function getPolicyLevelUsage( }, }, index: '.fleet-agents', + ignore_unavailable: true, }); const policied = agentResponse.body.aggregations?.policied as AggregationsSingleBucketAggregate; if (policied && typeof policied.doc_count === 'number') { @@ -118,6 +119,7 @@ export async function getLiveQueryUsage( }, }, index: '.fleet-actions', + ignore_unavailable: true, }); const result: LiveQueryUsage = { session: await getRouteMetric(soClient, 'live_query'), @@ -226,6 +228,7 @@ export async function getBeatUsage(esClient: ElasticsearchClient) { }, }, index: METRICS_INDICES, + ignore_unavailable: true, }); return extractBeatUsageMetrics(metricResponse); diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index e65ff1afcc9c33..d112630facbc6f 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -44,7 +44,8 @@ export const DEFAULT_INTERVAL_VALUE = 300000; // ms export const DEFAULT_TIMEPICKER_QUICK_RANGES = 'timepicker:quickRanges'; export const DEFAULT_TRANSFORMS = 'securitySolution:transforms'; export const SCROLLING_DISABLED_CLASS_NAME = 'scrolling-disabled'; -export const GLOBAL_HEADER_HEIGHT = 98; // px +export const GLOBAL_HEADER_HEIGHT = 96; // px +export const GLOBAL_HEADER_HEIGHT_WITH_GLOBAL_BANNER = 128; // px export const FILTERS_GLOBAL_HEIGHT = 109; // px export const FULL_SCREEN_TOGGLED_CLASS_NAME = 'fullScreenToggled'; export const NO_ALERT_INDEX = 'no-alert-index-049FC71A-4C2C-446F-9901-37XMC5024C51'; diff --git a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts index 99753242e76279..dfaad68e295ebd 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts @@ -58,7 +58,6 @@ export interface ActivityLogActionResponse { } export type ActivityLogEntry = ActivityLogAction | ActivityLogActionResponse; export interface ActivityLog { - total: number; page: number; pageSize: number; data: ActivityLogEntry[]; diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index b20b1501eecc57..a9a81aa285af7c 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -15,6 +15,7 @@ const allowedExperimentalValues = Object.freeze({ trustedAppsByPolicyEnabled: false, metricsEntitiesEnabled: false, ruleRegistryEnabled: false, + tGridEnabled: false, }); type ExperimentalConfigKeys = Array; diff --git a/x-pack/plugins/security_solution/common/index.ts b/x-pack/plugins/security_solution/common/index.ts index 1fec1c76430ebd..e6d7bcc9bd506c 100644 --- a/x-pack/plugins/security_solution/common/index.ts +++ b/x-pack/plugins/security_solution/common/index.ts @@ -4,3 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + +export * from './types'; +export * from './search_strategy'; +export * from './utility_types'; diff --git a/x-pack/plugins/security_solution/common/search_strategy/common/index.ts b/x-pack/plugins/security_solution/common/search_strategy/common/index.ts index 4fcfbdac3c1b4c..095ba4ca20afca 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/common/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/common/index.ts @@ -4,52 +4,27 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { estypes } from '@elastic/elasticsearch'; import { IEsSearchResponse } from '../../../../../../src/plugins/data/common'; +export type { + Inspect, + SortField, + TimerangeInput, + PaginationInputPaginated, + DocValueFields, + CursorType, + TotalValue, +} from '../../../../timelines/common'; +export { Direction } from '../../../../timelines/common'; export type Maybe = T | null; export type SearchHit = IEsSearchResponse['rawResponse']['hits']['hits'][0]; -export interface TotalValue { - value: number; - relation: string; -} - -export interface Inspect { - dsl: string[]; -} - export interface PageInfoPaginated { activePage: number; fakeTotalCount: number; showMorePagesIndicator: boolean; } - -export interface CursorType { - value?: Maybe; - tiebreaker?: Maybe; -} - -export enum Direction { - asc = 'asc', - desc = 'desc', -} - -export interface SortField { - field: Field; - direction: Direction; -} - -export interface TimerangeInput { - /** The interval string to use for last bucket. The format is '{value}{unit}'. For example '5m' would return the metrics for the last 5 minutes of the timespan. */ - interval: string; - /** The end of the timerange */ - to: string; - /** The beginning of the timerange */ - from: string; -} - export interface PaginationInput { /** The limit parameter allows you to configure the maximum amount of items to be returned */ limit: number; @@ -59,19 +34,6 @@ export interface PaginationInput { tiebreaker?: Maybe; } -export interface PaginationInputPaginated { - /** The activePage parameter defines the page of results you want to fetch */ - activePage: number; - /** The cursorStart parameter defines the start of the results to be displayed */ - cursorStart: number; - /** The fakePossibleCount parameter determines the total count in order to show 5 additional pages */ - fakePossibleCount: number; - /** The querySize parameter is the number of items to be returned */ - querySize: number; -} - -export type DocValueFields = estypes.SearchDocValueField; - export interface Explanation { value: number; description: string; @@ -111,13 +73,3 @@ export interface GenericBuckets { } export type StringOrNumber = string | number; - -export interface TimerangeFilter { - range: { - [timestamp: string]: { - gte: string; - lte: string; - format: string; - }; - }; -} diff --git a/x-pack/plugins/security_solution/common/search_strategy/index.ts b/x-pack/plugins/security_solution/common/search_strategy/index.ts index 575256b991d163..e3d6736878063b 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/index.ts @@ -8,3 +8,4 @@ export * from './common'; export * from './security_solution'; export * from './timeline'; +export * from './index_fields'; diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/all/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/all/index.ts index d747758640fab2..4e5f8af41a2ef0 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/all/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/all/index.ts @@ -5,37 +5,10 @@ * 2.0. */ -import { IEsSearchResponse } from '../../../../../../../../src/plugins/data/common'; -import { Ecs } from '../../../../ecs'; -import { CursorType, Inspect, Maybe, PaginationInputPaginated } from '../../../common'; -import { TimelineRequestOptionsPaginated } from '../..'; - -export interface TimelineEdges { - node: TimelineItem; - cursor: CursorType; -} - -export interface TimelineItem { - _id: string; - _index?: Maybe; - data: TimelineNonEcsData[]; - ecs: Ecs; -} - -export interface TimelineNonEcsData { - field: string; - value?: Maybe; -} - -export interface TimelineEventsAllStrategyResponse extends IEsSearchResponse { - edges: TimelineEdges[]; - totalCount: number; - pageInfo: Pick; - inspect?: Maybe; -} - -export interface TimelineEventsAllRequestOptions extends TimelineRequestOptionsPaginated { - fields: string[] | Array<{ field: string; include_unmapped: boolean }>; - fieldRequested: string[]; - language: 'eql' | 'kuery' | 'lucene'; -} +export type { + TimelineEdges, + TimelineItem, + TimelineNonEcsData, + TimelineEventsAllStrategyResponse, + TimelineEventsAllRequestOptions, +} from '../../../../../../timelines/common'; diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/common/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/common/index.ts index 4a5bd2c99a0eb6..e4d2ea52ffdff5 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/common/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/common/index.ts @@ -5,22 +5,8 @@ * 2.0. */ -import { Ecs } from '../../../../ecs'; -import { CursorType, Maybe } from '../../../common'; - -export interface TimelineEdges { - node: TimelineItem; - cursor: CursorType; -} - -export interface TimelineItem { - _id: string; - _index?: Maybe; - data: TimelineNonEcsData[]; - ecs: Ecs; -} - -export interface TimelineNonEcsData { - field: string; - value?: Maybe; -} +export type { + TimelineEdges, + TimelineItem, + TimelineNonEcsData, +} from '../../../../../../timelines/common'; diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/details/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/details/index.ts index 1f9820f8e5c2b0..3fd13e56cc7e7e 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/details/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/details/index.ts @@ -5,27 +5,8 @@ * 2.0. */ -import { IEsSearchResponse } from '../../../../../../../../src/plugins/data/common'; -import { Inspect, Maybe } from '../../../common'; -import { TimelineRequestOptionsPaginated } from '../..'; - -export interface TimelineEventsDetailsItem { - ariaRowindex?: Maybe; - category?: string; - field: string; - values?: Maybe; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - originalValue?: Maybe; - isObjectArray: boolean; -} - -export interface TimelineEventsDetailsStrategyResponse extends IEsSearchResponse { - data?: Maybe; - inspect?: Maybe; -} - -export interface TimelineEventsDetailsRequestOptions - extends Partial { - indexName: string; - eventId: string; -} +export type { + TimelineEventsDetailsItem, + TimelineEventsDetailsStrategyResponse, + TimelineEventsDetailsRequestOptions, +} from '../../../../../../timelines/common'; diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/eql/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/eql/index.ts index c508876032fca2..10e9bbd7670cd4 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/eql/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/eql/index.ts @@ -5,43 +5,10 @@ * 2.0. */ -import { EuiComboBoxOptionOption } from '@elastic/eui'; -import { - EqlSearchStrategyRequest, - EqlSearchStrategyResponse, -} from '../../../../../../../../src/plugins/data/common'; -import { Inspect, Maybe, PaginationInputPaginated } from '../../..'; -import { TimelineEdges, TimelineEventsAllRequestOptions } from '../..'; -import { EqlSearchResponse } from '../../../../detection_engine/types'; - -export interface TimelineEqlRequestOptions - extends EqlSearchStrategyRequest, - Omit { - eventCategoryField?: string; - tiebreakerField?: string; - timestampField?: string; - size?: number; -} - -export interface TimelineEqlResponse extends EqlSearchStrategyResponse> { - edges: TimelineEdges[]; - totalCount: number; - pageInfo: Pick; - inspect: Maybe; -} - -export interface EqlOptionsData { - keywordFields: EuiComboBoxOptionOption[]; - dateFields: EuiComboBoxOptionOption[]; - nonDateFields: EuiComboBoxOptionOption[]; -} - -export interface EqlOptionsSelected { - eventCategoryField?: string; - tiebreakerField?: string; - timestampField?: string; - query?: string; - size?: number; -} - -export type FieldsEqlOptions = keyof EqlOptionsSelected; +export type { + TimelineEqlRequestOptions, + TimelineEqlResponse, + EqlOptionsData, + EqlOptionsSelected, + FieldsEqlOptions, +} from '../../../../../../timelines/common'; diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/last_event_time/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/last_event_time/index.ts index f29dc4a3c74509..39f23a63c8afea 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/last_event_time/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/last_event_time/index.ts @@ -5,38 +5,11 @@ * 2.0. */ -import { IEsSearchResponse } from '../../../../../../../../src/plugins/data/common'; -import { Inspect, Maybe } from '../../../common'; -import { TimelineRequestBasicOptions } from '../..'; - -export enum LastEventIndexKey { - hostDetails = 'hostDetails', - hosts = 'hosts', - ipDetails = 'ipDetails', - network = 'network', -} - -export interface LastTimeDetails { - hostName?: Maybe; - ip?: Maybe; -} - -export interface TimelineEventsLastEventTimeStrategyResponse extends IEsSearchResponse { - lastSeen: Maybe; - inspect?: Maybe; -} - -export interface TimelineKpiStrategyResponse extends IEsSearchResponse { - destinationIpCount: number; - inspect?: Maybe; - hostCount: number; - processCount: number; - sourceIpCount: number; - userCount: number; -} - -export interface TimelineEventsLastEventTimeRequestOptions - extends Omit { - indexKey: LastEventIndexKey; - details: LastTimeDetails; -} +export { LastEventIndexKey } from '../../../../../../timelines/common'; + +export type { + LastTimeDetails, + TimelineEventsLastEventTimeStrategyResponse, + TimelineKpiStrategyResponse, + TimelineEventsLastEventTimeRequestOptions, +} from '../../../../../../timelines/common'; diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/index.ts index 9c2c23eb334a3d..7064ef033fc5a0 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/index.ts @@ -24,7 +24,12 @@ import { SortField, Maybe, } from '../common'; -import { DataProviderType, TimelineType, TimelineStatus } from '../../types/timeline'; +import { + DataProviderType, + TimelineType, + TimelineStatus, + RowRendererId, +} from '../../types/timeline'; export * from './events'; @@ -165,25 +170,6 @@ export interface SortTimelineInput { sortDirection?: Maybe; } -export enum RowRendererId { - alerts = 'alerts', - auditd = 'auditd', - auditd_file = 'auditd_file', - library = 'library', - netflow = 'netflow', - plain = 'plain', - registry = 'registry', - suricata = 'suricata', - system = 'system', - system_dns = 'system_dns', - system_endgame_process = 'system_endgame_process', - system_file = 'system_file', - system_fim = 'system_fim', - system_security_event = 'system_security_event', - system_socket = 'system_socket', - zeek = 'zeek', -} - export interface TimelineInput { columns?: Maybe; dataProviders?: Maybe; diff --git a/x-pack/plugins/index_management/public/application/components/page_error/index.ts b/x-pack/plugins/security_solution/common/types/index.ts similarity index 80% rename from x-pack/plugins/index_management/public/application/components/page_error/index.ts rename to x-pack/plugins/security_solution/common/types/index.ts index 040edfa362c636..9464a33082a495 100644 --- a/x-pack/plugins/index_management/public/application/components/page_error/index.ts +++ b/x-pack/plugins/security_solution/common/types/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export { PageErrorForbidden } from './page_error_forbidden'; +export * from './timeline'; diff --git a/x-pack/plugins/security_solution/common/types/timeline/actions/index.ts b/x-pack/plugins/security_solution/common/types/timeline/actions/index.ts new file mode 100644 index 00000000000000..782af107417c2a --- /dev/null +++ b/x-pack/plugins/security_solution/common/types/timeline/actions/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +export type { + ActionProps, + HeaderActionProps, + GenericActionRowCellRenderProps, + HeaderCellRender, + RowCellRender, + ControlColumnProps, +} from '../../../../../timelines/common'; diff --git a/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts b/x-pack/plugins/security_solution/common/types/timeline/cells/index.ts new file mode 100644 index 00000000000000..83b0ced332a62c --- /dev/null +++ b/x-pack/plugins/security_solution/common/types/timeline/cells/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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { CellValueElementProps } from '../../../../../timelines/common'; diff --git a/x-pack/plugins/security_solution/common/types/timeline/columns/index.ts b/x-pack/plugins/security_solution/common/types/timeline/columns/index.ts new file mode 100644 index 00000000000000..ee4d621e35d6cd --- /dev/null +++ b/x-pack/plugins/security_solution/common/types/timeline/columns/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { + ColumnHeaderType, + ColumnId, + ColumnHeaderOptions, + ColumnRenderer, +} from '../../../../../timelines/common'; diff --git a/x-pack/plugins/security_solution/common/types/timeline/data_provider/index.ts b/x-pack/plugins/security_solution/common/types/timeline/data_provider/index.ts new file mode 100644 index 00000000000000..f363176ac0a88c --- /dev/null +++ b/x-pack/plugins/security_solution/common/types/timeline/data_provider/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +export { IS_OPERATOR, EXISTS_OPERATOR } from '../../../../../timelines/common'; + +export type { + QueryOperator, + DataProviderType, + QueryMatch, + DataProvider, + DataProvidersAnd, +} from '../../../../../timelines/common'; diff --git a/x-pack/plugins/security_solution/common/types/timeline/index.ts b/x-pack/plugins/security_solution/common/types/timeline/index.ts index 7ae52a3990ff7d..05cf99195774b9 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/index.ts @@ -23,6 +23,13 @@ import { FlowTarget } from '../../search_strategy/security_solution/network'; import { errorSchema } from '../../detection_engine/schemas/response/error_schema'; import { Direction, Maybe } from '../../search_strategy'; +export * from './actions'; +export * from './cells'; +export * from './columns'; +export * from './data_provider'; +export * from './rows'; +export * from './store'; + /* * ColumnHeader Types */ @@ -492,6 +499,11 @@ export type TimelineExpandedDetail = { [tab in TimelineTabs]?: TimelineExpandedDetailType; }; +export type ToggleDetailPanel = TimelineExpandedDetailType & { + tabType?: TimelineTabs; + timelineId: string; +}; + export const pageInfoTimeline = runtimeTypes.type({ pageIndex: runtimeTypes.number, pageSize: runtimeTypes.number, diff --git a/x-pack/plugins/security_solution/common/types/timeline/rows/index.ts b/x-pack/plugins/security_solution/common/types/timeline/rows/index.ts new file mode 100644 index 00000000000000..ae2d19a5e2ca8c --- /dev/null +++ b/x-pack/plugins/security_solution/common/types/timeline/rows/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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +export type { RowRenderer } from '../../../../../timelines/common'; diff --git a/x-pack/plugins/security_solution/common/types/timeline/store.ts b/x-pack/plugins/security_solution/common/types/timeline/store.ts new file mode 100644 index 00000000000000..01fc9db7c8e1da --- /dev/null +++ b/x-pack/plugins/security_solution/common/types/timeline/store.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + ColumnHeaderOptions, + ColumnId, + RowRendererId, + TimelineExpandedDetail, + TimelineTypeLiteral, +} from '.'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { Filter } from '../../../../../../src/plugins/data/public'; + +import { Direction } from '../../search_strategy'; +import { DataProvider } from './data_provider'; + +export type KueryFilterQueryKind = 'kuery' | 'lucene' | 'eql'; + +export interface KueryFilterQuery { + kind: KueryFilterQueryKind; + expression: string; +} + +export interface SerializedFilterQuery { + kuery: KueryFilterQuery | null; + serializedQuery: string; +} + +export type SortDirection = 'none' | 'asc' | 'desc' | Direction; +export interface SortColumnTimeline { + columnId: string; + columnType: string; + sortDirection: SortDirection; +} + +export interface TimelinePersistInput { + id: string; + dataProviders?: DataProvider[]; + dateRange?: { + start: string; + end: string; + }; + excludedRowRendererIds?: RowRendererId[]; + expandedDetail?: TimelineExpandedDetail; + filters?: Filter[]; + columns: ColumnHeaderOptions[]; + itemsPerPage?: number; + indexNames: string[]; + kqlQuery?: { + filterQuery: SerializedFilterQuery | null; + }; + show?: boolean; + sort?: SortColumnTimeline[]; + showCheckboxes?: boolean; + timelineType?: TimelineTypeLiteral; + templateTimelineId?: string | null; + templateTimelineVersion?: number | null; +} + +/** Invoked when a column is sorted */ +export type OnColumnSorted = (sorted: { columnId: ColumnId; sortDirection: SortDirection }) => void; + +export type OnColumnsSorted = ( + sorted: Array<{ columnId: ColumnId; sortDirection: SortDirection }> +) => void; + +export type OnColumnRemoved = (columnId: ColumnId) => void; + +export type OnColumnResized = ({ columnId, delta }: { columnId: ColumnId; delta: number }) => void; + +/** Invoked when a user clicks to load more item */ +export type OnChangePage = (nextPage: number) => void; + +/** Invoked when a user checks/un-checks a row */ +export type OnRowSelected = ({ + eventIds, + isSelected, +}: { + eventIds: string[]; + isSelected: boolean; +}) => void; + +/** Invoked when a user checks/un-checks the select all checkbox */ +export type OnSelectAll = ({ isSelected }: { isSelected: boolean }) => void; + +/** Invoked when columns are updated */ +export type OnUpdateColumns = (columns: ColumnHeaderOptions[]) => void; + +/** Invoked when a user pins an event */ +export type OnPinEvent = (eventId: string) => void; + +/** Invoked when a user unpins an event */ +export type OnUnPinEvent = (eventId: string) => void; diff --git a/x-pack/plugins/security_solution/common/utils/field_formatters.test.ts b/x-pack/plugins/security_solution/common/utils/field_formatters.test.ts index b724c0f672b506..64d4f2986903a1 100644 --- a/x-pack/plugins/security_solution/common/utils/field_formatters.test.ts +++ b/x-pack/plugins/security_solution/common/utils/field_formatters.test.ts @@ -7,7 +7,7 @@ import { EventHit, EventSource } from '../search_strategy'; import { getDataFromFieldsHits, getDataFromSourceHits, getDataSafety } from './field_formatters'; -import { eventDetailsFormattedFields, eventHit } from './mock_event_details'; +import { eventDetailsFormattedFields, eventHit } from '@kbn/securitysolution-t-grid'; describe('Events Details Helpers', () => { const fields: EventHit['fields'] = eventHit.fields; diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts index f1ee0d39f545f5..bf5c281a43e39e 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts @@ -129,7 +129,13 @@ describe('Alerts detection rules', () => { }); it('Auto refreshes rules', () => { - cy.clock(Date.now()); + /** + * Ran into the error: timer created with setInterval() but cleared with cancelAnimationFrame() + * There are no cancelAnimationFrames in the codebase that are used to clear a setInterval so + * explicitly set the below overrides. see https://docs.cypress.io/api/commands/clock#Function-names + */ + + cy.clock(Date.now(), ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'Date']); goToManageAlertsDetectionRules(); waitForRulesTableToBeLoaded(); diff --git a/x-pack/plugins/security_solution/cypress/integration/overview/overview.spec.ts b/x-pack/plugins/security_solution/cypress/integration/overview/overview.spec.ts index 78ee3fdcdcdd50..3ff036fa0107fe 100644 --- a/x-pack/plugins/security_solution/cypress/integration/overview/overview.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/overview/overview.spec.ts @@ -45,7 +45,7 @@ describe('Overview Page', () => { describe('with no data', () => { it('Splash screen should be here', () => { - cy.stubSearchStrategyApi(emptyInstance, undefined, 'securitySolutionIndexFields'); + cy.stubSearchStrategyApi(emptyInstance, undefined, 'indexFields'); loginAndWaitForPage(OVERVIEW_URL); cy.get(OVERVIEW_EMPTY_PAGE).should('be.visible'); }); diff --git a/x-pack/plugins/security_solution/cypress/integration/timelines/data_providers.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timelines/data_providers.spec.ts index d42632a66eb260..a0e7e77f89b679 100644 --- a/x-pack/plugins/security_solution/cypress/integration/timelines/data_providers.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/timelines/data_providers.spec.ts @@ -12,6 +12,7 @@ import { TIMELINE_DATA_PROVIDERS_ACTION_MENU, IS_DRAGGING_DATA_PROVIDERS, TIMELINE_FLYOUT_HEADER, + TIMELINE_BOTTOM_BAR_CONTAINER, } from '../../screens/timeline'; import { HOSTS_NAMES_DRAGGABLE } from '../../screens/hosts/all_hosts'; @@ -46,7 +47,7 @@ describe('timeline data providers', () => { it('renders the data provider of a host dragged from the All Hosts widget on the hosts page', () => { dragAndDropFirstHostToTimeline(); openTimelineUsingToggle(); - cy.get(TIMELINE_DROPPED_DATA_PROVIDERS) + cy.get(`${TIMELINE_BOTTOM_BAR_CONTAINER} ${TIMELINE_DROPPED_DATA_PROVIDERS}`) .first() .invoke('text') .then((dataProviderText) => { diff --git a/x-pack/plugins/security_solution/cypress/integration/timelines/pagination.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timelines/pagination.spec.ts index 568fb90568fb33..8b65f99eb04b87 100644 --- a/x-pack/plugins/security_solution/cypress/integration/timelines/pagination.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/timelines/pagination.spec.ts @@ -6,6 +6,7 @@ */ import { + TIMELINE_BOTTOM_BAR_CONTAINER, TIMELINE_EVENT, TIMELINE_EVENTS_COUNT_NEXT_PAGE, TIMELINE_EVENTS_COUNT_PER_PAGE, @@ -50,10 +51,10 @@ describe('Pagination', () => { it('should be able to go to next / previous page', () => { cy.intercept('POST', '/internal/bsearch').as('refetch'); - cy.get(TIMELINE_EVENTS_COUNT_NEXT_PAGE).first().click(); + cy.get(`${TIMELINE_BOTTOM_BAR_CONTAINER} ${TIMELINE_EVENTS_COUNT_NEXT_PAGE}`).first().click(); cy.wait('@refetch').its('response.statusCode').should('eq', 200); - cy.get(TIMELINE_EVENTS_COUNT_PREV_PAGE).first().click(); + cy.get(`${TIMELINE_BOTTOM_BAR_CONTAINER} ${TIMELINE_EVENTS_COUNT_PREV_PAGE}`).first().click(); cy.wait('@refetch').its('response.statusCode').should('eq', 200); }); }); diff --git a/x-pack/plugins/security_solution/cypress/screens/timeline.ts b/x-pack/plugins/security_solution/cypress/screens/timeline.ts index 0a9e5b44feb1f6..25cd2357fe02bc 100644 --- a/x-pack/plugins/security_solution/cypress/screens/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/screens/timeline.ts @@ -143,6 +143,8 @@ export const TIMELINE_CORRELATION_TAB = '[data-test-subj="timelineTabs-eql"]'; export const IS_DRAGGING_DATA_PROVIDERS = '.is-dragging'; +export const TIMELINE_BOTTOM_BAR_CONTAINER = '[data-test-subj="timeline-bottom-bar-container"]'; + export const TIMELINE_DATA_PROVIDERS = '[data-test-subj="dataProviders"]'; export const TIMELINE_DATA_PROVIDERS_ACTION_MENU = '[data-test-subj="providerActions"]'; diff --git a/x-pack/plugins/security_solution/cypress/support/commands.js b/x-pack/plugins/security_solution/cypress/support/commands.js index 90eb9a38d7509c..e74d06cd621fb2 100644 --- a/x-pack/plugins/security_solution/cypress/support/commands.js +++ b/x-pack/plugins/security_solution/cypress/support/commands.js @@ -35,7 +35,7 @@ Cypress.Commands.add( 'stubSearchStrategyApi', function (stubObject, factoryQueryType, searchStrategyName = 'securitySolutionSearchStrategy') { cy.intercept('POST', '/internal/bsearch', (req) => { - if (searchStrategyName === 'securitySolutionIndexFields') { + if (searchStrategyName === 'indexFields') { req.reply(stubObject.rawResponse); } else if (factoryQueryType === 'overviewHost') { req.reply(stubObject.overviewHost); diff --git a/x-pack/plugins/security_solution/kibana.json b/x-pack/plugins/security_solution/kibana.json index 02dbc56bd33976..e26f0d9b65bfae 100644 --- a/x-pack/plugins/security_solution/kibana.json +++ b/x-pack/plugins/security_solution/kibana.json @@ -17,6 +17,7 @@ "inspector", "licensing", "maps", + "timelines", "triggersActionsUi", "uiActions" ], diff --git a/x-pack/plugins/security_solution/public/app/404.tsx b/x-pack/plugins/security_solution/public/app/404.tsx index c21f7a4d4d5782..2634ffd47bff1d 100644 --- a/x-pack/plugins/security_solution/public/app/404.tsx +++ b/x-pack/plugins/security_solution/public/app/404.tsx @@ -8,15 +8,15 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { WrapperPage } from '../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../common/components/page_wrapper'; export const NotFoundPage = React.memo(() => ( - + - + )); NotFoundPage.displayName = 'NotFoundPage'; diff --git a/x-pack/plugins/security_solution/public/app/app.tsx b/x-pack/plugins/security_solution/public/app/app.tsx index cfb25c4436db3b..c223570c77201c 100644 --- a/x-pack/plugins/security_solution/public/app/app.tsx +++ b/x-pack/plugins/security_solution/public/app/app.tsx @@ -11,7 +11,7 @@ import { Store, Action } from 'redux'; import { Provider as ReduxStoreProvider } from 'react-redux'; import { EuiErrorBoundary } from '@elastic/eui'; -import { AppLeaveHandler } from '../../../../../src/core/public'; +import { AppLeaveHandler, AppMountParameters } from '../../../../../src/core/public'; import { ManageUserInfo } from '../detections/components/user_info'; import { DEFAULT_DARK_MODE, APP_NAME } from '../../common/constants'; @@ -21,7 +21,6 @@ import { GlobalToaster, ManageGlobalToaster } from '../common/components/toaster import { KibanaContextProvider, useKibana, useUiSetting$ } from '../common/lib/kibana'; import { State } from '../common/store'; -import { ManageGlobalTimeline } from '../timelines/components/manage_timeline'; import { StartServices } from '../types'; import { PageRouter } from './routes'; import { EuiThemeProvider } from '../../../../../src/plugins/kibana_react/common'; @@ -31,10 +30,17 @@ interface StartAppComponent { children: React.ReactNode; history: History; onAppLeave: (handler: AppLeaveHandler) => void; + setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; store: Store; } -const StartAppComponent: FC = ({ children, history, onAppLeave, store }) => { +const StartAppComponent: FC = ({ + children, + history, + setHeaderActionMenu, + onAppLeave, + store, +}) => { const { i18n } = useKibana().services; const [darkMode] = useUiSetting$(DEFAULT_DARK_MODE); @@ -42,23 +48,25 @@ const StartAppComponent: FC = ({ children, history, onAppLeav - - - - - - - - {children} - - - - - - - - - + + + + + + + {children} + + + + + + + + @@ -72,6 +80,7 @@ interface SecurityAppComponentProps { history: History; onAppLeave: (handler: AppLeaveHandler) => void; services: StartServices; + setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; store: Store; } @@ -80,6 +89,7 @@ const SecurityAppComponent: React.FC = ({ history, onAppLeave, services, + setHeaderActionMenu, store, }) => ( = ({ ...services, }} > - + {children} diff --git a/x-pack/plugins/security_solution/public/app/home/global_header/index.tsx b/x-pack/plugins/security_solution/public/app/home/global_header/index.tsx new file mode 100644 index 00000000000000..98ff11423ce01c --- /dev/null +++ b/x-pack/plugins/security_solution/public/app/home/global_header/index.tsx @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + EuiHeaderSection, + EuiHeaderLinks, + EuiHeaderLink, + EuiHeaderSectionItem, +} from '@elastic/eui'; +import React, { useEffect, useMemo } from 'react'; +import { createPortalNode, OutPortal, InPortal } from 'react-reverse-portal'; +import { i18n } from '@kbn/i18n'; + +import { AppMountParameters } from '../../../../../../../src/core/public'; +import { toMountPoint } from '../../../../../../../src/plugins/kibana_react/public'; +import { MlPopover } from '../../../common/components/ml_popover/ml_popover'; +import { useKibana } from '../../../common/lib/kibana'; +import { ADD_DATA_PATH, APP_DETECTIONS_PATH } from '../../../../common/constants'; + +const BUTTON_ADD_DATA = i18n.translate('xpack.securitySolution.globalHeader.buttonAddData', { + defaultMessage: 'Add data', +}); + +/** + * This component uses the reverse portal to add the Add Data and ML job settings buttons on the + * right hand side of the Kibana global header + */ +export const GlobalHeader = React.memo( + ({ setHeaderActionMenu }: { setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'] }) => { + const portalNode = useMemo(() => createPortalNode(), []); + const { http } = useKibana().services; + + useEffect(() => { + let unmount = () => {}; + + setHeaderActionMenu((element) => { + const mount = toMountPoint(); + unmount = mount(element); + return unmount; + }); + + return () => { + portalNode.unmount(); + unmount(); + }; + }, [portalNode, setHeaderActionMenu]); + + return ( + + + {window.location.pathname.includes(APP_DETECTIONS_PATH) && ( + + + + )} + + + + {BUTTON_ADD_DATA} + + + + + + ); + } +); +GlobalHeader.displayName = 'GlobalHeader'; diff --git a/x-pack/plugins/security_solution/public/app/home/home_navigations.tsx b/x-pack/plugins/security_solution/public/app/home/home_navigations.tsx index 7ebcc967538366..8358e2f9377b82 100644 --- a/x-pack/plugins/security_solution/public/app/home/home_navigations.tsx +++ b/x-pack/plugins/security_solution/public/app/home/home_navigations.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import * as i18n from './translations'; +import * as i18n from '../translations'; import { SecurityPageName } from '../types'; import { SiemNavTab } from '../../common/components/navigation/types'; import { diff --git a/x-pack/plugins/security_solution/public/app/home/index.tsx b/x-pack/plugins/security_solution/public/app/home/index.tsx index 1b0ddcfb9ae7d2..9a57ab3fc3a738 100644 --- a/x-pack/plugins/security_solution/public/app/home/index.tsx +++ b/x-pack/plugins/security_solution/public/app/home/index.tsx @@ -5,57 +5,35 @@ * 2.0. */ -import React, { useEffect, useRef, useState } from 'react'; -import styled from 'styled-components'; +import React, { useRef } from 'react'; -import { TimelineId } from '../../../common/types/timeline'; import { DragDropContextWrapper } from '../../common/components/drag_and_drop/drag_drop_context_wrapper'; -import { Flyout } from '../../timelines/components/flyout'; +import { AppLeaveHandler, AppMountParameters } from '../../../../../../src/core/public'; import { SecuritySolutionAppWrapper } from '../../common/components/page'; -import { HeaderGlobal } from '../../common/components/header_global'; import { HelpMenu } from '../../common/components/help_menu'; -import { AutoSaveWarningMsg } from '../../timelines/components/timeline/auto_save_warning'; import { UseUrlState } from '../../common/components/url_state'; -import { useShowTimeline } from '../../common/utils/timeline/use_show_timeline'; import { navTabs } from './home_navigations'; import { useInitSourcerer, useSourcererScope } from '../../common/containers/sourcerer'; import { useKibana } from '../../common/lib/kibana'; import { DETECTIONS_SUB_PLUGIN_ID } from '../../../common/constants'; import { SourcererScopeName } from '../../common/store/sourcerer/model'; import { useUpgradeEndpointPackage } from '../../common/hooks/endpoint/upgrade'; -import { useThrottledResizeObserver } from '../../common/components/utils'; -import { AppLeaveHandler } from '../../../../../../src/core/public'; - -const Main = styled.main.attrs<{ paddingTop: number }>(({ paddingTop }) => ({ - style: { - paddingTop: `${paddingTop}px`, - }, -}))<{ paddingTop: number }>` - overflow: auto; - display: flex; - flex-direction: column; - flex: 1 1 auto; -`; - -Main.displayName = 'Main'; +import { GlobalHeader } from './global_header'; +import { SecuritySolutionTemplateWrapper } from './template_wrapper'; interface HomePageProps { children: React.ReactNode; onAppLeave: (handler: AppLeaveHandler) => void; + setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; } -const HomePageComponent: React.FC = ({ children, onAppLeave }) => { - const { application, overlays } = useKibana().services; +const HomePageComponent: React.FC = ({ + children, + onAppLeave, + setHeaderActionMenu, +}) => { + const { application } = useKibana().services; const subPluginId = useRef(''); - const { ref, height = 0 } = useThrottledResizeObserver(300); - const banners$ = overlays.banners.get$(); - const [headerFixed, setHeaderFixed] = useState(true); - const mainPaddingTop = headerFixed ? height : 0; - - useEffect(() => { - const subscription = banners$.subscribe((banners) => setHeaderFixed(!banners.length)); - return () => subscription.unsubscribe(); - }, [banners$]); // Only un/re-subscribe if the Observable changes application.currentAppId$.subscribe((appId) => { subPluginId.current = appId ?? ''; @@ -66,13 +44,13 @@ const HomePageComponent: React.FC = ({ children, onAppLeave }) => ? SourcererScopeName.detections : SourcererScopeName.default ); - const [showTimeline] = useShowTimeline(); - const { browserFields, indexPattern, indicesExist } = useSourcererScope( + const { browserFields, indexPattern } = useSourcererScope( subPluginId.current === DETECTIONS_SUB_PLUGIN_ID ? SourcererScopeName.detections : SourcererScopeName.default ); + // side effect: this will attempt to upgrade the endpoint package if it is not up to date // this will run when a user navigates to the Security Solution app and when they navigate between // tabs in the app. This is useful for keeping the endpoint package as up to date as possible until @@ -81,23 +59,14 @@ const HomePageComponent: React.FC = ({ children, onAppLeave }) => useUpgradeEndpointPackage(); return ( - - - -
- - - {indicesExist && showTimeline && ( - <> - - - - )} - + + + + + {children} - -
- + +
); diff --git a/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx b/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx new file mode 100644 index 00000000000000..08ebbeaee55d44 --- /dev/null +++ b/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx @@ -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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* eslint-disable react/display-name */ + +import React, { useRef } from 'react'; +import { KibanaPageTemplateProps } from '../../../../../../../../src/plugins/kibana_react/public'; +import { AppLeaveHandler } from '../../../../../../../../src/core/public'; +import { useKibana } from '../../../../common/lib/kibana'; +import { useShowTimeline } from '../../../../common/utils/timeline/use_show_timeline'; +import { useSourcererScope } from '../../../../common/containers/sourcerer'; +import { DETECTIONS_SUB_PLUGIN_ID } from '../../../../../common/constants'; +import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; +import { TimelineId } from '../../../../../common/types/timeline'; +import { AutoSaveWarningMsg } from '../../../../timelines/components/timeline/auto_save_warning'; +import { Flyout } from '../../../../timelines/components/flyout'; + +export const BOTTOM_BAR_CLASSNAME = 'timeline-bottom-bar'; + +export const SecuritySolutionBottomBar = React.memo( + ({ onAppLeave }: { onAppLeave: (handler: AppLeaveHandler) => void }) => { + const subPluginId = useRef(''); + const { application } = useKibana().services; + application.currentAppId$.subscribe((appId) => { + subPluginId.current = appId ?? ''; + }); + + const [showTimeline] = useShowTimeline(); + + const { indicesExist } = useSourcererScope( + subPluginId.current === DETECTIONS_SUB_PLUGIN_ID + ? SourcererScopeName.detections + : SourcererScopeName.default + ); + + return indicesExist && showTimeline ? ( + <> + + + + ) : null; + } +); + +export const SecuritySolutionBottomBarProps: KibanaPageTemplateProps['bottomBarProps'] = { + className: BOTTOM_BAR_CLASSNAME, + 'data-test-subj': 'timeline-bottom-bar-container', + position: 'fixed', + usePortal: false, +}; diff --git a/x-pack/plugins/security_solution/public/app/home/template_wrapper/global_kql_header/index.tsx b/x-pack/plugins/security_solution/public/app/home/template_wrapper/global_kql_header/index.tsx new file mode 100644 index 00000000000000..3e3c91133eab61 --- /dev/null +++ b/x-pack/plugins/security_solution/public/app/home/template_wrapper/global_kql_header/index.tsx @@ -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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import styled from 'styled-components'; +import { OutPortal } from 'react-reverse-portal'; +import { useGlobalHeaderPortal } from '../../../../common/hooks/use_global_header_portal'; + +const StyledStickyWrapper = styled.div` + position: sticky; + z-index: ${(props) => props.theme.eui.euiZLevel2}; + // TOP location is declared in src/public/rendering/_base.scss to keep in line with Kibana Chrome +`; + +export const GlobalKQLHeader = React.memo(() => { + const { globalKQLHeaderPortalNode } = useGlobalHeaderPortal(); + + return ( + + + + ); +}); + +GlobalKQLHeader.displayName = 'GlobalKQLHeader'; diff --git a/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx b/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx new file mode 100644 index 00000000000000..02fd07151f111a --- /dev/null +++ b/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx @@ -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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import styled from 'styled-components'; +import { EuiPanel } from '@elastic/eui'; +import { IS_DRAGGING_CLASS_NAME } from '@kbn/securitysolution-t-grid'; +import { AppLeaveHandler } from '../../../../../../../src/core/public'; +import { KibanaPageTemplate } from '../../../../../../../src/plugins/kibana_react/public'; +import { useSecuritySolutionNavigation } from '../../../common/components/navigation/use_security_solution_navigation'; +import { TimelineId } from '../../../../common/types/timeline'; +import { getTimelineShowStatusByIdSelector } from '../../../timelines/components/flyout/selectors'; +import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; +import { GlobalKQLHeader } from './global_kql_header'; +import { + BOTTOM_BAR_CLASSNAME, + SecuritySolutionBottomBar, + SecuritySolutionBottomBarProps, +} from './bottom_bar'; +import { useShowTimeline } from '../../../common/utils/timeline/use_show_timeline'; +import { gutterTimeline } from '../../../common/lib/helpers'; + +/* eslint-disable react/display-name */ + +/** + * Need to apply the styles via a className to effect the containing bottom bar + * rather than applying them to the timeline bar directly + */ +const StyledKibanaPageTemplate = styled(KibanaPageTemplate)<{ + $isShowingTimelineOverlay?: boolean; + $isTimelineBottomBarVisible?: boolean; +}>` + .${BOTTOM_BAR_CLASSNAME} { + animation: 'none !important'; // disable the default bottom bar slide animation + background: ${({ theme }) => + theme.eui.euiColorEmptyShade}; // Override bottom bar black background + color: inherit; // Necessary to override the bottom bar 'white text' + transform: ${( + { $isShowingTimelineOverlay } // Since the bottom bar wraps the whole overlay now, need to override any transforms when it is open + ) => ($isShowingTimelineOverlay ? 'none' : 'translateY(calc(100% - 50px))')}; + z-index: ${({ theme }) => theme.eui.euiZLevel8}; + + .${IS_DRAGGING_CLASS_NAME} & { + // When a drag is in process the bottom flyout should slide up to allow a drop + transform: none; + } + } + + // If the bottom bar is visible add padding to the navigation + ${({ $isTimelineBottomBarVisible }) => + $isTimelineBottomBarVisible && + ` + @media (min-width: 768px) { + .kbnPageTemplateSolutionNav { + padding-bottom: ${gutterTimeline}; + } + } + `} +`; + +interface SecuritySolutionPageWrapperProps { + onAppLeave: (handler: AppLeaveHandler) => void; +} + +export const SecuritySolutionTemplateWrapper: React.FC = React.memo( + ({ children, onAppLeave }) => { + const solutionNav = useSecuritySolutionNavigation(); + const [isTimelineBottomBarVisible] = useShowTimeline(); + const getTimelineShowStatus = useMemo(() => getTimelineShowStatusByIdSelector(), []); + const { show: isShowingTimelineOverlay } = useDeepEqualSelector((state) => + getTimelineShowStatus(state, TimelineId.active) + ); + + return ( + } + paddingSize="none" + solutionNav={solutionNav} + restrictWidth={false} + template="default" + > + + + {children} + + + ); + } +); diff --git a/x-pack/plugins/security_solution/public/app/index.tsx b/x-pack/plugins/security_solution/public/app/index.tsx index 1e304c26869602..194f119e35478e 100644 --- a/x-pack/plugins/security_solution/public/app/index.tsx +++ b/x-pack/plugins/security_solution/public/app/index.tsx @@ -15,12 +15,19 @@ export const renderApp = ({ element, history, onAppLeave, + setHeaderActionMenu, services, store, SubPluginRoutes, }: RenderAppProps): (() => void) => { render( - + , element diff --git a/x-pack/plugins/security_solution/public/app/routes.tsx b/x-pack/plugins/security_solution/public/app/routes.tsx index 6454653af5214d..a9a94a69982863 100644 --- a/x-pack/plugins/security_solution/public/app/routes.tsx +++ b/x-pack/plugins/security_solution/public/app/routes.tsx @@ -10,7 +10,7 @@ import React, { FC, memo, useEffect } from 'react'; import { Route, Router, Switch } from 'react-router-dom'; import { useDispatch } from 'react-redux'; -import { AppLeaveHandler } from '../../../../../src/core/public'; +import { AppLeaveHandler, AppMountParameters } from '../../../../../src/core/public'; import { ManageRoutesSpy } from '../common/utils/route/manage_spy_routes'; import { RouteCapture } from '../common/components/endpoint/route_capture'; import { AppAction } from '../common/store/actions'; @@ -21,9 +21,15 @@ interface RouterProps { children: React.ReactNode; history: History; onAppLeave: (handler: AppLeaveHandler) => void; + setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; } -const PageRouterComponent: FC = ({ children, history, onAppLeave }) => { +const PageRouterComponent: FC = ({ + children, + history, + onAppLeave, + setHeaderActionMenu, +}) => { const dispatch = useDispatch<(action: AppAction) => void>(); useEffect(() => { return () => { @@ -42,7 +48,9 @@ const PageRouterComponent: FC = ({ children, history, onAppLeave }) - {children} + + {children} + diff --git a/x-pack/plugins/security_solution/public/app/home/translations.ts b/x-pack/plugins/security_solution/public/app/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/app/home/translations.ts rename to x-pack/plugins/security_solution/public/app/translations.ts diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.tsx index 91fb45de04320b..dfd53ae5cc0b07 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.tsx @@ -38,7 +38,7 @@ export const Create = React.memo(() => { ); return ( - + {cases.getCreateCase({ onCancel: handleSetIsCancel, onSuccess, diff --git a/x-pack/plugins/security_solution/public/cases/pages/case.tsx b/x-pack/plugins/security_solution/public/cases/pages/case.tsx index 647647afbe0a4a..ad0176bda6905c 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/case.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/case.tsx @@ -7,7 +7,7 @@ import React from 'react'; -import { WrapperPage } from '../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { useGetUserCasesPermissions } from '../../common/lib/kibana'; import { SpyRoute } from '../../common/utils/route/spy_routes'; import { AllCases } from '../components/all_cases'; @@ -20,9 +20,9 @@ export const CasesPage = React.memo(() => { return userPermissions == null || userPermissions?.read ? ( <> - + - + ) : ( diff --git a/x-pack/plugins/security_solution/public/cases/pages/case_details.tsx b/x-pack/plugins/security_solution/public/cases/pages/case_details.tsx index a086409e55df52..f6bb27b7b7104f 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/case_details.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/case_details.tsx @@ -10,7 +10,7 @@ import { useParams } from 'react-router-dom'; import { SecurityPageName } from '../../app/types'; import { SpyRoute } from '../../common/utils/route/spy_routes'; -import { WrapperPage } from '../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { useGetUrlSearch } from '../../common/components/navigation/use_get_url_search'; import { useGetUserCasesPermissions, useKibana } from '../../common/lib/kibana'; import { getCaseUrl } from '../../common/components/link_to'; @@ -37,13 +37,13 @@ export const CaseDetailsPage = React.memo(() => { return caseId != null ? ( <> - + - + ) : null; diff --git a/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx b/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx index c942065e45278d..d3f235a5da7dc1 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx @@ -11,7 +11,7 @@ import styled from 'styled-components'; import { SecurityPageName } from '../../app/types'; import { getCaseUrl } from '../../common/components/link_to'; import { useGetUrlSearch } from '../../common/components/navigation/use_get_url_search'; -import { WrapperPage } from '../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { useGetUserCasesPermissions, useKibana } from '../../common/lib/kibana'; import { SpyRoute } from '../../common/utils/route/spy_routes'; import { navTabs } from '../../app/home/home_navigations'; @@ -51,7 +51,7 @@ const ConfigureCasesPageComponent: React.FC = () => { return ( <> - + @@ -63,7 +63,7 @@ const ConfigureCasesPageComponent: React.FC = () => { owner: [APP_ID], })} - + ); diff --git a/x-pack/plugins/security_solution/public/cases/pages/create_case.tsx b/x-pack/plugins/security_solution/public/cases/pages/create_case.tsx index 3c5197f19eff12..6c88c4afb63955 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/create_case.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/create_case.tsx @@ -10,7 +10,7 @@ import React, { useEffect, useMemo } from 'react'; import { SecurityPageName } from '../../app/types'; import { getCaseUrl } from '../../common/components/link_to'; import { useGetUrlSearch } from '../../common/components/navigation/use_get_url_search'; -import { WrapperPage } from '../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { useGetUserCasesPermissions, useKibana } from '../../common/lib/kibana'; import { SpyRoute } from '../../common/utils/route/spy_routes'; import { navTabs } from '../../app/home/home_navigations'; @@ -45,10 +45,10 @@ export const CreateCasePage = React.memo(() => { return ( <> - + - + ); diff --git a/x-pack/plugins/security_solution/public/common/components/accessibility/index.ts b/x-pack/plugins/security_solution/public/common/components/accessibility/index.ts new file mode 100644 index 00000000000000..f05644c85e5364 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/accessibility/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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './tooltip_with_keyboard_shortcut'; diff --git a/x-pack/plugins/security_solution/public/common/components/accessibility/tooltip_with_keyboard_shortcut/index.tsx b/x-pack/plugins/security_solution/public/common/components/accessibility/tooltip_with_keyboard_shortcut/index.tsx index 97922ecdc5b614..2d66b4e93e4dc1 100644 --- a/x-pack/plugins/security_solution/public/common/components/accessibility/tooltip_with_keyboard_shortcut/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/accessibility/tooltip_with_keyboard_shortcut/index.tsx @@ -10,7 +10,7 @@ import React from 'react'; import * as i18n from './translations'; -interface Props { +export interface TooltipWithKeyboardShortcutProps { additionalScreenReaderOnlyContext?: string; content: React.ReactNode; shortcut: string; @@ -22,7 +22,7 @@ const TooltipWithKeyboardShortcutComponent = ({ content, shortcut, showShortcut, -}: Props) => ( +}: TooltipWithKeyboardShortcutProps) => ( <>
{content}
{additionalScreenReaderOnlyContext !== '' && ( diff --git a/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx index 43d5c66655808b..58cca7bcbd1213 100644 --- a/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx @@ -6,12 +6,12 @@ */ import React, { useEffect, useMemo } from 'react'; - +import { useDispatch } from 'react-redux'; +import { timelineActions } from '../../../timelines/store/timeline'; import { Filter } from '../../../../../../../src/plugins/data/public'; import { TimelineIdLiteral } from '../../../../common/types/timeline'; import { StatefulEventsViewer } from '../events_viewer'; import { alertsDefaultModel } from './default_headers'; -import { useManageTimeline } from '../../../timelines/components/manage_timeline'; import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers'; import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell_rendering/default_cell_renderer'; import * as i18n from './translations'; @@ -70,22 +70,24 @@ const AlertsTableComponent: React.FC = ({ startDate, pageFilters = [], }) => { + const dispatch = useDispatch(); const alertsFilter = useMemo(() => [...defaultAlertsFilters, ...pageFilters], [pageFilters]); const { filterManager } = useKibana().services.data.query; - const { initializeTimeline } = useManageTimeline(); useEffect(() => { - initializeTimeline({ - id: timelineId, - documentType: i18n.ALERTS_DOCUMENT_TYPE, - filterManager, - defaultModel: alertsDefaultModel, - footerText: i18n.TOTAL_COUNT_OF_ALERTS, - title: i18n.ALERTS_TABLE_TITLE, - unit: i18n.UNIT, - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + dispatch( + timelineActions.initializeTGridSettings({ + id: timelineId, + documentType: i18n.ALERTS_DOCUMENT_TYPE, + filterManager, + defaultColumns: alertsDefaultModel.columns, + excludedRowRendererIds: alertsDefaultModel.excludedRowRendererIds, + footerText: i18n.TOTAL_COUNT_OF_ALERTS, + title: i18n.ALERTS_TABLE_TITLE, + // TODO: avoid passing this through the store + }) + ); + }, [dispatch, filterManager, timelineId]); return ( = ({ namespace, conditi const { isVisible, dismiss } = useCallOutStorage([message], namespace); const shouldRender = condition && isVisible(message); - return shouldRender ? : null; + return shouldRender ? ( + <> + + + + ) : null; }; export const CallOutSwitcher = memo(CallOutSwitcherComponent); diff --git a/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.test.tsx index 544f9b1abf8f2b..a01f22a0942de8 100644 --- a/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.test.tsx @@ -15,6 +15,8 @@ import { TestProviders } from '../../mock'; import { MIN_LEGEND_HEIGHT, DraggableLegend } from './draggable_legend'; import { LegendItem } from './draggable_legend_item'; +jest.mock('../../lib/kibana'); + jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); return { diff --git a/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.test.tsx index 4958f6bae4a307..175239fcaebe74 100644 --- a/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.test.tsx @@ -14,6 +14,8 @@ import { TestProviders } from '../../mock'; import { DraggableLegendItem, LegendItem } from './draggable_legend_item'; +jest.mock('../../../common/lib/kibana'); + jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); return { diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.test.tsx index dc0e24fcba8f5a..bc3b9c3eaa1c62 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.test.tsx @@ -13,6 +13,8 @@ import { TestProviders } from '../../mock'; import { DragDropContextWrapper } from './drag_drop_context_wrapper'; +jest.mock('../../lib/kibana'); + describe('DragDropContextWrapper', () => { describe('rendering', () => { test('it renders against the snapshot', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.tsx index 1073ed57dee19a..1ab19c44e29b2b 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.tsx @@ -11,6 +11,7 @@ import { DropResult, DragDropContext } from 'react-beautiful-dnd'; import { useDispatch } from 'react-redux'; import { Dispatch } from 'redux'; import deepEqual from 'fast-deep-equal'; +import { IS_DRAGGING_CLASS_NAME } from '@kbn/securitysolution-t-grid'; import { BeforeCapture } from './drag_drop_context'; import { BrowserFields } from '../../containers/source'; @@ -23,22 +24,24 @@ import { ADDED_TO_TIMELINE_MESSAGE, ADDED_TO_TIMELINE_TEMPLATE_MESSAGE, } from '../../hooks/translations'; -import { useAddToTimelineSensor } from '../../hooks/use_add_to_timeline'; import { displaySuccessToast, useStateToaster } from '../toasters'; import { TimelineId, TimelineType } from '../../../../common/types/timeline'; import { - addFieldToTimelineColumns, addProviderToTimeline, fieldWasDroppedOnTimelineColumns, - getTimelineIdFromColumnDroppableId, - IS_DRAGGING_CLASS_NAME, IS_TIMELINE_FIELD_DRAGGING_CLASS_NAME, providerWasDroppedOnTimeline, draggableIsField, userIsReArrangingProviders, } from './helpers'; import { useDeepEqualSelector } from '../../hooks/use_selector'; +import { useKibana } from '../../lib/kibana'; import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; +import { + addFieldToTimelineColumns, + getTimelineIdFromColumnDroppableId, +} from '../../../../../timelines/public'; +import { alertsHeaders } from '../alerts_viewer/default_headers'; // @ts-expect-error window['__react-beautiful-dnd-disable-dev-warnings'] = true; @@ -85,6 +88,7 @@ const onDragEndHandler = ({ } else if (fieldWasDroppedOnTimelineColumns(result)) { addFieldToTimelineColumns({ browserFields, + defaultsHeader: alertsHeaders, dispatch, result, timelineId: getTimelineIdFromColumnDroppableId(result.destination?.droppableId ?? ''), @@ -92,8 +96,6 @@ const onDragEndHandler = ({ } }; -const sensors = [useAddToTimelineSensor]; - /** * DragDropContextWrapperComponent handles all drag end events */ @@ -101,7 +103,8 @@ export const DragDropContextWrapperComponent: React.FC = ({ browserFields const dispatch = useDispatch(); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); const getDataProviders = useMemo(() => dragAndDropSelectors.getDataProvidersSelector(), []); - + const { timelines } = useKibana().services; + const sensors = [timelines.getUseAddToTimelineSensor()]; const { dataProviders: activeTimelineDataProviders, timelineType, diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx index 0d8011ee8b65db..bdc5545880e1c2 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx @@ -17,6 +17,8 @@ import { DragDropContextWrapper } from './drag_drop_context_wrapper'; import { ConditionalPortal, DraggableWrapper, getStyle } from './draggable_wrapper'; import { useMountAppended } from '../../utils/use_mount_appended'; +jest.mock('../../lib/kibana'); + jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); return { diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx index 0cb030862a3899..9db5b3899d8bc1 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx @@ -6,6 +6,7 @@ */ import { EuiScreenReaderOnly } from '@elastic/eui'; +import { DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME } from '@kbn/securitysolution-t-grid'; import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'; import { Draggable, @@ -24,12 +25,12 @@ import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../../../timelines/com import { TruncatableText } from '../truncatable_text'; import { WithHoverActions } from '../with_hover_actions'; -import { useDraggableKeyboardWrapper } from './draggable_keyboard_wrapper_hook'; import { DraggableWrapperHoverContent, useGetTimelineId } from './draggable_wrapper_hover_content'; -import { DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME, getDraggableId, getDroppableId } from './helpers'; +import { getDraggableId, getDroppableId } from './helpers'; import { ProviderContainer } from './provider_container'; import * as i18n from './translations'; +import { useKibana } from '../../lib/kibana'; // As right now, we do not know what we want there, we will keep it as a placeholder export const DragEffects = styled.div``; @@ -142,6 +143,7 @@ const DraggableWrapperComponent: React.FC = ({ const isDisabled = dataProvider.id.includes(`-${ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID}-`); const [hoverActionsOwnFocus, setHoverActionsOwnFocus] = useState(false); const dispatch = useDispatch(); + const { timelines } = useKibana().services; const handleClosePopOverTrigger = useCallback(() => { setClosePopOverTrigger((prevClosePopOverTrigger) => !prevClosePopOverTrigger); @@ -297,7 +299,7 @@ const DraggableWrapperComponent: React.FC = ({ setHoverActionsOwnFocus(true); }, []); - const { onBlur, onKeyDown } = useDraggableKeyboardWrapper({ + const { onBlur, onKeyDown } = timelines.getUseDraggableKeyboardWrapper()({ closePopover: handleClosePopOverTrigger, draggableId: getDraggableId(dataProvider.id), fieldName: dataProvider.queryMatch.field, diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.test.tsx index 0d688bd805999f..400b178c167f68 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.test.tsx @@ -17,14 +17,10 @@ import { TestProviders } from '../../mock'; import { FilterManager } from '../../../../../../../src/plugins/data/public'; import { useSourcererScope } from '../../containers/sourcerer'; import { DraggableWrapperHoverContent } from './draggable_wrapper_hover_content'; -import { - ManageGlobalTimeline, - getTimelineDefaults, -} from '../../../timelines/components/manage_timeline'; import { TimelineId } from '../../../../common/types/timeline'; +import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; jest.mock('../link_to'); - jest.mock('../../lib/kibana'); jest.mock('../../containers/sourcerer', () => { const original = jest.requireActual('../../containers/sourcerer'); @@ -42,29 +38,18 @@ jest.mock('uuid', () => { }; }); const mockStartDragToTimeline = jest.fn(); -jest.mock('../../hooks/use_add_to_timeline', () => { - const original = jest.requireActual('../../hooks/use_add_to_timeline'); +jest.mock('../../../../../timelines/public/hooks/use_add_to_timeline', () => { + const original = jest.requireActual('../../../../../timelines/public/hooks/use_add_to_timeline'); return { ...original, useAddToTimeline: () => ({ startDragToTimeline: mockStartDragToTimeline }), }; }); const mockAddFilters = jest.fn(); -const mockGetTimelineFilterManager = jest.fn().mockReturnValue({ - addFilters: mockAddFilters, -}); -jest.mock('../../../timelines/components/manage_timeline', () => { - const original = jest.requireActual('../../../timelines/components/manage_timeline'); - - return { - ...original, - useManageTimeline: () => ({ - getManageTimelineById: jest.fn().mockReturnValue({ indexToAdd: [] }), - getTimelineFilterManager: mockGetTimelineFilterManager, - isManagedTimeline: jest.fn().mockReturnValue(false), - }), - }; -}); +jest.mock('../../../common/hooks/use_selector', () => ({ + useShallowEqualSelector: jest.fn(), + useDeepEqualSelector: jest.fn(), +})); const mockUiSettingsForFilterManager = coreMock.createStart().uiSettings; const timelineId = TimelineId.active; @@ -85,6 +70,9 @@ const defaultProps = { describe('DraggableWrapperHoverContent', () => { beforeAll(() => { mockStartDragToTimeline.mockReset(); + (useDeepEqualSelector as jest.Mock).mockReturnValue({ + filterManager: { addFilters: mockAddFilters }, + }); (useSourcererScope as jest.Mock).mockReturnValue({ browserFields: mockBrowserFields, selectedPatterns: [], @@ -144,15 +132,10 @@ describe('DraggableWrapperHoverContent', () => { beforeEach(() => { onFilterAdded = jest.fn(); - const manageTimelineForTesting = { - [timelineId]: getTimelineDefaults(timelineId), - }; wrapper = mount( - - - + ); }); @@ -237,18 +220,9 @@ describe('DraggableWrapperHoverContent', () => { filterManager.addFilters = jest.fn(); onFilterAdded = jest.fn(); - const manageTimelineForTesting = { - [timelineId]: { - ...getTimelineDefaults(timelineId), - filterManager, - }, - }; - wrapper = mount( - - - + ); }); @@ -586,39 +560,4 @@ describe('DraggableWrapperHoverContent', () => { expect(wrapper.find(`[data-test-subj="copy-to-clipboard"]`).first().exists()).toBe(false); }); }); - - describe('Filter Manager', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - test('filter manager, not active timeline', () => { - mount( - - - - ); - - expect(mockGetTimelineFilterManager).not.toBeCalled(); - }); - test('filter manager, active timeline', () => { - mount( - - - - ); - - expect(mockGetTimelineFilterManager).toBeCalled(); - }); - test('filter manager, active timeline in draggableId', () => { - mount( - - - - ); - - expect(mockGetTimelineFilterManager).toBeCalled(); - }); - }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx index 880f0b4e18acab..71c3114015a03f 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx @@ -12,14 +12,12 @@ import { EuiScreenReaderOnly, EuiToolTip, } from '@elastic/eui'; + import React, { useCallback, useEffect, useRef, useMemo, useState } from 'react'; import { DraggableId } from 'react-beautiful-dnd'; import styled from 'styled-components'; -import { stopPropagationAndPreventDefault } from '../accessibility/helpers'; -import { TooltipWithKeyboardShortcut } from '../accessibility/tooltip_with_keyboard_shortcut'; import { getAllFieldsByName } from '../../containers/source'; -import { useAddToTimeline } from '../../hooks/use_add_to_timeline'; import { COPY_TO_CLIPBOARD_BUTTON_CLASS_NAME } from '../../lib/clipboard/clipboard'; import { WithCopyToClipboard } from '../../lib/clipboard/with_copy_to_clipboard'; import { useKibana } from '../../lib/kibana'; @@ -28,11 +26,14 @@ import { StatefulTopN } from '../top_n'; import { allowTopN } from './helpers'; import * as i18n from './translations'; -import { useManageTimeline } from '../../../timelines/components/manage_timeline'; +import { useDeepEqualSelector } from '../../hooks/use_selector'; import { TimelineId } from '../../../../common/types/timeline'; import { SELECTOR_TIMELINE_GLOBAL_CONTAINER } from '../../../timelines/components/timeline/styles'; import { SourcererScopeName } from '../../store/sourcerer/model'; import { useSourcererScope } from '../../containers/sourcerer'; +import { timelineSelectors } from '../../../timelines/store/timeline'; +import { stopPropagationAndPreventDefault } from '../../../../../timelines/public'; +import { TooltipWithKeyboardShortcut } from '../accessibility'; export const AdditionalContent = styled.div` padding: 2px; @@ -102,21 +103,25 @@ const DraggableWrapperHoverContentComponent: React.FC = ({ toggleTopN, value, }) => { - const { startDragToTimeline } = useAddToTimeline({ draggableId, fieldName: field }); const kibana = useKibana(); + const { timelines } = kibana.services; + const { startDragToTimeline } = timelines.getUseAddToTimeline()({ + draggableId, + fieldName: field, + }); const filterManagerBackup = useMemo(() => kibana.services.data.query.filterManager, [ kibana.services.data.query.filterManager, ]); - const { getTimelineFilterManager } = useManageTimeline(); + const getManageTimeline = useMemo(() => timelineSelectors.getManageTimelineById(), []); + const { filterManager: activeFilterMananager } = useDeepEqualSelector((state) => + getManageTimeline(state, timelineId ?? '') + ); const defaultFocusedButtonRef = useRef(null); const panelRef = useRef(null); const filterManager = useMemo( - () => - timelineId === TimelineId.active - ? getTimelineFilterManager(TimelineId.active) - : filterManagerBackup, - [timelineId, getTimelineFilterManager, filterManagerBackup] + () => (timelineId === TimelineId.active ? activeFilterMananager : filterManagerBackup), + [timelineId, activeFilterMananager, filterManagerBackup] ); // Regarding data from useManageTimeline: diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.test.tsx index 42f70e9d296b30..73a732b5d64583 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.test.tsx @@ -15,6 +15,8 @@ import { DragDropContextWrapper } from './drag_drop_context_wrapper'; import { DroppableWrapper } from './droppable_wrapper'; import { useMountAppended } from '../../utils/use_mount_appended'; +jest.mock('../../lib/kibana'); + describe('DroppableWrapper', () => { const mount = useMountAppended(); diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.test.ts b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.test.ts index 58d2e0e7dc70f4..a14a44cd9a68bd 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.test.ts @@ -7,6 +7,7 @@ import { omit } from 'lodash/fp'; import { DropResult } from 'react-beautiful-dnd'; +import { getTimelineIdFromColumnDroppableId } from '../../../../../timelines/public'; import { IdToDataProvider } from '../../store/drag_and_drop/model'; @@ -33,7 +34,6 @@ import { getDroppableId, getFieldIdFromDraggable, getProviderIdFromDraggable, - getTimelineIdFromColumnDroppableId, getTimelineProviderDraggableId, getTimelineProviderDroppableId, providerWasDroppedOnTimeline, diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts index e2e506e6e1a3f1..9717e1e1eda911 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts @@ -4,138 +4,53 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -import { isString } from 'lodash/fp'; -import { DropResult, FluidDragActions, Position } from 'react-beautiful-dnd'; +import { DropResult } from 'react-beautiful-dnd'; import { Dispatch } from 'redux'; import { ActionCreator } from 'typescript-fsa'; +import { getProviderIdFromDraggable } from '@kbn/securitysolution-t-grid'; -import { stopPropagationAndPreventDefault } from '../accessibility/helpers'; -import { alertsHeaders } from '../alerts_viewer/default_headers'; -import { BrowserField, BrowserFields, getAllFieldsByName } from '../../containers/source'; +import { BrowserField } from '../../containers/source'; import { dragAndDropActions } from '../../store/actions'; import { IdToDataProvider } from '../../store/drag_and_drop/model'; -import { ColumnHeaderOptions } from '../../../timelines/store/timeline/model'; -import { timelineActions } from '../../../timelines/store/timeline'; -import { DEFAULT_COLUMN_MIN_WIDTH } from '../../../timelines/components/timeline/body/constants'; import { addContentToTimeline } from '../../../timelines/components/timeline/data_providers/helpers'; import { DataProvider } from '../../../timelines/components/timeline/data_providers/data_provider'; -import { TimelineId } from '../../../../common/types/timeline'; - -export const draggableIdPrefix = 'draggableId'; - -export const droppableIdPrefix = 'droppableId'; - -export const draggableContentPrefix = `${draggableIdPrefix}.content.`; - -export const draggableTimelineProvidersPrefix = `${draggableIdPrefix}.timelineProviders.`; - -export const draggableFieldPrefix = `${draggableIdPrefix}.field.`; - -export const droppableContentPrefix = `${droppableIdPrefix}.content.`; - -export const droppableFieldPrefix = `${droppableIdPrefix}.field.`; - -export const droppableTimelineProvidersPrefix = `${droppableIdPrefix}.timelineProviders.`; - -export const droppableTimelineColumnsPrefix = `${droppableIdPrefix}.timelineColumns.`; - -export const droppableTimelineFlyoutBottomBarPrefix = `${droppableIdPrefix}.flyoutButton.`; - -export const getDraggableId = (dataProviderId: string): string => - `${draggableContentPrefix}${dataProviderId}`; - -export const getDraggableFieldId = ({ - contextId, - fieldId, -}: { - contextId: string; - fieldId: string; -}): string => `${draggableFieldPrefix}${escapeContextId(contextId)}.${escapeFieldId(fieldId)}`; - -export const getTimelineProviderDroppableId = ({ - groupIndex, - timelineId, -}: { - groupIndex: number; - timelineId: string; -}): string => `${droppableTimelineProvidersPrefix}${timelineId}.group.${groupIndex}`; - -export const getTimelineProviderDraggableId = ({ - dataProviderId, - groupIndex, - timelineId, -}: { - dataProviderId: string; - groupIndex: number; - timelineId: string; -}): string => - `${draggableTimelineProvidersPrefix}${timelineId}.group.${groupIndex}.${dataProviderId}`; - -export const getDroppableId = (visualizationPlaceholderId: string): string => - `${droppableContentPrefix}${visualizationPlaceholderId}`; - -export const sourceIsContent = (result: DropResult): boolean => - result.source.droppableId.startsWith(droppableContentPrefix); - -export const sourceAndDestinationAreSameTimelineProviders = (result: DropResult): boolean => { - const regex = /^droppableId\.timelineProviders\.(\S+)\./; - const sourceMatches = result.source.droppableId.match(regex) ?? []; - const destinationMatches = result.destination?.droppableId.match(regex) ?? []; - - return ( - sourceMatches.length >= 2 && - destinationMatches.length >= 2 && - sourceMatches[1] === destinationMatches[1] - ); -}; - -export const draggableIsContent = (result: DropResult | { draggableId: string }): boolean => - result.draggableId.startsWith(draggableContentPrefix); - -export const draggableIsField = (result: DropResult | { draggableId: string }): boolean => - result.draggableId.startsWith(draggableFieldPrefix); - -export const reasonIsDrop = (result: DropResult): boolean => result.reason === 'DROP'; - -export const destinationIsTimelineProviders = (result: DropResult): boolean => - result.destination != null && - result.destination.droppableId.startsWith(droppableTimelineProvidersPrefix); - -export const destinationIsTimelineColumns = (result: DropResult): boolean => - result.destination != null && - result.destination.droppableId.startsWith(droppableTimelineColumnsPrefix); - -export const destinationIsTimelineButton = (result: DropResult): boolean => - result.destination != null && - result.destination.droppableId.startsWith(droppableTimelineFlyoutBottomBarPrefix); - -export const getProviderIdFromDraggable = (result: DropResult): string => - result.draggableId.substring(result.draggableId.lastIndexOf('.') + 1); - -export const getFieldIdFromDraggable = (result: DropResult): string => - unEscapeFieldId(result.draggableId.substring(result.draggableId.lastIndexOf('.') + 1)); - -export const escapeDataProviderId = (path: string) => path.replace(/\./g, '_'); - -export const escapeContextId = (path: string) => path.replace(/\./g, '_'); - -export const escapeFieldId = (path: string) => path.replace(/\./g, '!!!DOT!!!'); - -export const unEscapeFieldId = (path: string) => path.replace(/!!!DOT!!!/g, '.'); - -export const providerWasDroppedOnTimeline = (result: DropResult): boolean => - reasonIsDrop(result) && - draggableIsContent(result) && - sourceIsContent(result) && - destinationIsTimelineProviders(result); - -export const userIsReArrangingProviders = (result: DropResult): boolean => - reasonIsDrop(result) && sourceAndDestinationAreSameTimelineProviders(result); - -export const fieldWasDroppedOnTimelineColumns = (result: DropResult): boolean => - reasonIsDrop(result) && draggableIsField(result) && destinationIsTimelineColumns(result); +export { + draggableIdPrefix, + droppableIdPrefix, + draggableContentPrefix, + draggableTimelineProvidersPrefix, + draggableFieldPrefix, + draggableIsField, + droppableContentPrefix, + droppableFieldPrefix, + droppableTimelineProvidersPrefix, + droppableTimelineColumnsPrefix, + droppableTimelineFlyoutBottomBarPrefix, + getDraggableId, + getDraggableFieldId, + getTimelineProviderDroppableId, + getTimelineProviderDraggableId, + getDroppableId, + sourceIsContent, + sourceAndDestinationAreSameTimelineProviders, + draggableIsContent, + reasonIsDrop, + destinationIsTimelineProviders, + destinationIsTimelineColumns, + destinationIsTimelineButton, + getProviderIdFromDraggable, + getFieldIdFromDraggable, + escapeDataProviderId, + escapeContextId, + escapeFieldId, + unEscapeFieldId, + providerWasDroppedOnTimeline, + userIsReArrangingProviders, + fieldWasDroppedOnTimelineColumns, + DRAG_TYPE_FIELD, + IS_TIMELINE_FIELD_DRAGGING_CLASS_NAME, +} from '@kbn/securitysolution-t-grid'; interface AddProviderToTimelineParams { activeTimelineDataProviders: DataProvider[]; dataProviders: IdToDataProvider; @@ -148,18 +63,6 @@ interface AddProviderToTimelineParams { timelineId: string; } -interface AddFieldToTimelineColumnsParams { - upsertColumn?: ActionCreator<{ - column: ColumnHeaderOptions; - id: string; - index: number; - }>; - browserFields: BrowserFields; - dispatch: Dispatch; - result: DropResult; - timelineId: string; -} - export const addProviderToTimeline = ({ activeTimelineDataProviders, dataProviders, @@ -186,73 +89,6 @@ export const addProviderToTimeline = ({ } }; -const linkFields: Record = { - 'signal.rule.name': 'signal.rule.id', - 'event.module': 'rule.reference', -}; - -export const addFieldToTimelineColumns = ({ - upsertColumn = timelineActions.upsertColumn, - browserFields, - dispatch, - result, - timelineId, -}: AddFieldToTimelineColumnsParams): void => { - const fieldId = getFieldIdFromDraggable(result); - const allColumns = getAllFieldsByName(browserFields); - const column = allColumns[fieldId]; - const initColumnHeader = - timelineId === TimelineId.detectionsPage || timelineId === TimelineId.detectionsRulesDetailsPage - ? alertsHeaders.find((c) => c.id === fieldId) ?? {} - : {}; - - if (column != null) { - dispatch( - upsertColumn({ - column: { - category: column.category, - columnHeaderType: 'not-filtered', - description: isString(column.description) ? column.description : undefined, - example: isString(column.example) ? column.example : undefined, - id: fieldId, - linkField: linkFields[fieldId] ?? undefined, - type: column.type, - aggregatable: column.aggregatable, - initialWidth: DEFAULT_COLUMN_MIN_WIDTH, - ...initColumnHeader, - }, - id: timelineId, - index: result.destination != null ? result.destination.index : 0, - }) - ); - } else { - // create a column definition, because it doesn't exist in the browserFields: - dispatch( - upsertColumn({ - column: { - columnHeaderType: 'not-filtered', - id: fieldId, - initialWidth: DEFAULT_COLUMN_MIN_WIDTH, - }, - id: timelineId, - index: result.destination != null ? result.destination.index : 0, - }) - ); - } -}; - -/** - * Prevents fields from being dragged or dropped to any area other than column - * header drop zone in the timeline - */ -export const DRAG_TYPE_FIELD = 'drag-type-field'; - -/** This class is added to the document body while dragging */ -export const IS_DRAGGING_CLASS_NAME = 'is-dragging'; - -/** This class is added to the document body while timeline field dragging */ -export const IS_TIMELINE_FIELD_DRAGGING_CLASS_NAME = 'is-timeline-field-dragging'; - export const allowTopN = ({ browserField, fieldName, @@ -347,125 +183,3 @@ export const allowTopN = ({ return isAllowlistedNonBrowserField || (isAggregatable && isAllowedType); }; - -export const getTimelineIdFromColumnDroppableId = (droppableId: string) => - droppableId.slice(droppableId.lastIndexOf('.') + 1); - -/** The draggable will move this many pixes via the keyboard when the arrow key is pressed */ -export const KEYBOARD_DRAG_OFFSET = 20; - -export const DRAGGABLE_KEYBOARD_WRAPPER_CLASS_NAME = 'draggable-keyboard-wrapper'; - -/** - * Temporarily disables tab focus on child links of the draggable to work - * around an issue where tab focus becomes stuck on the interactive children - * - * NOTE: This function is (intentionally) only effective when used in a key - * event handler, because it automatically restores focus capabilities on - * the next tick. - */ -export const temporarilyDisableInteractiveChildTabIndexes = (draggableElement: HTMLDivElement) => { - const interactiveChildren = draggableElement.querySelectorAll('a, button'); - interactiveChildren.forEach((interactiveChild) => { - interactiveChild.setAttribute('tabindex', '-1'); // DOM mutation - }); - - // restore the default tabindexs on the next tick: - setTimeout(() => { - interactiveChildren.forEach((interactiveChild) => { - interactiveChild.setAttribute('tabindex', '0'); // DOM mutation - }); - }, 0); -}; - -export const draggableKeyDownHandler = ({ - beginDrag, - cancelDragActions, - closePopover, - draggableElement, - dragActions, - dragToLocation, - endDrag, - keyboardEvent, - openPopover, - setDragActions, -}: { - beginDrag: () => FluidDragActions | null; - cancelDragActions: () => void; - closePopover?: () => void; - draggableElement: HTMLDivElement; - dragActions: FluidDragActions | null; - dragToLocation: ({ - // eslint-disable-next-line @typescript-eslint/no-shadow - dragActions, - position, - }: { - dragActions: FluidDragActions | null; - position: Position; - }) => void; - keyboardEvent: React.KeyboardEvent; - endDrag: (dragActions: FluidDragActions | null) => void; - openPopover?: () => void; - setDragActions: (value: React.SetStateAction) => void; -}) => { - let currentPosition: DOMRect | null = null; - - switch (keyboardEvent.key) { - case ' ': - if (!dragActions) { - // start dragging, because space was pressed - if (closePopover != null) { - closePopover(); - } - setDragActions(beginDrag()); - } else { - // end dragging, because space was pressed - endDrag(dragActions); - setDragActions(null); - } - break; - case 'Escape': - cancelDragActions(); - break; - case 'Tab': - // IMPORTANT: we do NOT want to stop propagation and prevent default when Tab is pressed - temporarilyDisableInteractiveChildTabIndexes(draggableElement); - break; - case 'ArrowUp': - currentPosition = draggableElement.getBoundingClientRect(); - dragToLocation({ - dragActions, - position: { x: currentPosition.x, y: currentPosition.y - KEYBOARD_DRAG_OFFSET }, - }); - break; - case 'ArrowDown': - currentPosition = draggableElement.getBoundingClientRect(); - dragToLocation({ - dragActions, - position: { x: currentPosition.x, y: currentPosition.y + KEYBOARD_DRAG_OFFSET }, - }); - break; - case 'ArrowLeft': - currentPosition = draggableElement.getBoundingClientRect(); - dragToLocation({ - dragActions, - position: { x: currentPosition.x - KEYBOARD_DRAG_OFFSET, y: currentPosition.y }, - }); - break; - case 'ArrowRight': - currentPosition = draggableElement.getBoundingClientRect(); - dragToLocation({ - dragActions, - position: { x: currentPosition.x + KEYBOARD_DRAG_OFFSET, y: currentPosition.y }, - }); - break; - case 'Enter': - stopPropagationAndPreventDefault(keyboardEvent); // prevents the first item in the popover from getting an errant ENTER - if (!dragActions && openPopover != null) { - openPopover(); - } - break; - default: - break; - } -}; diff --git a/x-pack/plugins/security_solution/public/common/components/draggables/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/draggables/index.test.tsx index 9c6b8c485986e4..f77bf0f347f794 100644 --- a/x-pack/plugins/security_solution/public/common/components/draggables/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/draggables/index.test.tsx @@ -21,6 +21,8 @@ import { tooltipContentIsExplicitlyNull, } from '.'; +jest.mock('../../lib/kibana'); + describe('draggables', () => { const mount = useMountAppended(); diff --git a/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/isolate_form.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/isolate_form.tsx index a66d1d05025cbd..2998b96fcf6eed 100644 --- a/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/isolate_form.tsx +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/host_isolation/isolate_form.tsx @@ -11,10 +11,10 @@ import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, - EuiSpacer, + EuiForm, + EuiFormRow, EuiText, EuiTextArea, - EuiTitle, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { CANCEL, COMMENT, COMMENT_PLACEHOLDER, CONFIRM } from './translations'; @@ -41,56 +41,62 @@ export const EndpointIsolateForm = memo( ); return ( - <> - -

- {hostName} }} - />{' '} - {messageAppend} -

-
+ + + +

+ {hostName} }} + /> +
+

+

+ {' '} + {messageAppend} +

+
+
- + + + - -

{COMMENT}

-
- - - - - - - - {CANCEL} - - - - - {CONFIRM} - - - - + + + + + {CANCEL} + + + + + {CONFIRM} + + + + +
); } ); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/alert_summary_view.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/alert_summary_view.test.tsx index b8f29996d603bb..c782804b0592b1 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/alert_summary_view.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/alert_summary_view.test.tsx @@ -17,6 +17,8 @@ import { TestProviders } from '../../mock'; import { mockBrowserFields } from '../../containers/source/mock'; import { useMountAppended } from '../../utils/use_mount_appended'; +jest.mock('../../lib/kibana'); + jest.mock('../../../detections/containers/detection_engine/rules/use_rule_async', () => { return { useRuleAsync: jest.fn(), diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx index 204b8c088304b5..1be05cc5605529 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx @@ -21,9 +21,8 @@ import { get, isEmpty } from 'lodash'; import memoizeOne from 'memoize-one'; import React from 'react'; import styled from 'styled-components'; -import { onFocusReFocusDraggable } from '../accessibility/helpers'; +import { onFocusReFocusDraggable } from '../../../../../timelines/public'; import { BrowserFields } from '../../containers/source'; -import { ColumnHeaderOptions } from '../../../timelines/store/timeline/model'; import { DragEffects } from '../drag_and_drop/draggable_wrapper'; import { DroppableWrapper } from '../drag_and_drop/droppable_wrapper'; import { DRAG_TYPE_FIELD, getDroppableId } from '../drag_and_drop/helpers'; @@ -38,6 +37,7 @@ import { OnUpdateColumns } from '../../../timelines/components/timeline/events'; import { getIconFromType, getExampleText } from './helpers'; import * as i18n from './translations'; import { EventFieldsData } from './types'; +import { ColumnHeaderOptions } from '../../../../common'; const HoverActionsContainer = styled(EuiPanel)` align-items: center; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx index 0c7515fe75d862..6aff259d8220e2 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx @@ -20,6 +20,8 @@ import { mockAlertDetailsData } from './__mocks__'; import { TimelineEventsDetailsItem } from '../../../../common/search_strategy'; import { TimelineTabs } from '../../../../common/types/timeline'; +jest.mock('../../../common/lib/kibana'); + jest.mock('../link_to'); describe('EventDetails', () => { const mount = useMountAppended(); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.test.tsx index f0865e1b8e0835..555b67da953d6c 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.test.tsx @@ -16,6 +16,8 @@ import { mockBrowserFields } from '../../containers/source/mock'; import { useMountAppended } from '../../utils/use_mount_appended'; import { TimelineTabs } from '../../../../common/types/timeline'; +jest.mock('../../lib/kibana'); + jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); return { diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.tsx index 93d0e6ccfbe3c2..3ad7e9aef19dcd 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.tsx @@ -11,26 +11,24 @@ import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import { useDispatch } from 'react-redux'; import { rgba } from 'polished'; import styled from 'styled-components'; - import { arrayIndexToAriaIndex, DATA_COLINDEX_ATTRIBUTE, DATA_ROWINDEX_ATTRIBUTE, isTab, onKeyDownFocusHandler, -} from '../accessibility/helpers'; +} from '../../../../../timelines/public'; + import { ADD_TIMELINE_BUTTON_CLASS_NAME } from '../../../timelines/components/flyout/add_timeline_button'; import { timelineActions, timelineSelectors } from '../../../timelines/store/timeline'; -import { ColumnHeaderOptions } from '../../../timelines/store/timeline/model'; import { BrowserFields, getAllFieldsByName } from '../../containers/source'; import { TimelineEventsDetailsItem } from '../../../../common/search_strategy/timeline'; import { getColumnHeaders } from '../../../timelines/components/timeline/body/column_headers/helpers'; import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; - import { getColumns } from './columns'; import { EVENT_FIELDS_TABLE_CLASS_NAME, onEventDetailsTabKeyPressed, search } from './helpers'; import { useDeepEqualSelector } from '../../hooks/use_selector'; -import { TimelineTabs } from '../../../../common/types/timeline'; +import { ColumnHeaderOptions, TimelineTabs } from '../../../../common/types/timeline'; interface Props { browserFields: BrowserFields; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx index 1f12c2de5e24fd..8392be420a2c53 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx @@ -15,15 +15,15 @@ import { getTableSkipFocus, handleSkipFocus, stopPropagationAndPreventDefault, -} from '../accessibility/helpers'; +} from '../../../../../timelines/public'; import { BrowserField, BrowserFields } from '../../containers/source'; -import { ColumnHeaderOptions } from '../../../timelines/store/timeline/model'; import { DEFAULT_DATE_COLUMN_MIN_WIDTH, DEFAULT_COLUMN_MIN_WIDTH, } from '../../../timelines/components/timeline/body/constants'; import * as i18n from './translations'; +import { ColumnHeaderOptions } from '../../../../common'; /** * Defines the behavior of the search input that appears above the table of data diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/default_headers.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/default_headers.tsx index 7c84a325cb667a..5051b39fe60933 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/default_headers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/default_headers.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { ColumnHeaderOptions } from '../../../timelines/store/timeline/model'; +import { ColumnHeaderOptions } from '../../../../common'; import { defaultColumnHeaderType } from '../../../timelines/components/timeline/body/column_headers/default_headers'; import { DEFAULT_COLUMN_MIN_WIDTH, diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx index 36986f5f8d3534..90a4e67d76b99d 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx @@ -21,9 +21,8 @@ import { mockBrowserFields, mockDocValueFields } from '../../containers/source/m import { eventsDefaultModel } from './default_model'; import { useMountAppended } from '../../utils/use_mount_appended'; import { inputsModel } from '../../store/inputs'; -import { TimelineId } from '../../../../common/types/timeline'; +import { TimelineId, SortDirection } from '../../../../common/types/timeline'; import { KqlMode } from '../../../timelines/store/timeline/model'; -import { SortDirection } from '../../../timelines/components/timeline/body/sort'; import { AlertsTableFilterGroup } from '../../../detections/components/alerts_table/alerts_filter_group'; import { SourcererScopeName } from '../../store/sourcerer/model'; import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers'; @@ -31,6 +30,8 @@ import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell import { useTimelineEvents } from '../../../timelines/containers'; import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features'; +jest.mock('../../lib/kibana'); + jest.mock('../../hooks/use_experimental_features'); const useIsExperimentalFeatureEnabledMock = useIsExperimentalFeatureEnabled as jest.Mock; @@ -144,18 +145,18 @@ describe('EventsViewer', () => { mockUseTimelineEvents.mockReturnValue([false, mockEventViewerResponseWithEvents]); }); - test('call the right reduce action to show event details', async () => { + test('call the right reduce action to show event details', () => { const wrapper = mount( ); - await act(async () => { + act(() => { wrapper.find(`[data-test-subj="expand-event"]`).first().simulate('click'); }); - await waitFor(() => { + waitFor(() => { expect(mockDispatch).toBeCalledTimes(2); expect(mockDispatch.mock.calls[1][0]).toEqual({ payload: { @@ -197,7 +198,7 @@ describe('EventsViewer', () => { ); expect(wrapper.find(`[data-test-subj="show-field-browser"]`).first().exists()).toBe(true); }); - // TO DO sourcerer @X + test('it renders the footer containing the pagination', () => { const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx index c99275ec49ab3e..5dadd740ae3bca 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx @@ -10,11 +10,12 @@ import React, { useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; import deepEqual from 'fast-deep-equal'; +import { useDispatch } from 'react-redux'; import { Direction } from '../../../../common/search_strategy'; import { BrowserFields, DocValueFields } from '../../containers/source'; import { useTimelineEvents } from '../../../timelines/containers'; import { useKibana } from '../../lib/kibana'; -import { ColumnHeaderOptions, KqlMode } from '../../../timelines/store/timeline/model'; +import { KqlMode } from '../../../timelines/store/timeline/model'; import { HeaderSection } from '../header_section'; import { defaultHeaders } from '../../../timelines/components/timeline/body/column_headers/default_headers'; import { Sort } from '../../../timelines/components/timeline/body/sort'; @@ -36,18 +37,21 @@ import { Query, } from '../../../../../../../src/plugins/data/public'; import { inputsModel } from '../../store'; -import { useManageTimeline } from '../../../timelines/components/manage_timeline'; import { ExitFullScreen } from '../exit_full_screen'; import { useGlobalFullScreen } from '../../containers/use_full_screen'; -import { TimelineId, TimelineTabs } from '../../../../common/types/timeline'; -import { RowRenderer } from '../../../timelines/components/timeline/body/renderers/row_renderer'; +import { + ColumnHeaderOptions, + ControlColumnProps, + RowRenderer, + TimelineId, + TimelineTabs, +} from '../../../../common/types/timeline'; import { GraphOverlay } from '../../../timelines/components/graph_overlay'; import { CellValueElementProps } from '../../../timelines/components/timeline/cell_rendering'; import { SELECTOR_TIMELINE_GLOBAL_CONTAINER } from '../../../timelines/components/timeline/styles'; -import { - defaultControlColumn, - ControlColumnProps, -} from '../../../timelines/components/timeline/body/control_columns'; +import { defaultControlColumn } from '../../../timelines/components/timeline/body/control_columns'; +import { timelineSelectors, timelineActions } from '../../../timelines/store/timeline'; +import { useDeepEqualSelector } from '../../hooks/use_selector'; export const EVENTS_VIEWER_HEADER_HEIGHT = 90; // px const UTILITY_BAR_HEIGHT = 19; // px @@ -162,21 +166,19 @@ const EventsViewerComponent: React.FC = ({ utilityBar, graphEventId, }) => { + const dispatch = useDispatch(); const { globalFullScreen, setGlobalFullScreen } = useGlobalFullScreen(); const columnsHeader = isEmpty(columns) ? defaultHeaders : columns; const kibana = useKibana(); const [isQueryLoading, setIsQueryLoading] = useState(false); - const { getManageTimelineById, setIsTimelineLoading } = useManageTimeline(); - useEffect(() => { - setIsTimelineLoading({ id, isLoading: isQueryLoading }); - }, [id, isQueryLoading, setIsTimelineLoading]); + dispatch(timelineActions.updateIsLoading({ id, isLoading: isQueryLoading })); + }, [dispatch, id, isQueryLoading]); - const { queryFields, title, unit } = useMemo(() => getManageTimelineById(id), [ - getManageTimelineById, - id, - ]); + const getManageTimeline = useMemo(() => timelineSelectors.getManageTimelineById(), []); + const unit = useMemo(() => (n: number) => i18n.UNIT(n), []); + const { queryFields, title } = useDeepEqualSelector((state) => getManageTimeline(state, id)); const justTitle = useMemo(() => {title}, [title]); @@ -284,6 +286,7 @@ const EventsViewerComponent: React.FC = ({ {canQueryTimeline ? ( diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx index cd27177643b449..571e04a106cf0b 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx @@ -22,6 +22,8 @@ import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell import { useTimelineEvents } from '../../../timelines/containers'; import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers'; +jest.mock('../../../common/lib/kibana'); + jest.mock('../../../timelines/containers', () => ({ useTimelineEvents: jest.fn(), })); @@ -60,7 +62,9 @@ describe('StatefulEventsViewer', () => { await waitFor(() => { wrapper.update(); - expect(wrapper.find('[data-test-subj="events-viewer-panel"]').first().exists()).toBe(true); + expect(wrapper.text()).toMatchInlineSnapshot( + `"Showing: 12 events1 fields sorted@timestamp1event.severityevent.categoryevent.actionhost.namesource.ipdestination.ipdestination.bytesuser.name_idmessage0 of 12 events123"` + ); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index b58aa2236d2924..32aa716d4bce3e 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -12,23 +12,23 @@ import styled from 'styled-components'; import { inputsModel, inputsSelectors, State } from '../../store'; import { inputsActions } from '../../store/actions'; -import { TimelineId } from '../../../../common/types/timeline'; +import { ControlColumnProps, RowRenderer, TimelineId } from '../../../../common/types/timeline'; import { timelineSelectors, timelineActions } from '../../../timelines/store/timeline'; import { SubsetTimelineModel, TimelineModel } from '../../../timelines/store/timeline/model'; import { Filter } from '../../../../../../../src/plugins/data/public'; -import { EventsViewer } from './events_viewer'; import { InspectButtonContainer } from '../inspect'; import { useGlobalFullScreen } from '../../containers/use_full_screen'; +import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features'; import { SourcererScopeName } from '../../store/sourcerer/model'; import { useSourcererScope } from '../../containers/sourcerer'; import { DetailsPanel } from '../../../timelines/components/side_panel'; -import { RowRenderer } from '../../../timelines/components/timeline/body/renderers/row_renderer'; import { CellValueElementProps } from '../../../timelines/components/timeline/cell_rendering'; - -const DEFAULT_EVENTS_VIEWER_HEIGHT = 652; +import { useKibana } from '../../lib/kibana'; +import { defaultControlColumn } from '../../../timelines/components/timeline/body/control_columns'; +import { EventsViewer } from './events_viewer'; const FullScreenContainer = styled.div<{ $isFullScreen: boolean }>` - height: ${({ $isFullScreen }) => ($isFullScreen ? '100%' : `${DEFAULT_EVENTS_VIEWER_HEIGHT}px`)}; + height: ${({ $isFullScreen }) => ($isFullScreen ? '100%' : undefined)}; flex: 1 1 auto; display: flex; width: 100%; @@ -83,6 +83,7 @@ const StatefulEventsViewerComponent: React.FC = ({ // If truthy, the graph viewer (Resolver) is showing graphEventId, }) => { + const { timelines: timelinesUi } = useKibana().services; const { browserFields, docValueFields, @@ -90,8 +91,9 @@ const StatefulEventsViewerComponent: React.FC = ({ selectedPatterns, loading: isLoadingIndexPattern, } = useSourcererScope(scopeId); - const { globalFullScreen } = useGlobalFullScreen(); - + const { globalFullScreen, setGlobalFullScreen } = useGlobalFullScreen(); + // TODO: Once we are past experimental phase this code should be removed + const tGridEnabled = useIsExperimentalFeatureEnabled('tGridEnabled'); useEffect(() => { if (createTimeline != null) { createTimeline({ @@ -111,37 +113,73 @@ const StatefulEventsViewerComponent: React.FC = ({ }, []); const globalFilters = useMemo(() => [...filters, ...(pageFilters ?? [])], [filters, pageFilters]); + const leadingControlColumns: ControlColumnProps[] = [defaultControlColumn]; + const trailingControlColumns: ControlColumnProps[] = []; return ( <> - + {tGridEnabled ? ( + timelinesUi.getTGrid<'embedded'>({ + type: 'embedded', + browserFields, + columns, + dataProviders: dataProviders!, + deletedEventIds, + docValueFields, + end, + filters: globalFilters, + globalFullScreen, + headerFilterGroup, + id, + indexNames: selectedPatterns, + indexPattern, + isLive, + isLoadingIndexPattern, + itemsPerPage, + itemsPerPageOptions: itemsPerPageOptions!, + kqlMode, + query, + onRuleChange, + renderCellValue, + rowRenderers, + setGlobalFullScreen, + start, + sort, + utilityBar, + graphEventId, + leadingControlColumns, + trailingControlColumns, + }) + ) : ( + + )} i18n.translate('xpack.securitySolution.eventsViewer.unit', { values: { totalCount }, diff --git a/x-pack/plugins/security_solution/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap index 994e98d8619a18..51326d54a61611 100644 --- a/x-pack/plugins/security_solution/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap @@ -4,17 +4,19 @@ exports[`rendering renders correctly 1`] = ` } > - -

Additional filters here.

-
-
+ +
`; diff --git a/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx index c6b5b6ccde5cd1..79c08e50451f78 100644 --- a/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx @@ -8,18 +8,9 @@ import React from 'react'; import styled from 'styled-components'; import { InPortal } from 'react-reverse-portal'; - +import { EuiPanel } from '@elastic/eui'; import { useGlobalHeaderPortal } from '../../hooks/use_global_header_portal'; -const Wrapper = styled.aside` - position: relative; - z-index: ${({ theme }) => theme.eui.euiZNavigation}; - background: ${({ theme }) => theme.eui.euiColorEmptyShade}; - border-bottom: ${({ theme }) => theme.eui.euiBorderThin}; - padding: ${({ theme }) => theme.eui.paddingSizes.m} ${({ theme }) => theme.eui.paddingSizes.l}; -`; -Wrapper.displayName = 'Wrapper'; - const FiltersGlobalContainer = styled.header<{ show: boolean }>` display: ${({ show }) => (show ? 'block' : 'none')}; `; @@ -32,13 +23,15 @@ export interface FiltersGlobalProps { } export const FiltersGlobal = React.memo(({ children, show = true }) => { - const { globalHeaderPortalNode } = useGlobalHeaderPortal(); + const { globalKQLHeaderPortalNode } = useGlobalHeaderPortal(); return ( - - - {children} - + + + + {children} + + ); }); diff --git a/x-pack/plugins/security_solution/public/common/components/header_global/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_global/index.test.tsx deleted file mode 100644 index 96a7eacb7fb08c..00000000000000 --- a/x-pack/plugins/security_solution/public/common/components/header_global/index.test.tsx +++ /dev/null @@ -1,51 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { mount } from 'enzyme'; - -import { useGetUserCasesPermissions } from '../../../common/lib/kibana'; -import { TestProviders } from '../../../common/mock'; -import { HeaderGlobal } from '.'; - -jest.mock('../../../common/lib/kibana'); - -describe('HeaderGlobal', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('does not display the cases tab when the user does not have read permissions', () => { - (useGetUserCasesPermissions as jest.Mock).mockReturnValue({ - crud: false, - read: false, - }); - - const wrapper = mount( - - - - ); - - expect(wrapper.find(`[data-test-subj="navigation-case"]`).exists()).toBeFalsy(); - }); - - it('displays the cases tab when the user has read permissions', () => { - (useGetUserCasesPermissions as jest.Mock).mockReturnValue({ - crud: true, - read: true, - }); - - const wrapper = mount( - - - - ); - - expect(wrapper.find(`[data-test-subj="navigation-case"]`).exists()).toBeTruthy(); - }); -}); diff --git a/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx b/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx deleted file mode 100644 index e91905183aab10..00000000000000 --- a/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx +++ /dev/null @@ -1,155 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui'; -import { pickBy } from 'lodash/fp'; -import React, { forwardRef, useCallback, useMemo } from 'react'; -import styled from 'styled-components'; -import { OutPortal } from 'react-reverse-portal'; - -import { navTabs } from '../../../app/home/home_navigations'; -import { useGlobalFullScreen, useTimelineFullScreen } from '../../containers/use_full_screen'; -import { SecurityPageName } from '../../../app/types'; -import { getAppOverviewUrl } from '../link_to'; -import { MlPopover } from '../ml_popover/ml_popover'; -import { SiemNavigation } from '../navigation'; -import * as i18n from './translations'; -import { useGetUrlSearch } from '../navigation/use_get_url_search'; -import { useGetUserCasesPermissions, useKibana } from '../../lib/kibana'; -import { APP_ID, ADD_DATA_PATH, APP_DETECTIONS_PATH } from '../../../../common/constants'; -import { useGlobalHeaderPortal } from '../../hooks/use_global_header_portal'; -import { LinkAnchor } from '../links'; - -const Wrapper = styled.header<{ $isFixed: boolean }>` - ${({ theme, $isFixed }) => ` - background: ${theme.eui.euiColorEmptyShade}; - border-bottom: ${theme.eui.euiBorderThin}; - width: 100%; - z-index: ${theme.eui.euiZNavigation}; - position: ${$isFixed ? 'fixed' : 'relative'}; - `} -`; -Wrapper.displayName = 'Wrapper'; - -const WrapperContent = styled.div<{ $globalFullScreen: boolean }>` - display: ${({ $globalFullScreen }) => ($globalFullScreen ? 'none' : 'block')}; - padding-top: ${({ $globalFullScreen, theme }) => - $globalFullScreen ? theme.eui.paddingSizes.s : theme.eui.paddingSizes.m}; -`; - -WrapperContent.displayName = 'WrapperContent'; - -const FlexItem = styled(EuiFlexItem)` - min-width: 0; -`; -FlexItem.displayName = 'FlexItem'; - -const FlexGroup = styled(EuiFlexGroup)<{ $hasSibling: boolean }>` - ${({ $hasSibling, theme }) => ` - border-bottom: ${theme.eui.euiBorderThin}; - margin-bottom: 1px; - padding-bottom: 4px; - padding-left: ${theme.eui.paddingSizes.l}; - padding-right: ${theme.eui.paddingSizes.l}; - ${$hasSibling ? `border-bottom: ${theme.eui.euiBorderThin};` : 'border-bottom-width: 0px;'} - `} -`; -FlexGroup.displayName = 'FlexGroup'; - -interface HeaderGlobalProps { - hideDetectionEngine?: boolean; - isFixed?: boolean; -} - -export const HeaderGlobal = React.memo( - forwardRef( - ({ hideDetectionEngine = false, isFixed = true }, ref) => { - const { globalHeaderPortalNode } = useGlobalHeaderPortal(); - const { globalFullScreen } = useGlobalFullScreen(); - const { timelineFullScreen } = useTimelineFullScreen(); - const search = useGetUrlSearch(navTabs.overview); - const { application, http } = useKibana().services; - const { navigateToApp, getUrlForApp } = application; - const overviewPath = useMemo( - () => getUrlForApp(APP_ID, { path: SecurityPageName.overview }), - [getUrlForApp] - ); - const overviewHref = useMemo(() => getAppOverviewUrl(overviewPath, search), [ - overviewPath, - search, - ]); - - const basePath = http.basePath.get(); - const goToOverview = useCallback( - (ev) => { - ev.preventDefault(); - navigateToApp(`${APP_ID}:${SecurityPageName.overview}`, { path: search }); - }, - [navigateToApp, search] - ); - - const hasCasesReadPermissions = useGetUserCasesPermissions()?.read; - - // build a list of tabs to exclude - const tabsToExclude = new Set([ - ...(hideDetectionEngine ? [SecurityPageName.detections] : []), - ...(!hasCasesReadPermissions ? [SecurityPageName.case] : []), - ]); - - // include the tab if it is not in the set of excluded ones - const tabsToDisplay = pickBy((_, key) => !tabsToExclude.has(key), navTabs); - - return ( - - - - - - - - - - - - - - - - - - - {window.location.pathname.includes(APP_DETECTIONS_PATH) && ( - - - - )} - - - - {i18n.BUTTON_ADD_DATA} - - - - - - - - - ); - } - ) -); -HeaderGlobal.displayName = 'HeaderGlobal'; diff --git a/x-pack/plugins/security_solution/public/common/components/header_page/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/header_page/__snapshots__/index.test.tsx.snap index 84c8971e3d352f..9cb9f28612b155 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_page/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/header_page/__snapshots__/index.test.tsx.snap @@ -1,14 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`HeaderPage it renders 1`] = ` -
- + - + - - +

Test supplement

-
-
- + + + -
+ `; diff --git a/x-pack/plugins/security_solution/public/common/components/header_page/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/index.test.tsx index 78bac02585b9f5..8a1748de582c43 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_page/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_page/index.test.tsx @@ -57,7 +57,7 @@ describe('HeaderPage', () => { ); - expect(wrapper.find('.siemHeaderPage__linkBack').first().exists()).toBe(true); + expect(wrapper.find('.securitySolutionHeaderPage__linkBack').first().exists()).toBe(true); }); test('it DOES NOT render the back link when not provided', () => { @@ -67,7 +67,7 @@ describe('HeaderPage', () => { ); - expect(wrapper.find('.siemHeaderPage__linkBack').first().exists()).toBe(false); + expect(wrapper.find('.securitySolutionHeaderPage__linkBack').first().exists()).toBe(false); }); test('it renders the first subtitle when provided', () => { @@ -134,27 +134,21 @@ describe('HeaderPage', () => { expect(wrapper.find('[data-test-subj="header-page-supplements"]').first().exists()).toBe(false); }); - test('it applies border styles when border is true', () => { - const wrapper = mount( - - - - ); - const siemHeaderPage = wrapper.find('.siemHeaderPage').first(); - - expect(siemHeaderPage).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin); - expect(siemHeaderPage).toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l); - }); - test('it DOES NOT apply border styles when border is false', () => { const wrapper = mount( ); - const siemHeaderPage = wrapper.find('.siemHeaderPage').first(); + const securitySolutionHeaderPage = wrapper.find('.securitySolutionHeaderPage').first(); - expect(siemHeaderPage).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin); - expect(siemHeaderPage).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l); + expect(securitySolutionHeaderPage).not.toHaveStyleRule( + 'border-bottom', + euiDarkVars.euiBorderThin + ); + expect(securitySolutionHeaderPage).not.toHaveStyleRule( + 'padding-bottom', + euiDarkVars.paddingSizes.l + ); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/header_page/index.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/index.tsx index d01869bb6999b0..1c87d70c0c7cb1 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_page/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_page/index.tsx @@ -5,7 +5,13 @@ * 2.0. */ -import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiProgress } from '@elastic/eui'; +import { + EuiBadge, + EuiProgress, + EuiPageHeader, + EuiPageHeaderSection, + EuiSpacer, +} from '@elastic/eui'; import React, { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import styled, { css } from 'styled-components'; @@ -25,36 +31,16 @@ interface HeaderProps { } const Header = styled.header.attrs({ - className: 'siemHeaderPage', + className: 'securitySolutionHeaderPage', })` ${({ border, theme }) => css` margin-bottom: ${theme.eui.euiSizeL}; - - ${border && - css` - border-bottom: ${theme.eui.euiBorderThin}; - padding-bottom: ${theme.eui.paddingSizes.l}; - .euiProgress { - top: ${theme.eui.paddingSizes.l}; - } - `} `} `; Header.displayName = 'Header'; -const FlexItem = styled(EuiFlexItem)` - ${({ theme }) => css` - display: block; - - @media only screen and (min-width: ${theme.eui.euiBreakpoints.m}) { - max-width: 50%; - } - `} -`; -FlexItem.displayName = 'FlexItem'; - const LinkBack = styled.div.attrs({ - className: 'siemHeaderPage__linkBack', + className: 'securitySolutionHeaderPage__linkBack', })` ${({ theme }) => css` font-size: ${theme.eui.euiFontSizeXS}; @@ -117,9 +103,9 @@ const HeaderPageComponent: React.FC = ({ [backOptions, history] ); return ( -
- - + <> + + {backOptions && ( = ({ {subtitle && } {subtitle2 && } {border && isLoading && } - + {children && ( - + {children} - + )} - - {!hideSourcerer && } -
+ {!hideSourcerer && } + + {/* Manually add a 'padding-bottom' to header */} + + ); }; diff --git a/x-pack/plugins/security_solution/public/common/components/header_page/title.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/title.test.tsx index 7ad9de29431c96..d21adbd00cc202 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_page/title.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_page/title.test.tsx @@ -13,6 +13,8 @@ import { TestProviders } from '../../mock'; import { Title } from './title'; import { useMountAppended } from '../../utils/use_mount_appended'; +jest.mock('../../lib/kibana'); + describe('Title', () => { const mount = useMountAppended(); diff --git a/x-pack/plugins/security_solution/public/common/components/inspect/index.tsx b/x-pack/plugins/security_solution/public/common/components/inspect/index.tsx index ddbcf710aff305..a0e2ff266ad288 100644 --- a/x-pack/plugins/security_solution/public/common/components/inspect/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/inspect/index.tsx @@ -131,7 +131,7 @@ const InspectButtonComponent: React.FC = ({ color="text" iconSide="left" iconType="inspect" - isDisabled={loading || isDisabled} + isDisabled={loading || isDisabled || false} isLoading={loading} onClick={handleClick} > @@ -145,7 +145,7 @@ const InspectButtonComponent: React.FC = ({ data-test-subj="inspect-icon-button" iconSize="m" iconType="inspect" - isDisabled={loading || isDisabled} + isDisabled={loading || isDisabled || false} title={i18n.INSPECT} onClick={handleClick} /> diff --git a/x-pack/plugins/security_solution/public/common/components/item_details_card/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/item_details_card/__snapshots__/index.test.tsx.snap index c7841f6d6bbcc2..f0fd8427140df2 100644 --- a/x-pack/plugins/security_solution/public/common/components/item_details_card/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/item_details_card/__snapshots__/index.test.tsx.snap @@ -14,6 +14,7 @@ exports[`item_details_card ItemDetailsAction should render correctly 1`] = ` exports[`item_details_card ItemDetailsCard should render correctly with actions 1`] = ` ( ); return ( - + diff --git a/x-pack/plugins/security_solution/public/common/components/ml/entity_draggable.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/entity_draggable.test.tsx index 115fb65dc70114..f08edb114b9a98 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/entity_draggable.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/entity_draggable.test.tsx @@ -13,6 +13,8 @@ import { EntityDraggableComponent } from './entity_draggable'; import { TestProviders } from '../../mock/test_providers'; import { useMountAppended } from '../../utils/use_mount_appended'; +jest.mock('../../../common/lib/kibana'); + jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); return { diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx index 6ad2bd30283d23..0d9b4001c17aaf 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx @@ -17,6 +17,8 @@ import { useMountAppended } from '../../../utils/use_mount_appended'; import { Anomalies } from '../types'; import { waitFor } from '@testing-library/dom'; +jest.mock('../../../lib/kibana'); + const startDate: string = '2020-07-07T08:20:18.966Z'; const endDate: string = '3000-01-01T00:00:00.000Z'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_scores.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_scores.test.tsx index 6b569a67cfebf7..5eb0751404872e 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_scores.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_scores.test.tsx @@ -18,6 +18,8 @@ import { Anomalies } from '../types'; import { useMountAppended } from '../../../utils/use_mount_appended'; import { waitFor } from '@testing-library/dom'; +jest.mock('../../../lib/kibana'); + const startDate: string = '2020-07-07T08:20:18.966Z'; const endDate: string = '3000-01-01T00:00:00.000Z'; const narrowDateRange = jest.fn(); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx index ae6ef4e680ffaa..2ecda8482e3400 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx @@ -16,6 +16,8 @@ import { Columns } from '../../paginated_table'; import { TestProviders } from '../../../mock'; import { useMountAppended } from '../../../utils/use_mount_appended'; +jest.mock('../../../lib/kibana'); + const startDate = new Date(2001).toISOString(); const endDate = new Date(3000).toISOString(); const interval = 'days'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx index b8a8ab88a74fd6..48c2ec3ee38d81 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx @@ -15,6 +15,8 @@ import React from 'react'; import { TestProviders } from '../../../mock'; import { useMountAppended } from '../../../utils/use_mount_appended'; +jest.mock('../../../../common/lib/kibana'); + const startDate = new Date(2001).toISOString(); const endDate = new Date(3000).toISOString(); describe('get_anomalies_network_table_columns', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx index 561805217e8a14..cc6ac5355f90b8 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx @@ -5,7 +5,13 @@ * 2.0. */ -import { EuiButtonEmpty, EuiCallOut, EuiPopover, EuiPopoverTitle, EuiSpacer } from '@elastic/eui'; +import { + EuiHeaderSectionItemButton, + EuiCallOut, + EuiPopover, + EuiPopoverTitle, + EuiSpacer, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import moment from 'moment'; import React, { Dispatch, useCallback, useReducer, useState } from 'react'; @@ -115,14 +121,19 @@ export const MlPopover = React.memo(() => { anchorPosition="downRight" id="integrations-popover" button={ - setIsPopoverOpen(!isPopoverOpen)} + textProps={{ style: { fontSize: '1rem' } }} > {i18n.ML_JOB_SETTINGS} - + } isOpen={isPopoverOpen} closePopover={() => setIsPopoverOpen(!isPopoverOpen)} @@ -138,7 +149,11 @@ export const MlPopover = React.memo(() => { anchorPosition="downRight" id="integrations-popover" button={ - { setIsPopoverOpen(!isPopoverOpen); dispatch({ type: 'refresh' }); }} + textProps={{ style: { fontSize: '1rem' } }} > {i18n.ML_JOB_SETTINGS} - + } isOpen={isPopoverOpen} closePopover={() => setIsPopoverOpen(!isPopoverOpen)} diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts index dffc7becaf42a6..c869df6ad388ee 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts @@ -306,6 +306,29 @@ describe('Navigation Breadcrumbs', () => { }, ]); }); + + test('should set "timeline.isOpen" to false when timeline is open', () => { + const breadcrumbs = getBreadcrumbsForRoute( + { + ...getMockObject('timelines', '/', undefined), + timeline: { + activeTab: TimelineTabs.query, + id: 'TIMELINE_ID', + isOpen: true, + graphEventId: 'GRAPH_EVENT_ID', + }, + }, + getUrlForAppMock + ); + expect(breadcrumbs).toEqual([ + { text: 'Security', href: 'securitySolutionoverview' }, + { + text: 'Timelines', + href: + "securitySolution:timelines?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))&timeline=(activeTab:query,graphEventId:GRAPH_EVENT_ID,id:TIMELINE_ID,isOpen:!f)", + }, + ]); + }); }); describe('setBreadcrumbs()', () => { 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 605478900d0662..a09945f705c582 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 @@ -61,10 +61,14 @@ const isAdminRoutes = (spyState: RouteSpyState): spyState is AdministrationRoute // eslint-disable-next-line complexity export const getBreadcrumbsForRoute = ( - object: RouteSpyState & TabNavigationProps, + objectParam: RouteSpyState & TabNavigationProps, getUrlForApp: GetUrlForApp ): ChromeBreadcrumb[] | null => { - const spyState: RouteSpyState = omit('navTabs', object); + const spyState: RouteSpyState = omit('navTabs', objectParam); + + // Sets `timeline.isOpen` to false in the state to avoid reopening the timeline on breadcrumb click. https://github.com/elastic/kibana/issues/100322 + const object = { ...objectParam, timeline: { ...objectParam.timeline, isOpen: false } }; + const overviewPath = getUrlForApp(APP_ID, { path: SecurityPageName.overview }); const siemRootBreadcrumb: ChromeBreadcrumb = { text: APP_NAME, diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx index 27db326dddec5c..c75b38e03acb46 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx @@ -9,12 +9,12 @@ import { mount } from 'enzyme'; import React from 'react'; import { CONSTANTS } from '../url_state/constants'; -import { SiemNavigationComponent } from './'; +import { TabNavigationComponent } from './'; import { setBreadcrumbs } from './breadcrumbs'; import { navTabs } from '../../../app/home/home_navigations'; import { HostsTableType } from '../../../hosts/store/model'; import { RouteSpyState } from '../../utils/route/types'; -import { SiemNavigationProps, SiemNavigationComponentProps } from './types'; +import { TabNavigationComponentProps, SecuritySolutionTabNavigationProps } from './types'; import { TimelineTabs } from '../../../../common/types/timeline'; jest.mock('react-router-dom', () => { @@ -48,7 +48,9 @@ jest.mock('../../lib/kibana', () => { jest.mock('../link_to'); describe('SIEM Navigation', () => { - const mockProps: SiemNavigationComponentProps & SiemNavigationProps & RouteSpyState = { + const mockProps: TabNavigationComponentProps & + SecuritySolutionTabNavigationProps & + RouteSpyState = { pageName: 'hosts', pathName: '/', detailName: undefined, @@ -89,7 +91,7 @@ describe('SIEM Navigation', () => { }, }, }; - const wrapper = mount(); + const wrapper = mount(); test('it calls setBreadcrumbs with correct path on mount', () => { expect(setBreadcrumbs).toHaveBeenNthCalledWith( 1, diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/index.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/index.tsx index 7ea0b26ae8b3b8..233b4b2cb1d029 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/index.tsx @@ -16,75 +16,93 @@ import { useRouteSpy } from '../../utils/route/use_route_spy'; import { makeMapStateToProps } from '../url_state/helpers'; import { setBreadcrumbs } from './breadcrumbs'; import { TabNavigation } from './tab_navigation'; -import { SiemNavigationProps, SiemNavigationComponentProps } from './types'; +import { TabNavigationComponentProps, SecuritySolutionTabNavigationProps } from './types'; -export const SiemNavigationComponent: React.FC< - SiemNavigationComponentProps & SiemNavigationProps & RouteSpyState -> = ({ - detailName, - display, - navTabs, - pageName, - pathName, - search, - tabName, - urlState, - flowTarget, - state, -}) => { - const { - chrome, - application: { getUrlForApp }, - } = useKibana().services; +/** + * @description - This component handels all of the tab navigation seen within a Security Soluton application page, not the Security Solution primary side navigation + * For the primary side nav see './use_security_solution_navigation' + */ +export const TabNavigationComponent: React.FC< + RouteSpyState & SecuritySolutionTabNavigationProps & TabNavigationComponentProps +> = React.memo( + ({ + detailName, + display, + flowTarget, + navTabs, + pageName, + pathName, + search, + state, + tabName, + urlState, + }) => { + const { + chrome, + application: { getUrlForApp }, + } = useKibana().services; - useEffect(() => { - if (pathName || pageName) { - setBreadcrumbs( - { - detailName, - filters: urlState.filters, - flowTarget, - navTabs, - pageName, - pathName, - query: urlState.query, - savedQuery: urlState.savedQuery, - search, - sourcerer: urlState.sourcerer, - state, - tabName, - timeline: urlState.timeline, - timerange: urlState.timerange, - }, - chrome, - getUrlForApp - ); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [chrome, pageName, pathName, search, navTabs, urlState, state]); + useEffect(() => { + if (pathName || pageName) { + setBreadcrumbs( + { + detailName, + filters: urlState.filters, + flowTarget, + navTabs, + pageName, + pathName, + query: urlState.query, + savedQuery: urlState.savedQuery, + search, + sourcerer: urlState.sourcerer, + state, + tabName, + timeline: urlState.timeline, + timerange: urlState.timerange, + }, + chrome, + getUrlForApp + ); + } + }, [ + chrome, + pageName, + pathName, + search, + navTabs, + urlState, + state, + detailName, + flowTarget, + tabName, + getUrlForApp, + ]); - return ( - - ); -}; + return ( + + ); + } +); +TabNavigationComponent.displayName = 'TabNavigationComponent'; -export const SiemNavigationRedux = compose< - React.ComponentClass +export const SecuritySolutionTabNavigationRedux = compose< + React.ComponentClass >(connect(makeMapStateToProps))( React.memo( - SiemNavigationComponent, + TabNavigationComponent, (prevProps, nextProps) => prevProps.pathName === nextProps.pathName && prevProps.search === nextProps.search && @@ -94,16 +112,16 @@ export const SiemNavigationRedux = compose< ) ); -const SiemNavigationContainer: React.FC = (props) => { - const [routeProps] = useRouteSpy(); - const stateNavReduxProps: RouteSpyState & SiemNavigationProps = { - ...routeProps, - ...props, - }; - - return ; -}; +export const SecuritySolutionTabNavigation: React.FC = React.memo( + (props) => { + const [routeProps] = useRouteSpy(); + const stateNavReduxProps: RouteSpyState & SecuritySolutionTabNavigationProps = { + ...routeProps, + ...props, + }; -export const SiemNavigation = React.memo(SiemNavigationContainer, (prevProps, nextProps) => - deepEqual(prevProps.navTabs, nextProps.navTabs) + return ; + }, + (prevProps, nextProps) => deepEqual(prevProps.navTabs, nextProps.navTabs) ); +SecuritySolutionTabNavigation.displayName = 'SecuritySolutionTabNavigation'; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts index 4253d08d1ed197..53565d79e6948a 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts @@ -7,17 +7,17 @@ import { UrlInputsModel } from '../../../store/inputs/model'; import { CONSTANTS } from '../../url_state/constants'; -import { HostsTableType } from '../../../../hosts/store/model'; import { SourcererScopePatterns } from '../../../store/sourcerer/model'; import { TimelineUrl } from '../../../../timelines/store/timeline/model'; import { Filter, Query } from '../../../../../../../../src/plugins/data/public'; -import { SiemNavigationProps } from '../types'; +import { SecuritySolutionTabNavigationProps } from '../types'; +import { SiemRouteType } from '../../../utils/route/types'; -export interface TabNavigationProps extends SiemNavigationProps { +export interface TabNavigationProps extends SecuritySolutionTabNavigationProps { pathName: string; pageName: string; - tabName: HostsTableType | undefined; + tabName: SiemRouteType | undefined; [CONSTANTS.appQuery]?: Query; [CONSTANTS.filters]?: Filter[]; [CONSTANTS.savedQuery]?: string; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/types.ts b/x-pack/plugins/security_solution/public/common/components/navigation/types.ts index 9700afcb8cd59e..1c317700b1d150 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/types.ts @@ -5,31 +5,20 @@ * 2.0. */ -import { Filter, Query } from '../../../../../../../src/plugins/data/public'; -import { HostsTableType } from '../../../hosts/store/model'; -import { UrlInputsModel } from '../../store/inputs/model'; -import { TimelineUrl } from '../../../timelines/store/timeline/model'; -import { CONSTANTS, UrlStateType } from '../url_state/constants'; +import { UrlStateType } from '../url_state/constants'; import { SecurityPageName } from '../../../app/types'; -import { SourcererScopePatterns } from '../../store/sourcerer/model'; +import { UrlState } from '../url_state/types'; +import { SiemRouteType } from '../../utils/route/types'; -export interface SiemNavigationProps { +export interface SecuritySolutionTabNavigationProps { display?: 'default' | 'condensed'; navTabs: Record; } - -export interface SiemNavigationComponentProps { - pathName: string; +export interface TabNavigationComponentProps { pageName: string; - tabName: HostsTableType | undefined; - urlState: { - [CONSTANTS.appQuery]?: Query; - [CONSTANTS.filters]?: Filter[]; - [CONSTANTS.savedQuery]?: string; - [CONSTANTS.sourcerer]: SourcererScopePatterns; - [CONSTANTS.timerange]: UrlInputsModel; - [CONSTANTS.timeline]: TimelineUrl; - }; + tabName: SiemRouteType | undefined; + urlState: UrlState; + pathName: string; } export type SearchNavTab = NavTab | { urlKey: UrlStateType; isDetailPage: boolean }; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx new file mode 100644 index 00000000000000..48d3cfb5abcc14 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx @@ -0,0 +1,214 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import { KibanaPageTemplateProps } from '../../../../../../../../src/plugins/kibana_react/public'; +import { useGetUserCasesPermissions, useKibana } from '../../../lib/kibana'; +import { SecurityPageName } from '../../../../app/types'; +import { useSecuritySolutionNavigation } from '.'; +import { CONSTANTS } from '../../url_state/constants'; +import { TimelineTabs } from '../../../../../common/types/timeline'; +import { useDeepEqualSelector } from '../../../hooks/use_selector'; +import { UrlInputsModel } from '../../../store/inputs/model'; +import { useRouteSpy } from '../../../utils/route/use_route_spy'; + +jest.mock('../../../lib/kibana'); +jest.mock('../../../hooks/use_selector'); +jest.mock('../../../utils/route/use_route_spy'); + +describe('useSecuritySolutionNavigation', () => { + const mockUrlState = { + [CONSTANTS.appQuery]: { query: 'host.name:"security-solution-es"', language: 'kuery' }, + [CONSTANTS.savedQuery]: '', + [CONSTANTS.sourcerer]: {}, + [CONSTANTS.timeline]: { + activeTab: TimelineTabs.query, + id: '', + isOpen: false, + graphEventId: '', + }, + [CONSTANTS.timerange]: { + global: { + [CONSTANTS.timerange]: { + from: '2020-07-07T08:20:18.966Z', + fromStr: 'now-24h', + kind: 'relative', + to: '2020-07-08T08:20:18.966Z', + toStr: 'now', + }, + linkTo: ['timeline'], + }, + timeline: { + [CONSTANTS.timerange]: { + from: '2020-07-07T08:20:18.966Z', + fromStr: 'now-24h', + kind: 'relative', + to: '2020-07-08T08:20:18.966Z', + toStr: 'now', + }, + linkTo: ['global'], + }, + } as UrlInputsModel, + }; + + const mockRouteSpy = [ + { + detailName: '', + flowTarget: '', + pathName: '', + search: '', + state: '', + tabName: '', + pageName: SecurityPageName.hosts, + }, + ]; + + beforeEach(() => { + (useDeepEqualSelector as jest.Mock).mockReturnValue({ urlState: mockUrlState }); + (useRouteSpy as jest.Mock).mockReturnValue(mockRouteSpy); + (useKibana as jest.Mock).mockReturnValue({ + services: { + application: { + navigateToApp: jest.fn(), + getUrlForApp: (appId: string, options?: { path?: string; absolute?: boolean }) => + `${appId}${options?.path ?? ''}`, + }, + chrome: { + setBreadcrumbs: jest.fn(), + }, + }, + }); + }); + + it('should create navigation config', async () => { + const { result } = renderHook<{}, KibanaPageTemplateProps['solutionNav']>(() => + useSecuritySolutionNavigation() + ); + + expect(result.current).toMatchInlineSnapshot(` + Object { + "icon": "logoSecurity", + "items": Array [ + Object { + "id": "securitySolution", + "items": Array [ + Object { + "data-href": "securitySolution:overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-test-subj": "navigation-overview", + "disabled": false, + "href": "securitySolution:overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "id": "overview", + "isSelected": false, + "name": "Overview", + "onClick": [Function], + }, + Object { + "data-href": "securitySolution:detections?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-test-subj": "navigation-detections", + "disabled": false, + "href": "securitySolution:detections?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "id": "detections", + "isSelected": false, + "name": "Detections", + "onClick": [Function], + }, + Object { + "data-href": "securitySolution:hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-test-subj": "navigation-hosts", + "disabled": false, + "href": "securitySolution:hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "id": "hosts", + "isSelected": true, + "name": "Hosts", + "onClick": [Function], + }, + Object { + "data-href": "securitySolution:network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-test-subj": "navigation-network", + "disabled": false, + "href": "securitySolution:network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "id": "network", + "isSelected": false, + "name": "Network", + "onClick": [Function], + }, + Object { + "data-href": "securitySolution:timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-test-subj": "navigation-timelines", + "disabled": false, + "href": "securitySolution:timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "id": "timelines", + "isSelected": false, + "name": "Timelines", + "onClick": [Function], + }, + Object { + "data-href": "securitySolution:administration", + "data-test-subj": "navigation-administration", + "disabled": false, + "href": "securitySolution:administration", + "id": "administration", + "isSelected": false, + "name": "Administration", + "onClick": [Function], + }, + ], + "name": "", + }, + ], + "name": "Security", + } + `); + }); + + describe('Permission gated routes', () => { + describe('cases', () => { + it('should display the cases navigation item when the user has read permissions', () => { + (useGetUserCasesPermissions as jest.Mock).mockReturnValue({ + crud: true, + read: true, + }); + + const { result } = renderHook<{}, KibanaPageTemplateProps['solutionNav']>(() => + useSecuritySolutionNavigation() + ); + + const caseNavItem = result.current?.items[0].items?.find( + (item) => item['data-test-subj'] === 'navigation-case' + ); + expect(caseNavItem).toMatchInlineSnapshot(` + Object { + "data-href": "securitySolution:case?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-test-subj": "navigation-case", + "disabled": false, + "href": "securitySolution:case?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "id": "case", + "isSelected": false, + "name": "Cases", + "onClick": [Function], + } + `); + }); + + it('should not display the cases navigation item when the user does not have read permissions', () => { + (useGetUserCasesPermissions as jest.Mock).mockReturnValue({ + crud: false, + read: false, + }); + + const { result } = renderHook<{}, KibanaPageTemplateProps['solutionNav']>(() => + useSecuritySolutionNavigation() + ); + + const caseNavItem = result.current?.items[0].items?.find( + (item) => item['data-test-subj'] === 'navigation-case' + ); + expect(caseNavItem).toBeFalsy(); + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx new file mode 100644 index 00000000000000..f2aee86912dd7a --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect } from 'react'; +import { pickBy } from 'lodash/fp'; +import { usePrimaryNavigation } from './use_primary_navigation'; +import { useGetUserCasesPermissions, useKibana } from '../../../lib/kibana'; +import { setBreadcrumbs } from '../breadcrumbs'; +import { makeMapStateToProps } from '../../url_state/helpers'; +import { useRouteSpy } from '../../../utils/route/use_route_spy'; +import { navTabs } from '../../../../app/home/home_navigations'; +import { useDeepEqualSelector } from '../../../hooks/use_selector'; +import { SecurityPageName } from '../../../../../common/constants'; + +/** + * @description - This hook provides the structure necessary by the KibanaPageTemplate for rendering the primary security_solution side navigation. + * TODO: Consolidate & re-use the logic in the hooks in this directory that are replicated from the tab_navigation to maintain breadcrumbs, telemetry, etc... + */ +export const useSecuritySolutionNavigation = () => { + const [routeProps] = useRouteSpy(); + const urlMapState = makeMapStateToProps(); + const { urlState } = useDeepEqualSelector(urlMapState); + const { + chrome, + application: { getUrlForApp }, + } = useKibana().services; + + const { detailName, flowTarget, pageName, pathName, search, state, tabName } = routeProps; + + useEffect(() => { + if (pathName || pageName) { + setBreadcrumbs( + { + detailName, + filters: urlState.filters, + flowTarget, + navTabs, + pageName, + pathName, + query: urlState.query, + savedQuery: urlState.savedQuery, + search, + sourcerer: urlState.sourcerer, + state, + tabName, + timeline: urlState.timeline, + timerange: urlState.timerange, + }, + chrome, + getUrlForApp + ); + } + }, [ + chrome, + pageName, + pathName, + search, + urlState, + state, + detailName, + flowTarget, + tabName, + getUrlForApp, + ]); + + const hasCasesReadPermissions = useGetUserCasesPermissions()?.read; + + // build a list of tabs to exclude + const tabsToExclude = new Set([ + ...(!hasCasesReadPermissions ? [SecurityPageName.case] : []), + ]); + + // include the tab if it is not in the set of excluded ones + const tabsToDisplay = pickBy((_, key) => !tabsToExclude.has(key), navTabs); + + return usePrimaryNavigation({ + query: urlState.query, + filters: urlState.filters, + navTabs: tabsToDisplay, + pageName, + sourcerer: urlState.sourcerer, + savedQuery: urlState.savedQuery, + timeline: urlState.timeline, + timerange: urlState.timerange, + }); +}; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/types.ts b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/types.ts new file mode 100644 index 00000000000000..f639b8a37f0da4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/types.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TabNavigationProps } from '../tab_navigation/types'; + +export type PrimaryNavigationItemsProps = Omit< + TabNavigationProps, + 'pathName' | 'pageName' | 'tabName' +> & { selectedTabId: string }; + +export type PrimaryNavigationProps = Omit; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx new file mode 100644 index 00000000000000..42ca7f4c65460e --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { APP_ID } from '../../../../../common/constants'; +import { track, METRIC_TYPE, TELEMETRY_EVENT } from '../../../lib/telemetry'; +import { getSearch } from '../helpers'; +import { PrimaryNavigationItemsProps } from './types'; +import { useKibana } from '../../../lib/kibana'; + +export const usePrimaryNavigationItems = ({ + filters, + navTabs, + query, + savedQuery, + selectedTabId, + sourcerer, + timeline, + timerange, +}: PrimaryNavigationItemsProps) => { + const { navigateToApp, getUrlForApp } = useKibana().services.application; + + const navItems = Object.values(navTabs).map((tab) => { + const { id, name, disabled } = tab; + const isSelected = selectedTabId === id; + const urlSearch = getSearch(tab, { + filters, + query, + savedQuery, + sourcerer, + timeline, + timerange, + }); + + const handleClick = (ev: React.MouseEvent) => { + ev.preventDefault(); + navigateToApp(`${APP_ID}:${id}`, { path: urlSearch }); + track(METRIC_TYPE.CLICK, `${TELEMETRY_EVENT.TAB_CLICKED}${id}`); + }; + + const appHref = getUrlForApp(`${APP_ID}:${id}`, { path: urlSearch }); + + return { + 'data-href': appHref, + 'data-test-subj': `navigation-${id}`, + disabled, + href: appHref, + id, + isSelected, + name, + onClick: handleClick, + }; + }); + + return [ + { + id: APP_ID, // TODO: When separating into sub-sections (detect, explore, investigate). Those names can also serve as the section id + items: navItems, + name: '', + }, + ]; +}; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx new file mode 100644 index 00000000000000..390f44b48b0b17 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getOr } from 'lodash/fp'; +import { useEffect, useState, useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { PrimaryNavigationProps } from './types'; +import { usePrimaryNavigationItems } from './use_navigation_items'; +import { KibanaPageTemplateProps } from '../../../../../../../../src/plugins/kibana_react/public'; + +const translatedNavTitle = i18n.translate('xpack.securitySolution.navigation.mainLabel', { + defaultMessage: 'Security', +}); + +export const usePrimaryNavigation = ({ + filters, + query, + navTabs, + pageName, + savedQuery, + sourcerer, + timeline, + timerange, +}: PrimaryNavigationProps): KibanaPageTemplateProps['solutionNav'] => { + const mapLocationToTab = useCallback( + (): string => + getOr( + '', + 'id', + Object.values(navTabs).find((item) => pageName === item.id && item.pageId == null) + ), + [pageName, navTabs] + ); + + const [selectedTabId, setSelectedTabId] = useState(mapLocationToTab()); + + useEffect(() => { + const currentTabSelected = mapLocationToTab(); + + if (currentTabSelected !== selectedTabId) { + setSelectedTabId(currentTabSelected); + } + + // we do need navTabs in case the selectedTabId appears after initial load (ex. checking permissions for anomalies) + }, [pageName, navTabs, mapLocationToTab, selectedTabId]); + + const navItems = usePrimaryNavigationItems({ + filters, + navTabs, + query, + savedQuery, + selectedTabId, + sourcerer, + timeline, + timerange, + }); + + return { + name: translatedNavTitle, + icon: 'logoSecurity', + items: navItems, + }; +}; diff --git a/x-pack/plugins/security_solution/public/common/components/page/index.tsx b/x-pack/plugins/security_solution/public/common/components/page/index.tsx index 30b89086fb99cb..051c1bd8ae5cb8 100644 --- a/x-pack/plugins/security_solution/public/common/components/page/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/page/index.tsx @@ -5,14 +5,10 @@ * 2.0. */ -import { EuiBadge, EuiDescriptionList, EuiFlexGroup, EuiIcon, EuiPage } from '@elastic/eui'; +import { EuiBadge, EuiDescriptionList, EuiFlexGroup, EuiIcon } from '@elastic/eui'; import styled, { createGlobalStyle } from 'styled-components'; -import { - GLOBAL_HEADER_HEIGHT, - FULL_SCREEN_TOGGLED_CLASS_NAME, - SCROLLING_DISABLED_CLASS_NAME, -} from '../../../../common/constants'; +import { FULL_SCREEN_TOGGLED_CLASS_NAME } from '../../../../common/constants'; export const SecuritySolutionAppWrapper = styled.div` display: flex; @@ -27,25 +23,6 @@ SecuritySolutionAppWrapper.displayName = 'SecuritySolutionAppWrapper'; and `EuiPopover`, `EuiToolTip` global styles */ export const AppGlobalStyle = createGlobalStyle<{ theme: { eui: { euiColorPrimary: string } } }>` - // fixes double scrollbar on views with EventsTable - #kibana-body { - overflow: hidden; - } - - div.kbnAppWrapper { - background-color: rgba(0,0,0,0); - } - - div.application { - background-color: rgba(0,0,0,0); - - // Security App wrapper - > div { - display: flex; - flex: 1 1 auto; - } - } - .euiPopover__panel.euiPopover__panel-isOpen { z-index: 9900 !important; min-width: 24px; @@ -82,10 +59,6 @@ export const AppGlobalStyle = createGlobalStyle<{ theme: { eui: { euiColorPrimar ${({ theme }) => `background-color: ${theme.eui.euiColorPrimary} !important`}; } - .${SCROLLING_DISABLED_CLASS_NAME} ${SecuritySolutionAppWrapper} { - max-height: calc(100vh - ${GLOBAL_HEADER_HEIGHT}px); - } - /* EuiScreenReaderOnly has a default 1px height and width. These extra pixels were adding additional height to every table row in the alerts table on the @@ -122,96 +95,6 @@ export const DescriptionListStyled = styled(EuiDescriptionList)` DescriptionListStyled.displayName = 'DescriptionListStyled'; -export const PageContainer = styled.div` - display: flex; - flex-direction: column; - align-items: stretch; - background-color: ${(props) => props.theme.eui.euiColorEmptyShade}; - height: 100%; - padding: 1rem; - overflow: hidden; - margin: 0px; -`; - -PageContainer.displayName = 'PageContainer'; - -export const PageContent = styled.div` - flex: 1 1 auto; - height: 100%; - position: relative; - overflow-y: hidden; - background-color: ${(props) => props.theme.eui.euiColorEmptyShade}; - margin-top: 62px; -`; - -PageContent.displayName = 'PageContent'; - -export const FlexPage = styled(EuiPage)` - flex: 1 0 0; -`; - -FlexPage.displayName = 'FlexPage'; - -export const PageHeader = styled.div` - background-color: ${(props) => props.theme.eui.euiColorEmptyShade}; - display: flex; - user-select: none; - padding: 1rem 1rem 0rem 1rem; - width: 100vw; - position: fixed; -`; - -PageHeader.displayName = 'PageHeader'; - -export const FooterContainer = styled.div` - flex: 0; - bottom: 0; - color: #666; - left: 0; - position: fixed; - text-align: left; - user-select: none; - width: 100%; - background-color: #f5f7fa; - padding: 16px; - border-top: 1px solid #d3dae6; -`; - -FooterContainer.displayName = 'FooterContainer'; - -export const PaneScrollContainer = styled.div` - height: 100%; - overflow-y: scroll; - > div:last-child { - margin-bottom: 3rem; - } -`; - -PaneScrollContainer.displayName = 'PaneScrollContainer'; - -export const Pane = styled.div` - height: 100%; - overflow: hidden; - user-select: none; -`; - -Pane.displayName = 'Pane'; - -export const PaneHeader = styled.div` - display: flex; -`; - -PaneHeader.displayName = 'PaneHeader'; - -export const Pane1FlexContent = styled.div` - display: flex; - flex-direction: row; - flex-wrap: wrap; - height: 100%; -`; - -Pane1FlexContent.displayName = 'Pane1FlexContent'; - export const CountBadge = (styled(EuiBadge)` margin-left: 5px; ` as unknown) as typeof EuiBadge; diff --git a/x-pack/plugins/security_solution/public/common/components/page_wrapper/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/page_wrapper/__snapshots__/index.test.tsx.snap new file mode 100644 index 00000000000000..5da587f23693b8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/page_wrapper/__snapshots__/index.test.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SecuritySolutionPageWrapper it renders 1`] = ` + +

+ Test page +

+
+`; diff --git a/x-pack/plugins/security_solution/public/common/components/wrapper_page/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/page_wrapper/index.test.tsx similarity index 65% rename from x-pack/plugins/security_solution/public/common/components/wrapper_page/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/page_wrapper/index.test.tsx index 3ec1e44205dd3f..f6ebf2a90abb4f 100644 --- a/x-pack/plugins/security_solution/public/common/components/wrapper_page/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/page_wrapper/index.test.tsx @@ -9,18 +9,18 @@ import { shallow } from 'enzyme'; import React from 'react'; import { TestProviders } from '../../mock'; -import { WrapperPage } from './index'; +import { SecuritySolutionPageWrapper } from './index'; -describe('WrapperPage', () => { +describe('SecuritySolutionPageWrapper', () => { test('it renders', () => { const wrapper = shallow( - +

{'Test page'}

-
+
); - expect(wrapper.find('Memo(WrapperPageComponent)')).toMatchSnapshot(); + expect(wrapper.find('Memo(SecuritySolutionPageWrapperComponent)')).toMatchSnapshot(); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/wrapper_page/index.tsx b/x-pack/plugins/security_solution/public/common/components/page_wrapper/index.tsx similarity index 68% rename from x-pack/plugins/security_solution/public/common/components/wrapper_page/index.tsx rename to x-pack/plugins/security_solution/public/common/components/page_wrapper/index.tsx index a3eb76a2728bf8..82e0ded264b061 100644 --- a/x-pack/plugins/security_solution/public/common/components/wrapper_page/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/page_wrapper/index.tsx @@ -15,30 +15,26 @@ import { gutterTimeline } from '../../lib/helpers'; import { AppGlobalStyle } from '../page/index'; const Wrapper = styled.div` - padding: ${(props) => `${props.theme.eui.paddingSizes.l}`}; - - &.siemWrapperPage--fullHeight { + &.securitySolutionWrapper--fullHeight { height: 100%; display: flex; flex-direction: column; flex: 1 1 auto; } - - &.siemWrapperPage--noPadding { + &.securitySolutionWrapper--noPadding { padding: 0; display: flex; flex-direction: column; flex: 1 1 auto; } - - &.siemWrapperPage--withTimeline { + &.securitySolutionWrapper--withTimeline { padding-bottom: ${gutterTimeline}; } `; Wrapper.displayName = 'Wrapper'; -interface WrapperPageProps { +interface SecuritySolutionPageWrapperProps { children: React.ReactNode; restrictWidth?: boolean | number | string; style?: Record; @@ -46,24 +42,19 @@ interface WrapperPageProps { noTimeline?: boolean; } -const WrapperPageComponent: React.FC = ({ - children, - className, - style, - noPadding, - noTimeline, - ...otherProps -}) => { +const SecuritySolutionPageWrapperComponent: React.FC< + SecuritySolutionPageWrapperProps & CommonProps +> = ({ children, className, style, noPadding, noTimeline, ...otherProps }) => { const { globalFullScreen, setGlobalFullScreen } = useGlobalFullScreen(); useEffect(() => { setGlobalFullScreen(false); // exit full screen mode on page load }, [setGlobalFullScreen]); const classes = classNames(className, { - siemWrapperPage: true, - 'siemWrapperPage--noPadding': noPadding, - 'siemWrapperPage--withTimeline': !noTimeline, - 'siemWrapperPage--fullHeight': globalFullScreen, + securitySolutionWrapper: true, + 'securitySolutionWrapper--noPadding': noPadding, + 'securitySolutionWrapper--withTimeline': !noTimeline, + 'securitySolutionWrapper--fullHeight': globalFullScreen, }); return ( @@ -74,4 +65,4 @@ const WrapperPageComponent: React.FC = ({ ); }; -export const WrapperPage = React.memo(WrapperPageComponent); +export const SecuritySolutionPageWrapper = React.memo(SecuritySolutionPageWrapperComponent); diff --git a/x-pack/plugins/security_solution/public/common/components/panel/index.tsx b/x-pack/plugins/security_solution/public/common/components/panel/index.tsx index 652d22409cb0c3..802fd4c7f44a60 100644 --- a/x-pack/plugins/security_solution/public/common/components/panel/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/panel/index.tsx @@ -25,7 +25,7 @@ import { EuiPanel } from '@elastic/eui'; * Ref: https://www.styled-components.com/docs/faqs#why-am-i-getting-html-attribute-warnings * Ref: https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html */ -export const Panel = styled(({ loading, ...props }) => )` +export const Panel = styled(({ loading, ...props }) => )` position: relative; ${({ loading }) => loading && diff --git a/x-pack/plugins/security_solution/public/common/components/stat_items/index.tsx b/x-pack/plugins/security_solution/public/common/components/stat_items/index.tsx index 5b4a8f67aa3617..2d8d55a5c943f3 100644 --- a/x-pack/plugins/security_solution/public/common/components/stat_items/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/stat_items/index.tsx @@ -222,7 +222,7 @@ export const StatItemsComponent = React.memo( return ( - + diff --git a/x-pack/plugins/security_solution/public/common/components/tables/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/tables/helpers.test.tsx index 8c2b97a4b8b38e..c122138f9547a5 100644 --- a/x-pack/plugins/security_solution/public/common/components/tables/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/tables/helpers.test.tsx @@ -18,6 +18,9 @@ import { import { TestProviders } from '../../mock'; import { getEmptyValue } from '../empty_value'; import { useMountAppended } from '../../utils/use_mount_appended'; + +jest.mock('../../lib/kibana'); + describe('Table Helpers', () => { const items = ['item1', 'item2', 'item3']; const mount = useMountAppended(); diff --git a/x-pack/plugins/security_solution/public/common/components/toasters/utils.ts b/x-pack/plugins/security_solution/public/common/components/toasters/utils.ts index 70e095c88576f9..04ceafde7ef74f 100644 --- a/x-pack/plugins/security_solution/public/common/components/toasters/utils.ts +++ b/x-pack/plugins/security_solution/public/common/components/toasters/utils.ts @@ -8,10 +8,10 @@ import type React from 'react'; import uuid from 'uuid'; import { isError } from 'lodash/fp'; +import { isAppError } from '@kbn/securitysolution-t-grid'; import { AppToast, ActionToaster } from './'; import { isToasterError } from './errors'; -import { isAppError } from '../../utils/api'; /** * Displays an error toast for the provided title and message diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx index 005602738f376e..4f6834e84d83a8 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx @@ -18,17 +18,11 @@ import { createSecuritySolutionStorageMock, mockIndexPattern, } from '../../mock'; -import { FilterManager } from '../../../../../../../src/plugins/data/public'; import { createStore, State } from '../../store'; import { Props } from './top_n'; import { StatefulTopN } from '.'; -import { - ManageGlobalTimeline, - getTimelineDefaults, -} from '../../../timelines/components/manage_timeline'; import { TimelineId } from '../../../../common/types/timeline'; -import { coreMock } from '../../../../../../../src/core/public/mocks'; jest.mock('react-router-dom', () => { const original = jest.requireActual('react-router-dom'); @@ -45,8 +39,6 @@ jest.mock('../link_to'); jest.mock('../../lib/kibana'); jest.mock('../../../timelines/store/timeline/actions'); -const mockUiSettingsForFilterManager = coreMock.createStart().uiSettings; - const field = 'process.name'; const value = 'nice'; @@ -175,9 +167,7 @@ describe('StatefulTopN', () => { beforeEach(() => { wrapper = mount( - - - + ); }); @@ -244,26 +234,16 @@ describe('StatefulTopN', () => { }); describe('rendering in a timeline context', () => { - let filterManager: FilterManager; let wrapper: ReactWrapper; beforeEach(() => { - filterManager = new FilterManager(mockUiSettingsForFilterManager); - const manageTimelineForTesting = { - [TimelineId.active]: { - ...getTimelineDefaults(TimelineId.active), - filterManager, - }, - }; testProps = { ...testProps, timelineId: TimelineId.active, }; wrapper = mount( - - - + ); }); @@ -320,25 +300,13 @@ describe('StatefulTopN', () => { }); describe('rendering in a NON-active timeline context', () => { test(`defaults to the 'Alert events' option when rendering in a NON-active timeline context (e.g. the Alerts table on the Detections page) when 'documentType' from 'useTimelineTypeContext()' is 'alerts'`, async () => { - const filterManager = new FilterManager(mockUiSettingsForFilterManager); - - const manageTimelineForTesting = { - [TimelineId.active]: { - ...getTimelineDefaults(TimelineId.active), - filterManager, - documentType: 'alerts', - }, - }; - testProps = { ...testProps, timelineId: TimelineId.detectionsPage, }; const wrapper = mount( - - - + ); await waitFor(() => { diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx b/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx index a2d5076031328c..8a7c6bcb4a9b52 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx +++ b/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx @@ -29,7 +29,6 @@ import { SecurityPageName } from '../../../../common/constants'; export const dispatchSetInitialStateFromUrl = ( dispatch: Dispatch ): DispatchSetInitialStateFromUrl => ({ - detailName, filterManager, indexPattern, pageName, diff --git a/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx b/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx index a8868436d9689c..c867862e690bde 100644 --- a/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx @@ -6,13 +6,13 @@ */ import { EuiPopover } from '@elastic/eui'; +import { + HOVER_ACTIONS_ALWAYS_SHOW_CLASS_NAME, + IS_DRAGGING_CLASS_NAME, +} from '@kbn/securitysolution-t-grid'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; -import { IS_DRAGGING_CLASS_NAME } from '../drag_and_drop/helpers'; - -export const HOVER_ACTIONS_ALWAYS_SHOW_CLASS_NAME = 'hover-actions-always-show'; - /** * To avoid expensive changes to the DOM, delay showing the popover menu */ diff --git a/x-pack/plugins/security_solution/public/common/components/wrapper_page/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/wrapper_page/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 89ed2f45a6bf1f..00000000000000 --- a/x-pack/plugins/security_solution/public/common/components/wrapper_page/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`WrapperPage it renders 1`] = ` - -

- Test page -

-
-`; diff --git a/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts b/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts index 3e690e50b04b14..4f558412576b4c 100644 --- a/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts +++ b/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts @@ -83,7 +83,7 @@ export const useTimelineLastEventTime = ({ TimelineEventsLastEventTimeRequestOptions, TimelineEventsLastEventTimeStrategyResponse >(request, { - strategy: 'securitySolutionTimelineSearchStrategy', + strategy: 'timelineSearchStrategy', abortSignal: abortCtrl.current.signal, }) .subscribe({ diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx index 1c17f95bb6ba04..3bc92dafd351fd 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx @@ -151,7 +151,7 @@ export const useFetchIndex = ( { indices: iNames, onlyCheckIfIndicesExist }, { abortSignal: abortCtrl.current.signal, - strategy: 'securitySolutionIndexFields', + strategy: 'indexFields', } ) .subscribe({ @@ -235,7 +235,7 @@ export const useIndexFields = (sourcererScopeName: SourcererScopeName) => { { indices: indicesName, onlyCheckIfIndicesExist: false }, { abortSignal: abortCtrl.current.signal, - strategy: 'securitySolutionIndexFields', + strategy: 'indexFields', } ) .subscribe({ diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.test.ts b/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.test.ts index da6b41080c1c72..6c5caa25a1f961 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.test.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.test.ts @@ -7,9 +7,10 @@ import { renderHook } from '@testing-library/react-hooks'; import { IEsError } from 'src/plugins/data/public'; +import { KibanaError, SecurityAppError } from '@kbn/securitysolution-t-grid'; import { useToasts } from '../lib/kibana'; -import { KibanaError, SecurityAppError } from '../utils/api'; + import { appErrorToErrorStack, convertErrorToEnumerable, diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.ts b/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.ts index 61b20e137f8707..0c2721e6ad4164 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.ts @@ -7,11 +7,17 @@ import { useCallback, useRef } from 'react'; import { isString } from 'lodash/fp'; +import { + AppError, + isAppError, + isKibanaError, + isSecurityAppError, +} from '@kbn/securitysolution-t-grid'; + import { IEsError, isEsError } from '../../../../../../src/plugins/data/public'; import { ErrorToastOptions, ToastsStart, Toast } from '../../../../../../src/core/public'; import { useToasts } from '../lib/kibana'; -import { AppError, isAppError, isKibanaError, isSecurityAppError } from '../utils/api'; export type UseAppToasts = Pick & { api: ToastsStart; diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_global_header_portal.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_global_header_portal.tsx index 5b5877a4c2dedc..8e8d73ff12849e 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_global_header_portal.tsx +++ b/x-pack/plugins/security_solution/public/common/hooks/use_global_header_portal.tsx @@ -11,10 +11,10 @@ import { createPortalNode } from 'react-reverse-portal'; /** * A singleton portal for rendering content in the global header */ -const globalHeaderPortalNodeSingleton = createPortalNode(); +const globalKQLHeaderPortalNodeSingleton = createPortalNode(); export const useGlobalHeaderPortal = () => { - const [globalHeaderPortalNode] = useState(globalHeaderPortalNodeSingleton); + const [globalKQLHeaderPortalNode] = useState(globalKQLHeaderPortalNodeSingleton); - return { globalHeaderPortalNode }; + return { globalKQLHeaderPortalNode }; }; diff --git a/x-pack/plugins/security_solution/public/common/lib/clipboard/with_copy_to_clipboard.tsx b/x-pack/plugins/security_solution/public/common/lib/clipboard/with_copy_to_clipboard.tsx index 1baa57166de3fb..2f5afc8a44489a 100644 --- a/x-pack/plugins/security_solution/public/common/lib/clipboard/with_copy_to_clipboard.tsx +++ b/x-pack/plugins/security_solution/public/common/lib/clipboard/with_copy_to_clipboard.tsx @@ -6,9 +6,10 @@ */ import { EuiToolTip } from '@elastic/eui'; + import React from 'react'; -import { TooltipWithKeyboardShortcut } from '../../components/accessibility/tooltip_with_keyboard_shortcut'; +import { TooltipWithKeyboardShortcut } from '../../components/accessibility'; import * as i18n from '../../components/drag_and_drop/translations'; import { Clipboard } from './clipboard'; diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts index eb0ae1ae1dee9e..09c3d2537e2726 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts @@ -6,6 +6,10 @@ */ import { notificationServiceMock } from '../../../../../../../../src/core/public/mocks'; + +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { createTGridMocks } from '../../../../../../timelines/public/mock'; + import { createKibanaContextProviderMock, createUseUiSettingMock, @@ -30,14 +34,24 @@ export const useKibana = jest.fn().mockReturnValue({ })), })), }, + query: { + ...mockStartServicesMock.data.query, + filterManager: { + addFilters: jest.fn(), + getFilters: jest.fn(), + getUpdates$: jest.fn().mockReturnValue({ subscribe: jest.fn() }), + setAppFilters: jest.fn(), + }, + }, }, + timelines: createTGridMocks(), }, }); export const useUiSetting = jest.fn(createUseUiSettingMock()); export const useUiSetting$ = jest.fn(createUseUiSetting$Mock()); export const useHttp = jest.fn().mockReturnValue(createStartServicesMock().http); export const useTimeZone = jest.fn(); -export const useDateFormat = jest.fn(); +export const useDateFormat = jest.fn().mockReturnValue('MMM D, YYYY @ HH:mm:ss.SSS'); export const useBasePath = jest.fn(() => '/test/base/path'); export const useToasts = jest .fn() 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 557c04e4e8a475..316f8b6214d1e7 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 @@ -43,6 +43,7 @@ export const mockGlobalState: State = { trustedAppsByPolicyEnabled: false, metricsEntitiesEnabled: false, ruleRegistryEnabled: false, + tGridEnabled: false, }, }, hosts: { diff --git a/x-pack/plugins/security_solution/public/common/mock/header.ts b/x-pack/plugins/security_solution/public/common/mock/header.ts index ae7d3c9e576a83..029ddb00d18325 100644 --- a/x-pack/plugins/security_solution/public/common/mock/header.ts +++ b/x-pack/plugins/security_solution/public/common/mock/header.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ColumnHeaderOptions } from '../../timelines/store/timeline/model'; +import { ColumnHeaderOptions } from '../../../common'; import { defaultColumnHeaderType } from '../../timelines/components/timeline/body/column_headers/default_headers'; import { DEFAULT_COLUMN_MIN_WIDTH, diff --git a/x-pack/plugins/security_solution/public/common/mock/mock_timeline_control_columns.tsx b/x-pack/plugins/security_solution/public/common/mock/mock_timeline_control_columns.tsx index 7604732f902034..7dae3e671d2711 100644 --- a/x-pack/plugins/security_solution/public/common/mock/mock_timeline_control_columns.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/mock_timeline_control_columns.tsx @@ -15,7 +15,7 @@ import { EuiPopoverTitle, EuiSpacer, } from '@elastic/eui'; -import { ControlColumnProps } from '../../timelines/components/timeline/body/control_columns'; +import { ControlColumnProps } from '../../../common/types/timeline'; const SelectionHeaderCell = () => { return ( diff --git a/x-pack/plugins/security_solution/public/common/mock/utils.ts b/x-pack/plugins/security_solution/public/common/mock/utils.ts index 30951b81611dbf..e0f8e651a58210 100644 --- a/x-pack/plugins/security_solution/public/common/mock/utils.ts +++ b/x-pack/plugins/security_solution/public/common/mock/utils.ts @@ -5,12 +5,20 @@ * 2.0. */ +import { AnyAction, Reducer } from 'redux'; +import reduceReducers from 'reduce-reducers'; + +import { tGridReducer } from '../../../../timelines/public'; + import { hostsReducer } from '../../hosts/store'; import { networkReducer } from '../../network/store'; import { timelineReducer } from '../../timelines/store/timeline/reducer'; import { managementReducer } from '../../management/store/reducer'; import { ManagementPluginReducer } from '../../management'; import { SubPluginsInitReducer } from '../store'; +import { mockGlobalState } from './global_state'; +import { TimelineState } from '../../timelines/store/timeline/types'; +import { defaultHeaders } from '../../timelines/components/timeline/body/column_headers/default_headers'; interface Global extends NodeJS.Global { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -19,10 +27,32 @@ interface Global extends NodeJS.Global { export const globalNode: Global = global; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const combineTimelineReducer = reduceReducers( + { + ...mockGlobalState.timeline, + timelineById: { + ...mockGlobalState.timeline.timelineById, + test: { + ...mockGlobalState.timeline.timelineById.test, + defaultColumns: defaultHeaders, + loadingText: 'events', + footerText: 'events', + documentType: '', + selectAll: false, + queryFields: [], + unit: (n: number) => n, + }, + }, + }, + tGridReducer, + timelineReducer +) as Reducer; + export const SUB_PLUGINS_REDUCER: SubPluginsInitReducer = { hosts: hostsReducer, network: networkReducer, - timeline: timelineReducer, + timeline: combineTimelineReducer, /** * These state's are wrapped in `Immutable`, but for compatibility with the overall app architecture, * they are cast to mutable versions here. diff --git a/x-pack/plugins/security_solution/public/common/store/inputs/model.ts b/x-pack/plugins/security_solution/public/common/store/inputs/model.ts index e784f6cebae17a..5791a4940cbedd 100644 --- a/x-pack/plugins/security_solution/public/common/store/inputs/model.ts +++ b/x-pack/plugins/security_solution/public/common/store/inputs/model.ts @@ -60,6 +60,7 @@ export interface GlobalGenericQuery { isInspected: boolean; loading: boolean; selectedInspectIndex: number; + invalidKqlQuery?: Error; } export interface GlobalGraphqlQuery extends GlobalGenericQuery { diff --git a/x-pack/plugins/security_solution/public/common/store/types.ts b/x-pack/plugins/security_solution/public/common/store/types.ts index fbf4caad9793dc..21e833abe1f9ba 100644 --- a/x-pack/plugins/security_solution/public/common/store/types.ts +++ b/x-pack/plugins/security_solution/public/common/store/types.ts @@ -37,18 +37,6 @@ export type StoreState = HostsPluginState & */ export type State = CombinedState; -export type KueryFilterQueryKind = 'kuery' | 'lucene' | 'eql'; - -export interface KueryFilterQuery { - kind: KueryFilterQueryKind; - expression: string; -} - -export interface SerializedFilterQuery { - kuery: KueryFilterQuery | null; - serializedQuery: string; -} - /** * like redux's `MiddlewareAPI` but `getState` returns an `Immutable` version of * state and `dispatch` accepts `Immutable` versions of actions. diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/index.tsx index 91b5a106844054..d766104e356ebb 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/index.tsx @@ -298,7 +298,7 @@ export const AlertsHistogramPanel = memo( return ( - + { diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx index 02a815bc59f3bd..9a142f6cba2470 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx @@ -6,11 +6,11 @@ */ import { defaultColumnHeaderType } from '../../../timelines/components/timeline/body/column_headers/default_headers'; -import { RowRendererId } from '../../../../common/types/timeline'; +import { ColumnHeaderOptions, RowRendererId } from '../../../../common/types/timeline'; import { Status } from '../../../../common/detection_engine/schemas/common/schemas'; import { Filter } from '../../../../../../../src/plugins/data/common/es_query'; -import { ColumnHeaderOptions, SubsetTimelineModel } from '../../../timelines/store/timeline/model'; +import { SubsetTimelineModel } from '../../../timelines/store/timeline/model'; import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; import { columns } from '../../configurations/security_solution_detections/columns'; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index f20754fc446d6e..7980160fea76cd 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -8,11 +8,11 @@ import { EuiPanel, EuiLoadingContent } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { connect, ConnectedProps } from 'react-redux'; +import { connect, ConnectedProps, useDispatch } from 'react-redux'; import { Dispatch } from 'redux'; import { Status } from '../../../../common/detection_engine/schemas/common/schemas'; import { Filter, esQuery } from '../../../../../../../src/plugins/data/public'; -import { TimelineIdLiteral } from '../../../../common/types/timeline'; +import { RowRendererId, TimelineIdLiteral } from '../../../../common/types/timeline'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import { StatefulEventsViewer } from '../../../common/components/events_viewer'; import { HeaderSection } from '../../../common/components/header_section'; @@ -23,8 +23,6 @@ import { inputsSelectors, State, inputsModel } from '../../../common/store'; import { timelineActions, timelineSelectors } from '../../../timelines/store/timeline'; import { TimelineModel } from '../../../timelines/store/timeline/model'; import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; -import { useManageTimeline } from '../../../timelines/components/manage_timeline'; - import { updateAlertStatusAction } from './actions'; import { requiredFieldsForActions, @@ -95,6 +93,7 @@ export const AlertsTableComponent: React.FC = ({ timelineId, to, }) => { + const dispatch = useDispatch(); const [showClearSelectionAction, setShowClearSelectionAction] = useState(false); const [filterGroup, setFilterGroup] = useState(FILTER_OPEN); const { @@ -106,7 +105,6 @@ export const AlertsTableComponent: React.FC = ({ const kibana = useKibana(); const [, dispatchToaster] = useStateToaster(); const { addWarning } = useAppToasts(); - const { initializeTimeline, setSelectAll } = useManageTimeline(); // TODO: Once we are past experimental phase this code should be removed const ruleRegistryEnabled = useIsExperimentalFeatureEnabled('ruleRegistryEnabled'); @@ -195,14 +193,16 @@ export const AlertsTableComponent: React.FC = ({ // Catches state change isSelectAllChecked->false upon user selection change to reset utility bar useEffect(() => { if (isSelectAllChecked) { - setSelectAll({ - id: timelineId, - selectAll: false, - }); + dispatch( + timelineActions.setTGridSelectAll({ + id: timelineId, + selectAll: false, + }) + ); } else { setShowClearSelectionAction(false); } - }, [isSelectAllChecked, setSelectAll, timelineId]); + }, [dispatch, isSelectAllChecked, timelineId]); // Callback for when open/closed filter changes const onFilterGroupChangedCallback = useCallback( @@ -218,23 +218,27 @@ export const AlertsTableComponent: React.FC = ({ // Callback for clearing entire selection from utility bar const clearSelectionCallback = useCallback(() => { clearSelected!({ id: timelineId }); - setSelectAll({ - id: timelineId, - selectAll: false, - }); + dispatch( + timelineActions.setTGridSelectAll({ + id: timelineId, + selectAll: false, + }) + ); setShowClearSelectionAction(false); - }, [clearSelected, setSelectAll, setShowClearSelectionAction, timelineId]); + }, [clearSelected, dispatch, timelineId]); // Callback for selecting all events on all pages from utility bar // Dispatches to stateful_body's selectAll via TimelineTypeContext props // as scope of response data required to actually set selectedEvents const selectAllOnAllPagesCallback = useCallback(() => { - setSelectAll({ - id: timelineId, - selectAll: true, - }); + dispatch( + timelineActions.setTGridSelectAll({ + id: timelineId, + selectAll: true, + }) + ); setShowClearSelectionAction(true); - }, [setSelectAll, setShowClearSelectionAction, timelineId]); + }, [dispatch, timelineId]); const updateAlertsStatusCallback: UpdateAlertsStatusCallback = useCallback( async ( @@ -330,22 +334,22 @@ export const AlertsTableComponent: React.FC = ({ : alertsDefaultModel; useEffect(() => { - initializeTimeline({ - defaultModel: { - ...defaultTimelineModel, - columns, - }, - documentType: i18n.ALERTS_DOCUMENT_TYPE, - filterManager, - footerText: i18n.TOTAL_COUNT_OF_ALERTS, - id: timelineId, - loadingText: i18n.LOADING_ALERTS, - selectAll: false, - queryFields: requiredFieldsForActions, - title: '', - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + dispatch( + timelineActions.initializeTGridSettings({ + defaultColumns: columns, + documentType: i18n.ALERTS_DOCUMENT_TYPE, + excludedRowRendererIds: defaultTimelineModel.excludedRowRendererIds as RowRendererId[], + filterManager, + footerText: i18n.TOTAL_COUNT_OF_ALERTS, + id: timelineId, + loadingText: i18n.LOADING_ALERTS, + selectAll: false, + queryFields: requiredFieldsForActions, + title: '', + showCheckboxes: true, + }) + ); + }, [dispatch, defaultTimelineModel, filterManager, timelineId]); const headerFilterGroup = useMemo( () => , @@ -354,7 +358,7 @@ export const AlertsTableComponent: React.FC = ({ if (loading || indexPatternsLoading || isEmpty(selectedPatterns)) { return ( - + diff --git a/x-pack/plugins/security_solution/public/detections/components/callouts/need_admin_for_update_callout/index.tsx b/x-pack/plugins/security_solution/public/detections/components/callouts/need_admin_for_update_callout/index.tsx index fd0be8e0021933..3b41c9280998b3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/callouts/need_admin_for_update_callout/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/callouts/need_admin_for_update_callout/index.tsx @@ -6,6 +6,7 @@ */ import React, { memo } from 'react'; +import { EuiSpacer } from '@elastic/eui'; import { CallOutMessage, CallOutPersistentSwitcher } from '../../../../common/components/callouts'; import { useUserData } from '../../user_info'; @@ -33,20 +34,22 @@ const needAdminForUpdateRulesMessage: CallOutMessage = { * hasIndexManage is also true, then the user should be performing the update on the page which is * why we do not show it for that condition. */ -const NeedAdminForUpdateCallOutComponent = (): JSX.Element => { +const NeedAdminForUpdateCallOutComponent = (): JSX.Element | null => { const [{ signalIndexMappingOutdated, hasIndexManage }] = useUserData(); const signalIndexMappingIsOutdated = signalIndexMappingOutdated != null && signalIndexMappingOutdated; const userDoesntHaveIndexManage = hasIndexManage != null && !hasIndexManage; - - return ( - - ); + const shouldShowCallout = signalIndexMappingIsOutdated && userDoesntHaveIndexManage; + + // Passing shouldShowCallout to the condition param will end up with an unecessary spacer being rendered + return shouldShowCallout ? ( + <> + + + + ) : null; }; export const NeedAdminForUpdateRulesCallOut = memo(NeedAdminForUpdateCallOutComponent); diff --git a/x-pack/plugins/security_solution/public/detections/components/callouts/no_api_integration_callout/index.tsx b/x-pack/plugins/security_solution/public/detections/components/callouts/no_api_integration_callout/index.tsx index f21c66380f30aa..7b483930db5053 100644 --- a/x-pack/plugins/security_solution/public/detections/components/callouts/no_api_integration_callout/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/callouts/no_api_integration_callout/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiCallOut, EuiButton } from '@elastic/eui'; +import { EuiCallOut, EuiButton, EuiSpacer } from '@elastic/eui'; import React, { memo, useCallback, useState } from 'react'; import * as i18n from './translations'; @@ -15,12 +15,15 @@ const NoApiIntegrationKeyCallOutComponent = () => { const handleCallOut = useCallback(() => setShowCallOut(false), [setShowCallOut]); return showCallOut ? ( - -

{i18n.NO_API_INTEGRATION_KEY_CALLOUT_MSG}

- - {i18n.DISMISS_CALLOUT} - -
+ <> + +

{i18n.NO_API_INTEGRATION_KEY_CALLOUT_MSG}

+ + {i18n.DISMISS_CALLOUT} + +
+ + ) : null; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule_details/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule_details/index.tsx index a09afa3ca21642..c1078e1ba77e7c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule_details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule_details/index.tsx @@ -82,7 +82,7 @@ const StepAboutRuleToggleDetailsComponent: React.FC = ({ ); return ( - + {loading && ( <> diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_panel/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_panel/index.tsx index f9e6031d826caf..ac9a153ad76bff 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_panel/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_panel/index.tsx @@ -24,7 +24,7 @@ const MyPanel = styled(EuiPanel)` MyPanel.displayName = 'MyPanel'; const StepPanelComponent: React.FC = ({ children, loading, title }) => ( - + {loading && } {children} diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.tsx index dbad1c57fda77d..3d81735122e731 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.tsx @@ -216,7 +216,7 @@ export const ValueListsModalComponent: React.FC = ({ - +

{i18n.TABLE_TITLE}

diff --git a/x-pack/plugins/security_solution/public/detections/configurations/examples/observablity_alerts/columns.ts b/x-pack/plugins/security_solution/public/detections/configurations/examples/observablity_alerts/columns.ts index 8cbb532501a2cd..70d2237a535ebb 100644 --- a/x-pack/plugins/security_solution/public/detections/configurations/examples/observablity_alerts/columns.ts +++ b/x-pack/plugins/security_solution/public/detections/configurations/examples/observablity_alerts/columns.ts @@ -6,10 +6,9 @@ */ import { EuiDataGridColumn } from '@elastic/eui'; - +import { ColumnHeaderOptions } from '../../../../../common'; import { defaultColumnHeaderType } from '../../../../timelines/components/timeline/body/column_headers/default_headers'; import { DEFAULT_DATE_COLUMN_MIN_WIDTH } from '../../../../timelines/components/timeline/body/constants'; -import { ColumnHeaderOptions } from '../../../../timelines/store/timeline/model'; import * as i18n from '../../../components/alerts_table/translations'; diff --git a/x-pack/plugins/security_solution/public/detections/configurations/examples/observablity_alerts/render_cell_value.test.tsx b/x-pack/plugins/security_solution/public/detections/configurations/examples/observablity_alerts/render_cell_value.test.tsx index 9c2114a4ef085c..7db75d3a73d907 100644 --- a/x-pack/plugins/security_solution/public/detections/configurations/examples/observablity_alerts/render_cell_value.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/configurations/examples/observablity_alerts/render_cell_value.test.tsx @@ -15,10 +15,12 @@ import { defaultHeaders, mockTimelineData, TestProviders } from '../../../../com import { TimelineNonEcsData } from '../../../../../common/search_strategy/timeline'; import { CellValueElementProps } from '../../../../timelines/components/timeline/cell_rendering'; import { DefaultCellRenderer } from '../../../../timelines/components/timeline/cell_rendering/default_cell_renderer'; -import { ColumnHeaderOptions } from '../../../../timelines/store/timeline/model'; +import { ColumnHeaderOptions } from '../../../../../common'; import { RenderCellValue } from '.'; +jest.mock('../../../../common/lib/kibana/'); + describe('RenderCellValue', () => { const columnId = '@timestamp'; const eventId = '_id-123'; diff --git a/x-pack/plugins/security_solution/public/detections/configurations/examples/security_solution_rac/columns.ts b/x-pack/plugins/security_solution/public/detections/configurations/examples/security_solution_rac/columns.ts index 96d2d870b12702..3365ce5432940f 100644 --- a/x-pack/plugins/security_solution/public/detections/configurations/examples/security_solution_rac/columns.ts +++ b/x-pack/plugins/security_solution/public/detections/configurations/examples/security_solution_rac/columns.ts @@ -6,10 +6,9 @@ */ import { EuiDataGridColumn } from '@elastic/eui'; - +import { ColumnHeaderOptions } from '../../../../../common'; import { defaultColumnHeaderType } from '../../../../timelines/components/timeline/body/column_headers/default_headers'; import { DEFAULT_DATE_COLUMN_MIN_WIDTH } from '../../../../timelines/components/timeline/body/constants'; -import { ColumnHeaderOptions } from '../../../../timelines/store/timeline/model'; import * as i18n from '../../../components/alerts_table/translations'; diff --git a/x-pack/plugins/security_solution/public/detections/configurations/examples/security_solution_rac/render_cell_value.test.tsx b/x-pack/plugins/security_solution/public/detections/configurations/examples/security_solution_rac/render_cell_value.test.tsx index aa4eb543a3d9b5..a8f295df2540d8 100644 --- a/x-pack/plugins/security_solution/public/detections/configurations/examples/security_solution_rac/render_cell_value.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/configurations/examples/security_solution_rac/render_cell_value.test.tsx @@ -15,9 +15,11 @@ import { defaultHeaders, mockTimelineData, TestProviders } from '../../../../com import { TimelineNonEcsData } from '../../../../../common/search_strategy/timeline'; import { CellValueElementProps } from '../../../../timelines/components/timeline/cell_rendering'; import { DefaultCellRenderer } from '../../../../timelines/components/timeline/cell_rendering/default_cell_renderer'; -import { ColumnHeaderOptions } from '../../../../timelines/store/timeline/model'; import { RenderCellValue } from '.'; +import { ColumnHeaderOptions } from '../../../../../common'; + +jest.mock('../../../../common/lib/kibana/'); describe('RenderCellValue', () => { const columnId = '@timestamp'; diff --git a/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts b/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts index 23a0740294e847..7f46c839ffe629 100644 --- a/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts +++ b/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/columns.ts @@ -6,13 +6,13 @@ */ import { EuiDataGridColumn } from '@elastic/eui'; +import { ColumnHeaderOptions } from '../../../../common'; import { defaultColumnHeaderType } from '../../../timelines/components/timeline/body/column_headers/default_headers'; import { DEFAULT_COLUMN_MIN_WIDTH, DEFAULT_DATE_COLUMN_MIN_WIDTH, } from '../../../timelines/components/timeline/body/constants'; -import { ColumnHeaderOptions } from '../../../timelines/store/timeline/model'; import * as i18n from '../../components/alerts_table/translations'; diff --git a/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/render_cell_value.test.tsx b/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/render_cell_value.test.tsx index 18350c102c049b..965ee913a1daa0 100644 --- a/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/render_cell_value.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/configurations/security_solution_detections/render_cell_value.test.tsx @@ -9,16 +9,18 @@ import { mount } from 'enzyme'; import { cloneDeep } from 'lodash/fp'; import React from 'react'; +import { ColumnHeaderOptions } from '../../../../common'; import { mockBrowserFields } from '../../../common/containers/source/mock'; import { DragDropContextWrapper } from '../../../common/components/drag_and_drop/drag_drop_context_wrapper'; import { defaultHeaders, mockTimelineData, TestProviders } from '../../../common/mock'; import { TimelineNonEcsData } from '../../../../common/search_strategy/timeline'; import { CellValueElementProps } from '../../../timelines/components/timeline/cell_rendering'; import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell_rendering/default_cell_renderer'; -import { ColumnHeaderOptions } from '../../../timelines/store/timeline/model'; import { RenderCellValue } from '.'; +jest.mock('../../../common/lib/kibana'); + describe('RenderCellValue', () => { const columnId = '@timestamp'; const eventId = '_id-123'; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_signal_index.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_signal_index.tsx index 84eaf8e3aa93c3..6f8d938dd987e3 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_signal_index.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_signal_index.tsx @@ -6,13 +6,13 @@ */ import { useEffect, useState } from 'react'; +import { isSecurityAppError } from '@kbn/securitysolution-t-grid'; import { DEFAULT_ALERTS_INDEX } from '../../../../../common/constants'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { createSignalIndex, getSignalIndex } from './api'; import * as i18n from './translations'; -import { isSecurityAppError } from '../../../../common/utils/api'; import { useAlertsPrivileges } from './use_alerts_privileges'; type Func = () => Promise; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_index.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_index.tsx index 8e231f0d1fdbba..d55d171708963f 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_index.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_index.tsx @@ -6,10 +6,9 @@ */ import { useEffect, useState, useCallback } from 'react'; - +import { isSecurityAppError } from '@kbn/securitysolution-t-grid'; import { useReadListIndex, useCreateListIndex } from '@kbn/securitysolution-list-hooks'; import { useHttp, useKibana } from '../../../../common/lib/kibana'; -import { isSecurityAppError } from '../../../../common/utils/api'; import * as i18n from './translations'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { useListsPrivileges } from './use_lists_privileges'; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_status.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_status.tsx index f848b71cf7bd36..4f524886935cd2 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_status.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_status.tsx @@ -6,8 +6,8 @@ */ import { useEffect, useRef, useState } from 'react'; +import { isNotFoundError } from '@kbn/securitysolution-t-grid'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { isNotFoundError } from '../../../../common/utils/api'; import { RuleStatusRowItemType } from '../../../pages/detection_engine/rules/all/columns'; import { getRuleStatusById, getRulesStatusByIds } from './api'; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx index 4a39e486b6fd5a..abd5a2781c8a77 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx @@ -6,11 +6,11 @@ */ import { renderHook, act } from '@testing-library/react-hooks'; +import { SecurityAppError } from '@kbn/securitysolution-t-grid'; import { useRuleWithFallback } from './use_rule_with_fallback'; import * as api from './api'; import { useAppToastsMock } from '../../../../common/hooks/use_app_toasts.mock'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { SecurityAppError } from '../../../../common/utils/api'; jest.mock('./api'); jest.mock('../alerts/api'); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.tsx index 11c30547848c38..da56275280f654 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.tsx @@ -6,9 +6,9 @@ */ import { useCallback, useEffect, useMemo } from 'react'; +import { isNotFoundError } from '@kbn/securitysolution-t-grid'; import { useAsync, withOptionalSignal } from '@kbn/securitysolution-hook-utils'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { isNotFoundError } from '../../../../common/utils/api'; import { useQueryAlerts } from '../alerts/use_query'; import { fetchRuleById } from './api'; import { transformInput } from './transforms'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index 8ae7e4fb2852b5..0c12d8256d66d2 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -11,18 +11,18 @@ import { noop } from 'lodash/fp'; import React, { useCallback, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useHistory } from 'react-router-dom'; +import { isTab } from '../../../../../timelines/public'; import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; import { useDeepEqualSelector, useShallowEqualSelector } from '../../../common/hooks/use_selector'; import { SecurityPageName } from '../../../app/types'; import { TimelineId } from '../../../../common/types/timeline'; import { useGlobalTime } from '../../../common/containers/use_global_time'; -import { isTab } from '../../../common/components/accessibility/helpers'; import { UpdateDateRange } from '../../../common/components/charts/common'; import { FiltersGlobal } from '../../../common/components/filters_global'; import { getRulesUrl } from '../../../common/components/link_to/redirect_to_detection_engine'; import { SiemSearchBar } from '../../../common/components/search_bar'; -import { WrapperPage } from '../../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../../common/components/page_wrapper'; import { inputsSelectors } from '../../../common/store/inputs'; import { setAbsoluteRangeDatePicker } from '../../../common/store/inputs/actions'; import { SpyRoute } from '../../../common/utils/route/spy_routes'; @@ -197,22 +197,22 @@ const DetectionEnginePageComponent = () => { if (isUserAuthenticated != null && !isUserAuthenticated && !loading) { return ( - + - + ); } if (!loading && (isSignalIndexExists === false || needsListsConfiguration)) { return ( - + - + ); } @@ -228,7 +228,7 @@ const DetectionEnginePageComponent = () => { - + { onShowOnlyThreatIndicatorAlertsChanged={onShowOnlyThreatIndicatorAlertsCallback} to={to} /> - + ) : ( - + - + )} diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx index dd3549ea20d365..8cc3113a5706a3 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx @@ -42,6 +42,9 @@ describe('ExceptionListsTable', () => { addError: jest.fn(), }, }, + timelines: { + getLastUpdated: () => null, + }, }, }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx index 7f734b10fd0200..f38bde4839f18b 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx @@ -26,7 +26,6 @@ import { Loader } from '../../../../../../common/components/loader'; import { Panel } from '../../../../../../common/components/panel'; import * as i18n from './translations'; import { AllRulesUtilityBar } from '../utility_bar'; -import { LastUpdatedAt } from '../../../../../../common/components/last_updated'; import { AllExceptionListsColumns, getAllExceptionListsColumns } from './columns'; import { useAllExceptionLists } from './use_all_exception_lists'; import { ReferenceErrorModal } from '../../../../../components/value_lists_management_modal/reference_error_modal'; @@ -62,7 +61,7 @@ const exceptionReferenceModalInitialState: ReferenceModalState = { export const ExceptionListsTable = React.memo( ({ formatUrl, history, hasPermissions, loading }) => { const { - services: { http, notifications }, + services: { http, notifications, timelines }, } = useKibana(); const { exportExceptionList, deleteExceptionList } = useApi(http); @@ -78,6 +77,7 @@ export const ExceptionListsTable = React.memo( namespaceTypes: ['single', 'agnostic'], notifications, showTrustedApps: false, + showEventFilters: false, }); const [loadingTableInfo, exceptionListsWithRuleRefs, exceptionsListsRef] = useAllExceptionLists( { @@ -344,7 +344,7 @@ export const ExceptionListsTable = React.memo( } + subtitle={timelines.getLastUpdated({ showUpdating: loading, updatedAt: lastUpdated })} > {!initLoading && } diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx index 8fd82a495e52f8..2ec34aaece60b4 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx @@ -47,7 +47,6 @@ import { hasMlAdminPermissions } from '../../../../../../common/machine_learning import { hasMlLicense } from '../../../../../../common/machine_learning/has_ml_license'; import { isBoolean } from '../../../../../common/utils/privileges'; import { AllRulesUtilityBar } from './utility_bar'; -import { LastUpdatedAt } from '../../../../../common/components/last_updated'; import { DEFAULT_RULES_TABLE_REFRESH_SETTING } from '../../../../../../common/constants'; import { AllRulesTabs } from '.'; import { useValueChanged } from '../../../../../common/hooks/use_value_changed'; @@ -104,6 +103,7 @@ export const RulesTables = React.memo( application: { capabilities: { actions }, }, + timelines, }, } = useKibana(); @@ -473,12 +473,10 @@ export const RulesTables = React.memo( split growLeftSplit={false} title={i18n.ALL_RULES} - subtitle={ - - } + subtitle={timelines.getLastUpdated({ + showUpdating: loading || isLoadingRules || isLoadingRulesStatuses, + updatedAt: lastUpdated, + })} > {shouldShowRulesTable && ( { return ( <> - + { text: i18n.BACK_TO_RULES, pageId: SecurityPageName.detections, }} - border isLoading={isLoading || loading} title={i18n.PAGE_TITLE} /> - + { - + { - + { - + { - + diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.tsx index 417e1c989ce9b4..2fedd6160af2c6 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/failure_history.tsx @@ -29,7 +29,7 @@ const FailureHistoryComponent: React.FC = ({ id }) => { const [loading, ruleStatus] = useRuleStatus(id); if (loading) { return ( - + @@ -60,7 +60,7 @@ const FailureHistoryComponent: React.FC = ({ id }) => { }, ]; return ( - + { - + { /> )} {ruleDetailTab === RuleDetailTabs.failures && } - + ) : ( - + - + )} diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx index 2d751459eb12fd..41710a822e5394 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx @@ -21,7 +21,7 @@ import { useParams, useHistory } from 'react-router-dom'; import { UpdateRulesSchema } from '../../../../../../common/detection_engine/schemas/request'; import { useRule, useUpdateRule } from '../../../../containers/detection_engine/rules'; import { useListsConfig } from '../../../../containers/detection_engine/lists/use_lists_config'; -import { WrapperPage } from '../../../../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../../../../common/components/page_wrapper'; import { getRuleDetailsUrl, getDetectionEngineUrl, @@ -335,7 +335,7 @@ const EditRulePageComponent: FC = () => { return ( <> - + {
- + diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx index 8bacb10444a7d0..29fd8e2e8b247c 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx @@ -16,7 +16,7 @@ import { getCreateRuleUrl, } from '../../../../common/components/link_to/redirect_to_detection_engine'; import { DetectionEngineHeaderPage } from '../../../components/detection_engine_header_page'; -import { WrapperPage } from '../../../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; import { SpyRoute } from '../../../../common/utils/route/spy_routes'; import { useUserData } from '../../../components/user_info'; @@ -182,7 +182,7 @@ const RulesPageComponent: React.FC = () => { subtitle={i18n.INITIAL_PROMPT_TEXT} title={i18n.IMPORT_RULE} /> - + { rulesNotUpdated={rulesNotUpdated} setRefreshRulesData={handleSetRefreshRulesData} /> - + diff --git a/x-pack/plugins/security_solution/public/hosts/components/hosts_table/index.test.tsx b/x-pack/plugins/security_solution/public/hosts/components/hosts_table/index.test.tsx index b1a0d13ed554b5..413b8cda9b6abd 100644 --- a/x-pack/plugins/security_solution/public/hosts/components/hosts_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/hosts/components/hosts_table/index.test.tsx @@ -23,6 +23,8 @@ import { HostsTableType } from '../../../hosts/store/model'; import { HostsTable } from './index'; import { mockData } from './mock'; +jest.mock('../../../common/lib/kibana'); + // Test will fail because we will to need to mock some core services to make the test work // For now let's forget about SiemSearchBar and QueryBar jest.mock('../../../common/components/search_bar', () => ({ diff --git a/x-pack/plugins/security_solution/public/hosts/components/uncommon_process_table/index.test.tsx b/x-pack/plugins/security_solution/public/hosts/components/uncommon_process_table/index.test.tsx index 751a2bf5a20558..2cd4ed1f57f84a 100644 --- a/x-pack/plugins/security_solution/public/hosts/components/uncommon_process_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/hosts/components/uncommon_process_table/index.test.tsx @@ -20,6 +20,8 @@ import { mockData } from './mock'; import { HostsType } from '../../store/model'; import * as i18n from './translations'; +jest.mock('../../../common/lib/kibana'); + jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); return { diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.test.tsx b/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.test.tsx index 2333d5e9b127c3..b51e20b801f408 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.test.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.test.tsx @@ -19,6 +19,8 @@ import { type } from './utils'; import { useMountAppended } from '../../../common/utils/use_mount_appended'; import { getHostDetailsPageFilters } from './helpers'; +jest.mock('../../../common/lib/kibana'); + jest.mock('../../../common/components/url_state/normalize_time_range.ts'); jest.mock('../../../common/containers/source', () => ({ 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 d88e4f048f917a..22edd2c19d6bd2 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 @@ -21,11 +21,11 @@ import { hostToCriteria } from '../../../common/components/ml/criteria/host_to_c import { hasMlUserPermissions } from '../../../../common/machine_learning/has_ml_user_permissions'; import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; import { scoreIntervalToDateTime } from '../../../common/components/ml/score/score_interval_to_datetime'; -import { SiemNavigation } from '../../../common/components/navigation'; +import { SecuritySolutionTabNavigation } from '../../../common/components/navigation'; import { HostsDetailsKpiComponent } from '../../components/kpi_hosts'; import { HostOverview } from '../../../overview/components/host_overview'; import { SiemSearchBar } from '../../../common/components/search_bar'; -import { WrapperPage } from '../../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../../common/components/page_wrapper'; import { useGlobalTime } from '../../../common/containers/use_global_time'; import { useKibana } from '../../../common/lib/kibana'; import { convertToBuildEsQuery } from '../../../common/lib/keury'; @@ -123,7 +123,7 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta - + = ({ detailName, hostDeta - @@ -207,14 +207,14 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta indexPattern={indexPattern} setAbsoluteRangeDatePicker={setAbsoluteRangeDatePicker} /> - + ) : ( - + - + )} diff --git a/x-pack/plugins/security_solution/public/hosts/pages/hosts.test.tsx b/x-pack/plugins/security_solution/public/hosts/pages/hosts.test.tsx index f1eab38c56db0a..d05b091381cca7 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/hosts.test.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/hosts.test.tsx @@ -18,7 +18,7 @@ import { kibanaObservable, createSecuritySolutionStorageMock, } from '../../common/mock'; -import { SiemNavigation } from '../../common/components/navigation'; +import { SecuritySolutionTabNavigation } from '../../common/components/navigation'; import { inputsActions } from '../../common/store/inputs'; import { State, createStore } from '../../common/store'; import { Hosts } from './hosts'; @@ -102,7 +102,7 @@ describe('Hosts - rendering', () => { ); - expect(wrapper.find(SiemNavigation).exists()).toBe(true); + expect(wrapper.find(SecuritySolutionTabNavigation).exists()).toBe(true); }); test('it should add the new filters after init', async () => { diff --git a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx index 57cded85d67ccf..7d31d291e75f17 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx @@ -11,6 +11,7 @@ import { noop } from 'lodash/fp'; import React, { useCallback, useMemo, useRef } from 'react'; import { useDispatch } from 'react-redux'; import { useParams } from 'react-router-dom'; +import { isTab } from '../../../../timelines/public'; import { SecurityPageName } from '../../app/types'; import { UpdateDateRange } from '../../common/components/charts/common'; @@ -18,10 +19,10 @@ import { FiltersGlobal } from '../../common/components/filters_global'; import { HeaderPage } from '../../common/components/header_page'; import { LastEventTime } from '../../common/components/last_event_time'; import { hasMlUserPermissions } from '../../../common/machine_learning/has_ml_user_permissions'; -import { SiemNavigation } from '../../common/components/navigation'; +import { SecuritySolutionTabNavigation } from '../../common/components/navigation'; import { HostsKpiComponent } from '../components/kpi_hosts'; import { SiemSearchBar } from '../../common/components/search_bar'; -import { WrapperPage } from '../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { useGlobalFullScreen } from '../../common/containers/use_full_screen'; import { useGlobalTime } from '../../common/containers/use_global_time'; import { TimelineId } from '../../../common/types/timeline'; @@ -42,7 +43,6 @@ import * as i18n from './translations'; import { filterHostData } from './navigation'; import { hostsModel } from '../store'; import { HostsTableType } from '../store/model'; -import { isTab } from '../../common/components/accessibility/helpers'; import { onTimelineTabKeyPressed, resetKeyboardFocus, @@ -164,10 +164,9 @@ const HostsComponent = () => { - + { - + @@ -207,14 +208,14 @@ const HostsComponent = () => { from={from} type={hostsModel.HostsType.page} /> - + ) : ( - + - + )} diff --git a/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx b/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx index f88709e6e95ac8..973dbc41925da0 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/navigation/events_query_tab_body.tsx @@ -10,6 +10,7 @@ import { useDispatch } from 'react-redux'; import { TimelineId } from '../../../../common/types/timeline'; import { StatefulEventsViewer } from '../../../common/components/events_viewer'; +import { timelineActions } from '../../../timelines/store/timeline'; import { HostsComponentsQueryProps } from './types'; import { eventsDefaultModel } from '../../../common/components/events_viewer/default_model'; import { @@ -20,7 +21,6 @@ import { MatrixHistogram } from '../../../common/components/matrix_histogram'; import { useGlobalFullScreen } from '../../../common/containers/use_full_screen'; import * as i18n from '../translations'; import { MatrixHistogramType } from '../../../../common/search_strategy/security_solution'; -import { useManageTimeline } from '../../../timelines/components/manage_timeline'; import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers'; import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell_rendering/default_cell_renderer'; import { SourcererScopeName } from '../../../common/store/sourcerer/model'; @@ -64,14 +64,15 @@ const EventsQueryTabBodyComponent: React.FC = ({ startDate, }) => { const dispatch = useDispatch(); - const { initializeTimeline } = useManageTimeline(); const { globalFullScreen } = useGlobalFullScreen(); useEffect(() => { - initializeTimeline({ - id: TimelineId.hostsPageEvents, - defaultModel: eventsDefaultModel, - }); - }, [dispatch, initializeTimeline]); + dispatch( + timelineActions.initializeTGridSettings({ + id: TimelineId.hostsPageEvents, + defaultColumns: eventsDefaultModel.columns, + }) + ); + }, [dispatch]); useEffect(() => { return () => { diff --git a/x-pack/plugins/security_solution/public/index.ts b/x-pack/plugins/security_solution/public/index.ts index 55262fe039b4e3..3d2412b326b549 100644 --- a/x-pack/plugins/security_solution/public/index.ts +++ b/x-pack/plugins/security_solution/public/index.ts @@ -8,6 +8,7 @@ import { PluginInitializerContext } from '../../../../src/core/public'; import { Plugin } from './plugin'; import { PluginSetup } from './types'; +export type { TimelineModel } from './timelines/store/timeline/model'; export const plugin = (context: PluginInitializerContext): Plugin => new Plugin(context); diff --git a/x-pack/plugins/security_solution/public/management/common/breadcrumbs.ts b/x-pack/plugins/security_solution/public/management/common/breadcrumbs.ts index 76acff7847671f..3bcbd81621588b 100644 --- a/x-pack/plugins/security_solution/public/management/common/breadcrumbs.ts +++ b/x-pack/plugins/security_solution/public/management/common/breadcrumbs.ts @@ -11,7 +11,7 @@ import { AdministrationSubTab } from '../types'; import { ENDPOINTS_TAB, EVENT_FILTERS_TAB, POLICIES_TAB, TRUSTED_APPS_TAB } from './translations'; import { AdministrationRouteSpyState } from '../../common/utils/route/types'; import { GetUrlForApp } from '../../common/components/navigation/types'; -import { ADMINISTRATION } from '../../app/home/translations'; +import { ADMINISTRATION } from '../../app/translations'; import { APP_ID, SecurityPageName } from '../../../common/constants'; const TabNameMappedToI18nKey: Record = { diff --git a/x-pack/plugins/security_solution/public/management/components/administration_list_page.tsx b/x-pack/plugins/security_solution/public/management/components/administration_list_page.tsx index 72a6de2a2de8d1..021c900824f8df 100644 --- a/x-pack/plugins/security_solution/public/management/components/administration_list_page.tsx +++ b/x-pack/plugins/security_solution/public/management/components/administration_list_page.tsx @@ -9,9 +9,9 @@ import React, { FC, memo } from 'react'; import { EuiPanel, EuiSpacer, CommonProps } from '@elastic/eui'; import styled from 'styled-components'; import { SecurityPageName } from '../../../common/constants'; -import { WrapperPage } from '../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { HeaderPage } from '../../common/components/header_page'; -import { SiemNavigation } from '../../common/components/navigation'; +import { SecuritySolutionTabNavigation } from '../../common/components/navigation'; import { SpyRoute } from '../../common/utils/route/spy_routes'; import { AdministrationSubTab } from '../types'; import { @@ -46,7 +46,7 @@ export const AdministrationListPage: FC + - - {children} + {children} - + ); } ); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/action.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/action.ts index 5b5bac3a0a6e19..949feb29643173 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/action.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/action.ts @@ -16,7 +16,7 @@ import { import { ServerApiError } from '../../../../common/types'; import { GetPolicyListResponse } from '../../policy/types'; import { GetPackagesResponse } from '../../../../../../fleet/common'; -import { EndpointState } from '../types'; +import { EndpointIndexUIQueryParams, EndpointState } from '../types'; import { IIndexPattern } from '../../../../../../../../src/plugins/data/public'; export interface ServerReturnedEndpointList { @@ -163,12 +163,29 @@ export type EndpointPendingActionsStateChanged = Action<'endpointPendingActionsS payload: EndpointState['endpointPendingActions']; }; +export interface EndpointDetailsActivityLogUpdatePaging { + type: 'endpointDetailsActivityLogUpdatePaging'; + payload: { + // disable paging when no more data after paging + disabled: boolean; + page: number; + pageSize: number; + }; +} + +export interface EndpointDetailsFlyoutTabChanged { + type: 'endpointDetailsFlyoutTabChanged'; + payload: { flyoutView: EndpointIndexUIQueryParams['show'] }; +} + export type EndpointAction = | ServerReturnedEndpointList | ServerFailedToReturnEndpointList | ServerReturnedEndpointDetails | ServerFailedToReturnEndpointDetails | AppRequestedEndpointActivityLog + | EndpointDetailsActivityLogUpdatePaging + | EndpointDetailsFlyoutTabChanged | EndpointDetailsActivityLogChanged | ServerReturnedEndpointPolicyResponse | ServerFailedToReturnEndpointPolicyResponse diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/builders.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/builders.ts index d43f361a0e6bb8..317b735e1169e5 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/builders.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/builders.ts @@ -19,9 +19,13 @@ export const initialEndpointPageState = (): Immutable => { loading: false, error: undefined, endpointDetails: { + flyoutView: undefined, activityLog: { - page: 1, - pageSize: 50, + paging: { + disabled: false, + page: 1, + pageSize: 50, + }, logData: createUninitialisedResourceState(), }, hostDetails: { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts index 7f7c5f84f8bffd..68dd47362bc383 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/index.test.ts @@ -42,9 +42,13 @@ describe('EndpointList store concerns', () => { loading: false, error: undefined, endpointDetails: { + flyoutView: undefined, activityLog: { - page: 1, - pageSize: 50, + paging: { + disabled: false, + page: 1, + pageSize: 50, + }, logData: { type: 'UninitialisedResourceState' }, }, hostDetails: { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts index 52da30fabf95a1..6cf5e989fb645d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.test.ts @@ -44,6 +44,7 @@ import { } from '../../../../common/lib/endpoint_isolation/mocks'; import { FleetActionGenerator } from '../../../../../common/endpoint/data_generators/fleet_action_generator'; import { endpointPageHttpMock } from '../mocks'; +import { EndpointDetailsTabsTypes } from '../view/details/components/endpoint_details_tabs'; jest.mock('../../policy/store/services/ingest', () => ({ sendGetAgentConfigList: () => Promise.resolve({ items: [] }), @@ -226,8 +227,16 @@ describe('endpoint list middleware', () => { const dispatchUserChangedUrl = () => { dispatchUserChangedUrlToEndpointList({ search: `?${search.split('?').pop()}` }); }; + const dispatchFlyoutViewChange = () => { + dispatch({ + type: 'endpointDetailsFlyoutTabChanged', + payload: { + flyoutView: EndpointDetailsTabsTypes.activityLog, + }, + }); + }; - const fleetActionGenerator = new FleetActionGenerator(Math.random().toString()); + const fleetActionGenerator = new FleetActionGenerator('seed'); const actionData = fleetActionGenerator.generate({ agents: [endpointList.hosts[0].metadata.agent.id], }); @@ -265,6 +274,7 @@ describe('endpoint list middleware', () => { it('should set ActivityLog state to loading', async () => { dispatchUserChangedUrl(); + dispatchFlyoutViewChange(); const loadingDispatched = waitForAction('endpointDetailsActivityLogChanged', { validate(action) { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts index 4f96223e8b7897..53b30aeb02bd53 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts @@ -35,6 +35,7 @@ import { getActivityLogDataPaging, getLastLoadedActivityLogData, detailsData, + getEndpointDetailsFlyoutView, } from './selectors'; import { AgentIdsPendingActions, EndpointState, PolicyIds } from '../types'; import { @@ -48,6 +49,7 @@ import { ENDPOINT_ACTION_LOG_ROUTE, HOST_METADATA_GET_ROUTE, HOST_METADATA_LIST_ROUTE, + BASE_POLICY_RESPONSE_ROUTE, metadataCurrentIndexPattern, } from '../../../../../common/endpoint/constants'; import { IIndexPattern, Query } from '../../../../../../../../src/plugins/data/public'; @@ -61,6 +63,7 @@ import { AppAction } from '../../../../common/store/actions'; import { resolvePathVariables } from '../../../../common/utils/resolve_path_variables'; import { ServerReturnedEndpointPackageInfo } from './action'; import { fetchPendingActionsByAgentId } from '../../../../common/lib/endpoint_pending_actions'; +import { EndpointDetailsTabsTypes } from '../view/details/components/endpoint_details_tabs'; type EndpointPageStore = ImmutableMiddlewareAPI; @@ -339,6 +342,28 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory(error.body ?? error), }); } - - // call the policy response api - try { - const policyResponse = await coreStart.http.get(`/api/endpoint/policy_response`, { - query: { agentId: selectedEndpoint }, - }); - dispatch({ - type: 'serverReturnedEndpointPolicyResponse', - payload: policyResponse, - }); - } catch (error) { - dispatch({ - type: 'serverFailedToReturnEndpointPolicyResponse', - payload: error, - }); - } } // page activity log API @@ -408,17 +417,24 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory(updatedLogData), }); - // TODO dispatch 'noNewLogData' if !activityLog.length - // resets paging to previous state + if (!activityLog.data.length) { + dispatch({ + type: 'endpointDetailsActivityLogUpdatePaging', + payload: { + disabled: true, + page: activityLog.page - 1, + pageSize: activityLog.pageSize, + }, + }); + } } else { dispatch({ type: 'endpointDetailsActivityLogChanged', diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts index 9460c27dfe705d..44c63edd8e95c5 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/reducer.ts @@ -29,12 +29,23 @@ const handleEndpointDetailsActivityLogChanged: CaseReducer { + const pagingOptions = + action.payload.type === 'LoadedResourceState' + ? { + ...state.endpointDetails.activityLog, + paging: { + ...state.endpointDetails.activityLog.paging, + page: action.payload.data.page, + pageSize: action.payload.data.pageSize, + }, + } + : { ...state.endpointDetails.activityLog }; return { ...state!, endpointDetails: { ...state.endpointDetails!, activityLog: { - ...state.endpointDetails.activityLog, + ...pagingOptions, logData: action.payload, }, }, @@ -138,7 +149,8 @@ export const endpointListReducer: StateReducer = (state = initialEndpointPageSta }, }; } else if (action.type === 'appRequestedEndpointActivityLog') { - const pageData = { + const paging = { + disabled: state.endpointDetails.activityLog.paging.disabled, page: action.payload.page, pageSize: action.payload.pageSize, }; @@ -148,10 +160,32 @@ export const endpointListReducer: StateReducer = (state = initialEndpointPageSta ...state.endpointDetails!, activityLog: { ...state.endpointDetails.activityLog, - ...pageData, + paging, }, }, }; + } else if (action.type === 'endpointDetailsActivityLogUpdatePaging') { + const paging = { + ...action.payload, + }; + return { + ...state, + endpointDetails: { + ...state.endpointDetails!, + activityLog: { + ...state.endpointDetails.activityLog, + paging, + }, + }, + }; + } else if (action.type === 'endpointDetailsFlyoutTabChanged') { + return { + ...state, + endpointDetails: { + ...state.endpointDetails!, + flyoutView: action.payload.flyoutView, + }, + }; } else if (action.type === 'endpointDetailsActivityLogChanged') { return handleEndpointDetailsActivityLogChanged(state, action); } else if (action.type === 'endpointPendingActionsStateChanged') { @@ -255,8 +289,11 @@ export const endpointListReducer: StateReducer = (state = initialEndpointPageSta const activityLog = { logData: createUninitialisedResourceState(), - page: 1, - pageSize: 50, + paging: { + disabled: false, + page: 1, + pageSize: 50, + }, }; // Reset `isolationRequestState` if needed 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 d9be85377c81d7..eeb54379e8e7df 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 @@ -364,13 +364,14 @@ export const getIsolationRequestError: ( } }); +export const getEndpointDetailsFlyoutView = ( + state: Immutable +): EndpointIndexUIQueryParams['show'] => state.endpointDetails.flyoutView; + export const getActivityLogDataPaging = ( state: Immutable -): Immutable> => { - return { - page: state.endpointDetails.activityLog.page, - pageSize: state.endpointDetails.activityLog.pageSize, - }; +): Immutable => { + return state.endpointDetails.activityLog.paging; }; export const getActivityLogData = ( diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts index 59aa2bd15dd74a..c985259588cb05 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts @@ -37,9 +37,13 @@ export interface EndpointState { /** api error from retrieving host list */ error?: ServerApiError; endpointDetails: { + flyoutView: EndpointIndexUIQueryParams['show']; activityLog: { - page: number; - pageSize: number; + paging: { + disabled: boolean; + page: number; + pageSize: number; + }; logData: AsyncResourceState; }; hostDetails: { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/endpoint_details_tabs.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/endpoint_details_tabs.tsx index 3e228be4565b1c..aa1f56529657ec 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/endpoint_details_tabs.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/endpoint_details_tabs.tsx @@ -5,10 +5,15 @@ * 2.0. */ +import { useDispatch } from 'react-redux'; import React, { memo, useCallback, useMemo, useState } from 'react'; -import styled from 'styled-components'; -import { EuiTabbedContent, EuiTabbedContentTab } from '@elastic/eui'; +import { EuiTab, EuiTabs, EuiFlyoutBody, EuiTabbedContentTab, EuiSpacer } from '@elastic/eui'; import { EndpointIndexUIQueryParams } from '../../../types'; +import { EndpointAction } from '../../../store/action'; +import { useEndpointSelector } from '../../hooks'; +import { getActivityLogDataPaging } from '../../../store/selectors'; +import { EndpointDetailsFlyoutHeader } from './flyout_header'; + export enum EndpointDetailsTabsTypes { overview = 'overview', activityLog = 'activity_log', @@ -24,29 +29,18 @@ interface EndpointDetailsTabs { content: JSX.Element; } -const StyledEuiTabbedContent = styled(EuiTabbedContent)` - overflow: hidden; - padding-bottom: ${(props) => props.theme.eui.paddingSizes.xl}; - - > [role='tabpanel'] { - height: 100%; - padding-right: 12px; - overflow: hidden; - overflow-y: auto; - ::-webkit-scrollbar { - -webkit-appearance: none; - width: 4px; - } - ::-webkit-scrollbar-thumb { - border-radius: 2px; - background-color: rgba(0, 0, 0, 0.5); - -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); - } - } -`; - export const EndpointDetailsFlyoutTabs = memo( - ({ show, tabs }: { show: EndpointIndexUIQueryParams['show']; tabs: EndpointDetailsTabs[] }) => { + ({ + hostname, + show, + tabs, + }: { + hostname?: string; + show: EndpointIndexUIQueryParams['show']; + tabs: EndpointDetailsTabs[]; + }) => { + const dispatch = useDispatch<(action: EndpointAction) => void>(); + const { pageSize } = useEndpointSelector(getActivityLogDataPaging); const [selectedTabId, setSelectedTabId] = useState(() => { return show === 'details' ? EndpointDetailsTabsTypes.overview @@ -54,8 +48,33 @@ export const EndpointDetailsFlyoutTabs = memo( }); const handleTabClick = useCallback( - (tab: EuiTabbedContentTab) => setSelectedTabId(tab.id as EndpointDetailsTabsId), - [setSelectedTabId] + (tab: EuiTabbedContentTab) => { + dispatch({ + type: 'endpointDetailsFlyoutTabChanged', + payload: { + flyoutView: tab.id as EndpointIndexUIQueryParams['show'], + }, + }); + if (tab.id === EndpointDetailsTabsTypes.activityLog) { + const paging = { + page: 1, + pageSize, + }; + dispatch({ + type: 'appRequestedEndpointActivityLog', + payload: paging, + }); + dispatch({ + type: 'endpointDetailsActivityLogUpdatePaging', + payload: { + disabled: false, + ...paging, + }, + }); + } + return setSelectedTabId(tab.id as EndpointDetailsTabsId); + }, + [dispatch, pageSize, setSelectedTabId] ); const selectedTab = useMemo(() => tabs.find((tab) => tab.id === selectedTabId), [ @@ -63,14 +82,27 @@ export const EndpointDetailsFlyoutTabs = memo( selectedTabId, ]); + const renderTabs = tabs.map((tab) => ( + handleTabClick(tab)} + isSelected={tab.id === selectedTabId} + key={tab.id} + data-test-subj={tab.id} + > + {tab.name} + + )); + return ( - + <> + + + {renderTabs} + + + {selectedTab?.content} + + ); } ); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/flyout_header.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/flyout_header.tsx new file mode 100644 index 00000000000000..f791c0d6adf179 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/flyout_header.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { EuiFlyoutHeader, EuiLoadingContent, EuiToolTip, EuiTitle } from '@elastic/eui'; +import { useEndpointSelector } from '../../hooks'; +import { detailsLoading } from '../../../store/selectors'; + +export const EndpointDetailsFlyoutHeader = memo( + ({ + hasBorder = false, + hostname, + children, + }: { + hasBorder?: boolean; + hostname?: string; + children?: React.ReactNode | React.ReactNodeArray; + }) => { + const hostDetailsLoading = useEndpointSelector(detailsLoading); + + return ( + + {hostDetailsLoading ? ( + + ) : ( + + +

+ {hostname} +

+
+
+ )} + {children} +
+ ); + } +); + +EndpointDetailsFlyoutHeader.displayName = 'EndpointDetailsFlyoutHeader'; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/log_entry.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/log_entry.tsx index c431cd682d25ba..4fe70039d12512 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/log_entry.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/log_entry.tsx @@ -78,7 +78,7 @@ const useLogEntryUIProps = ( if (isSuccessful) { return i18.ACTIVITY_LOG.LogEntry.response.isolationSuccessful; } else { - return i18.ACTIVITY_LOG.LogEntry.response.isolationSuccessful; + return i18.ACTIVITY_LOG.LogEntry.response.isolationFailed; } } else { if (isSuccessful) { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_activity_log.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_activity_log.tsx index 55479845bce0a3..f1701054c4d5f4 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_activity_log.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_activity_log.tsx @@ -5,11 +5,19 @@ * 2.0. */ -import React, { memo, useCallback } from 'react'; +import React, { memo, useCallback, useEffect, useRef } from 'react'; +import styled from 'styled-components'; -import { EuiButton, EuiEmptyPrompt, EuiLoadingContent, EuiSpacer } from '@elastic/eui'; +import { + EuiText, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingContent, + EuiEmptyPrompt, +} from '@elastic/eui'; import { useDispatch } from 'react-redux'; import { LogEntry } from './components/log_entry'; +import * as i18 from '../translations'; import { Immutable, ActivityLog } from '../../../../../../common/endpoint/types'; import { AsyncResourceState } from '../../../../state'; import { useEndpointSelector } from '../hooks'; @@ -19,54 +27,95 @@ import { getActivityLogError, getActivityLogIterableData, getActivityLogRequestLoaded, + getLastLoadedActivityLogData, getActivityLogRequestLoading, } from '../../store/selectors'; +const LoadMoreTrigger = styled.div` + height: 6px; + width: 100%; +`; + export const EndpointActivityLog = memo( ({ activityLog }: { activityLog: AsyncResourceState> }) => { const activityLogLoading = useEndpointSelector(getActivityLogRequestLoading); const activityLogLoaded = useEndpointSelector(getActivityLogRequestLoaded); + const activityLastLogData = useEndpointSelector(getLastLoadedActivityLogData); const activityLogData = useEndpointSelector(getActivityLogIterableData); + const activityLogSize = activityLogData.length; const activityLogError = useEndpointSelector(getActivityLogError); - const dispatch = useDispatch<(a: EndpointAction) => void>(); - const { page, pageSize } = useEndpointSelector(getActivityLogDataPaging); + const dispatch = useDispatch<(action: EndpointAction) => void>(); + const { page, pageSize, disabled: isPagingDisabled } = useEndpointSelector( + getActivityLogDataPaging + ); + + const loadMoreTrigger = useRef(null); + const getActivityLog = useCallback( + (entries: IntersectionObserverEntry[]) => { + const isTargetIntersecting = entries.some((entry) => entry.isIntersecting); + if (isTargetIntersecting && activityLogLoaded && !isPagingDisabled) { + dispatch({ + type: 'appRequestedEndpointActivityLog', + payload: { + page: page + 1, + pageSize, + }, + }); + } + }, + [activityLogLoaded, dispatch, isPagingDisabled, page, pageSize] + ); - const getActivityLog = useCallback(() => { - dispatch({ - type: 'appRequestedEndpointActivityLog', - payload: { - page: page + 1, - pageSize, - }, - }); - }, [dispatch, page, pageSize]); + useEffect(() => { + const observer = new IntersectionObserver(getActivityLog); + const element = loadMoreTrigger.current; + if (element) { + observer.observe(element); + } + return () => { + observer.disconnect(); + }; + }, [getActivityLog]); return ( <> - - {activityLogLoading || activityLogError ? ( - {'No logged actions'}} - body={

{'No actions have been logged for this endpoint.'}

} - /> - ) : ( - <> - - {activityLogLoading ? ( - - ) : ( - activityLogLoaded && - activityLogData.map((logEntry) => ( - - )) - )} - - {'show more'} - - - )} + + {(activityLogLoaded && !activityLogSize) || activityLogError ? ( + + {i18.ACTIVITY_LOG.LogEntry.emptyState.title}} + body={

{i18.ACTIVITY_LOG.LogEntry.emptyState.body}

} + data-test-subj="activityLogEmpty" + /> +
+ ) : ( + <> + + {activityLogLoaded && + activityLogData.map((logEntry) => ( + + ))} + {activityLogLoading && + activityLastLogData?.data.map((logEntry) => ( + + ))} + + + {activityLogLoading && } + {(!activityLogLoading || !isPagingDisabled) && ( + + )} + {isPagingDisabled && !activityLogLoading && ( + +

{i18.ACTIVITY_LOG.LogEntry.endOfLog}

+
+ )} +
+ + )} +
); } diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoints.stories.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoints.stories.tsx index d839bbfaae8756..d3c91f6f18499e 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoints.stories.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoints.stories.tsx @@ -20,7 +20,6 @@ export const dummyEndpointActivityLog = ( ): AsyncResourceState> => ({ type: 'LoadedResourceState', data: { - total: 20, page: 1, pageSize: 50, data: [ diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx index 59e0c0e787a222..e295ea145edcbe 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx @@ -5,21 +5,16 @@ * 2.0. */ +import { useDispatch } from 'react-redux'; import React, { useCallback, useEffect, useMemo, memo } from 'react'; -import styled from 'styled-components'; import { EuiFlyout, EuiFlyoutBody, - EuiFlyoutHeader, EuiFlyoutFooter, EuiLoadingContent, - EuiTitle, EuiText, EuiSpacer, EuiEmptyPrompt, - EuiToolTip, - EuiFlexGroup, - EuiFlexItem, } from '@elastic/eui'; import { useHistory } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -30,7 +25,6 @@ import { uiQueryParams, detailsData, detailsError, - detailsLoading, getActivityLogData, showView, policyResponseConfigurations, @@ -59,23 +53,12 @@ import { BackToEndpointDetailsFlyoutSubHeader } from './components/back_to_endpo import { FlyoutBodyNoTopPadding } from './components/flyout_body_no_top_padding'; import { getEndpointListPath } from '../../../../common/routing'; import { ActionsMenu } from './components/actions_menu'; - -const DetailsFlyoutBody = styled(EuiFlyoutBody)` - overflow-y: hidden; - flex: 1; - - .euiFlyoutBody__overflow { - overflow: hidden; - mask-image: none; - } - - .euiFlyoutBody__overflowContent { - height: 100%; - display: flex; - } -`; +import { EndpointIndexUIQueryParams } from '../../types'; +import { EndpointAction } from '../../store/action'; +import { EndpointDetailsFlyoutHeader } from './components/flyout_header'; export const EndpointDetailsFlyout = memo(() => { + const dispatch = useDispatch<(action: EndpointAction) => void>(); const history = useHistory(); const toasts = useToasts(); const queryParams = useEndpointSelector(uiQueryParams); @@ -86,13 +69,24 @@ export const EndpointDetailsFlyout = memo(() => { const activityLog = useEndpointSelector(getActivityLogData); const hostDetails = useEndpointSelector(detailsData); - const hostDetailsLoading = useEndpointSelector(detailsLoading); const hostDetailsError = useEndpointSelector(detailsError); const policyInfo = useEndpointSelector(policyVersionInfo); const hostStatus = useEndpointSelector(hostStatusInfo); const show = useEndpointSelector(showView); + const setFlyoutView = useCallback( + (flyoutView: EndpointIndexUIQueryParams['show']) => { + dispatch({ + type: 'endpointDetailsFlyoutTabChanged', + payload: { + flyoutView, + }, + }); + }, + [dispatch] + ); + const ContentLoadingMarkup = useMemo( () => ( <> @@ -133,9 +127,11 @@ export const EndpointDetailsFlyout = memo(() => { ...urlSearchParams, }) ); - }, [history, queryParamsWithoutSelectedEndpoint]); + setFlyoutView(undefined); + }, [setFlyoutView, history, queryParamsWithoutSelectedEndpoint]); useEffect(() => { + setFlyoutView(show); if (hostDetailsError !== undefined) { toasts.addDanger({ title: i18n.translate('xpack.securitySolution.endpoint.details.errorTitle', { @@ -146,7 +142,10 @@ export const EndpointDetailsFlyout = memo(() => { }), }); } - }, [hostDetailsError, toasts]); + return () => { + setFlyoutView(undefined); + }; + }, [hostDetailsError, setFlyoutView, show, toasts]); return ( { size="m" paddingSize="l" > - - {hostDetailsLoading ? ( - - ) : ( - - -

- {hostDetails?.host?.hostname} -

-
-
- )} -
+ {(show === 'policy_response' || show === 'isolate' || show === 'unisolate') && ( + + )} {hostDetails === undefined ? ( @@ -179,13 +165,11 @@ export const EndpointDetailsFlyout = memo(() => { ) : ( <> {(show === 'details' || show === 'activity_log') && ( - - - - - - - + )} {show === 'policy_response' && } diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index 6aab9336c21a43..4869ce84fad2cf 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -17,6 +17,7 @@ import { } from '../store/mock_endpoint_result_list'; import { AppContextTestRender, createAppRootMockRenderer } from '../../../../common/mock/endpoint'; import { + ActivityLog, HostInfo, HostPolicyResponse, HostPolicyResponseActionStatus, @@ -32,12 +33,15 @@ import { KibanaServices, useKibana, useToasts } from '../../../../common/lib/kib import { hostIsolationHttpMocks } from '../../../../common/lib/endpoint_isolation/mocks'; import { fireEvent } from '@testing-library/dom'; import { + createFailedResourceState, + createLoadedResourceState, isFailedResourceState, isLoadedResourceState, isUninitialisedResourceState, } from '../../../state'; import { getCurrentIsolationRequestState } from '../store/selectors'; import { licenseService } from '../../../../common/hooks/use_license'; +import { FleetActionGenerator } from '../../../../../common/endpoint/data_generators/fleet_action_generator'; // not sure why this can't be imported from '../../../../common/mock/formatted_relative'; // but sure enough it needs to be inline in this one file @@ -625,6 +629,30 @@ describe('when on the endpoint list page', () => { }); }; + const dispatchEndpointDetailsActivityLogChanged = ( + dataState: 'failed' | 'success', + data: ActivityLog + ) => { + reactTestingLibrary.act(() => { + const getPayload = () => { + switch (dataState) { + case 'failed': + return createFailedResourceState({ + statusCode: 500, + error: 'Internal Server Error', + message: 'An internal server error occurred.', + }); + case 'success': + return createLoadedResourceState(data); + } + }; + store.dispatch({ + type: 'endpointDetailsActivityLogChanged', + payload: getPayload(), + }); + }); + }; + beforeEach(async () => { mockEndpointListApi(); @@ -746,6 +774,120 @@ describe('when on the endpoint list page', () => { expect(renderResult.getByTestId('endpointDetailsActionsButton')).not.toBeNull(); }); + describe('when showing Activity Log panel', () => { + let renderResult: ReturnType; + const agentId = 'some_agent_id'; + + let getMockData: () => ActivityLog; + beforeEach(async () => { + window.IntersectionObserver = jest.fn(() => ({ + root: null, + rootMargin: '', + thresholds: [], + takeRecords: jest.fn(), + observe: jest.fn(), + unobserve: jest.fn(), + disconnect: jest.fn(), + })); + + const fleetActionGenerator = new FleetActionGenerator('seed'); + const responseData = fleetActionGenerator.generateResponse({ + agent_id: agentId, + }); + const actionData = fleetActionGenerator.generate({ + agents: [agentId], + }); + getMockData = () => ({ + page: 1, + pageSize: 50, + data: [ + { + type: 'response', + item: { + id: 'some_id_0', + data: responseData, + }, + }, + { + type: 'action', + item: { + id: 'some_id_1', + data: actionData, + }, + }, + ], + }); + + renderResult = render(); + await reactTestingLibrary.act(async () => { + await middlewareSpy.waitForAction('serverReturnedEndpointList'); + }); + const hostNameLinks = await renderResult.getAllByTestId('hostnameCellLink'); + reactTestingLibrary.fireEvent.click(hostNameLinks[0]); + }); + + afterEach(reactTestingLibrary.cleanup); + + it('should show the endpoint details flyout', async () => { + const activityLogTab = await renderResult.findByTestId('activity_log'); + reactTestingLibrary.act(() => { + reactTestingLibrary.fireEvent.click(activityLogTab); + }); + await middlewareSpy.waitForAction('endpointDetailsActivityLogChanged'); + reactTestingLibrary.act(() => { + dispatchEndpointDetailsActivityLogChanged('success', getMockData()); + }); + const endpointDetailsFlyout = await renderResult.queryByTestId('endpointDetailsFlyoutBody'); + expect(endpointDetailsFlyout).not.toBeNull(); + }); + + it('should display log accurately', async () => { + const activityLogTab = await renderResult.findByTestId('activity_log'); + reactTestingLibrary.act(() => { + reactTestingLibrary.fireEvent.click(activityLogTab); + }); + await middlewareSpy.waitForAction('endpointDetailsActivityLogChanged'); + reactTestingLibrary.act(() => { + dispatchEndpointDetailsActivityLogChanged('success', getMockData()); + }); + const logEntries = await renderResult.queryAllByTestId('timelineEntry'); + expect(logEntries.length).toEqual(2); + expect(`${logEntries[0]} .euiCommentTimeline__icon--update`).not.toBe(null); + expect(`${logEntries[1]} .euiCommentTimeline__icon--regular`).not.toBe(null); + }); + + it('should display empty state when API call has failed', async () => { + const activityLogTab = await renderResult.findByTestId('activity_log'); + reactTestingLibrary.act(() => { + reactTestingLibrary.fireEvent.click(activityLogTab); + }); + await middlewareSpy.waitForAction('endpointDetailsActivityLogChanged'); + reactTestingLibrary.act(() => { + dispatchEndpointDetailsActivityLogChanged('failed', getMockData()); + }); + const emptyState = await renderResult.queryByTestId('activityLogEmpty'); + expect(emptyState).not.toBe(null); + }); + + it('should display empty state when no log data', async () => { + const activityLogTab = await renderResult.findByTestId('activity_log'); + reactTestingLibrary.act(() => { + reactTestingLibrary.fireEvent.click(activityLogTab); + }); + await middlewareSpy.waitForAction('endpointDetailsActivityLogChanged'); + reactTestingLibrary.act(() => { + dispatchEndpointDetailsActivityLogChanged('success', { + page: 1, + pageSize: 50, + data: [], + }); + }); + + const emptyState = await renderResult.queryByTestId('activityLogEmpty'); + expect(emptyState).not.toBe(null); + }); + }); + describe('when showing host Policy Response panel', () => { let renderResult: ReturnType; beforeEach(async () => { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/translations.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/translations.ts index 18a5bd1e5130a5..89ffd2d23807ef 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/translations.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/translations.ts @@ -16,6 +16,26 @@ export const ACTIVITY_LOG = { defaultMessage: 'Activity Log', }), LogEntry: { + endOfLog: i18n.translate( + 'xpack.securitySolution.endpointDetails.activityLog.logEntry.action.endOfLog', + { + defaultMessage: 'Nothing more to show', + } + ), + emptyState: { + title: i18n.translate( + 'xpack.securitySolution.endpointDetails.activityLog.logEntry.emptyState.title', + { + defaultMessage: 'No logged actions', + } + ), + body: i18n.translate( + 'xpack.securitySolution.endpointDetails.activityLog.logEntry.emptyState.body', + { + defaultMessage: 'No actions have been logged for this endpoint.', + } + ), + }, action: { isolatedAction: i18n.translate( 'xpack.securitySolution.endpointDetails.activityLog.logEntry.action.isolated', diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx index 204c3a86ce3e69..e9cdd16554f33b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx @@ -42,7 +42,7 @@ import { useFormatUrl } from '../../../../common/components/link_to'; import { useNavigateToAppEventHandler } from '../../../../common/hooks/endpoint/use_navigate_to_app_event_handler'; import { MANAGEMENT_APP_ID } from '../../../common/constants'; import { PolicyDetailsRouteState } from '../../../../../common/endpoint/types'; -import { WrapperPage } from '../../../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; import { HeaderPage } from '../../../../common/components/header_page'; import { PolicyDetailsForm } from './policy_details_form'; @@ -51,7 +51,7 @@ const PolicyDetailsHeader = styled.div` padding: ${(props) => props.theme.eui.paddingSizes.xl} 0; background-color: #fafbfd; border-bottom: 1px solid #d3dae6; - .siemHeaderPage { + .securitySolutionHeaderPage { max-width: ${maxFormWidth}; margin: 0 auto; } @@ -159,7 +159,7 @@ export const PolicyDetails = React.memo(() => { // Else, if we have an error, then show error on the page. if (!policyItem) { return ( - + {isPolicyLoading ? ( ) : policyApiError ? ( @@ -168,7 +168,7 @@ export const PolicyDetails = React.memo(() => { ) : null} - + ); } @@ -190,7 +190,7 @@ export const PolicyDetails = React.memo(() => { onConfirm={handleSaveConfirmation} /> )} - { - + diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/__snapshots__/index.test.tsx.snap index e984ea5bb1711f..51b60c8ff292be 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/__snapshots__/index.test.tsx.snap @@ -427,7 +427,7 @@ exports[`TrustedAppsGrid renders correctly when loaded data 1`] = ` class="body-content undefined" >

diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/embeddable.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/embeddable.tsx index 82b5b8a3e7b3db..3087dbe4ad6edc 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/embeddable.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/embeddable.tsx @@ -20,7 +20,9 @@ export interface EmbeddableProps { export const Embeddable = React.memo(({ children }) => (

- {children} + + {children} +
)); Embeddable.displayName = 'Embeddable'; diff --git a/x-pack/plugins/security_solution/public/network/components/ip/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/ip/index.test.tsx index a3fd32008062cd..63971ae508d5cd 100644 --- a/x-pack/plugins/security_solution/public/network/components/ip/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/ip/index.test.tsx @@ -14,6 +14,8 @@ import { useMountAppended } from '../../../common/utils/use_mount_appended'; import { Ip } from '.'; +jest.mock('../../../common/lib/kibana'); + jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); return { diff --git a/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.test.tsx index 7ec18c078c73d7..a811f5c92c37a9 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_dns_table/index.test.tsx @@ -25,6 +25,8 @@ import { useMountAppended } from '../../../common/utils/use_mount_appended'; import { NetworkDnsTable } from '.'; import { mockData } from './mock'; +jest.mock('../../../common/lib/kibana'); + describe('NetworkTopNFlow Table Component', () => { const loadPage = jest.fn(); const state: State = mockGlobalState; diff --git a/x-pack/plugins/security_solution/public/network/components/network_http_table/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/network_http_table/index.test.tsx index f7f75d9f0a365d..f05372c76b36fc 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_http_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_http_table/index.test.tsx @@ -25,6 +25,7 @@ import { networkModel } from '../../store'; import { NetworkHttpTable } from '.'; import { mockData } from './mock'; +jest.mock('../../../common/lib/kibana'); jest.mock('../../../common/components/link_to'); describe('NetworkHttp Table Component', () => { diff --git a/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.test.tsx index 1501f56882290c..a0727fad65f188 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_top_countries_table/index.test.tsx @@ -27,6 +27,8 @@ import { networkModel } from '../../store'; import { NetworkTopCountriesTable } from '.'; import { mockData } from './mock'; +jest.mock('../../../common/lib/kibana'); + describe('NetworkTopCountries Table Component', () => { const loadPage = jest.fn(); const state: State = mockGlobalState; diff --git a/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.test.tsx index cd8c8c6543299c..e2b9447b588060 100644 --- a/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/network_top_n_flow_table/index.test.tsx @@ -25,6 +25,7 @@ import { NetworkTopNFlowTable } from '.'; import { mockData } from './mock'; import { FlowTargetSourceDest } from '../../../../common/search_strategy'; +jest.mock('../../../common/lib/kibana'); jest.mock('../../../common/components/link_to'); describe('NetworkTopNFlow Table Component', () => { diff --git a/x-pack/plugins/security_solution/public/network/components/port/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/port/index.test.tsx index ef1039bfc92e37..dd7ad20d2384a3 100644 --- a/x-pack/plugins/security_solution/public/network/components/port/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/port/index.test.tsx @@ -15,6 +15,8 @@ import { useMountAppended } from '../../../common/utils/use_mount_appended'; import { Port } from '.'; +jest.mock('../../../common/lib/kibana'); + jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); return { diff --git a/x-pack/plugins/security_solution/public/network/components/source_destination/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/source_destination/index.test.tsx index 01065ad5bf15f1..b59eb25cbfe256 100644 --- a/x-pack/plugins/security_solution/public/network/components/source_destination/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/source_destination/index.test.tsx @@ -49,6 +49,8 @@ import { NETWORK_TRANSPORT_FIELD_NAME, } from './field_names'; +jest.mock('../../../common/lib/kibana'); + jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); return { diff --git a/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.test.tsx b/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.test.tsx index f767e793c8f214..91f7ea3d7ac7a5 100644 --- a/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/source_destination/source_destination_ip.test.tsx @@ -38,6 +38,8 @@ import { SOURCE_GEO_REGION_NAME_FIELD_NAME, } from './geo_fields'; +jest.mock('../../../common/lib/kibana'); + jest.mock('../../../common/components/link_to'); describe('SourceDestinationIp', () => { diff --git a/x-pack/plugins/security_solution/public/network/components/tls_table/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/tls_table/index.test.tsx index 4b6c31f5b61768..8f2c7a098a0457 100644 --- a/x-pack/plugins/security_solution/public/network/components/tls_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/tls_table/index.test.tsx @@ -24,6 +24,8 @@ import { networkModel } from '../../store'; import { TlsTable } from '.'; import { mockTlsData } from './mock'; +jest.mock('../../../common/lib/kibana'); + describe('Tls Table Component', () => { const loadPage = jest.fn(); const state: State = mockGlobalState; diff --git a/x-pack/plugins/security_solution/public/network/components/users_table/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/users_table/index.test.tsx index 4b613e79a1d1a3..69027ad9bd9f8a 100644 --- a/x-pack/plugins/security_solution/public/network/components/users_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/users_table/index.test.tsx @@ -26,6 +26,8 @@ import { UsersTable } from '.'; import { mockUsersData } from './mock'; import { FlowTarget } from '../../../../common/search_strategy'; +jest.mock('../../../common/lib/kibana'); + describe('Users Table Component', () => { const loadPage = jest.fn(); const state: State = mockGlobalState; diff --git a/x-pack/plugins/security_solution/public/network/pages/details/index.tsx b/x-pack/plugins/security_solution/public/network/pages/details/index.tsx index 4cccb536c08bbd..02be5f78261c1d 100644 --- a/x-pack/plugins/security_solution/public/network/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/details/index.tsx @@ -28,7 +28,7 @@ import { manageQuery } from '../../../common/components/page/manage_query'; import { FlowTargetSelectConnected } from '../../components/flow_target_select_connected'; import { IpOverview } from '../../components/details'; import { SiemSearchBar } from '../../../common/components/search_bar'; -import { WrapperPage } from '../../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../../common/components/page_wrapper'; import { useNetworkDetails } from '../../containers/details'; import { useKibana } from '../../../common/lib/kibana'; import { decodeIpv6 } from '../../../common/lib/helpers'; @@ -128,7 +128,7 @@ const NetworkDetailsComponent: React.FC = () => { - + { hideHistogramIfEmpty={true} AnomaliesTableComponent={AnomaliesNetworkTable} /> - + ) : ( - + - + )} diff --git a/x-pack/plugins/security_solution/public/network/pages/network.tsx b/x-pack/plugins/security_solution/public/network/pages/network.tsx index 2bcc72d932a9bb..13c04a5e5ec5b7 100644 --- a/x-pack/plugins/security_solution/public/network/pages/network.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/network.tsx @@ -12,6 +12,7 @@ import { useDispatch } from 'react-redux'; import { useParams } from 'react-router-dom'; import styled from 'styled-components'; +import { isTab } from '../../../../timelines/public'; import { esQuery } from '../../../../../../src/plugins/data/public'; import { SecurityPageName } from '../../app/types'; import { UpdateDateRange } from '../../common/components/charts/common'; @@ -19,11 +20,11 @@ import { EmbeddedMap } from '../components/embeddables/embedded_map'; import { FiltersGlobal } from '../../common/components/filters_global'; import { HeaderPage } from '../../common/components/header_page'; import { LastEventTime } from '../../common/components/last_event_time'; -import { SiemNavigation } from '../../common/components/navigation'; +import { SecuritySolutionTabNavigation } from '../../common/components/navigation'; import { NetworkKpiComponent } from '../components/kpi_network'; import { SiemSearchBar } from '../../common/components/search_bar'; -import { WrapperPage } from '../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { useGlobalFullScreen } from '../../common/containers/use_full_screen'; import { useGlobalTime } from '../../common/containers/use_global_time'; import { LastEventIndexKey } from '../../../common/search_strategy'; @@ -46,7 +47,6 @@ import { showGlobalFilters, } from '../../timelines/components/timeline/helpers'; import { timelineSelectors } from '../../timelines/store/timeline'; -import { isTab } from '../../common/components/accessibility/helpers'; import { TimelineId } from '../../../common/types/timeline'; import { timelineDefaults } from '../../timelines/store/timeline/defaults'; import { useSourcererScope } from '../../common/containers/sourcerer'; @@ -155,10 +155,9 @@ const NetworkComponent = React.memo( - + ( - + @@ -217,13 +216,13 @@ const NetworkComponent = React.memo( ) : ( )} - + ) : ( - + - + )} diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx index b43d5af029ec47..45898427ee60b8 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/index.test.tsx @@ -15,6 +15,8 @@ import { TestProviders } from '../../../../common/mock'; import { EndpointOverview } from './index'; import { HostPolicyResponseActionStatus } from '../../../../../common/search_strategy/security_solution/hosts'; +jest.mock('../../../../common/lib/kibana'); + describe('EndpointOverview Component', () => { test('it renders with endpoint data', () => { const endpointData = { diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_host/index.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_host/index.tsx index 70f44a0008cbc4..f11b849f5df6b4 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_host/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_host/index.tsx @@ -115,7 +115,7 @@ const OverviewHostComponent: React.FC = ({ return ( - + <>{hostPageButton} diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx index 107a47f6cc1324..39fb6ff08ee539 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx @@ -120,7 +120,7 @@ const OverviewNetworkComponent: React.FC = ({ return ( - + <> {networkPageButton} diff --git a/x-pack/plugins/security_solution/public/overview/pages/overview.tsx b/x-pack/plugins/security_solution/public/overview/pages/overview.tsx index 4270d8ec164b30..2cf998e5e133a4 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/overview.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/overview.tsx @@ -12,7 +12,7 @@ import styled from 'styled-components'; import { AlertsByCategory } from '../components/alerts_by_category'; import { FiltersGlobal } from '../../common/components/filters_global'; import { SiemSearchBar } from '../../common/components/search_bar'; -import { WrapperPage } from '../../common/components/wrapper_page'; +import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { useGlobalTime } from '../../common/containers/use_global_time'; import { useFetchIndex } from '../../common/containers/source'; @@ -37,6 +37,10 @@ const SidebarFlexItem = styled(EuiFlexItem)` margin-right: 24px; `; +const StyledSecuritySolutionPageWrapper = styled(SecuritySolutionPageWrapper)` + overflow-x: auto; +`; + const OverviewComponent = () => { const getGlobalFiltersQuerySelector = useMemo( () => inputsSelectors.globalFiltersQuerySelector(), @@ -73,7 +77,7 @@ const OverviewComponent = () => { - + {!dismissMessage && !metadataIndexExists && isIngestEnabled && ( <> @@ -139,7 +143,7 @@ const OverviewComponent = () => { - + ) : ( diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index 781ed8ffdaa541..32e6748f38141c 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -6,8 +6,10 @@ */ import { i18n } from '@kbn/i18n'; +import reduceReducers from 'reduce-reducers'; import { BehaviorSubject, Subject, Subscription } from 'rxjs'; import { pluck } from 'rxjs/operators'; +import { AnyAction, Reducer } from 'redux'; import { PluginSetup, PluginStart, @@ -59,7 +61,7 @@ import { DETECTION_ENGINE, CASE, ADMINISTRATION, -} from './app/home/translations'; +} from './app/translations'; import { IndexFieldsStrategyRequest, IndexFieldsStrategyResponse, @@ -72,6 +74,7 @@ import { getLazyEndpointPolicyEditExtension } from './management/pages/policy/vi import { LazyEndpointPolicyCreateExtension } from './management/pages/policy/view/ingest_manager_integration/lazy_endpoint_policy_create_extension'; import { getLazyEndpointPackageCustomExtension } from './management/pages/policy/view/ingest_manager_integration/lazy_endpoint_package_custom_extension'; import { parseExperimentalConfigValue } from '../common/experimental_features'; +import type { TimelineState } from '../../timelines/public'; export class Plugin implements IPlugin { private kibanaVersion: string; @@ -471,7 +474,7 @@ export class Plugin implements IPlugin( { indices: defaultIndicesName, onlyCheckIfIndicesExist: true }, { - strategy: 'securitySolutionIndexFields', + strategy: 'indexFields', } ) .toPromise(), @@ -500,7 +503,6 @@ export class Plugin implements IPlugin; + this._store = createStore( createInitialState( { @@ -531,13 +540,17 @@ export class Plugin implements IPlugin - +
- + + + +
+ + ); +}; + +export const testTrailingControlColumns = [ + { + id: 'actions', + width: 96, + headerCellRender: SimpleHeaderCell, + rowCellRender: TestTrailingColumn, + }, +]; + +export const testLeadingControlColumn: ControlColumnProps = { + id: 'test-leading-control', + headerCellRender: SelectionHeaderCell, + rowCellRender: SelectionRowCell, + width: 100, +}; diff --git a/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts b/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts new file mode 100644 index 00000000000000..63f807d6d19db6 --- /dev/null +++ b/x-pack/plugins/timelines/public/mock/mock_timeline_data.ts @@ -0,0 +1,1511 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Ecs } from '../../common/ecs'; +import type { TimelineItem } from '../../common/search_strategy'; + +export const mockTimelineData: TimelineItem[] = [ + { + _id: '1', + data: [ + { field: '@timestamp', value: ['2018-11-05T19:03:25.937Z'] }, + { field: 'event.severity', value: ['3'] }, + { field: 'event.category', value: ['Access'] }, + { field: 'event.action', value: ['Action'] }, + { field: 'host.name', value: ['apache'] }, + { field: 'source.ip', value: ['192.168.0.1'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['john.dee'] }, + ], + ecs: { + _id: '1', + timestamp: '2018-11-05T19:03:25.937Z', + host: { name: ['apache'], ip: ['192.168.0.1'] }, + event: { + id: ['1'], + action: ['Action'], + category: ['Access'], + module: ['nginx'], + severity: [3], + }, + source: { ip: ['192.168.0.1'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['1'], name: ['john.dee'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '3', + data: [ + { field: '@timestamp', value: ['2018-11-07T19:03:25.937Z'] }, + { field: 'event.severity', value: ['1'] }, + { field: 'event.category', value: ['Access'] }, + { field: 'host.name', value: ['nginx'] }, + { field: 'source.ip', value: ['192.168.0.3'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['evan.davis'] }, + ], + ecs: { + _id: '3', + timestamp: '2018-11-07T19:03:25.937Z', + host: { name: ['nginx'], ip: ['192.168.0.1'] }, + event: { + id: ['3'], + category: ['Access'], + type: ['HTTP Request'], + module: ['nginx'], + severity: [1], + }, + source: { ip: ['192.168.0.3'], port: [443] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['3'], name: ['evan.davis'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '4', + data: [ + { field: '@timestamp', value: ['2018-11-08T19:03:25.937Z'] }, + { field: 'event.severity', value: ['1'] }, + { field: 'event.category', value: ['Attempted Administrator Privilege Gain'] }, + { field: 'host.name', value: ['suricata'] }, + { field: 'source.ip', value: ['192.168.0.3'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['jenny.jones'] }, + ], + ecs: { + _id: '4', + timestamp: '2018-11-08T19:03:25.937Z', + host: { name: ['suricata'], ip: ['192.168.0.1'] }, + event: { + id: ['4'], + category: ['Attempted Administrator Privilege Gain'], + type: ['Alert'], + module: ['suricata'], + severity: [1], + }, + source: { ip: ['192.168.0.3'], port: [53] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + suricata: { + eve: { + flow_id: [4], + proto: [''], + alert: { + signature: [ + 'ET EXPLOIT NETGEAR WNR2000v5 hidden_lang_avi Stack Overflow (CVE-2016-10174)', + ], + signature_id: [4], + }, + }, + }, + user: { id: ['4'], name: ['jenny.jones'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '5', + data: [ + { field: '@timestamp', value: ['2018-11-09T19:03:25.937Z'] }, + { field: 'event.severity', value: ['3'] }, + { field: 'event.category', value: ['Access'] }, + { field: 'host.name', value: ['joe.computer'] }, + { field: 'source.ip', value: ['192.168.0.3'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['becky.davis'] }, + ], + ecs: { + _id: '5', + timestamp: '2018-11-09T19:03:25.937Z', + host: { name: ['joe.computer'], ip: ['192.168.0.1'] }, + event: { + id: ['5'], + category: ['Access'], + type: ['HTTP Request'], + module: ['nginx'], + severity: [3], + }, + source: { ip: ['192.168.0.3'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['5'], name: ['becky.davis'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '6', + data: [ + { field: '@timestamp', value: ['2018-11-10T19:03:25.937Z'] }, + { field: 'event.severity', value: ['3'] }, + { field: 'event.category', value: ['Access'] }, + { field: 'host.name', value: ['braden.davis'] }, + { field: 'source.ip', value: ['192.168.0.6'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + ], + ecs: { + _id: '6', + timestamp: '2018-11-10T19:03:25.937Z', + host: { name: ['braden.davis'], ip: ['192.168.0.1'] }, + event: { + id: ['6'], + category: ['Access'], + type: ['HTTP Request'], + module: ['nginx'], + severity: [3], + }, + source: { ip: ['192.168.0.6'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '8', + data: [ + { field: '@timestamp', value: ['2018-11-12T19:03:25.937Z'] }, + { field: 'event.severity', value: ['2'] }, + { field: 'event.category', value: ['Web Application Attack'] }, + { field: 'host.name', value: ['joe.computer'] }, + { field: 'source.ip', value: ['192.168.0.8'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['jone.doe'] }, + ], + ecs: { + _id: '8', + timestamp: '2018-11-12T19:03:25.937Z', + host: { name: ['joe.computer'], ip: ['192.168.0.1'] }, + event: { + id: ['8'], + category: ['Web Application Attack'], + type: ['Alert'], + module: ['suricata'], + severity: [2], + }, + suricata: { + eve: { + flow_id: [8], + proto: [''], + alert: { + signature: ['ET WEB_SERVER Possible CVE-2014-6271 Attempt in HTTP Cookie'], + signature_id: [8], + }, + }, + }, + source: { ip: ['192.168.0.8'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['8'], name: ['jone.doe'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '7', + data: [ + { field: '@timestamp', value: ['2018-11-11T19:03:25.937Z'] }, + { field: 'event.severity', value: ['3'] }, + { field: 'event.category', value: ['Access'] }, + { field: 'host.name', value: ['joe.computer'] }, + { field: 'source.ip', value: ['192.168.0.7'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['jone.doe'] }, + ], + ecs: { + _id: '7', + timestamp: '2018-11-11T19:03:25.937Z', + host: { name: ['joe.computer'], ip: ['192.168.0.1'] }, + event: { + id: ['7'], + category: ['Access'], + type: ['HTTP Request'], + module: ['apache'], + severity: [3], + }, + source: { ip: ['192.168.0.7'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['7'], name: ['jone.doe'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '9', + data: [ + { field: '@timestamp', value: ['2018-11-13T19:03:25.937Z'] }, + { field: 'event.severity', value: ['3'] }, + { field: 'event.category', value: ['Access'] }, + { field: 'host.name', value: ['joe.computer'] }, + { field: 'source.ip', value: ['192.168.0.9'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['jone.doe'] }, + ], + ecs: { + _id: '9', + timestamp: '2018-11-13T19:03:25.937Z', + host: { name: ['joe.computer'], ip: ['192.168.0.1'] }, + event: { + id: ['9'], + category: ['Access'], + type: ['HTTP Request'], + module: ['nginx'], + severity: [3], + }, + source: { ip: ['192.168.0.9'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['9'], name: ['jone.doe'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '10', + data: [ + { field: '@timestamp', value: ['2018-11-14T19:03:25.937Z'] }, + { field: 'event.severity', value: ['3'] }, + { field: 'event.category', value: ['Access'] }, + { field: 'host.name', value: ['joe.computer'] }, + { field: 'source.ip', value: ['192.168.0.10'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['jone.doe'] }, + ], + ecs: { + _id: '10', + timestamp: '2018-11-14T19:03:25.937Z', + host: { name: ['joe.computer'], ip: ['192.168.0.1'] }, + event: { + id: ['10'], + category: ['Access'], + type: ['HTTP Request'], + module: ['nginx'], + severity: [3], + }, + source: { ip: ['192.168.0.10'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['10'], name: ['jone.doe'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '11', + data: [ + { field: '@timestamp', value: ['2018-11-15T19:03:25.937Z'] }, + { field: 'event.severity', value: ['3'] }, + { field: 'event.category', value: ['Access'] }, + { field: 'host.name', value: ['joe.computer'] }, + { field: 'source.ip', value: ['192.168.0.11'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['jone.doe'] }, + ], + ecs: { + _id: '11', + timestamp: '2018-11-15T19:03:25.937Z', + host: { name: ['joe.computer'], ip: ['192.168.0.1'] }, + event: { + id: ['11'], + category: ['Access'], + type: ['HTTP Request'], + module: ['nginx'], + severity: [3], + }, + source: { ip: ['192.168.0.11'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['11'], name: ['jone.doe'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '12', + data: [ + { field: '@timestamp', value: ['2018-11-16T19:03:25.937Z'] }, + { field: 'event.severity', value: ['3'] }, + { field: 'event.category', value: ['Access'] }, + { field: 'host.name', value: ['joe.computer'] }, + { field: 'source.ip', value: ['192.168.0.12'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['jone.doe'] }, + ], + ecs: { + _id: '12', + timestamp: '2018-11-16T19:03:25.937Z', + host: { name: ['joe.computer'], ip: ['192.168.0.1'] }, + event: { + id: ['12'], + category: ['Access'], + type: ['HTTP Request'], + module: ['nginx'], + severity: [3], + }, + source: { ip: ['192.168.0.12'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['12'], name: ['jone.doe'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '2', + data: [ + { field: '@timestamp', value: ['2018-11-06T19:03:25.937Z'] }, + { field: 'event.severity', value: ['3'] }, + { field: 'event.category', value: ['Authentication'] }, + { field: 'host.name', value: ['joe.computer'] }, + { field: 'source.ip', value: ['192.168.0.2'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['joe.bob'] }, + ], + ecs: { + _id: '2', + timestamp: '2018-11-06T19:03:25.937Z', + host: { name: ['joe.computer'], ip: ['192.168.0.1'] }, + event: { + id: ['2'], + category: ['Authentication'], + type: ['Authentication Success'], + module: ['authlog'], + severity: [3], + }, + source: { ip: ['192.168.0.2'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['1'], name: ['joe.bob'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '13', + data: [ + { field: '@timestamp', value: ['2018-13-12T19:03:25.937Z'] }, + { field: 'event.severity', value: ['1'] }, + { field: 'event.category', value: ['Web Application Attack'] }, + { field: 'host.name', value: ['joe.computer'] }, + { field: 'source.ip', value: ['192.168.0.8'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + ], + ecs: { + _id: '13', + timestamp: '2018-13-12T19:03:25.937Z', + host: { name: ['joe.computer'], ip: ['192.168.0.1'] }, + event: { + id: ['13'], + category: ['Web Application Attack'], + type: ['Alert'], + module: ['suricata'], + severity: [1], + }, + suricata: { + eve: { + flow_id: [13], + proto: [''], + alert: { + signature: ['ET WEB_SERVER Possible Attempt in HTTP Cookie'], + signature_id: [13], + }, + }, + }, + source: { ip: ['192.168.0.8'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '14', + data: [ + { field: '@timestamp', value: ['2019-03-07T05:06:51.000Z'] }, + { field: 'host.name', value: ['zeek-franfurt'] }, + { field: 'source.ip', value: ['192.168.26.101'] }, + { field: 'destination.ip', value: ['192.168.238.205'] }, + ], + ecs: { + _id: '14', + timestamp: '2019-03-07T05:06:51.000Z', + event: { + module: ['zeek'], + dataset: ['zeek.connection'], + }, + host: { + id: ['37c81253e0fc4c46839c19b981be5177'], + name: ['zeek-franfurt'], + ip: ['207.154.238.205', '10.19.0.5', 'fe80::d82b:9aff:fe0d:1e12'], + }, + source: { ip: ['185.176.26.101'], port: [44059] }, + destination: { ip: ['207.154.238.205'], port: [11568] }, + geo: { region_name: ['New York'], country_iso_code: ['US'] }, + network: { transport: ['tcp'] }, + zeek: { + session_id: ['C8DRTq362Fios6hw16'], + connection: { + local_resp: [false], + local_orig: [false], + missed_bytes: [0], + state: ['REJ'], + history: ['Sr'], + }, + }, + }, + }, + { + _id: '15', + data: [ + { field: '@timestamp', value: ['2019-03-07T00:51:28.000Z'] }, + { field: 'host.name', value: ['suricata-zeek-singapore'] }, + { field: 'source.ip', value: ['192.168.35.240'] }, + { field: 'destination.ip', value: ['192.168.67.3'] }, + ], + ecs: { + _id: '15', + timestamp: '2019-03-07T00:51:28.000Z', + event: { + module: ['zeek'], + dataset: ['zeek.dns'], + }, + host: { + id: ['af3fddf15f1d47979ce817ba0df10c6e'], + name: ['suricata-zeek-singapore'], + ip: ['206.189.35.240', '10.15.0.5', 'fe80::98c7:eff:fe29:4455'], + }, + source: { ip: ['206.189.35.240'], port: [57475] }, + destination: { ip: ['67.207.67.3'], port: [53] }, + geo: { region_name: ['New York'], country_iso_code: ['US'] }, + network: { transport: ['udp'] }, + zeek: { + session_id: ['CyIrMA1L1JtLqdIuol'], + dns: { + AA: [false], + RD: [false], + trans_id: [65252], + RA: [false], + TC: [false], + }, + }, + }, + }, + { + _id: '16', + data: [ + { field: '@timestamp', value: ['2019-03-05T07:00:20.000Z'] }, + { field: 'host.name', value: ['suricata-zeek-singapore'] }, + { field: 'source.ip', value: ['192.168.35.240'] }, + { field: 'destination.ip', value: ['192.168.164.26'] }, + ], + ecs: { + _id: '16', + timestamp: '2019-03-05T07:00:20.000Z', + event: { + module: ['zeek'], + dataset: ['zeek.http'], + }, + host: { + id: ['af3fddf15f1d47979ce817ba0df10c6e'], + name: ['suricata-zeek-singapore'], + ip: ['206.189.35.240', '10.15.0.5', 'fe80::98c7:eff:fe29:4455'], + }, + source: { ip: ['206.189.35.240'], port: [36220] }, + destination: { ip: ['192.241.164.26'], port: [80] }, + geo: { region_name: ['New York'], country_iso_code: ['US'] }, + http: { + version: ['1.1'], + request: { body: { bytes: [0] } }, + response: { status_code: [302], body: { bytes: [154] } }, + }, + zeek: { + session_id: ['CZLkpC22NquQJOpkwe'], + + http: { + resp_mime_types: ['text/html'], + trans_depth: ['3'], + status_msg: ['Moved Temporarily'], + resp_fuids: ['FzeujEPP7GTHmYPsc'], + tags: [], + }, + }, + }, + }, + { + _id: '17', + data: [ + { field: '@timestamp', value: ['2019-02-28T22:36:28.000Z'] }, + { field: 'host.name', value: ['zeek-franfurt'] }, + { field: 'source.ip', value: ['192.168.77.171'] }, + ], + ecs: { + _id: '17', + timestamp: '2019-02-28T22:36:28.000Z', + event: { + module: ['zeek'], + dataset: ['zeek.notice'], + }, + host: { + id: ['37c81253e0fc4c46839c19b981be5177'], + name: ['zeek-franfurt'], + ip: ['207.154.238.205', '10.19.0.5', 'fe80::d82b:9aff:fe0d:1e12'], + }, + source: { ip: ['8.42.77.171'] }, + zeek: { + notice: { + suppress_for: [3600], + msg: ['8.42.77.171 scanned at least 15 unique ports of host 207.154.238.205 in 0m0s'], + note: ['Scan::Port_Scan'], + sub: ['remote'], + dst: ['207.154.238.205'], + dropped: [false], + peer_descr: ['bro'], + }, + }, + }, + }, + { + _id: '18', + data: [ + { field: '@timestamp', value: ['2019-02-22T21:12:13.000Z'] }, + { field: 'host.name', value: ['zeek-sensor-amsterdam'] }, + { field: 'source.ip', value: ['192.168.66.184'] }, + { field: 'destination.ip', value: ['192.168.95.15'] }, + ], + ecs: { + _id: '18', + timestamp: '2019-02-22T21:12:13.000Z', + event: { + module: ['zeek'], + dataset: ['zeek.ssl'], + }, + host: { id: ['2ce8b1e7d69e4a1d9c6bcddc473da9d9'], name: ['zeek-sensor-amsterdam'] }, + source: { ip: ['188.166.66.184'], port: [34514] }, + destination: { ip: ['91.189.95.15'], port: [443] }, + geo: { region_name: ['England'], country_iso_code: ['GB'] }, + zeek: { + session_id: ['CmTxzt2OVXZLkGDaRe'], + ssl: { + cipher: ['TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'], + established: [false], + resumed: [false], + version: ['TLSv12'], + }, + }, + }, + }, + { + _id: '19', + data: [ + { field: '@timestamp', value: ['2019-03-03T04:26:38.000Z'] }, + { field: 'host.name', value: ['suricata-zeek-singapore'] }, + ], + ecs: { + _id: '19', + timestamp: '2019-03-03T04:26:38.000Z', + event: { + module: ['zeek'], + dataset: ['zeek.files'], + }, + host: { + id: ['af3fddf15f1d47979ce817ba0df10c6e'], + name: ['suricata-zeek-singapore'], + ip: ['206.189.35.240', '10.15.0.5', 'fe80::98c7:eff:fe29:4455'], + }, + zeek: { + session_id: ['Cu0n232QMyvNtzb75j'], + files: { + session_ids: ['Cu0n232QMyvNtzb75j'], + timedout: [false], + local_orig: [false], + tx_host: ['5.101.111.50'], + source: ['HTTP'], + is_orig: [false], + overflow_bytes: [0], + sha1: ['fa5195a5dfacc9d1c68d43600f0e0262cad14dde'], + duration: [0], + depth: [0], + analyzers: ['MD5', 'SHA1'], + mime_type: ['text/plain'], + rx_host: ['206.189.35.240'], + total_bytes: [88722], + fuid: ['FePz1uVEVCZ3I0FQi'], + seen_bytes: [1198], + missing_bytes: [0], + md5: ['f7653f1951693021daa9e6be61226e32'], + }, + }, + }, + }, + { + _id: '20', + data: [ + { field: '@timestamp', value: ['2019-03-13T05:42:11.815Z'] }, + { field: 'event.category', value: ['audit-rule'] }, + { field: 'host.name', value: ['zeek-sanfran'] }, + ], + ecs: { + _id: '20', + timestamp: '2019-03-13T05:42:11.815Z', + event: { + action: ['executed'], + module: ['auditd'], + category: ['audit-rule'], + }, + host: { + id: ['f896741c3b3b44bdb8e351a4ab6d2d7c'], + name: ['zeek-sanfran'], + ip: ['134.209.63.134', '10.46.0.5', 'fe80::a0d9:16ff:fecf:e70b'], + }, + user: { name: ['alice'] }, + process: { + pid: [5402], + name: ['gpgconf'], + ppid: [5401], + args: ['gpgconf', '--list-dirs', 'agent-socket'], + executable: ['/usr/bin/gpgconf'], + title: ['gpgconf --list-dirs agent-socket'], + working_directory: ['/'], + }, + }, + }, + { + _id: '21', + data: [ + { field: '@timestamp', value: ['2019-03-14T22:30:25.527Z'] }, + { field: 'event.category', value: ['user-login'] }, + { field: 'host.name', value: ['zeek-london'] }, + { field: 'source.ip', value: ['192.168.77.171'] }, + { field: 'user.name', value: ['root'] }, + ], + ecs: { + _id: '21', + timestamp: '2019-03-14T22:30:25.527Z', + event: { + action: ['logged-in'], + module: ['auditd'], + category: ['user-login'], + }, + auditd: { + result: ['success'], + session: ['14'], + data: { terminal: ['/dev/pts/0'], op: ['login'] }, + summary: { + actor: { primary: ['alice'], secondary: ['alice'] }, + object: { primary: ['/dev/pts/0'], secondary: ['8.42.77.171'], type: ['user-session'] }, + how: ['/usr/sbin/sshd'], + }, + }, + host: { + id: ['7c21f5ed03b04d0299569d221fe18bbc'], + name: ['zeek-london'], + ip: ['46.101.3.136', '10.16.0.5', 'fe80::4066:42ff:fe19:b3b9'], + }, + source: { ip: ['8.42.77.171'] }, + user: { name: ['root'] }, + process: { + pid: [17471], + executable: ['/usr/sbin/sshd'], + }, + }, + }, + { + _id: '22', + data: [ + { field: '@timestamp', value: ['2019-03-13T03:35:21.614Z'] }, + { field: 'event.category', value: ['user-login'] }, + { field: 'host.name', value: ['suricata-bangalore'] }, + { field: 'user.name', value: ['root'] }, + ], + ecs: { + _id: '22', + timestamp: '2019-03-13T03:35:21.614Z', + event: { + action: ['disposed-credentials'], + module: ['auditd'], + category: ['user-login'], + }, + auditd: { + result: ['success'], + session: ['340'], + data: { acct: ['alice'], terminal: ['ssh'], op: ['PAM:setcred'] }, + summary: { + actor: { primary: ['alice'], secondary: ['alice'] }, + object: { primary: ['ssh'], secondary: ['8.42.77.171'], type: ['user-session'] }, + how: ['/usr/sbin/sshd'], + }, + }, + host: { + id: ['0a63559c1acf4c419d979c4b4d8b83ff'], + name: ['suricata-bangalore'], + ip: ['139.59.11.147', '10.47.0.5', 'fe80::ec0b:1bff:fe29:80bd'], + }, + user: { name: ['root'] }, + process: { + pid: [21202], + executable: ['/usr/sbin/sshd'], + }, + }, + }, + { + _id: '23', + data: [ + { field: '@timestamp', value: ['2019-03-13T03:35:21.614Z'] }, + { field: 'event.category', value: ['user-login'] }, + { field: 'host.name', value: ['suricata-bangalore'] }, + { field: 'user.name', value: ['root'] }, + ], + ecs: { + _id: '23', + timestamp: '2019-03-13T03:35:21.614Z', + event: { + action: ['ended-session'], + module: ['auditd'], + category: ['user-login'], + }, + auditd: { + result: ['success'], + session: ['340'], + data: { acct: ['alice'], terminal: ['ssh'], op: ['PAM:session_close'] }, + summary: { + actor: { primary: ['alice'], secondary: ['alice'] }, + object: { primary: ['ssh'], secondary: ['8.42.77.171'], type: ['user-session'] }, + how: ['/usr/sbin/sshd'], + }, + }, + host: { + id: ['0a63559c1acf4c419d979c4b4d8b83ff'], + name: ['suricata-bangalore'], + ip: ['139.59.11.147', '10.47.0.5', 'fe80::ec0b:1bff:fe29:80bd'], + }, + user: { name: ['root'] }, + process: { + pid: [21202], + executable: ['/usr/sbin/sshd'], + }, + }, + }, + { + _id: '24', + data: [ + { field: '@timestamp', value: ['2019-03-18T23:17:01.645Z'] }, + { field: 'event.category', value: ['user-login'] }, + { field: 'host.name', value: ['zeek-london'] }, + { field: 'user.name', value: ['root'] }, + ], + ecs: { + _id: '24', + timestamp: '2019-03-18T23:17:01.645Z', + event: { + action: ['acquired-credentials'], + module: ['auditd'], + category: ['user-login'], + }, + auditd: { + result: ['success'], + session: ['unset'], + data: { acct: ['root'], terminal: ['cron'], op: ['PAM:setcred'] }, + summary: { + actor: { primary: ['unset'], secondary: ['root'] }, + object: { primary: ['cron'], type: ['user-session'] }, + how: ['/usr/sbin/cron'], + }, + }, + host: { + id: ['7c21f5ed03b04d0299569d221fe18bbc'], + name: ['zeek-london'], + ip: ['46.101.3.136', '10.16.0.5', 'fe80::4066:42ff:fe19:b3b9'], + }, + user: { name: ['root'] }, + process: { + pid: [9592], + executable: ['/usr/sbin/cron'], + }, + }, + }, + { + _id: '25', + data: [ + { field: '@timestamp', value: ['2019-03-19T01:17:01.336Z'] }, + { field: 'event.category', value: ['user-login'] }, + { field: 'host.name', value: ['siem-kibana'] }, + { field: 'user.name', value: ['root'] }, + ], + ecs: { + _id: '25', + timestamp: '2019-03-19T01:17:01.336Z', + event: { + action: ['started-session'], + module: ['auditd'], + category: ['user-login'], + }, + auditd: { + result: ['success'], + session: ['2908'], + data: { acct: ['root'], terminal: ['cron'], op: ['PAM:session_open'] }, + summary: { + actor: { primary: ['root'], secondary: ['root'] }, + object: { primary: ['cron'], type: ['user-session'] }, + how: ['/usr/sbin/cron'], + }, + }, + host: { id: ['aa7ca589f1b8220002f2fc61c64cfbf1'], name: ['siem-kibana'] }, + user: { name: ['root'] }, + process: { + pid: [725], + executable: ['/usr/sbin/cron'], + }, + }, + }, + { + _id: '26', + data: [ + { field: '@timestamp', value: ['2019-03-13T03:34:08.890Z'] }, + { field: 'event.category', value: ['user-login'] }, + { field: 'host.name', value: ['suricata-bangalore'] }, + { field: 'user.name', value: ['alice'] }, + ], + ecs: { + _id: '26', + timestamp: '2019-03-13T03:34:08.890Z', + event: { + action: ['was-authorized'], + module: ['auditd'], + category: ['user-login'], + }, + auditd: { + result: ['success'], + session: ['338'], + data: { terminal: ['/dev/pts/0'] }, + summary: { + actor: { primary: ['root'], secondary: ['alice'] }, + object: { primary: ['/dev/pts/0'], type: ['user-session'] }, + how: ['/sbin/pam_tally2'], + }, + }, + host: { + id: ['0a63559c1acf4c419d979c4b4d8b83ff'], + name: ['suricata-bangalore'], + ip: ['139.59.11.147', '10.47.0.5', 'fe80::ec0b:1bff:fe29:80bd'], + }, + user: { name: ['alice'] }, + process: { + pid: [21170], + executable: ['/sbin/pam_tally2'], + }, + }, + }, + { + _id: '27', + data: [ + { field: '@timestamp', value: ['2019-03-22T19:13:11.026Z'] }, + { field: 'event.action', value: ['connected-to'] }, + { field: 'event.category', value: ['audit-rule'] }, + { field: 'host.name', value: ['zeek-london'] }, + { field: 'destination.ip', value: ['192.168.216.34'] }, + { field: 'user.name', value: ['alice'] }, + ], + ecs: { + _id: '27', + timestamp: '2019-03-22T19:13:11.026Z', + event: { + action: ['connected-to'], + module: ['auditd'], + category: ['audit-rule'], + }, + auditd: { + result: ['success'], + session: ['246'], + summary: { + actor: { primary: ['alice'], secondary: ['alice'] }, + object: { primary: ['192.168.216.34'], secondary: ['80'], type: ['socket'] }, + how: ['/usr/bin/wget'], + }, + }, + host: { + id: ['7c21f5ed03b04d0299569d221fe18bbc'], + name: ['zeek-london'], + ip: ['46.101.3.136', '10.16.0.5', 'fe80::4066:42ff:fe19:b3b9'], + }, + destination: { ip: ['192.168.216.34'], port: [80] }, + user: { name: ['alice'] }, + process: { + pid: [1490], + name: ['wget'], + ppid: [1476], + executable: ['/usr/bin/wget'], + title: ['wget www.example.com'], + }, + }, + }, + { + _id: '28', + data: [ + { field: '@timestamp', value: ['2019-03-26T22:12:18.609Z'] }, + { field: 'event.action', value: ['opened-file'] }, + { field: 'event.category', value: ['audit-rule'] }, + { field: 'host.name', value: ['zeek-london'] }, + { field: 'user.name', value: ['root'] }, + ], + ecs: { + _id: '28', + timestamp: '2019-03-26T22:12:18.609Z', + event: { + action: ['opened-file'], + module: ['auditd'], + category: ['audit-rule'], + }, + auditd: { + result: ['success'], + session: ['242'], + summary: { + actor: { primary: ['unset'], secondary: ['root'] }, + object: { primary: ['/proc/15990/attr/current'], type: ['file'] }, + how: ['/lib/systemd/systemd-journald'], + }, + }, + file: { + path: ['/proc/15990/attr/current'], + device: ['00:00'], + inode: ['27672309'], + uid: ['0'], + owner: ['root'], + gid: ['0'], + group: ['root'], + mode: ['0666'], + }, + host: { + id: ['7c21f5ed03b04d0299569d221fe18bbc'], + name: ['zeek-london'], + ip: ['46.101.3.136', '10.16.0.5', 'fe80::4066:42ff:fe19:b3b9'], + }, + + user: { name: ['root'] }, + process: { + pid: [27244], + name: ['systemd-journal'], + ppid: [1], + executable: ['/lib/systemd/systemd-journald'], + title: ['/lib/systemd/systemd-journald'], + working_directory: ['/'], + }, + }, + }, + { + _id: '29', + data: [ + { field: '@timestamp', value: ['2019-04-08T21:18:57.000Z'] }, + { field: 'event.action', value: ['user_login'] }, + { field: 'event.category', value: null }, + { field: 'host.name', value: ['zeek-london'] }, + { field: 'user.name', value: ['Braden'] }, + ], + ecs: { + _id: '29', + event: { + action: ['user_login'], + dataset: ['login'], + kind: ['event'], + module: ['system'], + outcome: ['failure'], + }, + host: { + id: ['7c21f5ed03b04d0299569d221fe18bbc'], + name: ['zeek-london'], + ip: ['46.101.3.136', '10.16.0.5', 'fe80::4066:42ff:fe19:b3b9'], + }, + source: { + ip: ['128.199.212.120'], + }, + user: { + name: ['Braden'], + }, + process: { + pid: [6278], + }, + }, + }, + { + _id: '30', + data: [ + { field: '@timestamp', value: ['2019-04-08T22:27:14.814Z'] }, + { field: 'event.action', value: ['process_started'] }, + { field: 'event.category', value: null }, + { field: 'host.name', value: ['zeek-london'] }, + { field: 'user.name', value: ['Evan'] }, + ], + ecs: { + _id: '30', + event: { + action: ['process_started'], + dataset: ['login'], + kind: ['event'], + module: ['system'], + outcome: ['failure'], + }, + host: { + id: ['7c21f5ed03b04d0299569d221fe18bbc'], + name: ['zeek-london'], + ip: ['46.101.3.136', '10.16.0.5', 'fe80::4066:42ff:fe19:b3b9'], + }, + source: { + ip: ['128.199.212.120'], + }, + user: { + name: ['Evan'], + }, + process: { + pid: [6278], + }, + }, + }, + { + _id: '31', + data: [ + { field: '@timestamp', value: ['2018-11-05T19:03:25.937Z'] }, + { field: 'message', value: ['I am a log file message'] }, + { field: 'event.severity', value: ['3'] }, + { field: 'event.category', value: ['Access'] }, + { field: 'event.action', value: ['Action'] }, + { field: 'host.name', value: ['apache'] }, + { field: 'source.ip', value: ['192.168.0.1'] }, + { field: 'destination.ip', value: ['192.168.0.3'] }, + { field: 'destination.bytes', value: ['123456'] }, + { field: 'user.name', value: ['john.dee'] }, + ], + ecs: { + _id: '1', + timestamp: '2018-11-05T19:03:25.937Z', + host: { name: ['apache'], ip: ['192.168.0.1'] }, + event: { + id: ['1'], + action: ['Action'], + category: ['Access'], + module: ['nginx'], + severity: [3], + }, + message: ['I am a log file message'], + source: { ip: ['192.168.0.1'], port: [80] }, + destination: { ip: ['192.168.0.3'], port: [6343] }, + user: { id: ['1'], name: ['john.dee'] }, + geo: { region_name: ['xx'], country_iso_code: ['xx'] }, + }, + }, + { + _id: '32', + data: [], + ecs: { + _id: 'BuBP4W0BOpWiDweSoYSg', + timestamp: '2019-10-18T23:59:15.091Z', + threat: { + indicator: [ + { + matched: { + atomic: ['192.168.1.1'], + field: ['source.ip'], + type: ['ip'], + }, + event: { + dataset: ['threatintel.example_dataset'], + reference: ['https://example.com'], + }, + provider: ['indicator_provider'], + }, + ], + }, + }, + }, +]; + +export const mockFimFileCreatedEvent: Ecs = { + _id: 'WuBP4W0BOpWiDweSoYSg', + timestamp: '2019-10-18T23:59:15.091Z', + host: { + architecture: ['x86_64'], + os: { + family: ['debian'], + name: ['Ubuntu'], + kernel: ['4.15.0-1046-gcp'], + platform: ['ubuntu'], + version: ['16.04.6 LTS (Xenial Xerus)'], + }, + id: ['host-id-123'], + name: ['foohost'], + }, + file: { + path: ['/etc/subgid'], + size: [4445], + owner: ['root'], + inode: ['90027'], + ctime: ['2019-10-18T23:59:14.872Z'], + gid: ['0'], + type: ['file'], + mode: ['0644'], + mtime: ['2019-10-18T23:59:14.872Z'], + uid: ['0'], + group: ['root'], + }, + event: { + module: ['file_integrity'], + dataset: ['file'], + action: ['created'], + }, +}; + +export const mockFimFileDeletedEvent: Ecs = { + _id: 'M-BP4W0BOpWiDweSo4cm', + timestamp: '2019-10-18T23:59:16.247Z', + host: { + name: ['foohost'], + os: { + platform: ['ubuntu'], + version: ['16.04.6 LTS (Xenial Xerus)'], + family: ['debian'], + name: ['Ubuntu'], + kernel: ['4.15.0-1046-gcp'], + }, + id: ['host-id-123'], + architecture: ['x86_64'], + }, + event: { + module: ['file_integrity'], + dataset: ['file'], + action: ['deleted'], + }, + file: { + path: ['/etc/gshadow.lock'], + }, +}; + +export const mockSocketOpenedEvent: Ecs = { + _id: 'Vusu4m0BOpWiDweSLkXY', + timestamp: '2019-10-19T04:02:19.473Z', + network: { + direction: ['outbound'], + transport: ['tcp'], + community_id: ['1:network-community_id'], + }, + host: { + name: ['foohost'], + architecture: ['x86_64'], + os: { + platform: ['centos'], + version: ['7 (Core)'], + family: ['redhat'], + name: ['CentOS Linux'], + kernel: ['3.10.0-1062.1.2.el7.x86_64'], + }, + id: ['host-id-123'], + }, + process: { + pid: [2166], + name: ['google_accounts'], + }, + destination: { + ip: ['10.1.2.3'], + port: [80], + }, + user: { + name: ['root'], + }, + source: { + port: [59554], + ip: ['10.4.20.1'], + }, + event: { + action: ['socket_opened'], + module: ['system'], + dataset: ['socket'], + kind: ['event'], + }, + message: [ + 'Outbound socket (10.4.20.1:59554 -> 10.1.2.3:80) OPENED by process google_accounts (PID: 2166) and user root (UID: 0)', + ], +}; + +export const mockSocketClosedEvent: Ecs = { + _id: 'V-su4m0BOpWiDweSLkXY', + timestamp: '2019-10-19T04:02:19.473Z', + process: { + pid: [2166], + name: ['google_accounts'], + }, + user: { + name: ['root'], + }, + source: { + port: [59508], + ip: ['10.4.20.1'], + }, + event: { + dataset: ['socket'], + kind: ['event'], + action: ['socket_closed'], + module: ['system'], + }, + message: [ + 'Outbound socket (10.4.20.1:59508 -> 10.1.2.3:80) CLOSED by process google_accounts (PID: 2166) and user root (UID: 0)', + ], + network: { + community_id: ['1:network-community_id'], + direction: ['outbound'], + transport: ['tcp'], + }, + destination: { + ip: ['10.1.2.3'], + port: [80], + }, + host: { + name: ['foohost'], + architecture: ['x86_64'], + os: { + version: ['7 (Core)'], + family: ['redhat'], + name: ['CentOS Linux'], + kernel: ['3.10.0-1062.1.2.el7.x86_64'], + platform: ['centos'], + }, + id: ['host-id-123'], + }, +}; + +export const mockDnsEvent: Ecs = { + _id: 'VUTUqm0BgJt5sZM7nd5g', + destination: { + domain: ['ten.one.one.one'], + port: [53], + bytes: [137], + ip: ['10.1.1.1'], + geo: { + continent_name: ['Oceania'], + location: { + lat: [-33.494], + lon: [143.2104], + }, + country_iso_code: ['AU'], + country_name: ['Australia'], + city_name: [''], + }, + }, + host: { + architecture: ['armv7l'], + id: ['host-id'], + os: { + family: ['debian'], + platform: ['raspbian'], + version: ['9 (stretch)'], + name: ['Raspbian GNU/Linux'], + kernel: ['4.19.57-v7+'], + }, + name: ['iot.example.com'], + }, + dns: { + question: { + name: ['lookup.example.com'], + type: ['A'], + }, + response_code: ['NOERROR'], + resolved_ip: ['10.1.2.3'], + }, + timestamp: '2019-10-08T10:05:23.241Z', + network: { + community_id: ['1:network-community_id'], + direction: ['outbound'], + bytes: [177], + transport: ['udp'], + protocol: ['dns'], + }, + event: { + duration: [6937500], + category: ['network_traffic'], + dataset: ['dns'], + kind: ['event'], + end: ['2019-10-08T10:05:23.248Z'], + start: ['2019-10-08T10:05:23.241Z'], + }, + source: { + port: [58732], + bytes: [40], + ip: ['10.9.9.9'], + }, +}; + +export const mockEndpointProcessExecutionMalwarePreventionAlert: Ecs = { + process: { + hash: { + md5: ['177afc1eb0be88eb9983fb74111260c4'], + sha256: ['3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb'], + sha1: ['f573b85e9beb32121f1949217947b2adc6749e3d'], + }, + entity_id: [ + 'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTY5MjAtMTMyNDg5OTk2OTAuNDgzMzA3NzAw', + ], + executable: [ + 'C:\\Users\\sean\\Downloads\\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe', + ], + name: [ + 'C:\\Users\\sean\\Downloads\\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe', + ], + pid: [6920], + args: [ + 'C:\\Users\\sean\\Downloads\\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe', + ], + }, + host: { + os: { + full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1518)'], + name: ['Windows'], + version: ['1809 (10.0.17763.1518)'], + platform: ['windows'], + family: ['windows'], + kernel: ['1809 (10.0.17763.1518)'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'], + name: ['win2019-endpoint-1'], + }, + file: { + mtime: ['2020-11-04T21:40:51.494Z'], + path: [ + 'C:\\Users\\sean\\Downloads\\3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe', + ], + owner: ['sean'], + hash: { + md5: ['177afc1eb0be88eb9983fb74111260c4'], + sha256: ['3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb'], + sha1: ['f573b85e9beb32121f1949217947b2adc6749e3d'], + }, + name: ['3be13acde2f4dcded4fd8d518a513bfc9882407a6e384ffb17d12710db7d76fb.exe'], + extension: ['exe'], + size: [1604112], + }, + event: { + category: ['malware', 'intrusion_detection', 'process'], + outcome: ['success'], + severity: [73], + code: ['malicious_file'], + action: ['execution'], + id: ['LsuMZVr+sdhvehVM++++Gp2Y'], + kind: ['alert'], + created: ['2020-11-04T21:41:30.533Z'], + module: ['endpoint'], + type: ['info', 'start', 'denied'], + dataset: ['endpoint.alerts'], + }, + agent: { + type: ['endpoint'], + }, + timestamp: '2020-11-04T21:41:30.533Z', + message: ['Malware Prevention Alert'], + _id: '0dA2lXUBn9bLIbfPkY7d', +}; + +export const mockEndpointLibraryLoadEvent: Ecs = { + file: { + path: ['C:\\Windows\\System32\\bcrypt.dll'], + hash: { + md5: ['00439016776de367bad087d739a03797'], + sha1: ['2c4ba5c1482987d50a182bad915f52cd6611ee63'], + sha256: ['e70f5d8f87aab14e3160227d38387889befbe37fa4f8f5adc59eff52804b35fd'], + }, + name: ['bcrypt.dll'], + }, + host: { + os: { + full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'], + name: ['Windows'], + version: ['1809 (10.0.17763.1697)'], + family: ['windows'], + kernel: ['1809 (10.0.17763.1697)'], + platform: ['windows'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + name: ['win2019-endpoint-1'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'], + }, + event: { + category: ['library'], + kind: ['event'], + created: ['2021-02-05T21:27:23.921Z'], + module: ['endpoint'], + action: ['load'], + type: ['start'], + id: ['LzzWB9jjGmCwGMvk++++Da5H'], + dataset: ['endpoint.events.library'], + }, + process: { + name: ['sshd.exe'], + pid: [9644], + entity_id: [ + 'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTk2NDQtMTMyNTcwMzQwNDEuNzgyMTczODAw', + ], + executable: ['C:\\Program Files\\OpenSSH-Win64\\sshd.exe'], + }, + agent: { + type: ['endpoint'], + }, + user: { + name: ['SYSTEM'], + domain: ['NT AUTHORITY'], + }, + message: ['Endpoint DLL load event'], + timestamp: '2021-02-05T21:27:23.921Z', + _id: 'IAUYdHcBGrBB52F2zo8Q', +}; + +export const mockEndpointRegistryModificationEvent: Ecs = { + host: { + os: { + full: ['Windows Server 2019 Datacenter 1809 (10.0.17763.1697)'], + name: ['Windows'], + version: ['1809 (10.0.17763.1697)'], + family: ['windows'], + kernel: ['1809 (10.0.17763.1697)'], + platform: ['windows'], + }, + mac: ['aa:bb:cc:dd:ee:ff'], + name: ['win2019-endpoint-1'], + architecture: ['x86_64'], + ip: ['10.1.2.3'], + id: ['d8ad572e-d224-4044-a57d-f5a84c0dfe5d'], + }, + event: { + category: ['registry'], + kind: ['event'], + created: ['2021-02-04T13:44:31.559Z'], + module: ['endpoint'], + action: ['modification'], + type: ['change'], + id: ['LzzWB9jjGmCwGMvk++++CbOn'], + dataset: ['endpoint.events.registry'], + }, + process: { + name: ['GoogleUpdate.exe'], + pid: [7408], + entity_id: [ + 'MWQxNWNmOWUtM2RjNy01Yjk3LWY1ODYtNzQzZjdjMjUxOGIyLTc0MDgtMTMyNTY5MTk4NDguODY4NTI0ODAw', + ], + executable: ['C:\\Program Files (x86)\\Google\\Update\\GoogleUpdate.exe'], + }, + registry: { + hive: ['HKLM'], + key: [ + 'SOFTWARE\\WOW6432Node\\Google\\Update\\ClientState\\{430FD4D0-B729-4F61-AA34-91526481799D}\\CurrentState', + ], + path: [ + 'HKLM\\SOFTWARE\\WOW6432Node\\Google\\Update\\ClientState\\{430FD4D0-B729-4F61-AA34-91526481799D}\\CurrentState\\StateValue', + ], + value: ['StateValue'], + }, + agent: { + type: ['endpoint'], + }, + user: { + name: ['SYSTEM'], + domain: ['NT AUTHORITY'], + }, + message: ['Endpoint registry event'], + timestamp: '2021-02-04T13:44:31.559Z', + _id: '4cxLbXcBGrBB52F2uOfF', +}; diff --git a/x-pack/plugins/timelines/public/mock/plugin_mock.tsx b/x-pack/plugins/timelines/public/mock/plugin_mock.tsx new file mode 100644 index 00000000000000..8d2141d62f253b --- /dev/null +++ b/x-pack/plugins/timelines/public/mock/plugin_mock.tsx @@ -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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { + LastUpdatedAt, + LastUpdatedAtProps, + LoadingPanelProps, + LoadingPanel, + useDraggableKeyboardWrapper, +} from '../components'; +import { useAddToTimeline, useAddToTimelineSensor } from '../hooks/use_add_to_timeline'; + +export const createTGridMocks = () => ({ + // eslint-disable-next-line react/display-name + getTGrid: () => <>{'hello grid'}, + // eslint-disable-next-line react/display-name + getLastUpdated: (props: LastUpdatedAtProps) => , + // eslint-disable-next-line react/display-name + getLoadingPanel: (props: LoadingPanelProps) => , + getUseAddToTimeline: () => useAddToTimeline, + getUseAddToTimelineSensor: () => useAddToTimelineSensor, + getUseDraggableKeyboardWrapper: () => useDraggableKeyboardWrapper, +}); diff --git a/x-pack/plugins/timelines/public/mock/test_providers.tsx b/x-pack/plugins/timelines/public/mock/test_providers.tsx new file mode 100644 index 00000000000000..9fa6177cccee18 --- /dev/null +++ b/x-pack/plugins/timelines/public/mock/test_providers.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json'; +import { I18nProvider } from '@kbn/i18n/react'; + +import React from 'react'; +import { DragDropContext, DropResult, ResponderProvided } from 'react-beautiful-dnd'; +import { Provider as ReduxStoreProvider } from 'react-redux'; +import { Store } from 'redux'; +import { BehaviorSubject } from 'rxjs'; +import { ThemeProvider } from 'styled-components'; +import { createStore, TimelineState } from '../types'; +import { mockGlobalState } from './global_state'; + +import { createKibanaContextProviderMock, createStartServicesMock } from './kibana_react.mock'; +import { createSecuritySolutionStorageMock, localStorageMock } from './mock_local_storage'; + +const state: TimelineState = mockGlobalState; + +interface Props { + children: React.ReactNode; + store?: Store; + onDragEnd?: (result: DropResult, provided: ResponderProvided) => void; +} + +export const kibanaObservable = new BehaviorSubject(createStartServicesMock()); + +Object.defineProperty(window, 'localStorage', { + value: localStorageMock(), +}); +window.scrollTo = jest.fn(); +const MockKibanaContextProvider = createKibanaContextProviderMock(); +const { storage } = createSecuritySolutionStorageMock(); + +/** A utility for wrapping children in the providers required to run most tests */ +const TestProvidersComponent: React.FC = ({ + children, + store = createStore(state, storage), + onDragEnd = jest.fn(), +}) => ( + + + + ({ eui: euiDarkVars, darkMode: true })}> + {children} + + + + +); + +export const TestProviders = React.memo(TestProvidersComponent); diff --git a/x-pack/plugins/timelines/public/plugin.ts b/x-pack/plugins/timelines/public/plugin.ts index 76a692cf8ed102..a6076d91eea1df 100644 --- a/x-pack/plugins/timelines/public/plugin.ts +++ b/x-pack/plugins/timelines/public/plugin.ts @@ -5,27 +5,67 @@ * 2.0. */ -import { CoreSetup, Plugin, PluginInitializerContext } from '../../../../src/core/public'; -import { TimelinesPluginSetup, TimelineProps } from './types'; -import { getTimelineLazy } from './methods'; +import { Store } from 'redux'; -export class TimelinesPlugin implements Plugin { +import { Storage } from '../../../../src/plugins/kibana_utils/public'; +import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; +import { + CoreSetup, + Plugin, + PluginInitializerContext, + CoreStart, +} from '../../../../src/core/public'; +import type { TimelinesUIStart, TGridProps } from './types'; +import { getLastUpdatedLazy, getLoadingPanelLazy, getTGridLazy } from './methods'; +import type { LastUpdatedAtProps, LoadingPanelProps } from './components'; +import { tGridReducer } from './store/t_grid/reducer'; +import { useDraggableKeyboardWrapper } from './components/drag_and_drop/draggable_keyboard_wrapper_hook'; +import { useAddToTimeline, useAddToTimelineSensor } from './hooks/use_add_to_timeline'; + +export class TimelinesPlugin implements Plugin { constructor(private readonly initializerContext: PluginInitializerContext) {} + private _store: Store | undefined; + private _storage = new Storage(localStorage); + + public setup(core: CoreSetup) {} - public setup(core: CoreSetup): TimelinesPluginSetup { + public start(core: CoreStart, { data }: { data: DataPublicPluginStart }): TimelinesUIStart { const config = this.initializerContext.config.get<{ enabled: boolean }>(); if (!config.enabled) { - return {}; + return {} as TimelinesUIStart; } - return { - getTimeline: (props: TimelineProps) => { - return getTimelineLazy(props); + getTGrid: (props: TGridProps) => { + return getTGridLazy(props, { + store: this._store, + storage: this._storage, + data, + }); + }, + getTGridReducer: () => { + return tGridReducer; + }, + getLoadingPanel: (props: LoadingPanelProps) => { + return getLoadingPanelLazy(props); + }, + getLastUpdated: (props: LastUpdatedAtProps) => { + return getLastUpdatedLazy(props); + }, + getUseAddToTimeline: () => { + return useAddToTimeline; + }, + getUseAddToTimelineSensor: () => { + return useAddToTimelineSensor; + }, + getUseDraggableKeyboardWrapper: () => { + return useDraggableKeyboardWrapper; + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + setTGridEmbeddedStore: (store: any) => { + this._store = store; }, }; } - public start() {} - public stop() {} } diff --git a/x-pack/plugins/timelines/public/store/t_grid/actions.ts b/x-pack/plugins/timelines/public/store/t_grid/actions.ts new file mode 100644 index 00000000000000..74cccf4ac24010 --- /dev/null +++ b/x-pack/plugins/timelines/public/store/t_grid/actions.ts @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import actionCreatorFactory from 'typescript-fsa'; +import type { TimelineNonEcsData } from '../../../common/search_strategy'; +import type { + ColumnHeaderOptions, + SortColumnTimeline, + TimelineExpandedDetailType, +} from '../../../common/types/timeline'; +// eslint-disable-next-line no-duplicate-imports +import { TimelineTabs } from '../../../common/types/timeline'; +import { InitialyzeTGridSettings, TGridPersistInput } from './types'; + +const actionCreator = actionCreatorFactory('x-pack/timelines/t-grid'); + +export const createTGrid = actionCreator('CREATE_TIMELINE'); + +export const upsertColumn = actionCreator<{ + column: ColumnHeaderOptions; + id: string; + index: number; +}>('UPSERT_COLUMN'); + +export const applyDeltaToColumnWidth = actionCreator<{ + id: string; + columnId: string; + delta: number; +}>('APPLY_DELTA_TO_COLUMN_WIDTH'); + +export type ToggleDetailPanel = TimelineExpandedDetailType & { + tabType?: TimelineTabs; + timelineId: string; +}; + +export const toggleDetailPanel = actionCreator('TOGGLE_DETAIL_PANEL'); + +export const removeColumn = actionCreator<{ + id: string; + columnId: string; +}>('REMOVE_COLUMN'); + +export const updateIsLoading = actionCreator<{ + id: string; + isLoading: boolean; +}>('UPDATE_LOADING'); + +export const updateColumns = actionCreator<{ + id: string; + columns: ColumnHeaderOptions[]; +}>('UPDATE_COLUMNS'); + +export const updateItemsPerPage = actionCreator<{ id: string; itemsPerPage: number }>( + 'UPDATE_ITEMS_PER_PAGE' +); + +export const updateItemsPerPageOptions = actionCreator<{ + id: string; + itemsPerPageOptions: number[]; +}>('UPDATE_ITEMS_PER_PAGE_OPTIONS'); + +export const updateSort = actionCreator<{ id: string; sort: SortColumnTimeline[] }>('UPDATE_SORT'); + +export const setSelected = actionCreator<{ + id: string; + eventIds: Readonly>; + isSelected: boolean; + isSelectAllChecked: boolean; +}>('SET_TIMELINE_SELECTED'); + +export const clearSelected = actionCreator<{ + id: string; +}>('CLEAR_TIMELINE_SELECTED'); + +export const setEventsLoading = actionCreator<{ + id: string; + eventIds: string[]; + isLoading: boolean; +}>('SET_TIMELINE_EVENTS_LOADING'); + +export const clearEventsLoading = actionCreator<{ + id: string; +}>('CLEAR_TIMELINE_EVENTS_LOADING'); + +export const setEventsDeleted = actionCreator<{ + id: string; + eventIds: string[]; + isDeleted: boolean; +}>('SET_TIMELINE_EVENTS_DELETED'); + +export const clearEventsDeleted = actionCreator<{ + id: string; +}>('CLEAR_TIMELINE_EVENTS_DELETED'); + +export const initializeTGridSettings = actionCreator('INITIALIZE_TGRID'); + +export const setTGridSelectAll = actionCreator<{ id: string; selectAll: boolean }>( + 'SET_TGRID_SELECT_ALL' +); diff --git a/x-pack/plugins/timelines/public/store/t_grid/defaults.ts b/x-pack/plugins/timelines/public/store/t_grid/defaults.ts new file mode 100644 index 00000000000000..8caae1aabbe017 --- /dev/null +++ b/x-pack/plugins/timelines/public/store/t_grid/defaults.ts @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Direction } from '../../../common/search_strategy'; +import type { ColumnHeaderOptions, ColumnHeaderType } from '../../../common/types/timeline'; +import { + DEFAULT_COLUMN_MIN_WIDTH, + DEFAULT_DATE_COLUMN_MIN_WIDTH, +} from '../../components/t_grid/body/constants'; +import type { SubsetTGridModel } from './model'; +import * as i18n from './translations'; + +export const defaultColumnHeaderType: ColumnHeaderType = 'not-filtered'; + +export const defaultHeaders: ColumnHeaderOptions[] = [ + { + columnHeaderType: defaultColumnHeaderType, + id: '@timestamp', + type: 'number', + initialWidth: DEFAULT_DATE_COLUMN_MIN_WIDTH, + }, + { + columnHeaderType: defaultColumnHeaderType, + id: 'message', + initialWidth: DEFAULT_COLUMN_MIN_WIDTH, + }, + { + columnHeaderType: defaultColumnHeaderType, + id: 'event.category', + initialWidth: DEFAULT_COLUMN_MIN_WIDTH, + }, + { + columnHeaderType: defaultColumnHeaderType, + id: 'event.action', + initialWidth: DEFAULT_COLUMN_MIN_WIDTH, + }, + { + columnHeaderType: defaultColumnHeaderType, + id: 'host.name', + initialWidth: DEFAULT_COLUMN_MIN_WIDTH, + }, + { + columnHeaderType: defaultColumnHeaderType, + id: 'source.ip', + initialWidth: DEFAULT_COLUMN_MIN_WIDTH, + }, + { + columnHeaderType: defaultColumnHeaderType, + id: 'destination.ip', + initialWidth: DEFAULT_COLUMN_MIN_WIDTH, + }, + { + columnHeaderType: defaultColumnHeaderType, + id: 'user.name', + initialWidth: DEFAULT_COLUMN_MIN_WIDTH, + }, +]; + +export const tGridDefaults: SubsetTGridModel = { + columns: defaultHeaders, + dateRange: { start: '', end: '' }, + deletedEventIds: [], + excludedRowRendererIds: [], + expandedDetail: {}, + filters: [], + kqlQuery: { + filterQuery: null, + }, + indexNames: [], + isLoading: false, + isSelectAllChecked: false, + itemsPerPage: 25, + itemsPerPageOptions: [10, 25, 50, 100], + loadingEventIds: [], + selectedEventIds: {}, + showCheckboxes: false, + sort: [ + { + columnId: '@timestamp', + columnType: 'date', + sortDirection: Direction.desc, + }, + ], + savedObjectId: null, + version: null, +}; + +export const getTGridManageDefaults = (id: string) => ({ + defaultColumns: defaultHeaders, + loadingText: i18n.LOADING_EVENTS, + footerText: i18n.TOTAL_COUNT_OF_EVENTS, + documentType: '', + selectAll: false, + id, + isLoading: false, + queryFields: [], + title: '', + unit: (n: number) => i18n.UNIT(n), +}); diff --git a/x-pack/plugins/timelines/public/store/t_grid/helpers.ts b/x-pack/plugins/timelines/public/store/t_grid/helpers.ts new file mode 100644 index 00000000000000..e114f4516c79ed --- /dev/null +++ b/x-pack/plugins/timelines/public/store/t_grid/helpers.ts @@ -0,0 +1,424 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { omit, union } from 'lodash/fp'; + +import { isEmpty } from 'lodash'; +import type { ToggleDetailPanel } from './actions'; +import { TGridPersistInput, TimelineById, TimelineId } from './types'; +import type { TGridModel, TGridModelSettings } from './model'; + +import type { ColumnHeaderOptions, SortColumnTimeline } from '../../../common/types/timeline'; +import { getTGridManageDefaults, tGridDefaults } from './defaults'; + +export const isNotNull = (value: T | null): value is T => value !== null; +export type Maybe = T | null; + +enum TimelineTabs { + query = 'query', + graph = 'graph', + notes = 'notes', + pinned = 'pinned', + eql = 'eql', +} + +/** The default minimum width of a column (when a width for the column type is not specified) */ +export const DEFAULT_COLUMN_MIN_WIDTH = 180; // px + +/** The minimum width of a resized column */ +export const RESIZED_COLUMN_MIN_WITH = 70; // px + +export const shouldResetActiveTimelineContext = ( + id: string, + oldTimeline: TGridModel, + newTimeline: TGridModel +) => { + if (id === TimelineId.active && oldTimeline.savedObjectId !== newTimeline.savedObjectId) { + return true; + } + return false; +}; + +interface AddTimelineColumnParams { + column: ColumnHeaderOptions; + id: string; + index: number; + timelineById: TimelineById; +} + +interface TimelineNonEcsData { + field: string; + value?: Maybe; +} + +interface CreateTGridParams extends TGridPersistInput { + timelineById: TimelineById; +} + +/** Adds a new `Timeline` to the provided collection of `TimelineById` */ +export const createInitTGrid = ({ + id, + timelineById, + ...tGridProps +}: CreateTGridParams): TimelineById => { + const timeline = timelineById[id]; + return { + ...timelineById, + [id]: { + ...timeline, + ...tGridDefaults, + ...tGridProps, + isLoading: false, + savedObjectId: null, + version: null, + }, + }; +}; + +/** + * Adds or updates a column. When updating a column, it will be moved to the + * new index + */ +export const upsertTimelineColumn = ({ + column, + id, + index, + timelineById, +}: AddTimelineColumnParams): TimelineById => { + const timeline = timelineById[id]; + const alreadyExistsAtIndex = timeline.columns.findIndex((c) => c.id === column.id); + + if (alreadyExistsAtIndex !== -1) { + // remove the existing entry and add the new one at the specified index + const reordered = timeline.columns.filter((c) => c.id !== column.id); + reordered.splice(index, 0, column); // ⚠️ mutation + + return { + ...timelineById, + [id]: { + ...timeline, + columns: reordered, + }, + }; + } + + // add the new entry at the specified index + const columns = [...timeline.columns]; + columns.splice(index, 0, column); // ⚠️ mutation + + return { + ...timelineById, + [id]: { + ...timeline, + columns, + }, + }; +}; + +interface RemoveTimelineColumnParams { + id: string; + columnId: string; + timelineById: TimelineById; +} + +export const removeTimelineColumn = ({ + id, + columnId, + timelineById, +}: RemoveTimelineColumnParams): TimelineById => { + const timeline = timelineById[id]; + + const columns = timeline.columns.filter((c) => c.id !== columnId); + + return { + ...timelineById, + [id]: { + ...timeline, + columns, + }, + }; +}; + +interface InitializeTgridParams { + id: string; + timelineById: TimelineById; + tGridSettingsProps: Partial; +} + +export const setInitializeTgridSettings = ({ + id, + timelineById, + tGridSettingsProps, +}: InitializeTgridParams): TimelineById => { + const timeline = timelineById[id]; + + return { + ...timelineById, + [id]: { + ...tGridDefaults, + ...timeline, + ...getTGridManageDefaults(id), + ...tGridSettingsProps, + ...(!timeline || (isEmpty(timeline.columns) && !isEmpty(tGridSettingsProps.defaultColumns)) + ? { columns: tGridSettingsProps.defaultColumns } + : {}), + sort: tGridDefaults.sort, + loadingEventIds: tGridDefaults.loadingEventIds, + }, + }; +}; + +interface ApplyDeltaToTimelineColumnWidth { + id: string; + columnId: string; + delta: number; + timelineById: TimelineById; +} + +export const applyDeltaToTimelineColumnWidth = ({ + id, + columnId, + delta, + timelineById, +}: ApplyDeltaToTimelineColumnWidth): TimelineById => { + const timeline = timelineById[id]; + + const columnIndex = timeline.columns.findIndex((c) => c.id === columnId); + if (columnIndex === -1) { + // the column was not found + return { + ...timelineById, + [id]: { + ...timeline, + }, + }; + } + + const requestedWidth = + (timeline.columns[columnIndex].initialWidth ?? DEFAULT_COLUMN_MIN_WIDTH) + delta; // raw change in width + const initialWidth = Math.max(RESIZED_COLUMN_MIN_WITH, requestedWidth); // if the requested width is smaller than the min, use the min + + const columnWithNewWidth = { + ...timeline.columns[columnIndex], + initialWidth, + }; + + const columns = [ + ...timeline.columns.slice(0, columnIndex), + columnWithNewWidth, + ...timeline.columns.slice(columnIndex + 1), + ]; + + return { + ...timelineById, + [id]: { + ...timeline, + columns, + }, + }; +}; + +interface UpdateTimelineColumnsParams { + id: string; + columns: ColumnHeaderOptions[]; + timelineById: TimelineById; +} + +export const updateTimelineColumns = ({ + id, + columns, + timelineById, +}: UpdateTimelineColumnsParams): TimelineById => { + const timeline = timelineById[id]; + + return { + ...timelineById, + [id]: { + ...timeline, + columns, + }, + }; +}; + +interface UpdateTimelineSortParams { + id: string; + sort: SortColumnTimeline[]; + timelineById: TimelineById; +} + +export const updateTimelineSort = ({ + id, + sort, + timelineById, +}: UpdateTimelineSortParams): TimelineById => { + const timeline = timelineById[id]; + return { + ...timelineById, + [id]: { + ...timeline, + sort, + }, + }; +}; + +interface UpdateTimelineItemsPerPageParams { + id: string; + itemsPerPage: number; + timelineById: TimelineById; +} + +export const updateTimelineItemsPerPage = ({ + id, + itemsPerPage, + timelineById, +}: UpdateTimelineItemsPerPageParams) => { + const timeline = timelineById[id]; + return { + ...timelineById, + [id]: { + ...timeline, + itemsPerPage, + }, + }; +}; + +interface UpdateTimelinePerPageOptionsParams { + id: string; + itemsPerPageOptions: number[]; + timelineById: TimelineById; +} + +export const updateTimelinePerPageOptions = ({ + id, + itemsPerPageOptions, + timelineById, +}: UpdateTimelinePerPageOptionsParams) => { + const timeline = timelineById[id]; + return { + ...timelineById, + [id]: { + ...timeline, + itemsPerPageOptions, + }, + }; +}; + +interface SetDeletedTimelineEventsParams { + id: string; + eventIds: string[]; + isDeleted: boolean; + timelineById: TimelineById; +} + +export const setDeletedTimelineEvents = ({ + id, + eventIds, + isDeleted, + timelineById, +}: SetDeletedTimelineEventsParams): TimelineById => { + const timeline = timelineById[id]; + + const deletedEventIds = isDeleted + ? union(timeline.deletedEventIds, eventIds) + : timeline.deletedEventIds.filter((currentEventId) => !eventIds.includes(currentEventId)); + + const selectedEventIds = Object.fromEntries( + Object.entries(timeline.selectedEventIds).filter( + ([selectedEventId]) => !deletedEventIds.includes(selectedEventId) + ) + ); + + const isSelectAllChecked = + Object.keys(selectedEventIds).length > 0 ? timeline.isSelectAllChecked : false; + + return { + ...timelineById, + [id]: { + ...timeline, + deletedEventIds, + selectedEventIds, + isSelectAllChecked, + }, + }; +}; + +interface SetLoadingTimelineEventsParams { + id: string; + eventIds: string[]; + isLoading: boolean; + timelineById: TimelineById; +} + +export const setLoadingTimelineEvents = ({ + id, + eventIds, + isLoading, + timelineById, +}: SetLoadingTimelineEventsParams): TimelineById => { + const timeline = timelineById[id]; + + const loadingEventIds = isLoading + ? union(timeline.loadingEventIds, eventIds) + : timeline.loadingEventIds.filter((currentEventId) => !eventIds.includes(currentEventId)); + + return { + ...timelineById, + [id]: { + ...timeline, + loadingEventIds, + }, + }; +}; + +interface SetSelectedTimelineEventsParams { + id: string; + eventIds: Record; + isSelectAllChecked: boolean; + isSelected: boolean; + timelineById: TimelineById; +} + +export const setSelectedTimelineEvents = ({ + id, + eventIds, + isSelectAllChecked = false, + isSelected, + timelineById, +}: SetSelectedTimelineEventsParams): TimelineById => { + const timeline = timelineById[id]; + + const selectedEventIds = isSelected + ? { ...timeline.selectedEventIds, ...eventIds } + : omit(Object.keys(eventIds), timeline.selectedEventIds); + + return { + ...timelineById, + [id]: { + ...timeline, + selectedEventIds, + isSelectAllChecked, + }, + }; +}; + +export const updateTimelineDetailsPanel = (action: ToggleDetailPanel) => { + const { tabType } = action; + + const panelViewOptions = new Set(['eventDetail', 'hostDetail', 'networkDetail']); + const expandedTabType = tabType ?? TimelineTabs.query; + + return action.panelView && panelViewOptions.has(action.panelView) + ? { + [expandedTabType]: { + params: action.params ? { ...action.params } : {}, + panelView: action.panelView, + }, + } + : { + [expandedTabType]: {}, + }; +}; diff --git a/x-pack/plugins/timelines/public/store/t_grid/index.ts b/x-pack/plugins/timelines/public/store/t_grid/index.ts new file mode 100644 index 00000000000000..d37c62bc8c2657 --- /dev/null +++ b/x-pack/plugins/timelines/public/store/t_grid/index.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + Action, + applyMiddleware, + CombinedState, + compose, + createStore as createReduxStore, + PreloadedState, + Store, +} from 'redux'; + +import { createEpicMiddleware } from 'redux-observable'; +import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; +import { TimelineState, TGridEpicDependencies } from '../../types'; +import { tGridReducer } from './reducer'; +import { getTGridByIdSelector } from './selectors'; + +export * from './model'; +export * as tGridActions from './actions'; +export * as tGridSelectors from './selectors'; +export * from './types'; +export { tGridReducer }; + +export type State = CombinedState; +type ComposeType = typeof compose; +declare global { + interface Window { + __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: ComposeType; + } +} + +/** + * Factory for Security App's redux store. + */ +export const createStore = ( + state: PreloadedState, + storage: Storage +): Store => { + const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; + + const middlewareDependencies: TGridEpicDependencies = { + tGridByIdSelector: getTGridByIdSelector, + storage, + }; + + const epicMiddleware = createEpicMiddleware( + { + dependencies: middlewareDependencies, + } + ); + + const store: Store = createReduxStore( + tGridReducer, + state, + composeEnhancers(applyMiddleware(epicMiddleware)) + ); + + return store; +}; diff --git a/x-pack/plugins/timelines/public/store/t_grid/inputs.ts b/x-pack/plugins/timelines/public/store/t_grid/inputs.ts new file mode 100644 index 00000000000000..6c2beca3826aad --- /dev/null +++ b/x-pack/plugins/timelines/public/store/t_grid/inputs.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type Refetch = () => void; + +export interface InspectQuery { + dsl: string[]; + response: string[]; +} diff --git a/x-pack/plugins/timelines/public/store/t_grid/model.ts b/x-pack/plugins/timelines/public/store/t_grid/model.ts new file mode 100644 index 00000000000000..67b56540c8a423 --- /dev/null +++ b/x-pack/plugins/timelines/public/store/t_grid/model.ts @@ -0,0 +1,128 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EuiDataGridColumn } from '@elastic/eui'; +import type { Filter, FilterManager } from '../../../../../../src/plugins/data/public'; +import type { TimelineNonEcsData } from '../../../common/search_strategy'; +import type { + ColumnHeaderOptions, + TimelineExpandedDetail, + SortColumnTimeline, + SerializedFilterQuery, +} from '../../../common/types/timeline'; +// eslint-disable-next-line no-duplicate-imports +import { RowRendererId } from '../../../common/types/timeline'; + +export interface TGridModelSettings { + documentType: string; + defaultColumns: Array< + Pick & + ColumnHeaderOptions + >; + /** A list of Ids of excluded Row Renderers */ + excludedRowRendererIds: RowRendererId[]; + filterManager?: FilterManager; + footerText: string; + loadingText: string; + queryFields: string[]; + selectAll: boolean; + showCheckboxes?: boolean; + title: string; +} +export interface TGridModel extends TGridModelSettings { + /** The columns displayed in the timeline */ + columns: Array< + Pick & + ColumnHeaderOptions + >; + /** Specifies the granularity of the date range (e.g. 1 Day / Week / Month) applicable to the mini-map */ + dateRange: { + start: string; + end: string; + }; + /** Events to not be rendered **/ + deletedEventIds: string[]; + /** This holds the view information for the flyout when viewing timeline in a consuming view (i.e. hosts page) or the side panel in the primary timeline view */ + expandedDetail: TimelineExpandedDetail; + filters?: Filter[]; + /** When non-empty, display a graph view for this event */ + graphEventId?: string; + /** the KQL query in the KQL bar */ + kqlQuery: { + // TODO convert to nodebuilder + filterQuery: SerializedFilterQuery | null; + }; + /** Uniquely identifies the timeline */ + id: string; + indexNames: string[]; + isLoading: boolean; + /** If selectAll checkbox in header is checked **/ + isSelectAllChecked: boolean; + /** The number of items to show in a single page of results */ + itemsPerPage: number; + /** Displays a series of choices that when selected, become the value of `itemsPerPage` */ + itemsPerPageOptions: number[]; + /** Events to be rendered as loading **/ + loadingEventIds: string[]; + /** When true, shows checkboxes enabling selection. Selected events store in selectedEventIds **/ + showCheckboxes: boolean; + /** Specifies which column the timeline is sorted on, and the direction (ascending / descending) */ + sort: SortColumnTimeline[]; + /** Events selected on this timeline -- eventId to TimelineNonEcsData[] mapping of data required for batch actions **/ + selectedEventIds: Record; + savedObjectId: string | null; + version: string | null; +} + +export type TGridModelForTimeline = Pick< + TGridModel, + | 'columns' + | 'dateRange' + | 'deletedEventIds' + | 'excludedRowRendererIds' + | 'expandedDetail' + | 'filters' + | 'graphEventId' + | 'kqlQuery' + | 'id' + | 'indexNames' + | 'isLoading' + | 'isSelectAllChecked' + | 'itemsPerPage' + | 'itemsPerPageOptions' + | 'loadingEventIds' + | 'showCheckboxes' + | 'sort' + | 'selectedEventIds' + | 'savedObjectId' + | 'title' + | 'version' +>; + +export type SubsetTGridModel = Readonly< + Pick< + TGridModel, + | 'columns' + | 'dateRange' + | 'deletedEventIds' + | 'excludedRowRendererIds' + | 'expandedDetail' + | 'filters' + | 'kqlQuery' + | 'indexNames' + | 'isLoading' + | 'isSelectAllChecked' + | 'itemsPerPage' + | 'itemsPerPageOptions' + | 'loadingEventIds' + | 'showCheckboxes' + | 'sort' + | 'selectedEventIds' + | 'savedObjectId' + | 'version' + > +>; diff --git a/x-pack/plugins/timelines/public/store/t_grid/reducer.ts b/x-pack/plugins/timelines/public/store/t_grid/reducer.ts new file mode 100644 index 00000000000000..57c45f857554d3 --- /dev/null +++ b/x-pack/plugins/timelines/public/store/t_grid/reducer.ts @@ -0,0 +1,212 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { reducerWithInitialState } from 'typescript-fsa-reducers'; + +import { + applyDeltaToColumnWidth, + clearEventsDeleted, + clearEventsLoading, + clearSelected, + createTGrid, + initializeTGridSettings, + removeColumn, + setEventsDeleted, + setEventsLoading, + setTGridSelectAll, + setSelected, + toggleDetailPanel, + updateColumns, + updateIsLoading, + updateItemsPerPage, + updateItemsPerPageOptions, + updateSort, + upsertColumn, +} from './actions'; + +import { + applyDeltaToTimelineColumnWidth, + createInitTGrid, + setInitializeTgridSettings, + removeTimelineColumn, + setDeletedTimelineEvents, + setLoadingTimelineEvents, + setSelectedTimelineEvents, + updateTimelineColumns, + updateTimelineItemsPerPage, + updateTimelinePerPageOptions, + updateTimelineSort, + upsertTimelineColumn, + updateTimelineDetailsPanel, +} from './helpers'; + +import { TimelineState, EMPTY_TIMELINE_BY_ID } from './types'; + +export const initialTGridState: TimelineState = { + timelineById: EMPTY_TIMELINE_BY_ID, +}; + +/** The reducer for all timeline actions */ +export const tGridReducer = reducerWithInitialState(initialTGridState) + .case(upsertColumn, (state, { column, id, index }) => ({ + ...state, + timelineById: upsertTimelineColumn({ column, id, index, timelineById: state.timelineById }), + })) + .case(createTGrid, (state, timelineProps) => { + return { + ...state, + timelineById: createInitTGrid({ + ...timelineProps, + timelineById: state.timelineById, + }), + }; + }) + .case(toggleDetailPanel, (state, action) => ({ + ...state, + timelineById: { + ...state.timelineById, + [action.timelineId]: { + ...state.timelineById[action.timelineId], + expandedDetail: { + ...state.timelineById[action.timelineId].expandedDetail, + ...updateTimelineDetailsPanel(action), + }, + }, + }, + })) + .case(applyDeltaToColumnWidth, (state, { id, columnId, delta }) => ({ + ...state, + timelineById: applyDeltaToTimelineColumnWidth({ + id, + columnId, + delta, + timelineById: state.timelineById, + }), + })) + .case(removeColumn, (state, { id, columnId }) => ({ + ...state, + timelineById: removeTimelineColumn({ + id, + columnId, + timelineById: state.timelineById, + }), + })) + .case(setEventsDeleted, (state, { id, eventIds, isDeleted }) => ({ + ...state, + timelineById: setDeletedTimelineEvents({ + id, + eventIds, + timelineById: state.timelineById, + isDeleted, + }), + })) + .case(clearEventsDeleted, (state, { id }) => ({ + ...state, + timelineById: { + ...state.timelineById, + [id]: { + ...state.timelineById[id], + deletedEventIds: [], + }, + }, + })) + .case(setEventsLoading, (state, { id, eventIds, isLoading }) => ({ + ...state, + timelineById: setLoadingTimelineEvents({ + id, + eventIds, + timelineById: state.timelineById, + isLoading, + }), + })) + .case(clearEventsLoading, (state, { id }) => ({ + ...state, + timelineById: { + ...state.timelineById, + [id]: { + ...state.timelineById[id], + loadingEventIds: [], + }, + }, + })) + .case(setSelected, (state, { id, eventIds, isSelected, isSelectAllChecked }) => ({ + ...state, + timelineById: setSelectedTimelineEvents({ + id, + eventIds, + timelineById: state.timelineById, + isSelected, + isSelectAllChecked, + }), + })) + .case(clearSelected, (state, { id }) => ({ + ...state, + timelineById: { + ...state.timelineById, + [id]: { + ...state.timelineById[id], + selectedEventIds: {}, + isSelectAllChecked: false, + }, + }, + })) + .case(updateIsLoading, (state, { id, isLoading }) => ({ + ...state, + timelineById: { + ...state.timelineById, + [id]: { + ...state.timelineById[id], + isLoading, + }, + }, + })) + .case(updateColumns, (state, { id, columns }) => ({ + ...state, + timelineById: updateTimelineColumns({ + id, + columns, + timelineById: state.timelineById, + }), + })) + .case(updateSort, (state, { id, sort }) => ({ + ...state, + timelineById: updateTimelineSort({ id, sort, timelineById: state.timelineById }), + })) + .case(updateItemsPerPage, (state, { id, itemsPerPage }) => ({ + ...state, + timelineById: updateTimelineItemsPerPage({ + id, + itemsPerPage, + timelineById: state.timelineById, + }), + })) + .case(updateItemsPerPageOptions, (state, { id, itemsPerPageOptions }) => ({ + ...state, + timelineById: updateTimelinePerPageOptions({ + id, + itemsPerPageOptions, + timelineById: state.timelineById, + }), + })) + .case(initializeTGridSettings, (state, { id, ...tGridSettingsProps }) => ({ + ...state, + timelineById: setInitializeTgridSettings({ + id, + timelineById: state.timelineById, + tGridSettingsProps, + }), + })) + .case(setTGridSelectAll, (state, { id, selectAll }) => ({ + ...state, + timelineById: { + ...state.timelineById, + [id]: { + ...state.timelineById[id], + selectAll, + }, + }, + })) + .build(); diff --git a/x-pack/plugins/timelines/public/store/t_grid/selectors.ts b/x-pack/plugins/timelines/public/store/t_grid/selectors.ts new file mode 100644 index 00000000000000..710a842d4563af --- /dev/null +++ b/x-pack/plugins/timelines/public/store/t_grid/selectors.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { getOr } from 'lodash/fp'; +import { createSelector } from 'reselect'; +import { TGridModel } from '.'; +import { tGridDefaults, getTGridManageDefaults } from './defaults'; + +const getDefaultTgrid = (id: string) => ({ ...tGridDefaults, ...getTGridManageDefaults(id) }); + +export const selectTGridById = (state: unknown, timelineId: string): TGridModel => { + return getOr( + getOr(getDefaultTgrid(timelineId), ['timelineById', timelineId], state), + ['timeline', 'timelineById', timelineId], + state + ); +}; + +export const getTGridByIdSelector = () => createSelector(selectTGridById, (tGrid) => tGrid); + +export const getManageTimelineById = () => + createSelector( + selectTGridById, + ({ + documentType, + defaultColumns, + isLoading, + filterManager, + footerText, + loadingText, + queryFields, + selectAll, + title, + }) => ({ + documentType, + defaultColumns, + isLoading, + filterManager, + footerText, + loadingText, + queryFields, + selectAll, + title, + }) + ); diff --git a/x-pack/plugins/timelines/public/store/t_grid/translations.ts b/x-pack/plugins/timelines/public/store/t_grid/translations.ts new file mode 100644 index 00000000000000..fa2b6f1c038fe5 --- /dev/null +++ b/x-pack/plugins/timelines/public/store/t_grid/translations.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const EVENTS = i18n.translate('xpack.timelines.tGrid.eventsLabel', { + defaultMessage: 'Events', +}); + +export const LOADING_EVENTS = i18n.translate( + 'xpack.timelines.tGrid.footer.loadingEventsDataLabel', + { + defaultMessage: 'Loading Events', + } +); + +export const UNIT = (totalCount: number) => + i18n.translate('xpack.timelines.tGrid.unit', { + values: { totalCount }, + defaultMessage: `{totalCount, plural, =1 {event} other {events}}`, + }); + +export const TOTAL_COUNT_OF_EVENTS = i18n.translate( + 'xpack.timelines.tGrid.footer.totalCountOfEvents', + { + defaultMessage: 'events', + } +); diff --git a/x-pack/plugins/timelines/public/store/t_grid/types.ts b/x-pack/plugins/timelines/public/store/t_grid/types.ts new file mode 100644 index 00000000000000..c8c72e0310958d --- /dev/null +++ b/x-pack/plugins/timelines/public/store/t_grid/types.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; +import type { ColumnHeaderOptions } from '../../../common'; +import type { TGridModel, TGridModelSettings } from './model'; + +export interface AutoSavedWarningMsg { + timelineId: string | null; + newTimelineModel: TGridModel | null; +} + +/** A map of id to timeline */ +export interface TimelineById { + [id: string]: TGridModel; +} + +export interface InsertTimeline { + graphEventId?: string; + timelineId: string; + timelineSavedObjectId: string | null; + timelineTitle: string; +} + +export const EMPTY_TIMELINE_BY_ID: TimelineById = {}; // stable reference + +export interface TGridEpicDependencies { + // kibana$: Observable; + storage: Storage; + tGridByIdSelector: () => (state: State, timelineId: string) => TGridModel; +} + +/** The state of all timelines is stored here */ +export interface TimelineState { + timelineById: TimelineById; +} + +export enum TimelineId { + hostsPageEvents = 'hosts-page-events', + hostsPageExternalAlerts = 'hosts-page-external-alerts', + detectionsRulesDetailsPage = 'detections-rules-details-page', + detectionsPage = 'detections-page', + networkPageExternalAlerts = 'network-page-external-alerts', + active = 'timeline-1', + casePage = 'timeline-case', + test = 'test', // Reserved for testing purposes + alternateTest = 'alternateTest', +} + +export interface InitialyzeTGridSettings extends Partial { + id: string; +} + +export interface TGridPersistInput extends Partial> { + id: string; + dateRange: { + start: string; + end: string; + }; + columns: ColumnHeaderOptions[]; + indexNames: string[]; + showCheckboxes?: boolean; +} diff --git a/x-pack/plugins/timelines/public/types.ts b/x-pack/plugins/timelines/public/types.ts index 1fa6d33a6af602..ffef1ee35c8302 100644 --- a/x-pack/plugins/timelines/public/types.ts +++ b/x-pack/plugins/timelines/public/types.ts @@ -4,13 +4,44 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - import { ReactElement } from 'react'; - -export interface TimelinesPluginSetup { - getTimeline?: (props: TimelineProps) => ReactElement; +import type { SensorAPI } from 'react-beautiful-dnd'; +import { Store } from 'redux'; +import type { + LastUpdatedAtProps, + LoadingPanelProps, + UseDraggableKeyboardWrapper, + UseDraggableKeyboardWrapperProps, +} from './components'; +import type { TGridIntegratedProps } from './components/t_grid/integrated'; +import type { TGridStandaloneProps } from './components/t_grid/standalone'; +import type { UseAddToTimelineProps, UseAddToTimeline } from './hooks/use_add_to_timeline'; +export * from './store/t_grid'; +export interface TimelinesUIStart { + getTGrid: ( + props: GetTGridProps + ) => ReactElement>; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + getTGridReducer: () => any; + getLoadingPanel: (props: LoadingPanelProps) => ReactElement; + getLastUpdated: (props: LastUpdatedAtProps) => ReactElement; + getUseAddToTimeline: () => (props: UseAddToTimelineProps) => UseAddToTimeline; + getUseAddToTimelineSensor: () => (api: SensorAPI) => void; + getUseDraggableKeyboardWrapper: () => ( + props: UseDraggableKeyboardWrapperProps + ) => UseDraggableKeyboardWrapper; + setTGridEmbeddedStore: (store: Store) => void; } - -export interface TimelineProps { - timelineId: string; +interface TGridStandaloneCompProps extends TGridStandaloneProps { + type: 'standalone'; } +interface TGridIntegratedCompProps extends TGridIntegratedProps { + type: 'embedded'; +} +export type TGridType = 'standalone' | 'embedded'; +export type GetTGridProps = T extends 'standalone' + ? TGridStandaloneCompProps + : T extends 'embedded' + ? TGridIntegratedCompProps + : TGridIntegratedCompProps; +export type TGridProps = TGridStandaloneCompProps | TGridIntegratedCompProps; diff --git a/x-pack/plugins/timelines/server/config.ts b/x-pack/plugins/timelines/server/config.ts index 31be2566118039..958c6733338736 100644 --- a/x-pack/plugins/timelines/server/config.ts +++ b/x-pack/plugins/timelines/server/config.ts @@ -8,7 +8,7 @@ import { TypeOf, schema } from '@kbn/config-schema'; export const ConfigSchema = schema.object({ - enabled: schema.boolean({ defaultValue: false }), + enabled: schema.boolean({ defaultValue: true }), }); export type ConfigType = TypeOf; diff --git a/x-pack/plugins/timelines/server/index.ts b/x-pack/plugins/timelines/server/index.ts index 65e2b6494c6f47..8ad2bafdcc13a4 100644 --- a/x-pack/plugins/timelines/server/index.ts +++ b/x-pack/plugins/timelines/server/index.ts @@ -19,4 +19,4 @@ export function plugin(initializerContext: PluginInitializerContext) { return new TimelinesPlugin(initializerContext); } -export { TimelinesPluginSetup, TimelinesPluginStart } from './types'; +export { TimelinesPluginUI, TimelinesPluginStart } from './types'; diff --git a/x-pack/plugins/timelines/server/plugin.ts b/x-pack/plugins/timelines/server/plugin.ts index 825d42994e0963..78e91f965e7516 100644 --- a/x-pack/plugins/timelines/server/plugin.ts +++ b/x-pack/plugins/timelines/server/plugin.ts @@ -13,23 +13,41 @@ import { Logger, } from '../../../../src/core/server'; -import { TimelinesPluginSetup, TimelinesPluginStart } from './types'; +import { SetupPlugins, StartPlugins, TimelinesPluginUI, TimelinesPluginStart } from './types'; import { defineRoutes } from './routes'; +import { timelineSearchStrategyProvider } from './search_strategy/timeline'; +import { timelineEqlSearchStrategyProvider } from './search_strategy/timeline/eql'; +import { indexFieldsProvider } from './search_strategy/index_fields'; -export class TimelinesPlugin implements Plugin { +export class TimelinesPlugin + implements Plugin { private readonly logger: Logger; constructor(initializerContext: PluginInitializerContext) { this.logger = initializerContext.logger.get(); } - public setup(core: CoreSetup) { + public setup(core: CoreSetup, plugins: SetupPlugins) { this.logger.debug('timelines: Setup'); const router = core.http.createRouter(); // Register server side APIs defineRoutes(router); + // Register search strategy + core.getStartServices().then(([_, depsStart]) => { + const TimelineSearchStrategy = timelineSearchStrategyProvider(depsStart.data); + const TimelineEqlSearchStrategy = timelineEqlSearchStrategyProvider(depsStart.data); + const IndexFields = indexFieldsProvider(); + + plugins.data.search.registerSearchStrategy('indexFields', IndexFields); + plugins.data.search.registerSearchStrategy('timelineSearchStrategy', TimelineSearchStrategy); + plugins.data.search.registerSearchStrategy( + 'timelineEqlSearchStrategy', + TimelineEqlSearchStrategy + ); + }); + return {}; } diff --git a/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.test.ts b/x-pack/plugins/timelines/server/search_strategy/index_fields/index.test.ts similarity index 99% rename from x-pack/plugins/security_solution/server/search_strategy/index_fields/index.test.ts rename to x-pack/plugins/timelines/server/search_strategy/index_fields/index.test.ts index 51892a1a05d55c..f6d78f2f1259fd 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.test.ts +++ b/x-pack/plugins/timelines/server/search_strategy/index_fields/index.test.ts @@ -126,7 +126,7 @@ describe('Index Fields', () => { }, { description: - 'Type of the agent. The agent type always stays the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.', + 'Type of the agent. The agent type stays always the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.', example: 'filebeat', name: 'agent.type', type: 'string', @@ -252,7 +252,7 @@ describe('Index Fields', () => { { category: 'agent', description: - 'Type of the agent. The agent type always stays the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.', + 'Type of the agent. The agent type stays always the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.', example: 'filebeat', name: 'agent.type', type: 'string', @@ -426,7 +426,7 @@ describe('Index Fields', () => { { category: 'agent', description: - 'Type of the agent. The agent type always stays the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.', + 'Type of the agent. The agent type stays always the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.', example: 'filebeat', name: 'agent.type', type: 'string', diff --git a/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts b/x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts similarity index 99% rename from x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts rename to x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts index 884621b13dea1d..d100e8db21493f 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/index_fields/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts @@ -15,6 +15,8 @@ import { } from '../../../../../../src/plugins/data/server'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { FieldDescriptor } from '../../../../../../src/plugins/data/server/index_patterns'; + +// TODO cleanup path import { IndexFieldsStrategyResponse, IndexField, @@ -24,7 +26,7 @@ import { const apmIndexPattern = 'apm-*-transaction*'; -export const securitySolutionIndexFieldsProvider = (): ISearchStrategy< +export const indexFieldsProvider = (): ISearchStrategy< IndexFieldsStrategyRequest, IndexFieldsStrategyResponse > => { diff --git a/x-pack/plugins/security_solution/server/search_strategy/index_fields/mock.ts b/x-pack/plugins/timelines/server/search_strategy/index_fields/mock.ts similarity index 100% rename from x-pack/plugins/security_solution/server/search_strategy/index_fields/mock.ts rename to x-pack/plugins/timelines/server/search_strategy/index_fields/mock.ts diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/eql/__mocks__/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/__mocks__/index.ts similarity index 99% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/eql/__mocks__/index.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/eql/__mocks__/index.ts index a3499b5855f503..7a2a754e8e6b9c 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/eql/__mocks__/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/__mocks__/index.ts @@ -6,7 +6,7 @@ */ import { EqlSearchStrategyResponse } from '../../../../../../../../src/plugins/data/common'; -import { EqlSearchResponse } from '../../../../../common/detection_engine/types'; +import { EqlSearchResponse } from '../../../../../common'; export const sequenceResponse = ({ rawResponse: { diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/eql/helpers.test.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/eql/helpers.test.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.test.ts diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/eql/helpers.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.ts similarity index 96% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/eql/helpers.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.ts index 65be9a773adb97..976185bb1b176d 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/eql/helpers.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.ts @@ -8,8 +8,8 @@ import { isEmpty } from 'lodash/fp'; import { EqlSearchStrategyResponse } from '../../../../../../../src/plugins/data/common'; import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../../common/constants'; -import { EqlSearchResponse, EqlSequence } from '../../../../common/detection_engine/types'; -import { EventHit, TimelineEdges } from '../../../../common/search_strategy'; +import { EqlSearchResponse, EqlSequence, EventHit } from '../../../../common'; +import { TimelineEdges } from '../../../../common/search_strategy'; import { TimelineEqlRequestOptions, TimelineEqlResponse, diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/eql/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/index.ts similarity index 91% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/eql/index.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/eql/index.ts index 56e5bd63d6b238..9c59a33a1c12ab 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/eql/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/index.ts @@ -15,14 +15,14 @@ import { EqlSearchStrategyResponse, EQL_SEARCH_STRATEGY, } from '../../../../../../../src/plugins/data/common'; -import { EqlSearchResponse } from '../../../../common/detection_engine/types'; +import { EqlSearchResponse } from '../../../../common'; import { TimelineEqlRequestOptions, TimelineEqlResponse, } from '../../../../common/search_strategy/timeline/events/eql'; import { buildEqlDsl, parseEqlResponse } from './helpers'; -export const securitySolutionTimelineEqlSearchStrategyProvider = ( +export const timelineEqlSearchStrategyProvider = ( data: PluginStart ): ISearchStrategy => { const esEql = data.search.getSearchStrategy(EQL_SEARCH_STRATEGY); diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/constants.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/constants.ts similarity index 78% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/constants.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/constants.ts index 38188a1616bfc3..aae68dbcf86d1e 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/constants.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/constants.ts @@ -5,7 +5,40 @@ * 2.0. */ -import { CTI_ROW_RENDERER_FIELDS } from '../../../../../../common/cti/constants'; +// import { CTI_ROW_RENDERER_FIELDS } from '../../../../../../common/cti/constants'; + +// TODO: share with security_solution/common/cti/constants.ts +export const INDICATOR_DESTINATION_PATH = 'threat.indicator'; + +export const MATCHED_ATOMIC = 'matched.atomic'; +export const MATCHED_FIELD = 'matched.field'; +export const MATCHED_TYPE = 'matched.type'; +export const INDICATOR_MATCH_SUBFIELDS = [MATCHED_ATOMIC, MATCHED_FIELD, MATCHED_TYPE]; + +export const INDICATOR_MATCHED_ATOMIC = `${INDICATOR_DESTINATION_PATH}.${MATCHED_ATOMIC}`; +export const INDICATOR_MATCHED_FIELD = `${INDICATOR_DESTINATION_PATH}.${MATCHED_FIELD}`; +export const INDICATOR_MATCHED_TYPE = `${INDICATOR_DESTINATION_PATH}.${MATCHED_TYPE}`; + +export const EVENT_DATASET = 'event.dataset'; +export const EVENT_REFERENCE = 'event.reference'; +export const PROVIDER = 'provider'; +export const FIRSTSEEN = 'first_seen'; + +export const INDICATOR_DATASET = `${INDICATOR_DESTINATION_PATH}.${EVENT_DATASET}`; +export const INDICATOR_EVENT_URL = `${INDICATOR_DESTINATION_PATH}.event.url`; +export const INDICATOR_FIRSTSEEN = `${INDICATOR_DESTINATION_PATH}.${FIRSTSEEN}`; +export const INDICATOR_LASTSEEN = `${INDICATOR_DESTINATION_PATH}.last_seen`; +export const INDICATOR_PROVIDER = `${INDICATOR_DESTINATION_PATH}.${PROVIDER}`; +export const INDICATOR_REFERENCE = `${INDICATOR_DESTINATION_PATH}.${EVENT_REFERENCE}`; + +export const CTI_ROW_RENDERER_FIELDS = [ + INDICATOR_MATCHED_ATOMIC, + INDICATOR_MATCHED_FIELD, + INDICATOR_MATCHED_TYPE, + INDICATOR_DATASET, + INDICATOR_REFERENCE, + INDICATOR_PROVIDER, +]; export const TIMELINE_EVENTS_FIELDS = [ '@timestamp', diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/helpers.test.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/helpers.test.ts new file mode 100644 index 00000000000000..9197917ad764f8 --- /dev/null +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/helpers.test.ts @@ -0,0 +1,570 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { eventHit } from '@kbn/securitysolution-t-grid'; +import { EventHit } from '../../../../../../common/search_strategy'; +import { TIMELINE_EVENTS_FIELDS } from './constants'; +import { buildObjectForFieldPath, formatTimelineData } from './helpers'; + +describe('#formatTimelineData', () => { + it('happy path', async () => { + const res = await formatTimelineData( + [ + '@timestamp', + 'host.name', + 'destination.ip', + 'source.ip', + 'source.geo.location', + 'threat.indicator.matched.field', + ], + TIMELINE_EVENTS_FIELDS, + eventHit + ); + expect(res).toEqual({ + cursor: { + tiebreaker: 'beats-ci-immutable-ubuntu-1804-1605624279743236239', + value: '1605624488922', + }, + node: { + _id: 'tkCt1nUBaEgqnrVSZ8R_', + _index: 'auditbeat-7.8.0-2020.11.05-000003', + data: [ + { + field: '@timestamp', + value: ['2020-11-17T14:48:08.922Z'], + }, + { + field: 'host.name', + value: ['beats-ci-immutable-ubuntu-1804-1605624279743236239'], + }, + { + field: 'threat.indicator.matched.field', + value: ['matched_field', 'other_matched_field', 'matched_field_2'], + }, + { + field: 'source.geo.location', + value: [`{"lon":118.7778,"lat":32.0617}`], + }, + ], + ecs: { + '@timestamp': ['2020-11-17T14:48:08.922Z'], + _id: 'tkCt1nUBaEgqnrVSZ8R_', + _index: 'auditbeat-7.8.0-2020.11.05-000003', + agent: { + type: ['auditbeat'], + }, + event: { + action: ['process_started'], + category: ['process'], + dataset: ['process'], + kind: ['event'], + module: ['system'], + type: ['start'], + }, + host: { + id: ['e59991e835905c65ed3e455b33e13bd6'], + ip: ['10.224.1.237', 'fe80::4001:aff:fee0:1ed', '172.17.0.1'], + name: ['beats-ci-immutable-ubuntu-1804-1605624279743236239'], + os: { + family: ['debian'], + }, + }, + message: ['Process go (PID: 4313) by user jenkins STARTED'], + process: { + args: ['go', 'vet', './...'], + entity_id: ['Z59cIkAAIw8ZoK0H'], + executable: [ + '/var/lib/jenkins/workspace/Beats_beats_PR-22624/.gvm/versions/go1.14.7.linux.amd64/bin/go', + ], + hash: { + sha1: ['1eac22336a41e0660fb302add9d97daa2bcc7040'], + }, + name: ['go'], + pid: ['4313'], + ppid: ['3977'], + working_directory: [ + '/var/lib/jenkins/workspace/Beats_beats_PR-22624/src/github.com/elastic/beats/libbeat', + ], + }, + timestamp: '2020-11-17T14:48:08.922Z', + user: { + name: ['jenkins'], + }, + threat: { + indicator: [ + { + event: { + dataset: [], + reference: [], + }, + matched: { + atomic: ['matched_atomic'], + field: ['matched_field', 'other_matched_field'], + type: [], + }, + provider: ['yourself'], + }, + { + event: { + dataset: [], + reference: [], + }, + matched: { + atomic: ['matched_atomic_2'], + field: ['matched_field_2'], + type: [], + }, + provider: ['other_you'], + }, + ], + }, + }, + }, + }); + }); + + it('rule signal results', async () => { + const response: EventHit = { + _index: '.siem-signals-patrykkopycinski-default-000007', + _id: 'a77040f198355793c35bf22b900902371309be615381f0a2ec92c208b6132562', + _score: 0, + _source: { + signal: { + threshold_result: { + count: 10000, + value: '2a990c11-f61b-4c8e-b210-da2574e9f9db', + }, + parent: { + depth: 0, + index: + 'apm-*-transaction*,auditbeat-*,endgame-*,filebeat-*,logs-*,packetbeat-*,winlogbeat-*', + id: '0268af90-d8da-576a-9747-2a191519416a', + type: 'event', + }, + depth: 1, + _meta: { + version: 14, + }, + rule: { + note: null, + throttle: null, + references: [], + severity_mapping: [], + description: 'asdasd', + created_at: '2021-01-09T11:25:45.046Z', + language: 'kuery', + threshold: { + field: '', + value: 200, + }, + building_block_type: null, + output_index: '.siem-signals-patrykkopycinski-default', + type: 'threshold', + rule_name_override: null, + enabled: true, + exceptions_list: [], + updated_at: '2021-01-09T13:36:39.204Z', + timestamp_override: null, + from: 'now-360s', + id: '696c24e0-526d-11eb-836c-e1620268b945', + timeline_id: null, + max_signals: 100, + severity: 'low', + risk_score: 21, + risk_score_mapping: [], + author: [], + query: '_id :*', + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + filters: [ + { + $state: { + store: 'appState', + }, + meta: { + negate: false, + alias: null, + disabled: false, + type: 'exists', + value: 'exists', + key: '_index', + }, + exists: { + field: '_index', + }, + }, + { + $state: { + store: 'appState', + }, + meta: { + negate: false, + alias: 'id_exists', + disabled: false, + type: 'exists', + value: 'exists', + key: '_id', + }, + exists: { + field: '_id', + }, + }, + ], + created_by: 'patryk_test_user', + version: 1, + saved_id: null, + tags: [], + rule_id: '2a990c11-f61b-4c8e-b210-da2574e9f9db', + license: '', + immutable: false, + timeline_title: null, + meta: { + from: '1m', + kibana_siem_app_url: 'http://localhost:5601/app/security', + }, + name: 'Threshold test', + updated_by: 'patryk_test_user', + interval: '5m', + false_positives: [], + to: 'now', + threat: [], + actions: [], + }, + original_time: '2021-01-09T13:39:32.595Z', + ancestors: [ + { + depth: 0, + index: + 'apm-*-transaction*,auditbeat-*,endgame-*,filebeat-*,logs-*,packetbeat-*,winlogbeat-*', + id: '0268af90-d8da-576a-9747-2a191519416a', + type: 'event', + }, + ], + parents: [ + { + depth: 0, + index: + 'apm-*-transaction*,auditbeat-*,endgame-*,filebeat-*,logs-*,packetbeat-*,winlogbeat-*', + id: '0268af90-d8da-576a-9747-2a191519416a', + type: 'event', + }, + ], + status: 'open', + }, + }, + fields: { + 'signal.rule.output_index': ['.siem-signals-patrykkopycinski-default'], + 'signal.rule.from': ['now-360s'], + 'signal.rule.language': ['kuery'], + '@timestamp': ['2021-01-09T13:41:40.517Z'], + 'signal.rule.query': ['_id :*'], + 'signal.rule.type': ['threshold'], + 'signal.rule.id': ['696c24e0-526d-11eb-836c-e1620268b945'], + 'signal.rule.risk_score': [21], + 'signal.status': ['open'], + 'event.kind': ['signal'], + 'signal.original_time': ['2021-01-09T13:39:32.595Z'], + 'signal.rule.severity': ['low'], + 'signal.rule.version': ['1'], + 'signal.rule.index': [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + 'signal.rule.name': ['Threshold test'], + 'signal.rule.to': ['now'], + }, + _type: '', + sort: ['1610199700517'], + }; + + expect( + await formatTimelineData( + ['@timestamp', 'host.name', 'destination.ip', 'source.ip'], + TIMELINE_EVENTS_FIELDS, + response + ) + ).toEqual({ + cursor: { + tiebreaker: null, + value: '', + }, + node: { + _id: 'a77040f198355793c35bf22b900902371309be615381f0a2ec92c208b6132562', + _index: '.siem-signals-patrykkopycinski-default-000007', + data: [ + { + field: '@timestamp', + value: ['2021-01-09T13:41:40.517Z'], + }, + ], + ecs: { + '@timestamp': ['2021-01-09T13:41:40.517Z'], + timestamp: '2021-01-09T13:41:40.517Z', + _id: 'a77040f198355793c35bf22b900902371309be615381f0a2ec92c208b6132562', + _index: '.siem-signals-patrykkopycinski-default-000007', + event: { + kind: ['signal'], + }, + signal: { + original_time: ['2021-01-09T13:39:32.595Z'], + status: ['open'], + threshold_result: ['{"count":10000,"value":"2a990c11-f61b-4c8e-b210-da2574e9f9db"}'], + rule: { + building_block_type: [], + exceptions_list: [], + from: ['now-360s'], + id: ['696c24e0-526d-11eb-836c-e1620268b945'], + index: [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'logs-*', + 'packetbeat-*', + 'winlogbeat-*', + ], + language: ['kuery'], + name: ['Threshold test'], + output_index: ['.siem-signals-patrykkopycinski-default'], + risk_score: ['21'], + query: ['_id :*'], + severity: ['low'], + to: ['now'], + type: ['threshold'], + version: ['1'], + timeline_id: [], + timeline_title: [], + saved_id: [], + note: [], + threshold: [ + JSON.stringify({ + field: '', + value: 200, + }), + ], + filters: [ + JSON.stringify({ + $state: { + store: 'appState', + }, + meta: { + negate: false, + alias: null, + disabled: false, + type: 'exists', + value: 'exists', + key: '_index', + }, + exists: { + field: '_index', + }, + }), + JSON.stringify({ + $state: { + store: 'appState', + }, + meta: { + negate: false, + alias: 'id_exists', + disabled: false, + type: 'exists', + value: 'exists', + key: '_id', + }, + exists: { + field: '_id', + }, + }), + ], + }, + }, + }, + }, + }); + }); + + describe('buildObjectForFieldPath', () => { + it('builds an object from a single non-nested field', () => { + expect(buildObjectForFieldPath('@timestamp', eventHit)).toEqual({ + '@timestamp': ['2020-11-17T14:48:08.922Z'], + }); + }); + + it('builds an object with no fields response', () => { + const { fields, ...fieldLessHit } = eventHit; + // @ts-expect-error fieldLessHit is intentionally missing fields + expect(buildObjectForFieldPath('@timestamp', fieldLessHit)).toEqual({ + '@timestamp': [], + }); + }); + + it('does not misinterpret non-nested fields with a common prefix', () => { + // @ts-expect-error hit is minimal + const hit: EventHit = { + fields: { + 'foo.bar': ['baz'], + 'foo.barBaz': ['foo'], + }, + }; + + expect(buildObjectForFieldPath('foo.barBaz', hit)).toEqual({ + foo: { barBaz: ['foo'] }, + }); + }); + + it('builds an array of objects from a nested field', () => { + // @ts-expect-error hit is minimal + const hit: EventHit = { + fields: { + foo: [{ bar: ['baz'] }], + }, + }; + expect(buildObjectForFieldPath('foo.bar', hit)).toEqual({ + foo: [{ bar: ['baz'] }], + }); + }); + + it('builds intermediate objects for nested fields', () => { + // @ts-expect-error nestedHit is minimal + const nestedHit: EventHit = { + fields: { + 'foo.bar': [ + { + baz: ['host.name'], + }, + ], + }, + }; + expect(buildObjectForFieldPath('foo.bar.baz', nestedHit)).toEqual({ + foo: { + bar: [ + { + baz: ['host.name'], + }, + ], + }, + }); + }); + + it('builds intermediate objects at multiple levels', () => { + expect(buildObjectForFieldPath('threat.indicator.matched.atomic', eventHit)).toEqual({ + threat: { + indicator: [ + { + matched: { + atomic: ['matched_atomic'], + }, + }, + { + matched: { + atomic: ['matched_atomic_2'], + }, + }, + ], + }, + }); + }); + + it('preserves multiple values for a single leaf', () => { + expect(buildObjectForFieldPath('threat.indicator.matched.field', eventHit)).toEqual({ + threat: { + indicator: [ + { + matched: { + field: ['matched_field', 'other_matched_field'], + }, + }, + { + matched: { + field: ['matched_field_2'], + }, + }, + ], + }, + }); + }); + + describe('multiple levels of nested fields', () => { + let nestedHit: EventHit; + + beforeEach(() => { + // @ts-expect-error nestedHit is minimal + nestedHit = { + fields: { + 'nested_1.foo': [ + { + 'nested_2.bar': [ + { leaf: ['leaf_value'], leaf_2: ['leaf_2_value'] }, + { leaf_2: ['leaf_2_value_2', 'leaf_2_value_3'] }, + ], + }, + { + 'nested_2.bar': [ + { leaf: ['leaf_value_2'], leaf_2: ['leaf_2_value_4'] }, + { leaf: ['leaf_value_3'], leaf_2: ['leaf_2_value_5'] }, + ], + }, + ], + }, + }; + }); + + it('includes objects without the field', () => { + expect(buildObjectForFieldPath('nested_1.foo.nested_2.bar.leaf', nestedHit)).toEqual({ + nested_1: { + foo: [ + { + nested_2: { + bar: [{ leaf: ['leaf_value'] }, { leaf: [] }], + }, + }, + { + nested_2: { + bar: [{ leaf: ['leaf_value_2'] }, { leaf: ['leaf_value_3'] }], + }, + }, + ], + }, + }); + }); + + it('groups multiple leaf values', () => { + expect(buildObjectForFieldPath('nested_1.foo.nested_2.bar.leaf_2', nestedHit)).toEqual({ + nested_1: { + foo: [ + { + nested_2: { + bar: [ + { leaf_2: ['leaf_2_value'] }, + { leaf_2: ['leaf_2_value_2', 'leaf_2_value_3'] }, + ], + }, + }, + { + nested_2: { + bar: [{ leaf_2: ['leaf_2_value_4'] }, { leaf_2: ['leaf_2_value_5'] }], + }, + }, + ], + }, + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/helpers.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/helpers.ts similarity index 96% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/helpers.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/helpers.ts index 8e0e5e96551934..4c07482ed53a8a 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/helpers.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/helpers.ts @@ -30,8 +30,11 @@ const getTimestamp = (hit: EventHit): string => { return ''; }; -export const buildFieldsRequest = (fields: string[]) => - uniq([...fields.filter((f) => !f.startsWith('_')), ...TIMELINE_EVENTS_FIELDS]).map((field) => ({ +export const buildFieldsRequest = (fields: string[], excludeEcsData?: boolean) => + uniq([ + ...fields.filter((f) => !f.startsWith('_')), + ...(excludeEcsData ? [] : TIMELINE_EVENTS_FIELDS), + ]).map((field) => ({ field, include_unmapped: true, })); diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/index.ts similarity index 70% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/index.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/index.ts index a26fbe05f70517..c1b567b99cfb1d 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/index.ts @@ -6,7 +6,6 @@ */ import { cloneDeep } from 'lodash/fp'; - import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../../../../common/constants'; import { IEsSearchResponse } from '../../../../../../../../../src/plugins/data/common'; import { @@ -16,33 +15,48 @@ import { TimelineEventsAllRequestOptions, TimelineEdges, } from '../../../../../../common/search_strategy'; -import { inspectStringifyObject } from '../../../../../utils/build_query'; -import { SecuritySolutionTimelineFactory } from '../../types'; +import { TimelineFactory } from '../../types'; import { buildTimelineEventsAllQuery } from './query.events_all.dsl'; import { TIMELINE_EVENTS_FIELDS } from './constants'; import { buildFieldsRequest, formatTimelineData } from './helpers'; +import { inspectStringifyObject } from '../../../../../utils/build_query'; -export const timelineEventsAll: SecuritySolutionTimelineFactory = { +export const timelineEventsAll: TimelineFactory = { buildDsl: (options: TimelineEventsAllRequestOptions) => { if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) { throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`); } const { fieldRequested, ...queryOptions } = cloneDeep(options); - queryOptions.fields = buildFieldsRequest(fieldRequested); + queryOptions.fields = buildFieldsRequest(fieldRequested, queryOptions.excludeEcsData); return buildTimelineEventsAllQuery(queryOptions); }, parse: async ( options: TimelineEventsAllRequestOptions, response: IEsSearchResponse ): Promise => { - const { fieldRequested, ...queryOptions } = cloneDeep(options); - queryOptions.fields = buildFieldsRequest(fieldRequested); + // eslint-disable-next-line prefer-const + let { fieldRequested, ...queryOptions } = cloneDeep(options); + queryOptions.fields = buildFieldsRequest(fieldRequested, queryOptions.excludeEcsData); const { activePage, querySize } = options.pagination; const totalCount = response.rawResponse.hits.total || 0; const hits = response.rawResponse.hits.hits; + + if (fieldRequested.includes('*') && hits.length > 0) { + fieldRequested = Object.keys(hits[0]?.fields ?? {}).reduce((acc, f) => { + if (!acc.includes(f)) { + return [...acc, f]; + } + return acc; + }, fieldRequested); + } + const edges: TimelineEdges[] = await Promise.all( hits.map((hit) => - formatTimelineData(options.fieldRequested, TIMELINE_EVENTS_FIELDS, hit as EventHit) + formatTimelineData( + fieldRequested, + options.excludeEcsData ? [] : TIMELINE_EVENTS_FIELDS, + hit as EventHit + ) ) ); const inspect = { diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.ts similarity index 96% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.ts index 8aa69b2d87dc9e..40df5376cefc93 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.ts @@ -13,7 +13,7 @@ import { TimelineEventsAllRequestOptions, TimelineRequestSortField, } from '../../../../../../common/search_strategy'; -import { createQueryFilterClauses } from '../../../../../utils/build_query'; +import { createQueryFilterClauses } from '../../../../../../server/utils/build_query'; export const buildTimelineEventsAllQuery = ({ defaultIndex, diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/details/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/index.ts similarity index 89% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/details/index.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/index.ts index a4d6eebfb71b83..26e6267b36d77f 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/details/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/index.ts @@ -16,8 +16,8 @@ import { TimelineEventsDetailsItem, EventSource, } from '../../../../../../common/search_strategy'; -import { inspectStringifyObject } from '../../../../../utils/build_query'; -import { SecuritySolutionTimelineFactory } from '../../types'; +import { inspectStringifyObject } from '../../../../../../server/utils/build_query'; +import { TimelineFactory } from '../../types'; import { buildTimelineDetailsQuery } from './query.events_details.dsl'; import { getDataFromFieldsHits, @@ -25,7 +25,7 @@ import { getDataSafety, } from '../../../../../../common/utils/field_formatters'; -export const timelineEventsDetails: SecuritySolutionTimelineFactory = { +export const timelineEventsDetails: TimelineFactory = { buildDsl: (options: TimelineEventsDetailsRequestOptions) => { const { indexName, eventId, docValueFields = [] } = options; return buildTimelineDetailsQuery(indexName, eventId, docValueFields); diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.test.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.test.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.test.ts diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts similarity index 100% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/index.ts similarity index 87% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/index.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/index.ts index e8de5ffc84c45e..e140fa10387047 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/index.ts @@ -10,7 +10,7 @@ import { TimelineEventsQueries, } from '../../../../../common/search_strategy/timeline'; -import { SecuritySolutionTimelineFactory } from '../types'; +import { TimelineFactory } from '../types'; import { timelineEventsAll } from './all'; import { timelineEventsDetails } from './details'; import { timelineKpi } from './kpi'; @@ -18,7 +18,7 @@ import { timelineEventsLastEventTime } from './last_event_time'; export const timelineEventsFactory: Record< TimelineEventsQueries, - SecuritySolutionTimelineFactory + TimelineFactory > = { [TimelineEventsQueries.all]: timelineEventsAll, [TimelineEventsQueries.details]: timelineEventsDetails, diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/kpi/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/index.ts similarity index 90% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/kpi/index.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/index.ts index ad9ad538c1e49c..86a7819e64156e 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/kpi/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/index.ts @@ -14,10 +14,10 @@ import { TimelineKpiStrategyResponse, } from '../../../../../../common/search_strategy/timeline'; import { inspectStringifyObject } from '../../../../../utils/build_query'; -import { SecuritySolutionTimelineFactory } from '../../types'; +import { TimelineFactory } from '../../types'; import { buildTimelineKpiQuery } from './query.kpi.dsl'; -export const timelineKpi: SecuritySolutionTimelineFactory = { +export const timelineKpi: TimelineFactory = { buildDsl: (options: TimelineRequestBasicOptions) => buildTimelineKpiQuery(options), parse: async ( options: TimelineRequestBasicOptions, diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/kpi/query.kpi.dsl.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/query.kpi.dsl.ts similarity index 96% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/kpi/query.kpi.dsl.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/query.kpi.dsl.ts index 12b0a0baead0d8..41eed7cbb4fa32 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/kpi/query.kpi.dsl.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/query.kpi.dsl.ts @@ -12,7 +12,7 @@ import { TimerangeInput, TimelineRequestBasicOptions, } from '../../../../../../common/search_strategy'; -import { createQueryFilterClauses } from '../../../../../utils/build_query'; +import { createQueryFilterClauses } from '../../../../../utils/filters'; export const buildTimelineKpiQuery = ({ defaultIndex, diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/last_event_time/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/index.ts similarity index 89% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/last_event_time/index.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/index.ts index 3b02e5621ed1ad..9b96743ff85083 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/last_event_time/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/index.ts @@ -14,10 +14,10 @@ import { TimelineEventsLastEventTimeRequestOptions, } from '../../../../../../common/search_strategy/timeline'; import { inspectStringifyObject } from '../../../../../utils/build_query'; -import { SecuritySolutionTimelineFactory } from '../../types'; +import { TimelineFactory } from '../../types'; import { buildLastEventTimeQuery } from './query.events_last_event_time.dsl'; -export const timelineEventsLastEventTime: SecuritySolutionTimelineFactory = { +export const timelineEventsLastEventTime: TimelineFactory = { buildDsl: (options: TimelineEventsLastEventTimeRequestOptions) => buildLastEventTimeQuery(options), parse: async ( diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/last_event_time/query.events_last_event_time.dsl.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/query.events_last_event_time.dsl.ts similarity index 100% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/events/last_event_time/query.events_last_event_time.dsl.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/query.events_last_event_time.dsl.ts diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/index.ts similarity index 72% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/index.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/index.ts index 264f95691b641e..2ac9c343c843a8 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/index.ts @@ -6,12 +6,12 @@ */ import { TimelineFactoryQueryTypes } from '../../../../common/search_strategy/timeline'; -import { SecuritySolutionTimelineFactory } from './types'; +import { TimelineFactory } from './types'; import { timelineEventsFactory } from './events'; -export const securitySolutionTimelineFactory: Record< +export const timelineFactory: Record< TimelineFactoryQueryTypes, - SecuritySolutionTimelineFactory + TimelineFactory > = { ...timelineEventsFactory, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/types.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/types.ts similarity index 88% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/factory/types.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/factory/types.ts index d90b25c934b916..2f0f279c5baa01 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/factory/types.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/types.ts @@ -12,7 +12,7 @@ import { TimelineStrategyResponseType, } from '../../../../common/search_strategy/timeline'; -export interface SecuritySolutionTimelineFactory { +export interface TimelineFactory { buildDsl: (options: TimelineStrategyRequestType) => unknown; parse: ( options: TimelineStrategyRequestType, diff --git a/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts similarity index 81% rename from x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts rename to x-pack/plugins/timelines/server/search_strategy/timeline/index.ts index 4dfa9831f9e6e0..dd46c0496df64d 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/timeline/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts @@ -17,10 +17,10 @@ import { TimelineStrategyResponseType, TimelineStrategyRequestType, } from '../../../common/search_strategy/timeline'; -import { securitySolutionTimelineFactory } from './factory'; -import { SecuritySolutionTimelineFactory } from './factory/types'; +import { timelineFactory } from './factory'; +import { TimelineFactory } from './factory/types'; -export const securitySolutionTimelineSearchStrategyProvider = ( +export const timelineSearchStrategyProvider = ( data: PluginStart ): ISearchStrategy, TimelineStrategyResponseType> => { const es = data.search.getSearchStrategy(ENHANCED_ES_SEARCH_STRATEGY); @@ -29,8 +29,7 @@ export const securitySolutionTimelineSearchStrategyProvider = = - securitySolutionTimelineFactory[request.factoryQueryType]; + const queryFactory: TimelineFactory = timelineFactory[request.factoryQueryType]; const dsl = queryFactory.buildDsl(request); return es.search({ ...request, params: dsl }, options, deps).pipe( map((response) => { diff --git a/x-pack/plugins/timelines/server/types.ts b/x-pack/plugins/timelines/server/types.ts index 5bcc90b48f0b99..9ea4ef430d8fd7 100644 --- a/x-pack/plugins/timelines/server/types.ts +++ b/x-pack/plugins/timelines/server/types.ts @@ -5,7 +5,18 @@ * 2.0. */ +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { DataPluginSetup, DataPluginStart } from '../../../../src/plugins/data/server/plugin'; + // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface TimelinesPluginSetup {} +export interface TimelinesPluginUI {} // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface TimelinesPluginStart {} + +export interface SetupPlugins { + data: DataPluginSetup; +} + +export interface StartPlugins { + data: DataPluginStart; +} diff --git a/x-pack/plugins/timelines/server/utils/beat_schema/fields.ts b/x-pack/plugins/timelines/server/utils/beat_schema/fields.ts new file mode 100644 index 00000000000000..4f1dc0079b2360 --- /dev/null +++ b/x-pack/plugins/timelines/server/utils/beat_schema/fields.ts @@ -0,0 +1,36119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { BeatFields } from '../../../common/search_strategy/index_fields'; + +/* eslint-disable @typescript-eslint/naming-convention */ +export const fieldsBeat: BeatFields = { + _id: { + category: 'base', + description: 'Each document has an _id that uniquely identifies it', + example: 'Y-6TfmcB0WOhS6qyMv3s', + name: '_id', + type: 'keyword', + }, + _index: { + category: 'base', + description: + 'An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.', + example: 'auditbeat-8.0.0-2019.02.19-000001', + name: '_index', + type: 'keyword', + }, + '@timestamp': { + category: 'base', + description: + 'Date/time when the event originated. This is the date/time extracted from the event, typically representing when the event was generated by the source. If the event source has no original timestamp, this value is typically populated by the first time the event was received by the pipeline. Required field for all events.', + example: '2016-05-23T08:05:34.853Z', + name: '@timestamp', + type: 'date', + }, + labels: { + category: 'base', + description: + 'Custom key/value pairs. Can be used to add meta information to events. Should not contain nested objects. All values are stored as keyword. Example: `docker` and `k8s` labels.', + example: '{"application": "foo-bar", "env": "production"}', + name: 'labels', + type: 'object', + }, + message: { + category: 'base', + description: + 'For log events the message field contains the log message, optimized for viewing in a log viewer. For structured logs without an original message field, other fields can be concatenated to form a human-readable summary of the event. If multiple messages exist, they can be combined into one message.', + example: 'Hello World', + name: 'message', + type: 'text', + }, + tags: { + category: 'base', + description: 'List of keywords used to tag each event.', + example: '["production", "env2"]', + name: 'tags', + type: 'keyword', + }, + 'agent.ephemeral_id': { + category: 'agent', + description: + 'Ephemeral identifier of this agent (if one exists). This id normally changes across restarts, but `agent.id` does not.', + example: '8a4f500f', + name: 'agent.ephemeral_id', + type: 'keyword', + }, + 'agent.id': { + category: 'agent', + description: + 'Unique identifier of this agent (if one exists). Example: For Beats this would be beat.id.', + example: '8a4f500d', + name: 'agent.id', + type: 'keyword', + }, + 'agent.name': { + category: 'agent', + description: + 'Custom name of the agent. This is a name that can be given to an agent. This can be helpful if for example two Filebeat instances are running on the same host but a human readable separation is needed on which Filebeat instance data is coming from. If no name is given, the name is often left empty.', + example: 'foo', + name: 'agent.name', + type: 'keyword', + }, + 'agent.type': { + category: 'agent', + description: + 'Type of the agent. The agent type stays always the same and should be given by the agent used. In case of Filebeat the agent would always be Filebeat also if two Filebeat instances are run on the same machine.', + example: 'filebeat', + name: 'agent.type', + type: 'keyword', + }, + 'agent.version': { + category: 'agent', + description: 'Version of the agent.', + example: '6.0.0-rc2', + name: 'agent.version', + type: 'keyword', + }, + 'as.number': { + category: 'as', + description: + 'Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet.', + example: 15169, + name: 'as.number', + type: 'long', + }, + 'as.organization.name': { + category: 'as', + description: 'Organization name.', + example: 'Google LLC', + name: 'as.organization.name', + type: 'keyword', + }, + 'client.address': { + category: 'client', + description: + 'Some event client addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the `.address` field. Then it should be duplicated to `.ip` or `.domain`, depending on which one it is.', + name: 'client.address', + type: 'keyword', + }, + 'client.as.number': { + category: 'client', + description: + 'Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet.', + example: 15169, + name: 'client.as.number', + type: 'long', + }, + 'client.as.organization.name': { + category: 'client', + description: 'Organization name.', + example: 'Google LLC', + name: 'client.as.organization.name', + type: 'keyword', + }, + 'client.bytes': { + category: 'client', + description: 'Bytes sent from the client to the server.', + example: 184, + name: 'client.bytes', + type: 'long', + format: 'bytes', + }, + 'client.domain': { + category: 'client', + description: 'Client domain.', + name: 'client.domain', + type: 'keyword', + }, + 'client.geo.city_name': { + category: 'client', + description: 'City name.', + example: 'Montreal', + name: 'client.geo.city_name', + type: 'keyword', + }, + 'client.geo.continent_name': { + category: 'client', + description: 'Name of the continent.', + example: 'North America', + name: 'client.geo.continent_name', + type: 'keyword', + }, + 'client.geo.country_iso_code': { + category: 'client', + description: 'Country ISO code.', + example: 'CA', + name: 'client.geo.country_iso_code', + type: 'keyword', + }, + 'client.geo.country_name': { + category: 'client', + description: 'Country name.', + example: 'Canada', + name: 'client.geo.country_name', + type: 'keyword', + }, + 'client.geo.location': { + category: 'client', + description: 'Longitude and latitude.', + example: '{ "lon": -73.614830, "lat": 45.505918 }', + name: 'client.geo.location', + type: 'geo_point', + }, + 'client.geo.name': { + category: 'client', + description: + 'User-defined description of a location, at the level of granularity they care about. Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. Not typically used in automated geolocation.', + example: 'boston-dc', + name: 'client.geo.name', + type: 'keyword', + }, + 'client.geo.region_iso_code': { + category: 'client', + description: 'Region ISO code.', + example: 'CA-QC', + name: 'client.geo.region_iso_code', + type: 'keyword', + }, + 'client.geo.region_name': { + category: 'client', + description: 'Region name.', + example: 'Quebec', + name: 'client.geo.region_name', + type: 'keyword', + }, + 'client.ip': { + category: 'client', + description: 'IP address of the client. Can be one or multiple IPv4 or IPv6 addresses.', + name: 'client.ip', + type: 'ip', + }, + 'client.mac': { + category: 'client', + description: 'MAC address of the client.', + name: 'client.mac', + type: 'keyword', + }, + 'client.nat.ip': { + category: 'client', + description: + 'Translated IP of source based NAT sessions (e.g. internal client to internet). Typically connections traversing load balancers, firewalls, or routers.', + name: 'client.nat.ip', + type: 'ip', + }, + 'client.nat.port': { + category: 'client', + description: + 'Translated port of source based NAT sessions (e.g. internal client to internet). Typically connections traversing load balancers, firewalls, or routers.', + name: 'client.nat.port', + type: 'long', + format: 'string', + }, + 'client.packets': { + category: 'client', + description: 'Packets sent from the client to the server.', + example: 12, + name: 'client.packets', + type: 'long', + }, + 'client.port': { + category: 'client', + description: 'Port of the client.', + name: 'client.port', + type: 'long', + format: 'string', + }, + 'client.registered_domain': { + category: 'client', + description: + 'The highest registered client domain, stripped of the subdomain. For example, the registered domain for "foo.google.com" is "google.com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk".', + example: 'google.com', + name: 'client.registered_domain', + type: 'keyword', + }, + 'client.top_level_domain': { + category: 'client', + description: + 'The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for google.com is "com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk".', + example: 'co.uk', + name: 'client.top_level_domain', + type: 'keyword', + }, + 'client.user.domain': { + category: 'client', + description: + 'Name of the directory the user is a member of. For example, an LDAP or Active Directory domain name.', + name: 'client.user.domain', + type: 'keyword', + }, + 'client.user.email': { + category: 'client', + description: 'User email address.', + name: 'client.user.email', + type: 'keyword', + }, + 'client.user.full_name': { + category: 'client', + description: "User's full name, if available.", + example: 'Albert Einstein', + name: 'client.user.full_name', + type: 'keyword', + }, + 'client.user.group.domain': { + category: 'client', + description: + 'Name of the directory the group is a member of. For example, an LDAP or Active Directory domain name.', + name: 'client.user.group.domain', + type: 'keyword', + }, + 'client.user.group.id': { + category: 'client', + description: 'Unique identifier for the group on the system/platform.', + name: 'client.user.group.id', + type: 'keyword', + }, + 'client.user.group.name': { + category: 'client', + description: 'Name of the group.', + name: 'client.user.group.name', + type: 'keyword', + }, + 'client.user.hash': { + category: 'client', + description: + 'Unique user hash to correlate information for a user in anonymized form. Useful if `user.id` or `user.name` contain confidential information and cannot be used.', + name: 'client.user.hash', + type: 'keyword', + }, + 'client.user.id': { + category: 'client', + description: 'Unique identifiers of the user.', + name: 'client.user.id', + type: 'keyword', + }, + 'client.user.name': { + category: 'client', + description: 'Short name or login of the user.', + example: 'albert', + name: 'client.user.name', + type: 'keyword', + }, + 'cloud.account.id': { + category: 'cloud', + description: + 'The cloud account or organization id used to identify different entities in a multi-tenant environment. Examples: AWS account id, Google Cloud ORG Id, or other unique identifier.', + example: 666777888999, + name: 'cloud.account.id', + type: 'keyword', + }, + 'cloud.availability_zone': { + category: 'cloud', + description: 'Availability zone in which this host is running.', + example: 'us-east-1c', + name: 'cloud.availability_zone', + type: 'keyword', + }, + 'cloud.instance.id': { + category: 'cloud', + description: 'Instance ID of the host machine.', + example: 'i-1234567890abcdef0', + name: 'cloud.instance.id', + type: 'keyword', + }, + 'cloud.instance.name': { + category: 'cloud', + description: 'Instance name of the host machine.', + name: 'cloud.instance.name', + type: 'keyword', + }, + 'cloud.machine.type': { + category: 'cloud', + description: 'Machine type of the host machine.', + example: 't2.medium', + name: 'cloud.machine.type', + type: 'keyword', + }, + 'cloud.provider': { + category: 'cloud', + description: 'Name of the cloud provider. Example values are aws, azure, gcp, or digitalocean.', + example: 'aws', + name: 'cloud.provider', + type: 'keyword', + }, + 'cloud.region': { + category: 'cloud', + description: 'Region in which this host is running.', + example: 'us-east-1', + name: 'cloud.region', + type: 'keyword', + }, + 'code_signature.exists': { + category: 'code_signature', + description: 'Boolean to capture if a signature is present.', + example: 'true', + name: 'code_signature.exists', + type: 'boolean', + }, + 'code_signature.status': { + category: 'code_signature', + description: + 'Additional information about the certificate status. This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked.', + example: 'ERROR_UNTRUSTED_ROOT', + name: 'code_signature.status', + type: 'keyword', + }, + 'code_signature.subject_name': { + category: 'code_signature', + description: 'Subject name of the code signer', + example: 'Microsoft Corporation', + name: 'code_signature.subject_name', + type: 'keyword', + }, + 'code_signature.trusted': { + category: 'code_signature', + description: + 'Stores the trust status of the certificate chain. Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status.', + example: 'true', + name: 'code_signature.trusted', + type: 'boolean', + }, + 'code_signature.valid': { + category: 'code_signature', + description: + 'Boolean to capture if the digital signature is verified against the binary content. Leave unpopulated if a certificate was unchecked.', + example: 'true', + name: 'code_signature.valid', + type: 'boolean', + }, + 'container.id': { + category: 'container', + description: 'Unique container id.', + name: 'container.id', + type: 'keyword', + }, + 'container.image.name': { + category: 'container', + description: 'Name of the image the container was built on.', + name: 'container.image.name', + type: 'keyword', + }, + 'container.image.tag': { + category: 'container', + description: 'Container image tags.', + name: 'container.image.tag', + type: 'keyword', + }, + 'container.labels': { + category: 'container', + description: 'Image labels.', + name: 'container.labels', + type: 'object', + }, + 'container.name': { + category: 'container', + description: 'Container name.', + name: 'container.name', + type: 'keyword', + }, + 'container.runtime': { + category: 'container', + description: 'Runtime managing this container.', + example: 'docker', + name: 'container.runtime', + type: 'keyword', + }, + 'destination.address': { + category: 'destination', + description: + 'Some event destination addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the `.address` field. Then it should be duplicated to `.ip` or `.domain`, depending on which one it is.', + name: 'destination.address', + type: 'keyword', + }, + 'destination.as.number': { + category: 'destination', + description: + 'Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet.', + example: 15169, + name: 'destination.as.number', + type: 'long', + }, + 'destination.as.organization.name': { + category: 'destination', + description: 'Organization name.', + example: 'Google LLC', + name: 'destination.as.organization.name', + type: 'keyword', + }, + 'destination.bytes': { + category: 'destination', + description: 'Bytes sent from the destination to the source.', + example: 184, + name: 'destination.bytes', + type: 'long', + format: 'bytes', + }, + 'destination.domain': { + category: 'destination', + description: 'Destination domain.', + name: 'destination.domain', + type: 'keyword', + }, + 'destination.geo.city_name': { + category: 'destination', + description: 'City name.', + example: 'Montreal', + name: 'destination.geo.city_name', + type: 'keyword', + }, + 'destination.geo.continent_name': { + category: 'destination', + description: 'Name of the continent.', + example: 'North America', + name: 'destination.geo.continent_name', + type: 'keyword', + }, + 'destination.geo.country_iso_code': { + category: 'destination', + description: 'Country ISO code.', + example: 'CA', + name: 'destination.geo.country_iso_code', + type: 'keyword', + }, + 'destination.geo.country_name': { + category: 'destination', + description: 'Country name.', + example: 'Canada', + name: 'destination.geo.country_name', + type: 'keyword', + }, + 'destination.geo.location': { + category: 'destination', + description: 'Longitude and latitude.', + example: '{ "lon": -73.614830, "lat": 45.505918 }', + name: 'destination.geo.location', + type: 'geo_point', + }, + 'destination.geo.name': { + category: 'destination', + description: + 'User-defined description of a location, at the level of granularity they care about. Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. Not typically used in automated geolocation.', + example: 'boston-dc', + name: 'destination.geo.name', + type: 'keyword', + }, + 'destination.geo.region_iso_code': { + category: 'destination', + description: 'Region ISO code.', + example: 'CA-QC', + name: 'destination.geo.region_iso_code', + type: 'keyword', + }, + 'destination.geo.region_name': { + category: 'destination', + description: 'Region name.', + example: 'Quebec', + name: 'destination.geo.region_name', + type: 'keyword', + }, + 'destination.ip': { + category: 'destination', + description: 'IP address of the destination. Can be one or multiple IPv4 or IPv6 addresses.', + name: 'destination.ip', + type: 'ip', + }, + 'destination.mac': { + category: 'destination', + description: 'MAC address of the destination.', + name: 'destination.mac', + type: 'keyword', + }, + 'destination.nat.ip': { + category: 'destination', + description: + 'Translated ip of destination based NAT sessions (e.g. internet to private DMZ) Typically used with load balancers, firewalls, or routers.', + name: 'destination.nat.ip', + type: 'ip', + }, + 'destination.nat.port': { + category: 'destination', + description: + 'Port the source session is translated to by NAT Device. Typically used with load balancers, firewalls, or routers.', + name: 'destination.nat.port', + type: 'long', + format: 'string', + }, + 'destination.packets': { + category: 'destination', + description: 'Packets sent from the destination to the source.', + example: 12, + name: 'destination.packets', + type: 'long', + }, + 'destination.port': { + category: 'destination', + description: 'Port of the destination.', + name: 'destination.port', + type: 'long', + format: 'string', + }, + 'destination.registered_domain': { + category: 'destination', + description: + 'The highest registered destination domain, stripped of the subdomain. For example, the registered domain for "foo.google.com" is "google.com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk".', + example: 'google.com', + name: 'destination.registered_domain', + type: 'keyword', + }, + 'destination.top_level_domain': { + category: 'destination', + description: + 'The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for google.com is "com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk".', + example: 'co.uk', + name: 'destination.top_level_domain', + type: 'keyword', + }, + 'destination.user.domain': { + category: 'destination', + description: + 'Name of the directory the user is a member of. For example, an LDAP or Active Directory domain name.', + name: 'destination.user.domain', + type: 'keyword', + }, + 'destination.user.email': { + category: 'destination', + description: 'User email address.', + name: 'destination.user.email', + type: 'keyword', + }, + 'destination.user.full_name': { + category: 'destination', + description: "User's full name, if available.", + example: 'Albert Einstein', + name: 'destination.user.full_name', + type: 'keyword', + }, + 'destination.user.group.domain': { + category: 'destination', + description: + 'Name of the directory the group is a member of. For example, an LDAP or Active Directory domain name.', + name: 'destination.user.group.domain', + type: 'keyword', + }, + 'destination.user.group.id': { + category: 'destination', + description: 'Unique identifier for the group on the system/platform.', + name: 'destination.user.group.id', + type: 'keyword', + }, + 'destination.user.group.name': { + category: 'destination', + description: 'Name of the group.', + name: 'destination.user.group.name', + type: 'keyword', + }, + 'destination.user.hash': { + category: 'destination', + description: + 'Unique user hash to correlate information for a user in anonymized form. Useful if `user.id` or `user.name` contain confidential information and cannot be used.', + name: 'destination.user.hash', + type: 'keyword', + }, + 'destination.user.id': { + category: 'destination', + description: 'Unique identifiers of the user.', + name: 'destination.user.id', + type: 'keyword', + }, + 'destination.user.name': { + category: 'destination', + description: 'Short name or login of the user.', + example: 'albert', + name: 'destination.user.name', + type: 'keyword', + }, + 'dll.code_signature.exists': { + category: 'dll', + description: 'Boolean to capture if a signature is present.', + example: 'true', + name: 'dll.code_signature.exists', + type: 'boolean', + }, + 'dll.code_signature.status': { + category: 'dll', + description: + 'Additional information about the certificate status. This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked.', + example: 'ERROR_UNTRUSTED_ROOT', + name: 'dll.code_signature.status', + type: 'keyword', + }, + 'dll.code_signature.subject_name': { + category: 'dll', + description: 'Subject name of the code signer', + example: 'Microsoft Corporation', + name: 'dll.code_signature.subject_name', + type: 'keyword', + }, + 'dll.code_signature.trusted': { + category: 'dll', + description: + 'Stores the trust status of the certificate chain. Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status.', + example: 'true', + name: 'dll.code_signature.trusted', + type: 'boolean', + }, + 'dll.code_signature.valid': { + category: 'dll', + description: + 'Boolean to capture if the digital signature is verified against the binary content. Leave unpopulated if a certificate was unchecked.', + example: 'true', + name: 'dll.code_signature.valid', + type: 'boolean', + }, + 'dll.hash.md5': { + category: 'dll', + description: 'MD5 hash.', + name: 'dll.hash.md5', + type: 'keyword', + }, + 'dll.hash.sha1': { + category: 'dll', + description: 'SHA1 hash.', + name: 'dll.hash.sha1', + type: 'keyword', + }, + 'dll.hash.sha256': { + category: 'dll', + description: 'SHA256 hash.', + name: 'dll.hash.sha256', + type: 'keyword', + }, + 'dll.hash.sha512': { + category: 'dll', + description: 'SHA512 hash.', + name: 'dll.hash.sha512', + type: 'keyword', + }, + 'dll.name': { + category: 'dll', + description: 'Name of the library. This generally maps to the name of the file on disk.', + example: 'kernel32.dll', + name: 'dll.name', + type: 'keyword', + }, + 'dll.path': { + category: 'dll', + description: 'Full file path of the library.', + example: 'C:\\Windows\\System32\\kernel32.dll', + name: 'dll.path', + type: 'keyword', + }, + 'dll.pe.company': { + category: 'dll', + description: 'Internal company name of the file, provided at compile-time.', + example: 'Microsoft Corporation', + name: 'dll.pe.company', + type: 'keyword', + }, + 'dll.pe.description': { + category: 'dll', + description: 'Internal description of the file, provided at compile-time.', + example: 'Paint', + name: 'dll.pe.description', + type: 'keyword', + }, + 'dll.pe.file_version': { + category: 'dll', + description: 'Internal version of the file, provided at compile-time.', + example: '6.3.9600.17415', + name: 'dll.pe.file_version', + type: 'keyword', + }, + 'dll.pe.original_file_name': { + category: 'dll', + description: 'Internal name of the file, provided at compile-time.', + example: 'MSPAINT.EXE', + name: 'dll.pe.original_file_name', + type: 'keyword', + }, + 'dll.pe.product': { + category: 'dll', + description: 'Internal product name of the file, provided at compile-time.', + example: 'Microsoft® Windows® Operating System', + name: 'dll.pe.product', + type: 'keyword', + }, + 'dns.answers': { + category: 'dns', + description: + 'An array containing an object for each answer section returned by the server. The main keys that should be present in these objects are defined by ECS. Records that have more information may contain more keys than what ECS defines. Not all DNS data sources give all details about DNS answers. At minimum, answer objects must contain the `data` key. If more information is available, map as much of it to ECS as possible, and add any additional fields to the answer objects as custom fields.', + name: 'dns.answers', + type: 'object', + }, + 'dns.answers.class': { + category: 'dns', + description: 'The class of DNS data contained in this resource record.', + example: 'IN', + name: 'dns.answers.class', + type: 'keyword', + }, + 'dns.answers.data': { + category: 'dns', + description: + 'The data describing the resource. The meaning of this data depends on the type and class of the resource record.', + example: '10.10.10.10', + name: 'dns.answers.data', + type: 'keyword', + }, + 'dns.answers.name': { + category: 'dns', + description: + "The domain name to which this resource record pertains. If a chain of CNAME is being resolved, each answer's `name` should be the one that corresponds with the answer's `data`. It should not simply be the original `question.name` repeated.", + example: 'www.google.com', + name: 'dns.answers.name', + type: 'keyword', + }, + 'dns.answers.ttl': { + category: 'dns', + description: + 'The time interval in seconds that this resource record may be cached before it should be discarded. Zero values mean that the data should not be cached.', + example: 180, + name: 'dns.answers.ttl', + type: 'long', + }, + 'dns.answers.type': { + category: 'dns', + description: 'The type of data contained in this resource record.', + example: 'CNAME', + name: 'dns.answers.type', + type: 'keyword', + }, + 'dns.header_flags': { + category: 'dns', + description: + 'Array of 2 letter DNS header flags. Expected values are: AA, TC, RD, RA, AD, CD, DO.', + example: '["RD","RA"]', + name: 'dns.header_flags', + type: 'keyword', + }, + 'dns.id': { + category: 'dns', + description: + 'The DNS packet identifier assigned by the program that generated the query. The identifier is copied to the response.', + example: 62111, + name: 'dns.id', + type: 'keyword', + }, + 'dns.op_code': { + category: 'dns', + description: + 'The DNS operation code that specifies the kind of query in the message. This value is set by the originator of a query and copied into the response.', + example: 'QUERY', + name: 'dns.op_code', + type: 'keyword', + }, + 'dns.question.class': { + category: 'dns', + description: 'The class of records being queried.', + example: 'IN', + name: 'dns.question.class', + type: 'keyword', + }, + 'dns.question.name': { + category: 'dns', + description: + 'The name being queried. If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \\t, \\r, and \\n respectively.', + example: 'www.google.com', + name: 'dns.question.name', + type: 'keyword', + }, + 'dns.question.registered_domain': { + category: 'dns', + description: + 'The highest registered domain, stripped of the subdomain. For example, the registered domain for "foo.google.com" is "google.com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk".', + example: 'google.com', + name: 'dns.question.registered_domain', + type: 'keyword', + }, + 'dns.question.subdomain': { + category: 'dns', + description: + 'The subdomain is all of the labels under the registered_domain. If the domain has multiple levels of subdomain, such as "sub2.sub1.example.com", the subdomain field should contain "sub2.sub1", with no trailing period.', + example: 'www', + name: 'dns.question.subdomain', + type: 'keyword', + }, + 'dns.question.top_level_domain': { + category: 'dns', + description: + 'The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for google.com is "com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk".', + example: 'co.uk', + name: 'dns.question.top_level_domain', + type: 'keyword', + }, + 'dns.question.type': { + category: 'dns', + description: 'The type of record being queried.', + example: 'AAAA', + name: 'dns.question.type', + type: 'keyword', + }, + 'dns.resolved_ip': { + category: 'dns', + description: + 'Array containing all IPs seen in `answers.data`. The `answers` array can be difficult to use, because of the variety of data formats it can contain. Extracting all IP addresses seen in there to `dns.resolved_ip` makes it possible to index them as IP addresses, and makes them easier to visualize and query for.', + example: '["10.10.10.10","10.10.10.11"]', + name: 'dns.resolved_ip', + type: 'ip', + }, + 'dns.response_code': { + category: 'dns', + description: 'The DNS response code.', + example: 'NOERROR', + name: 'dns.response_code', + type: 'keyword', + }, + 'dns.type': { + category: 'dns', + description: + 'The type of DNS event captured, query or answer. If your source of DNS events only gives you DNS queries, you should only create dns events of type `dns.type:query`. If your source of DNS events gives you answers as well, you should create one event per query (optionally as soon as the query is seen). And a second event containing all query details as well as an array of answers.', + example: 'answer', + name: 'dns.type', + type: 'keyword', + }, + 'ecs.version': { + category: 'ecs', + description: + 'ECS version this event conforms to. `ecs.version` is a required field and must exist in all events. When querying across multiple indices -- which may conform to slightly different ECS versions -- this field lets integrations adjust to the schema version of the events.', + example: '1.0.0', + name: 'ecs.version', + type: 'keyword', + }, + 'error.code': { + category: 'error', + description: 'Error code describing the error.', + name: 'error.code', + type: 'keyword', + }, + 'error.id': { + category: 'error', + description: 'Unique identifier for the error.', + name: 'error.id', + type: 'keyword', + }, + 'error.message': { + category: 'error', + description: 'Error message.', + name: 'error.message', + type: 'text', + }, + 'error.stack_trace': { + category: 'error', + description: 'The stack trace of this error in plain text.', + name: 'error.stack_trace', + type: 'keyword', + }, + 'error.type': { + category: 'error', + description: 'The type of the error, for example the class name of the exception.', + example: 'java.lang.NullPointerException', + name: 'error.type', + type: 'keyword', + }, + 'event.action': { + category: 'event', + description: + 'The action captured by the event. This describes the information in the event. It is more specific than `event.category`. Examples are `group-add`, `process-started`, `file-created`. The value is normally defined by the implementer.', + example: 'user-password-change', + name: 'event.action', + type: 'keyword', + }, + 'event.category': { + category: 'event', + description: + 'This is one of four ECS Categorization Fields, and indicates the second level in the ECS category hierarchy. `event.category` represents the "big buckets" of ECS categories. For example, filtering on `event.category:process` yields all events relating to process activity. This field is closely related to `event.type`, which is used as a subcategory. This field is an array. This will allow proper categorization of some events that fall in multiple categories.', + example: 'authentication', + name: 'event.category', + type: 'keyword', + }, + 'event.code': { + category: 'event', + description: + 'Identification code for this event, if one exists. Some event sources use event codes to identify messages unambiguously, regardless of message language or wording adjustments over time. An example of this is the Windows Event ID.', + example: 4648, + name: 'event.code', + type: 'keyword', + }, + 'event.created': { + category: 'event', + description: + "event.created contains the date/time when the event was first read by an agent, or by your pipeline. This field is distinct from @timestamp in that @timestamp typically contain the time extracted from the original event. In most situations, these two timestamps will be slightly different. The difference can be used to calculate the delay between your source generating an event, and the time when your agent first processed it. This can be used to monitor your agent's or pipeline's ability to keep up with your event source. In case the two timestamps are identical, @timestamp should be used.", + example: '2016-05-23T08:05:34.857Z', + name: 'event.created', + type: 'date', + }, + 'event.dataset': { + category: 'event', + description: + "Name of the dataset. If an event source publishes more than one type of log or events (e.g. access log, error log), the dataset is used to specify which one the event comes from. It's recommended but not required to start the dataset name with the module name, followed by a dot, then the dataset name.", + example: 'apache.access', + name: 'event.dataset', + type: 'keyword', + }, + 'event.duration': { + category: 'event', + description: + 'Duration of the event in nanoseconds. If event.start and event.end are known this value should be the difference between the end and start time.', + name: 'event.duration', + type: 'long', + format: 'duration', + }, + 'event.end': { + category: 'event', + description: + 'event.end contains the date when the event ended or when the activity was last observed.', + name: 'event.end', + type: 'date', + }, + 'event.hash': { + category: 'event', + description: + 'Hash (perhaps logstash fingerprint) of raw field to be able to demonstrate log integrity.', + example: '123456789012345678901234567890ABCD', + name: 'event.hash', + type: 'keyword', + }, + 'event.id': { + category: 'event', + description: 'Unique ID to describe the event.', + example: '8a4f500d', + name: 'event.id', + type: 'keyword', + }, + 'event.ingested': { + category: 'event', + description: + "Timestamp when an event arrived in the central data store. This is different from `@timestamp`, which is when the event originally occurred. It's also different from `event.created`, which is meant to capture the first time an agent saw the event. In normal conditions, assuming no tampering, the timestamps should chronologically look like this: `@timestamp` < `event.created` < `event.ingested`.", + example: '2016-05-23T08:05:35.101Z', + name: 'event.ingested', + type: 'date', + }, + 'event.kind': { + category: 'event', + description: + 'This is one of four ECS Categorization Fields, and indicates the highest level in the ECS category hierarchy. `event.kind` gives high-level information about what type of information the event contains, without being specific to the contents of the event. For example, values of this field distinguish alert events from metric events. The value of this field can be used to inform how these kinds of events should be handled. They may warrant different retention, different access control, it may also help understand whether the data coming in at a regular interval or not.', + example: 'alert', + name: 'event.kind', + type: 'keyword', + }, + 'event.module': { + category: 'event', + description: + 'Name of the module this data is coming from. If your monitoring agent supports the concept of modules or plugins to process events of a given source (e.g. Apache logs), `event.module` should contain the name of this module.', + example: 'apache', + name: 'event.module', + type: 'keyword', + }, + 'event.original': { + category: 'event', + description: + 'Raw text message of entire event. Used to demonstrate log integrity. This field is not indexed and doc_values are disabled. It cannot be searched, but it can be retrieved from `_source`.', + example: + 'Sep 19 08:26:10 host CEF:0|Security| threatmanager|1.0|100| worm successfully stopped|10|src=10.0.0.1 dst=2.1.2.2spt=1232', + name: 'event.original', + type: 'keyword', + }, + 'event.outcome': { + category: 'event', + description: + 'This is one of four ECS Categorization Fields, and indicates the lowest level in the ECS category hierarchy. `event.outcome` simply denotes whether the event represents a success or a failure from the perspective of the entity that produced the event. Note that when a single transaction is described in multiple events, each event may populate different values of `event.outcome`, according to their perspective. Also note that in the case of a compound event (a single event that contains multiple logical events), this field should be populated with the value that best captures the overall success or failure from the perspective of the event producer. Further note that not all events will have an associated outcome. For example, this field is generally not populated for metric events, events with `event.type:info`, or any events for which an outcome does not make logical sense.', + example: 'success', + name: 'event.outcome', + type: 'keyword', + }, + 'event.provider': { + category: 'event', + description: + 'Source of the event. Event transports such as Syslog or the Windows Event Log typically mention the source of an event. It can be the name of the software that generated the event (e.g. Sysmon, httpd), or of a subsystem of the operating system (kernel, Microsoft-Windows-Security-Auditing).', + example: 'kernel', + name: 'event.provider', + type: 'keyword', + }, + 'event.reference': { + category: 'event', + description: + 'Reference URL linking to additional information about this event. This URL links to a static definition of the this event. Alert events, indicated by `event.kind:alert`, are a common use case for this field.', + example: 'https://system.vendor.com/event/#0001234', + name: 'event.reference', + type: 'keyword', + }, + 'event.risk_score': { + category: 'event', + description: + "Risk score or priority of the event (e.g. security solutions). Use your system's original value here.", + name: 'event.risk_score', + type: 'float', + }, + 'event.risk_score_norm': { + category: 'event', + description: + 'Normalized risk score or priority of the event, on a scale of 0 to 100. This is mainly useful if you use more than one system that assigns risk scores, and you want to see a normalized value across all systems.', + name: 'event.risk_score_norm', + type: 'float', + }, + 'event.sequence': { + category: 'event', + description: + 'Sequence number of the event. The sequence number is a value published by some event sources, to make the exact ordering of events unambiguous, regardless of the timestamp precision.', + name: 'event.sequence', + type: 'long', + format: 'string', + }, + 'event.severity': { + category: 'event', + description: + "The numeric severity of the event according to your event source. What the different severity values mean can be different between sources and use cases. It's up to the implementer to make sure severities are consistent across events from the same source. The Syslog severity belongs in `log.syslog.severity.code`. `event.severity` is meant to represent the severity according to the event source (e.g. firewall, IDS). If the event source does not publish its own severity, you may optionally copy the `log.syslog.severity.code` to `event.severity`.", + example: 7, + name: 'event.severity', + type: 'long', + format: 'string', + }, + 'event.start': { + category: 'event', + description: + 'event.start contains the date when the event started or when the activity was first observed.', + name: 'event.start', + type: 'date', + }, + 'event.timezone': { + category: 'event', + description: + 'This field should be populated when the event\'s timestamp does not include timezone information already (e.g. default Syslog timestamps). It\'s optional otherwise. Acceptable timezone formats are: a canonical ID (e.g. "Europe/Amsterdam"), abbreviated (e.g. "EST") or an HH:mm differential (e.g. "-05:00").', + name: 'event.timezone', + type: 'keyword', + }, + 'event.type': { + category: 'event', + description: + 'This is one of four ECS Categorization Fields, and indicates the third level in the ECS category hierarchy. `event.type` represents a categorization "sub-bucket" that, when used along with the `event.category` field values, enables filtering events down to a level appropriate for single visualization. This field is an array. This will allow proper categorization of some events that fall in multiple event types.', + name: 'event.type', + type: 'keyword', + }, + 'event.url': { + category: 'event', + description: + 'URL linking to an external system to continue investigation of this event. This URL links to another system where in-depth investigation of the specific occurence of this event can take place. Alert events, indicated by `event.kind:alert`, are a common use case for this field.', + example: 'https://mysystem.mydomain.com/alert/5271dedb-f5b0-4218-87f0-4ac4870a38fe', + name: 'event.url', + type: 'keyword', + }, + 'file.accessed': { + category: 'file', + description: + 'Last time the file was accessed. Note that not all filesystems keep track of access time.', + name: 'file.accessed', + type: 'date', + }, + 'file.attributes': { + category: 'file', + description: + "Array of file attributes. Attributes names will vary by platform. Here's a non-exhaustive list of values that are expected in this field: archive, compressed, directory, encrypted, execute, hidden, read, readonly, system, write.", + example: '["readonly", "system"]', + name: 'file.attributes', + type: 'keyword', + }, + 'file.code_signature.exists': { + category: 'file', + description: 'Boolean to capture if a signature is present.', + example: 'true', + name: 'file.code_signature.exists', + type: 'boolean', + }, + 'file.code_signature.status': { + category: 'file', + description: + 'Additional information about the certificate status. This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked.', + example: 'ERROR_UNTRUSTED_ROOT', + name: 'file.code_signature.status', + type: 'keyword', + }, + 'file.code_signature.subject_name': { + category: 'file', + description: 'Subject name of the code signer', + example: 'Microsoft Corporation', + name: 'file.code_signature.subject_name', + type: 'keyword', + }, + 'file.code_signature.trusted': { + category: 'file', + description: + 'Stores the trust status of the certificate chain. Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status.', + example: 'true', + name: 'file.code_signature.trusted', + type: 'boolean', + }, + 'file.code_signature.valid': { + category: 'file', + description: + 'Boolean to capture if the digital signature is verified against the binary content. Leave unpopulated if a certificate was unchecked.', + example: 'true', + name: 'file.code_signature.valid', + type: 'boolean', + }, + 'file.created': { + category: 'file', + description: 'File creation time. Note that not all filesystems store the creation time.', + name: 'file.created', + type: 'date', + }, + 'file.ctime': { + category: 'file', + description: + 'Last time the file attributes or metadata changed. Note that changes to the file content will update `mtime`. This implies `ctime` will be adjusted at the same time, since `mtime` is an attribute of the file.', + name: 'file.ctime', + type: 'date', + }, + 'file.device': { + category: 'file', + description: 'Device that is the source of the file.', + example: 'sda', + name: 'file.device', + type: 'keyword', + }, + 'file.directory': { + category: 'file', + description: + 'Directory where the file is located. It should include the drive letter, when appropriate.', + example: '/home/alice', + name: 'file.directory', + type: 'keyword', + }, + 'file.drive_letter': { + category: 'file', + description: + 'Drive letter where the file is located. This field is only relevant on Windows. The value should be uppercase, and not include the colon.', + example: 'C', + name: 'file.drive_letter', + type: 'keyword', + }, + 'file.extension': { + category: 'file', + description: 'File extension.', + example: 'png', + name: 'file.extension', + type: 'keyword', + }, + 'file.gid': { + category: 'file', + description: 'Primary group ID (GID) of the file.', + example: '1001', + name: 'file.gid', + type: 'keyword', + }, + 'file.group': { + category: 'file', + description: 'Primary group name of the file.', + example: 'alice', + name: 'file.group', + type: 'keyword', + }, + 'file.hash.md5': { + category: 'file', + description: 'MD5 hash.', + name: 'file.hash.md5', + type: 'keyword', + }, + 'file.hash.sha1': { + category: 'file', + description: 'SHA1 hash.', + name: 'file.hash.sha1', + type: 'keyword', + }, + 'file.hash.sha256': { + category: 'file', + description: 'SHA256 hash.', + name: 'file.hash.sha256', + type: 'keyword', + }, + 'file.hash.sha512': { + category: 'file', + description: 'SHA512 hash.', + name: 'file.hash.sha512', + type: 'keyword', + }, + 'file.inode': { + category: 'file', + description: 'Inode representing the file in the filesystem.', + example: '256383', + name: 'file.inode', + type: 'keyword', + }, + 'file.mime_type': { + category: 'file', + description: + 'MIME type should identify the format of the file or stream of bytes using https://www.iana.org/assignments/media-types/media-types.xhtml[IANA official types], where possible. When more than one type is applicable, the most specific type should be used.', + name: 'file.mime_type', + type: 'keyword', + }, + 'file.mode': { + category: 'file', + description: 'Mode of the file in octal representation.', + example: '0640', + name: 'file.mode', + type: 'keyword', + }, + 'file.mtime': { + category: 'file', + description: 'Last time the file content was modified.', + name: 'file.mtime', + type: 'date', + }, + 'file.name': { + category: 'file', + description: 'Name of the file including the extension, without the directory.', + example: 'example.png', + name: 'file.name', + type: 'keyword', + }, + 'file.owner': { + category: 'file', + description: "File owner's username.", + example: 'alice', + name: 'file.owner', + type: 'keyword', + }, + 'file.path': { + category: 'file', + description: + 'Full path to the file, including the file name. It should include the drive letter, when appropriate.', + example: '/home/alice/example.png', + name: 'file.path', + type: 'keyword', + }, + 'file.pe.company': { + category: 'file', + description: 'Internal company name of the file, provided at compile-time.', + example: 'Microsoft Corporation', + name: 'file.pe.company', + type: 'keyword', + }, + 'file.pe.description': { + category: 'file', + description: 'Internal description of the file, provided at compile-time.', + example: 'Paint', + name: 'file.pe.description', + type: 'keyword', + }, + 'file.pe.file_version': { + category: 'file', + description: 'Internal version of the file, provided at compile-time.', + example: '6.3.9600.17415', + name: 'file.pe.file_version', + type: 'keyword', + }, + 'file.pe.original_file_name': { + category: 'file', + description: 'Internal name of the file, provided at compile-time.', + example: 'MSPAINT.EXE', + name: 'file.pe.original_file_name', + type: 'keyword', + }, + 'file.pe.product': { + category: 'file', + description: 'Internal product name of the file, provided at compile-time.', + example: 'Microsoft® Windows® Operating System', + name: 'file.pe.product', + type: 'keyword', + }, + 'file.size': { + category: 'file', + description: 'File size in bytes. Only relevant when `file.type` is "file".', + example: 16384, + name: 'file.size', + type: 'long', + }, + 'file.target_path': { + category: 'file', + description: 'Target path for symlinks.', + name: 'file.target_path', + type: 'keyword', + }, + 'file.type': { + category: 'file', + description: 'File type (file, dir, or symlink).', + example: 'file', + name: 'file.type', + type: 'keyword', + }, + 'file.uid': { + category: 'file', + description: 'The user ID (UID) or security identifier (SID) of the file owner.', + example: '1001', + name: 'file.uid', + type: 'keyword', + }, + 'geo.city_name': { + category: 'geo', + description: 'City name.', + example: 'Montreal', + name: 'geo.city_name', + type: 'keyword', + }, + 'geo.continent_name': { + category: 'geo', + description: 'Name of the continent.', + example: 'North America', + name: 'geo.continent_name', + type: 'keyword', + }, + 'geo.country_iso_code': { + category: 'geo', + description: 'Country ISO code.', + example: 'CA', + name: 'geo.country_iso_code', + type: 'keyword', + }, + 'geo.country_name': { + category: 'geo', + description: 'Country name.', + example: 'Canada', + name: 'geo.country_name', + type: 'keyword', + }, + 'geo.location': { + category: 'geo', + description: 'Longitude and latitude.', + example: '{ "lon": -73.614830, "lat": 45.505918 }', + name: 'geo.location', + type: 'geo_point', + }, + 'geo.name': { + category: 'geo', + description: + 'User-defined description of a location, at the level of granularity they care about. Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. Not typically used in automated geolocation.', + example: 'boston-dc', + name: 'geo.name', + type: 'keyword', + }, + 'geo.region_iso_code': { + category: 'geo', + description: 'Region ISO code.', + example: 'CA-QC', + name: 'geo.region_iso_code', + type: 'keyword', + }, + 'geo.region_name': { + category: 'geo', + description: 'Region name.', + example: 'Quebec', + name: 'geo.region_name', + type: 'keyword', + }, + 'group.domain': { + category: 'group', + description: + 'Name of the directory the group is a member of. For example, an LDAP or Active Directory domain name.', + name: 'group.domain', + type: 'keyword', + }, + 'group.id': { + category: 'group', + description: 'Unique identifier for the group on the system/platform.', + name: 'group.id', + type: 'keyword', + }, + 'group.name': { + category: 'group', + description: 'Name of the group.', + name: 'group.name', + type: 'keyword', + }, + 'hash.md5': { + category: 'hash', + description: 'MD5 hash.', + name: 'hash.md5', + type: 'keyword', + }, + 'hash.sha1': { + category: 'hash', + description: 'SHA1 hash.', + name: 'hash.sha1', + type: 'keyword', + }, + 'hash.sha256': { + category: 'hash', + description: 'SHA256 hash.', + name: 'hash.sha256', + type: 'keyword', + }, + 'hash.sha512': { + category: 'hash', + description: 'SHA512 hash.', + name: 'hash.sha512', + type: 'keyword', + }, + 'host.architecture': { + category: 'host', + description: 'Operating system architecture.', + example: 'x86_64', + name: 'host.architecture', + type: 'keyword', + }, + 'host.domain': { + category: 'host', + description: + "Name of the domain of which the host is a member. For example, on Windows this could be the host's Active Directory domain or NetBIOS domain name. For Linux this could be the domain of the host's LDAP provider.", + example: 'CONTOSO', + name: 'host.domain', + type: 'keyword', + }, + 'host.geo.city_name': { + category: 'host', + description: 'City name.', + example: 'Montreal', + name: 'host.geo.city_name', + type: 'keyword', + }, + 'host.geo.continent_name': { + category: 'host', + description: 'Name of the continent.', + example: 'North America', + name: 'host.geo.continent_name', + type: 'keyword', + }, + 'host.geo.country_iso_code': { + category: 'host', + description: 'Country ISO code.', + example: 'CA', + name: 'host.geo.country_iso_code', + type: 'keyword', + }, + 'host.geo.country_name': { + category: 'host', + description: 'Country name.', + example: 'Canada', + name: 'host.geo.country_name', + type: 'keyword', + }, + 'host.geo.location': { + category: 'host', + description: 'Longitude and latitude.', + example: '{ "lon": -73.614830, "lat": 45.505918 }', + name: 'host.geo.location', + type: 'geo_point', + }, + 'host.geo.name': { + category: 'host', + description: + 'User-defined description of a location, at the level of granularity they care about. Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. Not typically used in automated geolocation.', + example: 'boston-dc', + name: 'host.geo.name', + type: 'keyword', + }, + 'host.geo.region_iso_code': { + category: 'host', + description: 'Region ISO code.', + example: 'CA-QC', + name: 'host.geo.region_iso_code', + type: 'keyword', + }, + 'host.geo.region_name': { + category: 'host', + description: 'Region name.', + example: 'Quebec', + name: 'host.geo.region_name', + type: 'keyword', + }, + 'host.hostname': { + category: 'host', + description: + 'Hostname of the host. It normally contains what the `hostname` command returns on the host machine.', + name: 'host.hostname', + type: 'keyword', + }, + 'host.id': { + category: 'host', + description: + 'Unique host id. As hostname is not always unique, use values that are meaningful in your environment. Example: The current usage of `beat.name`.', + name: 'host.id', + type: 'keyword', + }, + 'host.ip': { + category: 'host', + description: 'Host ip addresses.', + name: 'host.ip', + type: 'ip', + }, + 'host.mac': { + category: 'host', + description: 'Host mac addresses.', + name: 'host.mac', + type: 'keyword', + }, + 'host.name': { + category: 'host', + description: + 'Name of the host. It can contain what `hostname` returns on Unix systems, the fully qualified domain name, or a name specified by the user. The sender decides which value to use.', + name: 'host.name', + type: 'keyword', + }, + 'host.os.family': { + category: 'host', + description: 'OS family (such as redhat, debian, freebsd, windows).', + example: 'debian', + name: 'host.os.family', + type: 'keyword', + }, + 'host.os.full': { + category: 'host', + description: 'Operating system name, including the version or code name.', + example: 'Mac OS Mojave', + name: 'host.os.full', + type: 'keyword', + }, + 'host.os.kernel': { + category: 'host', + description: 'Operating system kernel version as a raw string.', + example: '4.4.0-112-generic', + name: 'host.os.kernel', + type: 'keyword', + }, + 'host.os.name': { + category: 'host', + description: 'Operating system name, without the version.', + example: 'Mac OS X', + name: 'host.os.name', + type: 'keyword', + }, + 'host.os.platform': { + category: 'host', + description: 'Operating system platform (such centos, ubuntu, windows).', + example: 'darwin', + name: 'host.os.platform', + type: 'keyword', + }, + 'host.os.version': { + category: 'host', + description: 'Operating system version as a raw string.', + example: '10.14.1', + name: 'host.os.version', + type: 'keyword', + }, + 'host.type': { + category: 'host', + description: + 'Type of host. For Cloud providers this can be the machine type like `t2.medium`. If vm, this could be the container, for example, or other information meaningful in your environment.', + name: 'host.type', + type: 'keyword', + }, + 'host.uptime': { + category: 'host', + description: 'Seconds the host has been up.', + example: 1325, + name: 'host.uptime', + type: 'long', + }, + 'host.user.domain': { + category: 'host', + description: + 'Name of the directory the user is a member of. For example, an LDAP or Active Directory domain name.', + name: 'host.user.domain', + type: 'keyword', + }, + 'host.user.email': { + category: 'host', + description: 'User email address.', + name: 'host.user.email', + type: 'keyword', + }, + 'host.user.full_name': { + category: 'host', + description: "User's full name, if available.", + example: 'Albert Einstein', + name: 'host.user.full_name', + type: 'keyword', + }, + 'host.user.group.domain': { + category: 'host', + description: + 'Name of the directory the group is a member of. For example, an LDAP or Active Directory domain name.', + name: 'host.user.group.domain', + type: 'keyword', + }, + 'host.user.group.id': { + category: 'host', + description: 'Unique identifier for the group on the system/platform.', + name: 'host.user.group.id', + type: 'keyword', + }, + 'host.user.group.name': { + category: 'host', + description: 'Name of the group.', + name: 'host.user.group.name', + type: 'keyword', + }, + 'host.user.hash': { + category: 'host', + description: + 'Unique user hash to correlate information for a user in anonymized form. Useful if `user.id` or `user.name` contain confidential information and cannot be used.', + name: 'host.user.hash', + type: 'keyword', + }, + 'host.user.id': { + category: 'host', + description: 'Unique identifiers of the user.', + name: 'host.user.id', + type: 'keyword', + }, + 'host.user.name': { + category: 'host', + description: 'Short name or login of the user.', + example: 'albert', + name: 'host.user.name', + type: 'keyword', + }, + 'http.request.body.bytes': { + category: 'http', + description: 'Size in bytes of the request body.', + example: 887, + name: 'http.request.body.bytes', + type: 'long', + format: 'bytes', + }, + 'http.request.body.content': { + category: 'http', + description: 'The full HTTP request body.', + example: 'Hello world', + name: 'http.request.body.content', + type: 'keyword', + }, + 'http.request.bytes': { + category: 'http', + description: 'Total size in bytes of the request (body and headers).', + example: 1437, + name: 'http.request.bytes', + type: 'long', + format: 'bytes', + }, + 'http.request.method': { + category: 'http', + description: + 'HTTP request method. The field value must be normalized to lowercase for querying. See the documentation section "Implementing ECS".', + example: 'get, post, put', + name: 'http.request.method', + type: 'keyword', + }, + 'http.request.referrer': { + category: 'http', + description: 'Referrer for this HTTP request.', + example: 'https://blog.example.com/', + name: 'http.request.referrer', + type: 'keyword', + }, + 'http.response.body.bytes': { + category: 'http', + description: 'Size in bytes of the response body.', + example: 887, + name: 'http.response.body.bytes', + type: 'long', + format: 'bytes', + }, + 'http.response.body.content': { + category: 'http', + description: 'The full HTTP response body.', + example: 'Hello world', + name: 'http.response.body.content', + type: 'keyword', + }, + 'http.response.bytes': { + category: 'http', + description: 'Total size in bytes of the response (body and headers).', + example: 1437, + name: 'http.response.bytes', + type: 'long', + format: 'bytes', + }, + 'http.response.status_code': { + category: 'http', + description: 'HTTP response status code.', + example: 404, + name: 'http.response.status_code', + type: 'long', + format: 'string', + }, + 'http.version': { + category: 'http', + description: 'HTTP version.', + example: 1.1, + name: 'http.version', + type: 'keyword', + }, + 'interface.alias': { + category: 'interface', + description: + 'Interface alias as reported by the system, typically used in firewall implementations for e.g. inside, outside, or dmz logical interface naming.', + example: 'outside', + name: 'interface.alias', + type: 'keyword', + }, + 'interface.id': { + category: 'interface', + description: 'Interface ID as reported by an observer (typically SNMP interface ID).', + example: 10, + name: 'interface.id', + type: 'keyword', + }, + 'interface.name': { + category: 'interface', + description: 'Interface name as reported by the system.', + example: 'eth0', + name: 'interface.name', + type: 'keyword', + }, + 'log.level': { + category: 'log', + description: + "Original log level of the log event. If the source of the event provides a log level or textual severity, this is the one that goes in `log.level`. If your source doesn't specify one, you may put your event transport's severity here (e.g. Syslog severity). Some examples are `warn`, `err`, `i`, `informational`.", + example: 'error', + name: 'log.level', + type: 'keyword', + }, + 'log.logger': { + category: 'log', + description: + 'The name of the logger inside an application. This is usually the name of the class which initialized the logger, or can be a custom name.', + example: 'org.elasticsearch.bootstrap.Bootstrap', + name: 'log.logger', + type: 'keyword', + }, + 'log.origin.file.line': { + category: 'log', + description: + 'The line number of the file containing the source code which originated the log event.', + example: 42, + name: 'log.origin.file.line', + type: 'integer', + }, + 'log.origin.file.name': { + category: 'log', + description: + 'The name of the file containing the source code which originated the log event. Note that this is not the name of the log file.', + example: 'Bootstrap.java', + name: 'log.origin.file.name', + type: 'keyword', + }, + 'log.origin.function': { + category: 'log', + description: 'The name of the function or method which originated the log event.', + example: 'init', + name: 'log.origin.function', + type: 'keyword', + }, + 'log.original': { + category: 'log', + description: + "This is the original log message and contains the full log message before splitting it up in multiple parts. In contrast to the `message` field which can contain an extracted part of the log message, this field contains the original, full log message. It can have already some modifications applied like encoding or new lines removed to clean up the log message. This field is not indexed and doc_values are disabled so it can't be queried but the value can be retrieved from `_source`.", + example: 'Sep 19 08:26:10 localhost My log', + name: 'log.original', + type: 'keyword', + }, + 'log.syslog': { + category: 'log', + description: + 'The Syslog metadata of the event, if the event was transmitted via Syslog. Please see RFCs 5424 or 3164.', + name: 'log.syslog', + type: 'object', + }, + 'log.syslog.facility.code': { + category: 'log', + description: + 'The Syslog numeric facility of the log event, if available. According to RFCs 5424 and 3164, this value should be an integer between 0 and 23.', + example: 23, + name: 'log.syslog.facility.code', + type: 'long', + format: 'string', + }, + 'log.syslog.facility.name': { + category: 'log', + description: 'The Syslog text-based facility of the log event, if available.', + example: 'local7', + name: 'log.syslog.facility.name', + type: 'keyword', + }, + 'log.syslog.priority': { + category: 'log', + description: + 'Syslog numeric priority of the event, if available. According to RFCs 5424 and 3164, the priority is 8 * facility + severity. This number is therefore expected to contain a value between 0 and 191.', + example: 135, + name: 'log.syslog.priority', + type: 'long', + format: 'string', + }, + 'log.syslog.severity.code': { + category: 'log', + description: + "The Syslog numeric severity of the log event, if available. If the event source publishing via Syslog provides a different numeric severity value (e.g. firewall, IDS), your source's numeric severity should go to `event.severity`. If the event source does not specify a distinct severity, you can optionally copy the Syslog severity to `event.severity`.", + example: 3, + name: 'log.syslog.severity.code', + type: 'long', + }, + 'log.syslog.severity.name': { + category: 'log', + description: + "The Syslog numeric severity of the log event, if available. If the event source publishing via Syslog provides a different severity value (e.g. firewall, IDS), your source's text severity should go to `log.level`. If the event source does not specify a distinct severity, you can optionally copy the Syslog severity to `log.level`.", + example: 'Error', + name: 'log.syslog.severity.name', + type: 'keyword', + }, + 'network.application': { + category: 'network', + description: + 'A name given to an application level protocol. This can be arbitrarily assigned for things like microservices, but also apply to things like skype, icq, facebook, twitter. This would be used in situations where the vendor or service can be decoded such as from the source/dest IP owners, ports, or wire format. The field value must be normalized to lowercase for querying. See the documentation section "Implementing ECS".', + example: 'aim', + name: 'network.application', + type: 'keyword', + }, + 'network.bytes': { + category: 'network', + description: + 'Total bytes transferred in both directions. If `source.bytes` and `destination.bytes` are known, `network.bytes` is their sum.', + example: 368, + name: 'network.bytes', + type: 'long', + format: 'bytes', + }, + 'network.community_id': { + category: 'network', + description: + 'A hash of source and destination IPs and ports, as well as the protocol used in a communication. This is a tool-agnostic standard to identify flows. Learn more at https://github.com/corelight/community-id-spec.', + example: '1:hO+sN4H+MG5MY/8hIrXPqc4ZQz0=', + name: 'network.community_id', + type: 'keyword', + }, + 'network.direction': { + category: 'network', + description: + "Direction of the network traffic. Recommended values are: * inbound * outbound * internal * external * unknown When mapping events from a host-based monitoring context, populate this field from the host's point of view. When mapping events from a network or perimeter-based monitoring context, populate this field from the point of view of your network perimeter.", + example: 'inbound', + name: 'network.direction', + type: 'keyword', + }, + 'network.forwarded_ip': { + category: 'network', + description: 'Host IP address when the source IP address is the proxy.', + example: '192.1.1.2', + name: 'network.forwarded_ip', + type: 'ip', + }, + 'network.iana_number': { + category: 'network', + description: + 'IANA Protocol Number (https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml). Standardized list of protocols. This aligns well with NetFlow and sFlow related logs which use the IANA Protocol Number.', + example: 6, + name: 'network.iana_number', + type: 'keyword', + }, + 'network.inner': { + category: 'network', + description: + 'Network.inner fields are added in addition to network.vlan fields to describe the innermost VLAN when q-in-q VLAN tagging is present. Allowed fields include vlan.id and vlan.name. Inner vlan fields are typically used when sending traffic with multiple 802.1q encapsulations to a network sensor (e.g. Zeek, Wireshark.)', + name: 'network.inner', + type: 'object', + }, + 'network.inner.vlan.id': { + category: 'network', + description: 'VLAN ID as reported by the observer.', + example: 10, + name: 'network.inner.vlan.id', + type: 'keyword', + }, + 'network.inner.vlan.name': { + category: 'network', + description: 'Optional VLAN name as reported by the observer.', + example: 'outside', + name: 'network.inner.vlan.name', + type: 'keyword', + }, + 'network.name': { + category: 'network', + description: 'Name given by operators to sections of their network.', + example: 'Guest Wifi', + name: 'network.name', + type: 'keyword', + }, + 'network.packets': { + category: 'network', + description: + 'Total packets transferred in both directions. If `source.packets` and `destination.packets` are known, `network.packets` is their sum.', + example: 24, + name: 'network.packets', + type: 'long', + }, + 'network.protocol': { + category: 'network', + description: + 'L7 Network protocol name. ex. http, lumberjack, transport protocol. The field value must be normalized to lowercase for querying. See the documentation section "Implementing ECS".', + example: 'http', + name: 'network.protocol', + type: 'keyword', + }, + 'network.transport': { + category: 'network', + description: + 'Same as network.iana_number, but instead using the Keyword name of the transport layer (udp, tcp, ipv6-icmp, etc.) The field value must be normalized to lowercase for querying. See the documentation section "Implementing ECS".', + example: 'tcp', + name: 'network.transport', + type: 'keyword', + }, + 'network.type': { + category: 'network', + description: + 'In the OSI Model this would be the Network Layer. ipv4, ipv6, ipsec, pim, etc The field value must be normalized to lowercase for querying. See the documentation section "Implementing ECS".', + example: 'ipv4', + name: 'network.type', + type: 'keyword', + }, + 'network.vlan.id': { + category: 'network', + description: 'VLAN ID as reported by the observer.', + example: 10, + name: 'network.vlan.id', + type: 'keyword', + }, + 'network.vlan.name': { + category: 'network', + description: 'Optional VLAN name as reported by the observer.', + example: 'outside', + name: 'network.vlan.name', + type: 'keyword', + }, + 'observer.egress': { + category: 'observer', + description: + 'Observer.egress holds information like interface number and name, vlan, and zone information to classify egress traffic. Single armed monitoring such as a network sensor on a span port should only use observer.ingress to categorize traffic.', + name: 'observer.egress', + type: 'object', + }, + 'observer.egress.interface.alias': { + category: 'observer', + description: + 'Interface alias as reported by the system, typically used in firewall implementations for e.g. inside, outside, or dmz logical interface naming.', + example: 'outside', + name: 'observer.egress.interface.alias', + type: 'keyword', + }, + 'observer.egress.interface.id': { + category: 'observer', + description: 'Interface ID as reported by an observer (typically SNMP interface ID).', + example: 10, + name: 'observer.egress.interface.id', + type: 'keyword', + }, + 'observer.egress.interface.name': { + category: 'observer', + description: 'Interface name as reported by the system.', + example: 'eth0', + name: 'observer.egress.interface.name', + type: 'keyword', + }, + 'observer.egress.vlan.id': { + category: 'observer', + description: 'VLAN ID as reported by the observer.', + example: 10, + name: 'observer.egress.vlan.id', + type: 'keyword', + }, + 'observer.egress.vlan.name': { + category: 'observer', + description: 'Optional VLAN name as reported by the observer.', + example: 'outside', + name: 'observer.egress.vlan.name', + type: 'keyword', + }, + 'observer.egress.zone': { + category: 'observer', + description: + 'Network zone of outbound traffic as reported by the observer to categorize the destination area of egress traffic, e.g. Internal, External, DMZ, HR, Legal, etc.', + example: 'Public_Internet', + name: 'observer.egress.zone', + type: 'keyword', + }, + 'observer.geo.city_name': { + category: 'observer', + description: 'City name.', + example: 'Montreal', + name: 'observer.geo.city_name', + type: 'keyword', + }, + 'observer.geo.continent_name': { + category: 'observer', + description: 'Name of the continent.', + example: 'North America', + name: 'observer.geo.continent_name', + type: 'keyword', + }, + 'observer.geo.country_iso_code': { + category: 'observer', + description: 'Country ISO code.', + example: 'CA', + name: 'observer.geo.country_iso_code', + type: 'keyword', + }, + 'observer.geo.country_name': { + category: 'observer', + description: 'Country name.', + example: 'Canada', + name: 'observer.geo.country_name', + type: 'keyword', + }, + 'observer.geo.location': { + category: 'observer', + description: 'Longitude and latitude.', + example: '{ "lon": -73.614830, "lat": 45.505918 }', + name: 'observer.geo.location', + type: 'geo_point', + }, + 'observer.geo.name': { + category: 'observer', + description: + 'User-defined description of a location, at the level of granularity they care about. Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. Not typically used in automated geolocation.', + example: 'boston-dc', + name: 'observer.geo.name', + type: 'keyword', + }, + 'observer.geo.region_iso_code': { + category: 'observer', + description: 'Region ISO code.', + example: 'CA-QC', + name: 'observer.geo.region_iso_code', + type: 'keyword', + }, + 'observer.geo.region_name': { + category: 'observer', + description: 'Region name.', + example: 'Quebec', + name: 'observer.geo.region_name', + type: 'keyword', + }, + 'observer.hostname': { + category: 'observer', + description: 'Hostname of the observer.', + name: 'observer.hostname', + type: 'keyword', + }, + 'observer.ingress': { + category: 'observer', + description: + 'Observer.ingress holds information like interface number and name, vlan, and zone information to classify ingress traffic. Single armed monitoring such as a network sensor on a span port should only use observer.ingress to categorize traffic.', + name: 'observer.ingress', + type: 'object', + }, + 'observer.ingress.interface.alias': { + category: 'observer', + description: + 'Interface alias as reported by the system, typically used in firewall implementations for e.g. inside, outside, or dmz logical interface naming.', + example: 'outside', + name: 'observer.ingress.interface.alias', + type: 'keyword', + }, + 'observer.ingress.interface.id': { + category: 'observer', + description: 'Interface ID as reported by an observer (typically SNMP interface ID).', + example: 10, + name: 'observer.ingress.interface.id', + type: 'keyword', + }, + 'observer.ingress.interface.name': { + category: 'observer', + description: 'Interface name as reported by the system.', + example: 'eth0', + name: 'observer.ingress.interface.name', + type: 'keyword', + }, + 'observer.ingress.vlan.id': { + category: 'observer', + description: 'VLAN ID as reported by the observer.', + example: 10, + name: 'observer.ingress.vlan.id', + type: 'keyword', + }, + 'observer.ingress.vlan.name': { + category: 'observer', + description: 'Optional VLAN name as reported by the observer.', + example: 'outside', + name: 'observer.ingress.vlan.name', + type: 'keyword', + }, + 'observer.ingress.zone': { + category: 'observer', + description: + 'Network zone of incoming traffic as reported by the observer to categorize the source area of ingress traffic. e.g. internal, External, DMZ, HR, Legal, etc.', + example: 'DMZ', + name: 'observer.ingress.zone', + type: 'keyword', + }, + 'observer.ip': { + category: 'observer', + description: 'IP addresses of the observer.', + name: 'observer.ip', + type: 'ip', + }, + 'observer.mac': { + category: 'observer', + description: 'MAC addresses of the observer', + name: 'observer.mac', + type: 'keyword', + }, + 'observer.name': { + category: 'observer', + description: + 'Custom name of the observer. This is a name that can be given to an observer. This can be helpful for example if multiple firewalls of the same model are used in an organization. If no custom name is needed, the field can be left empty.', + example: '1_proxySG', + name: 'observer.name', + type: 'keyword', + }, + 'observer.os.family': { + category: 'observer', + description: 'OS family (such as redhat, debian, freebsd, windows).', + example: 'debian', + name: 'observer.os.family', + type: 'keyword', + }, + 'observer.os.full': { + category: 'observer', + description: 'Operating system name, including the version or code name.', + example: 'Mac OS Mojave', + name: 'observer.os.full', + type: 'keyword', + }, + 'observer.os.kernel': { + category: 'observer', + description: 'Operating system kernel version as a raw string.', + example: '4.4.0-112-generic', + name: 'observer.os.kernel', + type: 'keyword', + }, + 'observer.os.name': { + category: 'observer', + description: 'Operating system name, without the version.', + example: 'Mac OS X', + name: 'observer.os.name', + type: 'keyword', + }, + 'observer.os.platform': { + category: 'observer', + description: 'Operating system platform (such centos, ubuntu, windows).', + example: 'darwin', + name: 'observer.os.platform', + type: 'keyword', + }, + 'observer.os.version': { + category: 'observer', + description: 'Operating system version as a raw string.', + example: '10.14.1', + name: 'observer.os.version', + type: 'keyword', + }, + 'observer.product': { + category: 'observer', + description: 'The product name of the observer.', + example: 's200', + name: 'observer.product', + type: 'keyword', + }, + 'observer.serial_number': { + category: 'observer', + description: 'Observer serial number.', + name: 'observer.serial_number', + type: 'keyword', + }, + 'observer.type': { + category: 'observer', + description: + 'The type of the observer the data is coming from. There is no predefined list of observer types. Some examples are `forwarder`, `firewall`, `ids`, `ips`, `proxy`, `poller`, `sensor`, `APM server`.', + example: 'firewall', + name: 'observer.type', + type: 'keyword', + }, + 'observer.vendor': { + category: 'observer', + description: 'Vendor name of the observer.', + example: 'Symantec', + name: 'observer.vendor', + type: 'keyword', + }, + 'observer.version': { + category: 'observer', + description: 'Observer version.', + name: 'observer.version', + type: 'keyword', + }, + 'organization.id': { + category: 'organization', + description: 'Unique identifier for the organization.', + name: 'organization.id', + type: 'keyword', + }, + 'organization.name': { + category: 'organization', + description: 'Organization name.', + name: 'organization.name', + type: 'keyword', + }, + 'os.family': { + category: 'os', + description: 'OS family (such as redhat, debian, freebsd, windows).', + example: 'debian', + name: 'os.family', + type: 'keyword', + }, + 'os.full': { + category: 'os', + description: 'Operating system name, including the version or code name.', + example: 'Mac OS Mojave', + name: 'os.full', + type: 'keyword', + }, + 'os.kernel': { + category: 'os', + description: 'Operating system kernel version as a raw string.', + example: '4.4.0-112-generic', + name: 'os.kernel', + type: 'keyword', + }, + 'os.name': { + category: 'os', + description: 'Operating system name, without the version.', + example: 'Mac OS X', + name: 'os.name', + type: 'keyword', + }, + 'os.platform': { + category: 'os', + description: 'Operating system platform (such centos, ubuntu, windows).', + example: 'darwin', + name: 'os.platform', + type: 'keyword', + }, + 'os.version': { + category: 'os', + description: 'Operating system version as a raw string.', + example: '10.14.1', + name: 'os.version', + type: 'keyword', + }, + 'package.architecture': { + category: 'package', + description: 'Package architecture.', + example: 'x86_64', + name: 'package.architecture', + type: 'keyword', + }, + 'package.build_version': { + category: 'package', + description: + 'Additional information about the build version of the installed package. For example use the commit SHA of a non-released package.', + example: '36f4f7e89dd61b0988b12ee000b98966867710cd', + name: 'package.build_version', + type: 'keyword', + }, + 'package.checksum': { + category: 'package', + description: 'Checksum of the installed package for verification.', + example: '68b329da9893e34099c7d8ad5cb9c940', + name: 'package.checksum', + type: 'keyword', + }, + 'package.description': { + category: 'package', + description: 'Description of the package.', + example: 'Open source programming language to build simple/reliable/efficient software.', + name: 'package.description', + type: 'keyword', + }, + 'package.install_scope': { + category: 'package', + description: 'Indicating how the package was installed, e.g. user-local, global.', + example: 'global', + name: 'package.install_scope', + type: 'keyword', + }, + 'package.installed': { + category: 'package', + description: 'Time when package was installed.', + name: 'package.installed', + type: 'date', + }, + 'package.license': { + category: 'package', + description: + 'License under which the package was released. Use a short name, e.g. the license identifier from SPDX License List where possible (https://spdx.org/licenses/).', + example: 'Apache License 2.0', + name: 'package.license', + type: 'keyword', + }, + 'package.name': { + category: 'package', + description: 'Package name', + example: 'go', + name: 'package.name', + type: 'keyword', + }, + 'package.path': { + category: 'package', + description: 'Path where the package is installed.', + example: '/usr/local/Cellar/go/1.12.9/', + name: 'package.path', + type: 'keyword', + }, + 'package.reference': { + category: 'package', + description: 'Home page or reference URL of the software in this package, if available.', + example: 'https://golang.org', + name: 'package.reference', + type: 'keyword', + }, + 'package.size': { + category: 'package', + description: 'Package size in bytes.', + example: 62231, + name: 'package.size', + type: 'long', + format: 'string', + }, + 'package.type': { + category: 'package', + description: + 'Type of package. This should contain the package file type, rather than the package manager name. Examples: rpm, dpkg, brew, npm, gem, nupkg, jar.', + example: 'rpm', + name: 'package.type', + type: 'keyword', + }, + 'package.version': { + category: 'package', + description: 'Package version', + example: '1.12.9', + name: 'package.version', + type: 'keyword', + }, + 'pe.company': { + category: 'pe', + description: 'Internal company name of the file, provided at compile-time.', + example: 'Microsoft Corporation', + name: 'pe.company', + type: 'keyword', + }, + 'pe.description': { + category: 'pe', + description: 'Internal description of the file, provided at compile-time.', + example: 'Paint', + name: 'pe.description', + type: 'keyword', + }, + 'pe.file_version': { + category: 'pe', + description: 'Internal version of the file, provided at compile-time.', + example: '6.3.9600.17415', + name: 'pe.file_version', + type: 'keyword', + }, + 'pe.original_file_name': { + category: 'pe', + description: 'Internal name of the file, provided at compile-time.', + example: 'MSPAINT.EXE', + name: 'pe.original_file_name', + type: 'keyword', + }, + 'pe.product': { + category: 'pe', + description: 'Internal product name of the file, provided at compile-time.', + example: 'Microsoft® Windows® Operating System', + name: 'pe.product', + type: 'keyword', + }, + 'process.args': { + category: 'process', + description: + 'Array of process arguments, starting with the absolute path to the executable. May be filtered to protect sensitive information.', + example: '["/usr/bin/ssh","-l","user","10.0.0.16"]', + name: 'process.args', + type: 'keyword', + }, + 'process.args_count': { + category: 'process', + description: + 'Length of the process.args array. This field can be useful for querying or performing bucket analysis on how many arguments were provided to start a process. More arguments may be an indication of suspicious activity.', + example: 4, + name: 'process.args_count', + type: 'long', + }, + 'process.code_signature.exists': { + category: 'process', + description: 'Boolean to capture if a signature is present.', + example: 'true', + name: 'process.code_signature.exists', + type: 'boolean', + }, + 'process.code_signature.status': { + category: 'process', + description: + 'Additional information about the certificate status. This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked.', + example: 'ERROR_UNTRUSTED_ROOT', + name: 'process.code_signature.status', + type: 'keyword', + }, + 'process.code_signature.subject_name': { + category: 'process', + description: 'Subject name of the code signer', + example: 'Microsoft Corporation', + name: 'process.code_signature.subject_name', + type: 'keyword', + }, + 'process.code_signature.trusted': { + category: 'process', + description: + 'Stores the trust status of the certificate chain. Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status.', + example: 'true', + name: 'process.code_signature.trusted', + type: 'boolean', + }, + 'process.code_signature.valid': { + category: 'process', + description: + 'Boolean to capture if the digital signature is verified against the binary content. Leave unpopulated if a certificate was unchecked.', + example: 'true', + name: 'process.code_signature.valid', + type: 'boolean', + }, + 'process.command_line': { + category: 'process', + description: + 'Full command line that started the process, including the absolute path to the executable, and all arguments. Some arguments may be filtered to protect sensitive information.', + example: '/usr/bin/ssh -l user 10.0.0.16', + name: 'process.command_line', + type: 'keyword', + }, + 'process.entity_id': { + category: 'process', + description: + 'Unique identifier for the process. The implementation of this is specified by the data source, but some examples of what could be used here are a process-generated UUID, Sysmon Process GUIDs, or a hash of some uniquely identifying components of a process. Constructing a globally unique identifier is a common practice to mitigate PID reuse as well as to identify a specific process over time, across multiple monitored hosts.', + example: 'c2c455d9f99375d', + name: 'process.entity_id', + type: 'keyword', + }, + 'process.executable': { + category: 'process', + description: 'Absolute path to the process executable.', + example: '/usr/bin/ssh', + name: 'process.executable', + type: 'keyword', + }, + 'process.exit_code': { + category: 'process', + description: + 'The exit code of the process, if this is a termination event. The field should be absent if there is no exit code for the event (e.g. process start).', + example: 137, + name: 'process.exit_code', + type: 'long', + }, + 'process.hash.md5': { + category: 'process', + description: 'MD5 hash.', + name: 'process.hash.md5', + type: 'keyword', + }, + 'process.hash.sha1': { + category: 'process', + description: 'SHA1 hash.', + name: 'process.hash.sha1', + type: 'keyword', + }, + 'process.hash.sha256': { + category: 'process', + description: 'SHA256 hash.', + name: 'process.hash.sha256', + type: 'keyword', + }, + 'process.hash.sha512': { + category: 'process', + description: 'SHA512 hash.', + name: 'process.hash.sha512', + type: 'keyword', + }, + 'process.name': { + category: 'process', + description: 'Process name. Sometimes called program name or similar.', + example: 'ssh', + name: 'process.name', + type: 'keyword', + }, + 'process.parent.args': { + category: 'process', + description: 'Array of process arguments. May be filtered to protect sensitive information.', + example: '["ssh","-l","user","10.0.0.16"]', + name: 'process.parent.args', + type: 'keyword', + }, + 'process.parent.args_count': { + category: 'process', + description: + 'Length of the process.args array. This field can be useful for querying or performing bucket analysis on how many arguments were provided to start a process. More arguments may be an indication of suspicious activity.', + example: 4, + name: 'process.parent.args_count', + type: 'long', + }, + 'process.parent.code_signature.exists': { + category: 'process', + description: 'Boolean to capture if a signature is present.', + example: 'true', + name: 'process.parent.code_signature.exists', + type: 'boolean', + }, + 'process.parent.code_signature.status': { + category: 'process', + description: + 'Additional information about the certificate status. This is useful for logging cryptographic errors with the certificate validity or trust status. Leave unpopulated if the validity or trust of the certificate was unchecked.', + example: 'ERROR_UNTRUSTED_ROOT', + name: 'process.parent.code_signature.status', + type: 'keyword', + }, + 'process.parent.code_signature.subject_name': { + category: 'process', + description: 'Subject name of the code signer', + example: 'Microsoft Corporation', + name: 'process.parent.code_signature.subject_name', + type: 'keyword', + }, + 'process.parent.code_signature.trusted': { + category: 'process', + description: + 'Stores the trust status of the certificate chain. Validating the trust of the certificate chain may be complicated, and this field should only be populated by tools that actively check the status.', + example: 'true', + name: 'process.parent.code_signature.trusted', + type: 'boolean', + }, + 'process.parent.code_signature.valid': { + category: 'process', + description: + 'Boolean to capture if the digital signature is verified against the binary content. Leave unpopulated if a certificate was unchecked.', + example: 'true', + name: 'process.parent.code_signature.valid', + type: 'boolean', + }, + 'process.parent.command_line': { + category: 'process', + description: + 'Full command line that started the process, including the absolute path to the executable, and all arguments. Some arguments may be filtered to protect sensitive information.', + example: '/usr/bin/ssh -l user 10.0.0.16', + name: 'process.parent.command_line', + type: 'keyword', + }, + 'process.parent.entity_id': { + category: 'process', + description: + 'Unique identifier for the process. The implementation of this is specified by the data source, but some examples of what could be used here are a process-generated UUID, Sysmon Process GUIDs, or a hash of some uniquely identifying components of a process. Constructing a globally unique identifier is a common practice to mitigate PID reuse as well as to identify a specific process over time, across multiple monitored hosts.', + example: 'c2c455d9f99375d', + name: 'process.parent.entity_id', + type: 'keyword', + }, + 'process.parent.executable': { + category: 'process', + description: 'Absolute path to the process executable.', + example: '/usr/bin/ssh', + name: 'process.parent.executable', + type: 'keyword', + }, + 'process.parent.exit_code': { + category: 'process', + description: + 'The exit code of the process, if this is a termination event. The field should be absent if there is no exit code for the event (e.g. process start).', + example: 137, + name: 'process.parent.exit_code', + type: 'long', + }, + 'process.parent.hash.md5': { + category: 'process', + description: 'MD5 hash.', + name: 'process.parent.hash.md5', + type: 'keyword', + }, + 'process.parent.hash.sha1': { + category: 'process', + description: 'SHA1 hash.', + name: 'process.parent.hash.sha1', + type: 'keyword', + }, + 'process.parent.hash.sha256': { + category: 'process', + description: 'SHA256 hash.', + name: 'process.parent.hash.sha256', + type: 'keyword', + }, + 'process.parent.hash.sha512': { + category: 'process', + description: 'SHA512 hash.', + name: 'process.parent.hash.sha512', + type: 'keyword', + }, + 'process.parent.name': { + category: 'process', + description: 'Process name. Sometimes called program name or similar.', + example: 'ssh', + name: 'process.parent.name', + type: 'keyword', + }, + 'process.parent.pgid': { + category: 'process', + description: 'Identifier of the group of processes the process belongs to.', + name: 'process.parent.pgid', + type: 'long', + format: 'string', + }, + 'process.parent.pid': { + category: 'process', + description: 'Process id.', + example: 4242, + name: 'process.parent.pid', + type: 'long', + format: 'string', + }, + 'process.parent.ppid': { + category: 'process', + description: "Parent process' pid.", + example: 4241, + name: 'process.parent.ppid', + type: 'long', + format: 'string', + }, + 'process.parent.start': { + category: 'process', + description: 'The time the process started.', + example: '2016-05-23T08:05:34.853Z', + name: 'process.parent.start', + type: 'date', + }, + 'process.parent.thread.id': { + category: 'process', + description: 'Thread ID.', + example: 4242, + name: 'process.parent.thread.id', + type: 'long', + format: 'string', + }, + 'process.parent.thread.name': { + category: 'process', + description: 'Thread name.', + example: 'thread-0', + name: 'process.parent.thread.name', + type: 'keyword', + }, + 'process.parent.title': { + category: 'process', + description: + 'Process title. The proctitle, some times the same as process name. Can also be different: for example a browser setting its title to the web page currently opened.', + name: 'process.parent.title', + type: 'keyword', + }, + 'process.parent.uptime': { + category: 'process', + description: 'Seconds the process has been up.', + example: 1325, + name: 'process.parent.uptime', + type: 'long', + }, + 'process.parent.working_directory': { + category: 'process', + description: 'The working directory of the process.', + example: '/home/alice', + name: 'process.parent.working_directory', + type: 'keyword', + }, + 'process.pe.company': { + category: 'process', + description: 'Internal company name of the file, provided at compile-time.', + example: 'Microsoft Corporation', + name: 'process.pe.company', + type: 'keyword', + }, + 'process.pe.description': { + category: 'process', + description: 'Internal description of the file, provided at compile-time.', + example: 'Paint', + name: 'process.pe.description', + type: 'keyword', + }, + 'process.pe.file_version': { + category: 'process', + description: 'Internal version of the file, provided at compile-time.', + example: '6.3.9600.17415', + name: 'process.pe.file_version', + type: 'keyword', + }, + 'process.pe.original_file_name': { + category: 'process', + description: 'Internal name of the file, provided at compile-time.', + example: 'MSPAINT.EXE', + name: 'process.pe.original_file_name', + type: 'keyword', + }, + 'process.pe.product': { + category: 'process', + description: 'Internal product name of the file, provided at compile-time.', + example: 'Microsoft® Windows® Operating System', + name: 'process.pe.product', + type: 'keyword', + }, + 'process.pgid': { + category: 'process', + description: 'Identifier of the group of processes the process belongs to.', + name: 'process.pgid', + type: 'long', + format: 'string', + }, + 'process.pid': { + category: 'process', + description: 'Process id.', + example: 4242, + name: 'process.pid', + type: 'long', + format: 'string', + }, + 'process.ppid': { + category: 'process', + description: "Parent process' pid.", + example: 4241, + name: 'process.ppid', + type: 'long', + format: 'string', + }, + 'process.start': { + category: 'process', + description: 'The time the process started.', + example: '2016-05-23T08:05:34.853Z', + name: 'process.start', + type: 'date', + }, + 'process.thread.id': { + category: 'process', + description: 'Thread ID.', + example: 4242, + name: 'process.thread.id', + type: 'long', + format: 'string', + }, + 'process.thread.name': { + category: 'process', + description: 'Thread name.', + example: 'thread-0', + name: 'process.thread.name', + type: 'keyword', + }, + 'process.title': { + category: 'process', + description: + 'Process title. The proctitle, some times the same as process name. Can also be different: for example a browser setting its title to the web page currently opened.', + name: 'process.title', + type: 'keyword', + }, + 'process.uptime': { + category: 'process', + description: 'Seconds the process has been up.', + example: 1325, + name: 'process.uptime', + type: 'long', + }, + 'process.working_directory': { + category: 'process', + description: 'The working directory of the process.', + example: '/home/alice', + name: 'process.working_directory', + type: 'keyword', + }, + 'registry.data.bytes': { + category: 'registry', + description: + 'Original bytes written with base64 encoding. For Windows registry operations, such as SetValueEx and RegQueryValueEx, this corresponds to the data pointed by `lp_data`. This is optional but provides better recoverability and should be populated for REG_BINARY encoded values.', + example: 'ZQBuAC0AVQBTAAAAZQBuAAAAAAA=', + name: 'registry.data.bytes', + type: 'keyword', + }, + 'registry.data.strings': { + category: 'registry', + description: + 'Content when writing string types. Populated as an array when writing string data to the registry. For single string registry types (REG_SZ, REG_EXPAND_SZ), this should be an array with one string. For sequences of string with REG_MULTI_SZ, this array will be variable length. For numeric data, such as REG_DWORD and REG_QWORD, this should be populated with the decimal representation (e.g `"1"`).', + example: '["C:\\rta\\red_ttp\\bin\\myapp.exe"]', + name: 'registry.data.strings', + type: 'keyword', + }, + 'registry.data.type': { + category: 'registry', + description: 'Standard registry type for encoding contents', + example: 'REG_SZ', + name: 'registry.data.type', + type: 'keyword', + }, + 'registry.hive': { + category: 'registry', + description: 'Abbreviated name for the hive.', + example: 'HKLM', + name: 'registry.hive', + type: 'keyword', + }, + 'registry.key': { + category: 'registry', + description: 'Hive-relative path of keys.', + example: + 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\winword.exe', + name: 'registry.key', + type: 'keyword', + }, + 'registry.path': { + category: 'registry', + description: 'Full path, including hive, key and value', + example: + 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\winword.exe\\Debugger', + name: 'registry.path', + type: 'keyword', + }, + 'registry.value': { + category: 'registry', + description: 'Name of the value written.', + example: 'Debugger', + name: 'registry.value', + type: 'keyword', + }, + 'related.hash': { + category: 'related', + description: + "All the hashes seen on your event. Populating this field, then using it to search for hashes can help in situations where you're unsure what the hash algorithm is (and therefore which key name to search).", + name: 'related.hash', + type: 'keyword', + }, + 'related.ip': { + category: 'related', + description: 'All of the IPs seen on your event.', + name: 'related.ip', + type: 'ip', + }, + 'related.user': { + category: 'related', + description: 'All the user names seen on your event.', + name: 'related.user', + type: 'keyword', + }, + 'rule.author': { + category: 'rule', + description: + 'Name, organization, or pseudonym of the author or authors who created the rule used to generate this event.', + example: '["Star-Lord"]', + name: 'rule.author', + type: 'keyword', + }, + 'rule.category': { + category: 'rule', + description: + 'A categorization value keyword used by the entity using the rule for detection of this event.', + example: 'Attempted Information Leak', + name: 'rule.category', + type: 'keyword', + }, + 'rule.description': { + category: 'rule', + description: 'The description of the rule generating the event.', + example: 'Block requests to public DNS over HTTPS / TLS protocols', + name: 'rule.description', + type: 'keyword', + }, + 'rule.id': { + category: 'rule', + description: + 'A rule ID that is unique within the scope of an agent, observer, or other entity using the rule for detection of this event.', + example: 101, + name: 'rule.id', + type: 'keyword', + }, + 'rule.license': { + category: 'rule', + description: + 'Name of the license under which the rule used to generate this event is made available.', + example: 'Apache 2.0', + name: 'rule.license', + type: 'keyword', + }, + 'rule.name': { + category: 'rule', + description: 'The name of the rule or signature generating the event.', + example: 'BLOCK_DNS_over_TLS', + name: 'rule.name', + type: 'keyword', + }, + 'rule.reference': { + category: 'rule', + description: + "Reference URL to additional information about the rule used to generate this event. The URL can point to the vendor's documentation about the rule. If that's not available, it can also be a link to a more general page describing this type of alert.", + example: 'https://en.wikipedia.org/wiki/DNS_over_TLS', + name: 'rule.reference', + type: 'keyword', + }, + 'rule.ruleset': { + category: 'rule', + description: + 'Name of the ruleset, policy, group, or parent category in which the rule used to generate this event is a member.', + example: 'Standard_Protocol_Filters', + name: 'rule.ruleset', + type: 'keyword', + }, + 'rule.uuid': { + category: 'rule', + description: + 'A rule ID that is unique within the scope of a set or group of agents, observers, or other entities using the rule for detection of this event.', + example: 1100110011, + name: 'rule.uuid', + type: 'keyword', + }, + 'rule.version': { + category: 'rule', + description: 'The version / revision of the rule being used for analysis.', + example: 1.1, + name: 'rule.version', + type: 'keyword', + }, + 'server.address': { + category: 'server', + description: + 'Some event server addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the `.address` field. Then it should be duplicated to `.ip` or `.domain`, depending on which one it is.', + name: 'server.address', + type: 'keyword', + }, + 'server.as.number': { + category: 'server', + description: + 'Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet.', + example: 15169, + name: 'server.as.number', + type: 'long', + }, + 'server.as.organization.name': { + category: 'server', + description: 'Organization name.', + example: 'Google LLC', + name: 'server.as.organization.name', + type: 'keyword', + }, + 'server.bytes': { + category: 'server', + description: 'Bytes sent from the server to the client.', + example: 184, + name: 'server.bytes', + type: 'long', + format: 'bytes', + }, + 'server.domain': { + category: 'server', + description: 'Server domain.', + name: 'server.domain', + type: 'keyword', + }, + 'server.geo.city_name': { + category: 'server', + description: 'City name.', + example: 'Montreal', + name: 'server.geo.city_name', + type: 'keyword', + }, + 'server.geo.continent_name': { + category: 'server', + description: 'Name of the continent.', + example: 'North America', + name: 'server.geo.continent_name', + type: 'keyword', + }, + 'server.geo.country_iso_code': { + category: 'server', + description: 'Country ISO code.', + example: 'CA', + name: 'server.geo.country_iso_code', + type: 'keyword', + }, + 'server.geo.country_name': { + category: 'server', + description: 'Country name.', + example: 'Canada', + name: 'server.geo.country_name', + type: 'keyword', + }, + 'server.geo.location': { + category: 'server', + description: 'Longitude and latitude.', + example: '{ "lon": -73.614830, "lat": 45.505918 }', + name: 'server.geo.location', + type: 'geo_point', + }, + 'server.geo.name': { + category: 'server', + description: + 'User-defined description of a location, at the level of granularity they care about. Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. Not typically used in automated geolocation.', + example: 'boston-dc', + name: 'server.geo.name', + type: 'keyword', + }, + 'server.geo.region_iso_code': { + category: 'server', + description: 'Region ISO code.', + example: 'CA-QC', + name: 'server.geo.region_iso_code', + type: 'keyword', + }, + 'server.geo.region_name': { + category: 'server', + description: 'Region name.', + example: 'Quebec', + name: 'server.geo.region_name', + type: 'keyword', + }, + 'server.ip': { + category: 'server', + description: 'IP address of the server. Can be one or multiple IPv4 or IPv6 addresses.', + name: 'server.ip', + type: 'ip', + }, + 'server.mac': { + category: 'server', + description: 'MAC address of the server.', + name: 'server.mac', + type: 'keyword', + }, + 'server.nat.ip': { + category: 'server', + description: + 'Translated ip of destination based NAT sessions (e.g. internet to private DMZ) Typically used with load balancers, firewalls, or routers.', + name: 'server.nat.ip', + type: 'ip', + }, + 'server.nat.port': { + category: 'server', + description: + 'Translated port of destination based NAT sessions (e.g. internet to private DMZ) Typically used with load balancers, firewalls, or routers.', + name: 'server.nat.port', + type: 'long', + format: 'string', + }, + 'server.packets': { + category: 'server', + description: 'Packets sent from the server to the client.', + example: 12, + name: 'server.packets', + type: 'long', + }, + 'server.port': { + category: 'server', + description: 'Port of the server.', + name: 'server.port', + type: 'long', + format: 'string', + }, + 'server.registered_domain': { + category: 'server', + description: + 'The highest registered server domain, stripped of the subdomain. For example, the registered domain for "foo.google.com" is "google.com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk".', + example: 'google.com', + name: 'server.registered_domain', + type: 'keyword', + }, + 'server.top_level_domain': { + category: 'server', + description: + 'The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for google.com is "com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk".', + example: 'co.uk', + name: 'server.top_level_domain', + type: 'keyword', + }, + 'server.user.domain': { + category: 'server', + description: + 'Name of the directory the user is a member of. For example, an LDAP or Active Directory domain name.', + name: 'server.user.domain', + type: 'keyword', + }, + 'server.user.email': { + category: 'server', + description: 'User email address.', + name: 'server.user.email', + type: 'keyword', + }, + 'server.user.full_name': { + category: 'server', + description: "User's full name, if available.", + example: 'Albert Einstein', + name: 'server.user.full_name', + type: 'keyword', + }, + 'server.user.group.domain': { + category: 'server', + description: + 'Name of the directory the group is a member of. For example, an LDAP or Active Directory domain name.', + name: 'server.user.group.domain', + type: 'keyword', + }, + 'server.user.group.id': { + category: 'server', + description: 'Unique identifier for the group on the system/platform.', + name: 'server.user.group.id', + type: 'keyword', + }, + 'server.user.group.name': { + category: 'server', + description: 'Name of the group.', + name: 'server.user.group.name', + type: 'keyword', + }, + 'server.user.hash': { + category: 'server', + description: + 'Unique user hash to correlate information for a user in anonymized form. Useful if `user.id` or `user.name` contain confidential information and cannot be used.', + name: 'server.user.hash', + type: 'keyword', + }, + 'server.user.id': { + category: 'server', + description: 'Unique identifiers of the user.', + name: 'server.user.id', + type: 'keyword', + }, + 'server.user.name': { + category: 'server', + description: 'Short name or login of the user.', + example: 'albert', + name: 'server.user.name', + type: 'keyword', + }, + 'service.ephemeral_id': { + category: 'service', + description: + 'Ephemeral identifier of this service (if one exists). This id normally changes across restarts, but `service.id` does not.', + example: '8a4f500f', + name: 'service.ephemeral_id', + type: 'keyword', + }, + 'service.id': { + category: 'service', + description: + 'Unique identifier of the running service. If the service is comprised of many nodes, the `service.id` should be the same for all nodes. This id should uniquely identify the service. This makes it possible to correlate logs and metrics for one specific service, no matter which particular node emitted the event. Note that if you need to see the events from one specific host of the service, you should filter on that `host.name` or `host.id` instead.', + example: 'd37e5ebfe0ae6c4972dbe9f0174a1637bb8247f6', + name: 'service.id', + type: 'keyword', + }, + 'service.name': { + category: 'service', + description: + 'Name of the service data is collected from. The name of the service is normally user given. This allows for distributed services that run on multiple hosts to correlate the related instances based on the name. In the case of Elasticsearch the `service.name` could contain the cluster name. For Beats the `service.name` is by default a copy of the `service.type` field if no name is specified.', + example: 'elasticsearch-metrics', + name: 'service.name', + type: 'keyword', + }, + 'service.node.name': { + category: 'service', + description: + "Name of a service node. This allows for two nodes of the same service running on the same host to be differentiated. Therefore, `service.node.name` should typically be unique across nodes of a given service. In the case of Elasticsearch, the `service.node.name` could contain the unique node name within the Elasticsearch cluster. In cases where the service doesn't have the concept of a node name, the host name or container name can be used to distinguish running instances that make up this service. If those do not provide uniqueness (e.g. multiple instances of the service running on the same host) - the node name can be manually set.", + example: 'instance-0000000016', + name: 'service.node.name', + type: 'keyword', + }, + 'service.state': { + category: 'service', + description: 'Current state of the service.', + name: 'service.state', + type: 'keyword', + }, + 'service.type': { + category: 'service', + description: + 'The type of the service data is collected from. The type can be used to group and correlate logs and metrics from one service type. Example: If logs or metrics are collected from Elasticsearch, `service.type` would be `elasticsearch`.', + example: 'elasticsearch', + name: 'service.type', + type: 'keyword', + }, + 'service.version': { + category: 'service', + description: + 'Version of the service the data was collected from. This allows to look at a data set only for a specific version of a service.', + example: '3.2.4', + name: 'service.version', + type: 'keyword', + }, + 'source.address': { + category: 'source', + description: + 'Some event source addresses are defined ambiguously. The event will sometimes list an IP, a domain or a unix socket. You should always store the raw address in the `.address` field. Then it should be duplicated to `.ip` or `.domain`, depending on which one it is.', + name: 'source.address', + type: 'keyword', + }, + 'source.as.number': { + category: 'source', + description: + 'Unique number allocated to the autonomous system. The autonomous system number (ASN) uniquely identifies each network on the Internet.', + example: 15169, + name: 'source.as.number', + type: 'long', + }, + 'source.as.organization.name': { + category: 'source', + description: 'Organization name.', + example: 'Google LLC', + name: 'source.as.organization.name', + type: 'keyword', + }, + 'source.bytes': { + category: 'source', + description: 'Bytes sent from the source to the destination.', + example: 184, + name: 'source.bytes', + type: 'long', + format: 'bytes', + }, + 'source.domain': { + category: 'source', + description: 'Source domain.', + name: 'source.domain', + type: 'keyword', + }, + 'source.geo.city_name': { + category: 'source', + description: 'City name.', + example: 'Montreal', + name: 'source.geo.city_name', + type: 'keyword', + }, + 'source.geo.continent_name': { + category: 'source', + description: 'Name of the continent.', + example: 'North America', + name: 'source.geo.continent_name', + type: 'keyword', + }, + 'source.geo.country_iso_code': { + category: 'source', + description: 'Country ISO code.', + example: 'CA', + name: 'source.geo.country_iso_code', + type: 'keyword', + }, + 'source.geo.country_name': { + category: 'source', + description: 'Country name.', + example: 'Canada', + name: 'source.geo.country_name', + type: 'keyword', + }, + 'source.geo.location': { + category: 'source', + description: 'Longitude and latitude.', + example: '{ "lon": -73.614830, "lat": 45.505918 }', + name: 'source.geo.location', + type: 'geo_point', + }, + 'source.geo.name': { + category: 'source', + description: + 'User-defined description of a location, at the level of granularity they care about. Could be the name of their data centers, the floor number, if this describes a local physical entity, city names. Not typically used in automated geolocation.', + example: 'boston-dc', + name: 'source.geo.name', + type: 'keyword', + }, + 'source.geo.region_iso_code': { + category: 'source', + description: 'Region ISO code.', + example: 'CA-QC', + name: 'source.geo.region_iso_code', + type: 'keyword', + }, + 'source.geo.region_name': { + category: 'source', + description: 'Region name.', + example: 'Quebec', + name: 'source.geo.region_name', + type: 'keyword', + }, + 'source.ip': { + category: 'source', + description: 'IP address of the source. Can be one or multiple IPv4 or IPv6 addresses.', + name: 'source.ip', + type: 'ip', + }, + 'source.mac': { + category: 'source', + description: 'MAC address of the source.', + name: 'source.mac', + type: 'keyword', + }, + 'source.nat.ip': { + category: 'source', + description: + 'Translated ip of source based NAT sessions (e.g. internal client to internet) Typically connections traversing load balancers, firewalls, or routers.', + name: 'source.nat.ip', + type: 'ip', + }, + 'source.nat.port': { + category: 'source', + description: + 'Translated port of source based NAT sessions. (e.g. internal client to internet) Typically used with load balancers, firewalls, or routers.', + name: 'source.nat.port', + type: 'long', + format: 'string', + }, + 'source.packets': { + category: 'source', + description: 'Packets sent from the source to the destination.', + example: 12, + name: 'source.packets', + type: 'long', + }, + 'source.port': { + category: 'source', + description: 'Port of the source.', + name: 'source.port', + type: 'long', + format: 'string', + }, + 'source.registered_domain': { + category: 'source', + description: + 'The highest registered source domain, stripped of the subdomain. For example, the registered domain for "foo.google.com" is "google.com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk".', + example: 'google.com', + name: 'source.registered_domain', + type: 'keyword', + }, + 'source.top_level_domain': { + category: 'source', + description: + 'The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for google.com is "com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk".', + example: 'co.uk', + name: 'source.top_level_domain', + type: 'keyword', + }, + 'source.user.domain': { + category: 'source', + description: + 'Name of the directory the user is a member of. For example, an LDAP or Active Directory domain name.', + name: 'source.user.domain', + type: 'keyword', + }, + 'source.user.email': { + category: 'source', + description: 'User email address.', + name: 'source.user.email', + type: 'keyword', + }, + 'source.user.full_name': { + category: 'source', + description: "User's full name, if available.", + example: 'Albert Einstein', + name: 'source.user.full_name', + type: 'keyword', + }, + 'source.user.group.domain': { + category: 'source', + description: + 'Name of the directory the group is a member of. For example, an LDAP or Active Directory domain name.', + name: 'source.user.group.domain', + type: 'keyword', + }, + 'source.user.group.id': { + category: 'source', + description: 'Unique identifier for the group on the system/platform.', + name: 'source.user.group.id', + type: 'keyword', + }, + 'source.user.group.name': { + category: 'source', + description: 'Name of the group.', + name: 'source.user.group.name', + type: 'keyword', + }, + 'source.user.hash': { + category: 'source', + description: + 'Unique user hash to correlate information for a user in anonymized form. Useful if `user.id` or `user.name` contain confidential information and cannot be used.', + name: 'source.user.hash', + type: 'keyword', + }, + 'source.user.id': { + category: 'source', + description: 'Unique identifiers of the user.', + name: 'source.user.id', + type: 'keyword', + }, + 'source.user.name': { + category: 'source', + description: 'Short name or login of the user.', + example: 'albert', + name: 'source.user.name', + type: 'keyword', + }, + 'threat.framework': { + category: 'threat', + description: + 'Name of the threat framework used to further categorize and classify the tactic and technique of the reported threat. Framework classification can be provided by detecting systems, evaluated at ingest time, or retrospectively tagged to events.', + example: 'MITRE ATT&CK', + name: 'threat.framework', + type: 'keyword', + }, + 'threat.tactic.id': { + category: 'threat', + description: + 'The id of tactic used by this threat. You can use the Mitre ATT&CK Matrix Tactic categorization, for example. (ex. https://attack.mitre.org/tactics/TA0040/ )', + example: 'TA0040', + name: 'threat.tactic.id', + type: 'keyword', + }, + 'threat.tactic.name': { + category: 'threat', + description: + 'Name of the type of tactic used by this threat. You can use the Mitre ATT&CK Matrix Tactic categorization, for example. (ex. https://attack.mitre.org/tactics/TA0040/ )', + example: 'impact', + name: 'threat.tactic.name', + type: 'keyword', + }, + 'threat.tactic.reference': { + category: 'threat', + description: + 'The reference url of tactic used by this threat. You can use the Mitre ATT&CK Matrix Tactic categorization, for example. (ex. https://attack.mitre.org/tactics/TA0040/ )', + example: 'https://attack.mitre.org/tactics/TA0040/', + name: 'threat.tactic.reference', + type: 'keyword', + }, + 'threat.technique.id': { + category: 'threat', + description: + 'The id of technique used by this tactic. You can use the Mitre ATT&CK Matrix Tactic categorization, for example. (ex. https://attack.mitre.org/techniques/T1499/ )', + example: 'T1499', + name: 'threat.technique.id', + type: 'keyword', + }, + 'threat.technique.name': { + category: 'threat', + description: + 'The name of technique used by this tactic. You can use the Mitre ATT&CK Matrix Tactic categorization, for example. (ex. https://attack.mitre.org/techniques/T1499/ )', + example: 'endpoint denial of service', + name: 'threat.technique.name', + type: 'keyword', + }, + 'threat.technique.reference': { + category: 'threat', + description: + 'The reference url of technique used by this tactic. You can use the Mitre ATT&CK Matrix Tactic categorization, for example. (ex. https://attack.mitre.org/techniques/T1499/ )', + example: 'https://attack.mitre.org/techniques/T1499/', + name: 'threat.technique.reference', + type: 'keyword', + }, + 'tls.cipher': { + category: 'tls', + description: 'String indicating the cipher used during the current connection.', + example: 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256', + name: 'tls.cipher', + type: 'keyword', + }, + 'tls.client.certificate': { + category: 'tls', + description: + 'PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list.', + example: 'MII...', + name: 'tls.client.certificate', + type: 'keyword', + }, + 'tls.client.certificate_chain': { + category: 'tls', + description: + 'Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain.', + example: '["MII...","MII..."]', + name: 'tls.client.certificate_chain', + type: 'keyword', + }, + 'tls.client.hash.md5': { + category: 'tls', + description: + 'Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash.', + example: '0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC', + name: 'tls.client.hash.md5', + type: 'keyword', + }, + 'tls.client.hash.sha1': { + category: 'tls', + description: + 'Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash.', + example: '9E393D93138888D288266C2D915214D1D1CCEB2A', + name: 'tls.client.hash.sha1', + type: 'keyword', + }, + 'tls.client.hash.sha256': { + category: 'tls', + description: + 'Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash.', + example: '0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0', + name: 'tls.client.hash.sha256', + type: 'keyword', + }, + 'tls.client.issuer': { + category: 'tls', + description: + 'Distinguished name of subject of the issuer of the x.509 certificate presented by the client.', + example: 'CN=MyDomain Root CA, OU=Infrastructure Team, DC=mydomain, DC=com', + name: 'tls.client.issuer', + type: 'keyword', + }, + 'tls.client.ja3': { + category: 'tls', + description: 'A hash that identifies clients based on how they perform an SSL/TLS handshake.', + example: 'd4e5b18d6b55c71272893221c96ba240', + name: 'tls.client.ja3', + type: 'keyword', + }, + 'tls.client.not_after': { + category: 'tls', + description: 'Date/Time indicating when client certificate is no longer considered valid.', + example: '2021-01-01T00:00:00.000Z', + name: 'tls.client.not_after', + type: 'date', + }, + 'tls.client.not_before': { + category: 'tls', + description: 'Date/Time indicating when client certificate is first considered valid.', + example: '1970-01-01T00:00:00.000Z', + name: 'tls.client.not_before', + type: 'date', + }, + 'tls.client.server_name': { + category: 'tls', + description: + 'Also called an SNI, this tells the server which hostname to which the client is attempting to connect. When this value is available, it should get copied to `destination.domain`.', + example: 'www.elastic.co', + name: 'tls.client.server_name', + type: 'keyword', + }, + 'tls.client.subject': { + category: 'tls', + description: 'Distinguished name of subject of the x.509 certificate presented by the client.', + example: 'CN=myclient, OU=Documentation Team, DC=mydomain, DC=com', + name: 'tls.client.subject', + type: 'keyword', + }, + 'tls.client.supported_ciphers': { + category: 'tls', + description: 'Array of ciphers offered by the client during the client hello.', + example: + '["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","..."]', + name: 'tls.client.supported_ciphers', + type: 'keyword', + }, + 'tls.curve': { + category: 'tls', + description: 'String indicating the curve used for the given cipher, when applicable.', + example: 'secp256r1', + name: 'tls.curve', + type: 'keyword', + }, + 'tls.established': { + category: 'tls', + description: + 'Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel.', + name: 'tls.established', + type: 'boolean', + }, + 'tls.next_protocol': { + category: 'tls', + description: + 'String indicating the protocol being tunneled. Per the values in the IANA registry (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case.', + example: 'http/1.1', + name: 'tls.next_protocol', + type: 'keyword', + }, + 'tls.resumed': { + category: 'tls', + description: + 'Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation.', + name: 'tls.resumed', + type: 'boolean', + }, + 'tls.server.certificate': { + category: 'tls', + description: + 'PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list.', + example: 'MII...', + name: 'tls.server.certificate', + type: 'keyword', + }, + 'tls.server.certificate_chain': { + category: 'tls', + description: + 'Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain.', + example: '["MII...","MII..."]', + name: 'tls.server.certificate_chain', + type: 'keyword', + }, + 'tls.server.hash.md5': { + category: 'tls', + description: + 'Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash.', + example: '0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC', + name: 'tls.server.hash.md5', + type: 'keyword', + }, + 'tls.server.hash.sha1': { + category: 'tls', + description: + 'Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash.', + example: '9E393D93138888D288266C2D915214D1D1CCEB2A', + name: 'tls.server.hash.sha1', + type: 'keyword', + }, + 'tls.server.hash.sha256': { + category: 'tls', + description: + 'Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash.', + example: '0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0', + name: 'tls.server.hash.sha256', + type: 'keyword', + }, + 'tls.server.issuer': { + category: 'tls', + description: 'Subject of the issuer of the x.509 certificate presented by the server.', + example: 'CN=MyDomain Root CA, OU=Infrastructure Team, DC=mydomain, DC=com', + name: 'tls.server.issuer', + type: 'keyword', + }, + 'tls.server.ja3s': { + category: 'tls', + description: 'A hash that identifies servers based on how they perform an SSL/TLS handshake.', + example: '394441ab65754e2207b1e1b457b3641d', + name: 'tls.server.ja3s', + type: 'keyword', + }, + 'tls.server.not_after': { + category: 'tls', + description: 'Timestamp indicating when server certificate is no longer considered valid.', + example: '2021-01-01T00:00:00.000Z', + name: 'tls.server.not_after', + type: 'date', + }, + 'tls.server.not_before': { + category: 'tls', + description: 'Timestamp indicating when server certificate is first considered valid.', + example: '1970-01-01T00:00:00.000Z', + name: 'tls.server.not_before', + type: 'date', + }, + 'tls.server.subject': { + category: 'tls', + description: 'Subject of the x.509 certificate presented by the server.', + example: 'CN=www.mydomain.com, OU=Infrastructure Team, DC=mydomain, DC=com', + name: 'tls.server.subject', + type: 'keyword', + }, + 'tls.version': { + category: 'tls', + description: 'Numeric part of the version parsed from the original string.', + example: '1.2', + name: 'tls.version', + type: 'keyword', + }, + 'tls.version_protocol': { + category: 'tls', + description: 'Normalized lowercase protocol name parsed from original string.', + example: 'tls', + name: 'tls.version_protocol', + type: 'keyword', + }, + 'tracing.trace.id': { + category: 'tracing', + description: + 'Unique identifier of the trace. A trace groups multiple events like transactions that belong together. For example, a user request handled by multiple inter-connected services.', + example: '4bf92f3577b34da6a3ce929d0e0e4736', + name: 'tracing.trace.id', + type: 'keyword', + }, + 'tracing.transaction.id': { + category: 'tracing', + description: + 'Unique identifier of the transaction. A transaction is the highest level of work measured within a service, such as a request to a server.', + example: '00f067aa0ba902b7', + name: 'tracing.transaction.id', + type: 'keyword', + }, + 'url.domain': { + category: 'url', + description: + 'Domain of the url, such as "www.elastic.co". In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the `domain` field.', + example: 'www.elastic.co', + name: 'url.domain', + type: 'keyword', + }, + 'url.extension': { + category: 'url', + description: + 'The field contains the file extension from the original request url. The file extension is only set if it exists, as not every url has a file extension. The leading period must not be included. For example, the value must be "png", not ".png".', + example: 'png', + name: 'url.extension', + type: 'keyword', + }, + 'url.fragment': { + category: 'url', + description: + 'Portion of the url after the `#`, such as "top". The `#` is not part of the fragment.', + name: 'url.fragment', + type: 'keyword', + }, + 'url.full': { + category: 'url', + description: + 'If full URLs are important to your use case, they should be stored in `url.full`, whether this field is reconstructed or present in the event source.', + example: 'https://www.elastic.co:443/search?q=elasticsearch#top', + name: 'url.full', + type: 'keyword', + }, + 'url.original': { + category: 'url', + description: + 'Unmodified original url as seen in the event source. Note that in network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not.', + example: 'https://www.elastic.co:443/search?q=elasticsearch#top or /search?q=elasticsearch', + name: 'url.original', + type: 'keyword', + }, + 'url.password': { + category: 'url', + description: 'Password of the request.', + name: 'url.password', + type: 'keyword', + }, + 'url.path': { + category: 'url', + description: 'Path of the request, such as "/search".', + name: 'url.path', + type: 'keyword', + }, + 'url.port': { + category: 'url', + description: 'Port of the request, such as 443.', + example: 443, + name: 'url.port', + type: 'long', + format: 'string', + }, + 'url.query': { + category: 'url', + description: + 'The query field describes the query string of the request, such as "q=elasticsearch". The `?` is excluded from the query string. If a URL contains no `?`, there is no query field. If there is a `?` but no query, the query field exists with an empty string. The `exists` query can be used to differentiate between the two cases.', + name: 'url.query', + type: 'keyword', + }, + 'url.registered_domain': { + category: 'url', + description: + 'The highest registered url domain, stripped of the subdomain. For example, the registered domain for "foo.google.com" is "google.com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last two labels will not work well for TLDs such as "co.uk".', + example: 'google.com', + name: 'url.registered_domain', + type: 'keyword', + }, + 'url.scheme': { + category: 'url', + description: 'Scheme of the request, such as "https". Note: The `:` is not part of the scheme.', + example: 'https', + name: 'url.scheme', + type: 'keyword', + }, + 'url.top_level_domain': { + category: 'url', + description: + 'The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for google.com is "com". This value can be determined precisely with a list like the public suffix list (http://publicsuffix.org). Trying to approximate this by simply taking the last label will not work well for effective TLDs such as "co.uk".', + example: 'co.uk', + name: 'url.top_level_domain', + type: 'keyword', + }, + 'url.username': { + category: 'url', + description: 'Username of the request.', + name: 'url.username', + type: 'keyword', + }, + 'user.domain': { + category: 'user', + description: + 'Name of the directory the user is a member of. For example, an LDAP or Active Directory domain name.', + name: 'user.domain', + type: 'keyword', + }, + 'user.email': { + category: 'user', + description: 'User email address.', + name: 'user.email', + type: 'keyword', + }, + 'user.full_name': { + category: 'user', + description: "User's full name, if available.", + example: 'Albert Einstein', + name: 'user.full_name', + type: 'keyword', + }, + 'user.group.domain': { + category: 'user', + description: + 'Name of the directory the group is a member of. For example, an LDAP or Active Directory domain name.', + name: 'user.group.domain', + type: 'keyword', + }, + 'user.group.id': { + category: 'user', + description: 'Unique identifier for the group on the system/platform.', + name: 'user.group.id', + type: 'keyword', + }, + 'user.group.name': { + category: 'user', + description: 'Name of the group.', + name: 'user.group.name', + type: 'keyword', + }, + 'user.hash': { + category: 'user', + description: + 'Unique user hash to correlate information for a user in anonymized form. Useful if `user.id` or `user.name` contain confidential information and cannot be used.', + name: 'user.hash', + type: 'keyword', + }, + 'user.id': { + category: 'user', + description: 'Unique identifiers of the user.', + name: 'user.id', + type: 'keyword', + }, + 'user.name': { + category: 'user', + description: 'Short name or login of the user.', + example: 'albert', + name: 'user.name', + type: 'keyword', + }, + 'user_agent.device.name': { + category: 'user_agent', + description: 'Name of the device.', + example: 'iPhone', + name: 'user_agent.device.name', + type: 'keyword', + }, + 'user_agent.name': { + category: 'user_agent', + description: 'Name of the user agent.', + example: 'Safari', + name: 'user_agent.name', + type: 'keyword', + }, + 'user_agent.original': { + category: 'user_agent', + description: 'Unparsed user_agent string.', + example: + 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1', + name: 'user_agent.original', + type: 'keyword', + }, + 'user_agent.os.family': { + category: 'user_agent', + description: 'OS family (such as redhat, debian, freebsd, windows).', + example: 'debian', + name: 'user_agent.os.family', + type: 'keyword', + }, + 'user_agent.os.full': { + category: 'user_agent', + description: 'Operating system name, including the version or code name.', + example: 'Mac OS Mojave', + name: 'user_agent.os.full', + type: 'keyword', + }, + 'user_agent.os.kernel': { + category: 'user_agent', + description: 'Operating system kernel version as a raw string.', + example: '4.4.0-112-generic', + name: 'user_agent.os.kernel', + type: 'keyword', + }, + 'user_agent.os.name': { + category: 'user_agent', + description: 'Operating system name, without the version.', + example: 'Mac OS X', + name: 'user_agent.os.name', + type: 'keyword', + }, + 'user_agent.os.platform': { + category: 'user_agent', + description: 'Operating system platform (such centos, ubuntu, windows).', + example: 'darwin', + name: 'user_agent.os.platform', + type: 'keyword', + }, + 'user_agent.os.version': { + category: 'user_agent', + description: 'Operating system version as a raw string.', + example: '10.14.1', + name: 'user_agent.os.version', + type: 'keyword', + }, + 'user_agent.version': { + category: 'user_agent', + description: 'Version of the user agent.', + example: 12, + name: 'user_agent.version', + type: 'keyword', + }, + 'vlan.id': { + category: 'vlan', + description: 'VLAN ID as reported by the observer.', + example: 10, + name: 'vlan.id', + type: 'keyword', + }, + 'vlan.name': { + category: 'vlan', + description: 'Optional VLAN name as reported by the observer.', + example: 'outside', + name: 'vlan.name', + type: 'keyword', + }, + 'vulnerability.category': { + category: 'vulnerability', + description: + 'The type of system or architecture that the vulnerability affects. These may be platform-specific (for example, Debian or SUSE) or general (for example, Database or Firewall). For example (https://qualysguard.qualys.com/qwebhelp/fo_portal/knowledgebase/vulnerability_categories.htm[Qualys vulnerability categories]) This field must be an array.', + example: '["Firewall"]', + name: 'vulnerability.category', + type: 'keyword', + }, + 'vulnerability.classification': { + category: 'vulnerability', + description: + 'The classification of the vulnerability scoring system. For example (https://www.first.org/cvss/)', + example: 'CVSS', + name: 'vulnerability.classification', + type: 'keyword', + }, + 'vulnerability.description': { + category: 'vulnerability', + description: + 'The description of the vulnerability that provides additional context of the vulnerability. For example (https://cve.mitre.org/about/faqs.html#cve_entry_descriptions_created[Common Vulnerabilities and Exposure CVE description])', + example: 'In macOS before 2.12.6, there is a vulnerability in the RPC...', + name: 'vulnerability.description', + type: 'keyword', + }, + 'vulnerability.enumeration': { + category: 'vulnerability', + description: + 'The type of identifier used for this vulnerability. For example (https://cve.mitre.org/about/)', + example: 'CVE', + name: 'vulnerability.enumeration', + type: 'keyword', + }, + 'vulnerability.id': { + category: 'vulnerability', + description: + 'The identification (ID) is the number portion of a vulnerability entry. It includes a unique identification number for the vulnerability. For example (https://cve.mitre.org/about/faqs.html#what_is_cve_id)[Common Vulnerabilities and Exposure CVE ID]', + example: 'CVE-2019-00001', + name: 'vulnerability.id', + type: 'keyword', + }, + 'vulnerability.reference': { + category: 'vulnerability', + description: + 'A resource that provides additional information, context, and mitigations for the identified vulnerability.', + example: 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6111', + name: 'vulnerability.reference', + type: 'keyword', + }, + 'vulnerability.report_id': { + category: 'vulnerability', + description: 'The report or scan identification number.', + example: 20191018.0001, + name: 'vulnerability.report_id', + type: 'keyword', + }, + 'vulnerability.scanner.vendor': { + category: 'vulnerability', + description: 'The name of the vulnerability scanner vendor.', + example: 'Tenable', + name: 'vulnerability.scanner.vendor', + type: 'keyword', + }, + 'vulnerability.score.base': { + category: 'vulnerability', + description: + 'Scores can range from 0.0 to 10.0, with 10.0 being the most severe. Base scores cover an assessment for exploitability metrics (attack vector, complexity, privileges, and user interaction), impact metrics (confidentiality, integrity, and availability), and scope. For example (https://www.first.org/cvss/specification-document)', + example: 5.5, + name: 'vulnerability.score.base', + type: 'float', + }, + 'vulnerability.score.environmental': { + category: 'vulnerability', + description: + 'Scores can range from 0.0 to 10.0, with 10.0 being the most severe. Environmental scores cover an assessment for any modified Base metrics, confidentiality, integrity, and availability requirements. For example (https://www.first.org/cvss/specification-document)', + example: 5.5, + name: 'vulnerability.score.environmental', + type: 'float', + }, + 'vulnerability.score.temporal': { + category: 'vulnerability', + description: + 'Scores can range from 0.0 to 10.0, with 10.0 being the most severe. Temporal scores cover an assessment for code maturity, remediation level, and confidence. For example (https://www.first.org/cvss/specification-document)', + name: 'vulnerability.score.temporal', + type: 'float', + }, + 'vulnerability.score.version': { + category: 'vulnerability', + description: + 'The National Vulnerability Database (NVD) provides qualitative severity rankings of "Low", "Medium", and "High" for CVSS v2.0 base score ranges in addition to the severity ratings for CVSS v3.0 as they are defined in the CVSS v3.0 specification. CVSS is owned and managed by FIRST.Org, Inc. (FIRST), a US-based non-profit organization, whose mission is to help computer security incident response teams across the world. For example (https://nvd.nist.gov/vuln-metrics/cvss)', + example: 2, + name: 'vulnerability.score.version', + type: 'keyword', + }, + 'vulnerability.severity': { + category: 'vulnerability', + description: + 'The severity of the vulnerability can help with metrics and internal prioritization regarding remediation. For example (https://nvd.nist.gov/vuln-metrics/cvss)', + example: 'Critical', + name: 'vulnerability.severity', + type: 'keyword', + }, + 'agent.hostname': { + category: 'agent', + description: + 'Deprecated - use agent.name or agent.id to identify an agent. Hostname of the agent. ', + name: 'agent.hostname', + type: 'keyword', + }, + 'beat.timezone': { + category: 'beat', + name: 'beat.timezone', + type: 'alias', + }, + fields: { + category: 'base', + description: 'Contains user configurable fields. ', + name: 'fields', + type: 'object', + }, + 'beat.name': { + category: 'beat', + name: 'beat.name', + type: 'alias', + }, + 'beat.hostname': { + category: 'beat', + name: 'beat.hostname', + type: 'alias', + }, + 'timeseries.instance': { + category: 'timeseries', + description: 'Time series instance id', + name: 'timeseries.instance', + type: 'keyword', + }, + 'cloud.project.id': { + category: 'cloud', + description: 'Name of the project in Google Cloud. ', + example: 'project-x', + name: 'cloud.project.id', + }, + 'cloud.image.id': { + category: 'cloud', + description: 'Image ID for the cloud instance. ', + example: 'ami-abcd1234', + name: 'cloud.image.id', + }, + 'meta.cloud.provider': { + category: 'meta', + name: 'meta.cloud.provider', + type: 'alias', + }, + 'meta.cloud.instance_id': { + category: 'meta', + name: 'meta.cloud.instance_id', + type: 'alias', + }, + 'meta.cloud.instance_name': { + category: 'meta', + name: 'meta.cloud.instance_name', + type: 'alias', + }, + 'meta.cloud.machine_type': { + category: 'meta', + name: 'meta.cloud.machine_type', + type: 'alias', + }, + 'meta.cloud.availability_zone': { + category: 'meta', + name: 'meta.cloud.availability_zone', + type: 'alias', + }, + 'meta.cloud.project_id': { + category: 'meta', + name: 'meta.cloud.project_id', + type: 'alias', + }, + 'meta.cloud.region': { + category: 'meta', + name: 'meta.cloud.region', + type: 'alias', + }, + 'docker.container.id': { + category: 'docker', + name: 'docker.container.id', + type: 'alias', + }, + 'docker.container.image': { + category: 'docker', + name: 'docker.container.image', + type: 'alias', + }, + 'docker.container.name': { + category: 'docker', + name: 'docker.container.name', + type: 'alias', + }, + 'docker.container.labels': { + category: 'docker', + description: 'Image labels. ', + name: 'docker.container.labels', + type: 'object', + }, + 'host.containerized': { + category: 'host', + description: 'If the host is a container. ', + name: 'host.containerized', + type: 'boolean', + }, + 'host.os.build': { + category: 'host', + description: 'OS build information. ', + example: '18D109', + name: 'host.os.build', + type: 'keyword', + }, + 'host.os.codename': { + category: 'host', + description: 'OS codename, if any. ', + example: 'stretch', + name: 'host.os.codename', + type: 'keyword', + }, + 'kubernetes.pod.name': { + category: 'kubernetes', + description: 'Kubernetes pod name ', + name: 'kubernetes.pod.name', + type: 'keyword', + }, + 'kubernetes.pod.uid': { + category: 'kubernetes', + description: 'Kubernetes Pod UID ', + name: 'kubernetes.pod.uid', + type: 'keyword', + }, + 'kubernetes.namespace': { + category: 'kubernetes', + description: 'Kubernetes namespace ', + name: 'kubernetes.namespace', + type: 'keyword', + }, + 'kubernetes.node.name': { + category: 'kubernetes', + description: 'Kubernetes node name ', + name: 'kubernetes.node.name', + type: 'keyword', + }, + 'kubernetes.labels.*': { + category: 'kubernetes', + description: 'Kubernetes labels map ', + name: 'kubernetes.labels.*', + type: 'object', + }, + 'kubernetes.annotations.*': { + category: 'kubernetes', + description: 'Kubernetes annotations map ', + name: 'kubernetes.annotations.*', + type: 'object', + }, + 'kubernetes.replicaset.name': { + category: 'kubernetes', + description: 'Kubernetes replicaset name ', + name: 'kubernetes.replicaset.name', + type: 'keyword', + }, + 'kubernetes.deployment.name': { + category: 'kubernetes', + description: 'Kubernetes deployment name ', + name: 'kubernetes.deployment.name', + type: 'keyword', + }, + 'kubernetes.statefulset.name': { + category: 'kubernetes', + description: 'Kubernetes statefulset name ', + name: 'kubernetes.statefulset.name', + type: 'keyword', + }, + 'kubernetes.container.name': { + category: 'kubernetes', + description: 'Kubernetes container name ', + name: 'kubernetes.container.name', + type: 'keyword', + }, + 'kubernetes.container.image': { + category: 'kubernetes', + description: 'Kubernetes container image ', + name: 'kubernetes.container.image', + type: 'keyword', + }, + 'process.exe': { + category: 'process', + name: 'process.exe', + type: 'alias', + }, + 'jolokia.agent.version': { + category: 'jolokia', + description: 'Version number of jolokia agent. ', + name: 'jolokia.agent.version', + type: 'keyword', + }, + 'jolokia.agent.id': { + category: 'jolokia', + description: + 'Each agent has a unique id which can be either provided during startup of the agent in form of a configuration parameter or being autodetected. If autodected, the id has several parts: The IP, the process id, hashcode of the agent and its type. ', + name: 'jolokia.agent.id', + type: 'keyword', + }, + 'jolokia.server.product': { + category: 'jolokia', + description: 'The container product if detected. ', + name: 'jolokia.server.product', + type: 'keyword', + }, + 'jolokia.server.version': { + category: 'jolokia', + description: "The container's version (if detected). ", + name: 'jolokia.server.version', + type: 'keyword', + }, + 'jolokia.server.vendor': { + category: 'jolokia', + description: 'The vendor of the container the agent is running in. ', + name: 'jolokia.server.vendor', + type: 'keyword', + }, + 'jolokia.url': { + category: 'jolokia', + description: 'The URL how this agent can be contacted. ', + name: 'jolokia.url', + type: 'keyword', + }, + 'jolokia.secured': { + category: 'jolokia', + description: 'Whether the agent was configured for authentication or not. ', + name: 'jolokia.secured', + type: 'boolean', + }, + 'file.setuid': { + category: 'file', + description: 'Set if the file has the `setuid` bit set. Omitted otherwise.', + example: 'true', + name: 'file.setuid', + type: 'boolean', + }, + 'file.setgid': { + category: 'file', + description: 'Set if the file has the `setgid` bit set. Omitted otherwise.', + example: 'true', + name: 'file.setgid', + type: 'boolean', + }, + 'file.origin': { + category: 'file', + description: + 'An array of strings describing a possible external origin for this file. For example, the URL it was downloaded from. Only supported in macOS, via the kMDItemWhereFroms attribute. Omitted if origin information is not available. ', + name: 'file.origin', + type: 'keyword', + }, + 'file.selinux.user': { + category: 'file', + description: 'The owner of the object.', + name: 'file.selinux.user', + type: 'keyword', + }, + 'file.selinux.role': { + category: 'file', + description: "The object's SELinux role.", + name: 'file.selinux.role', + type: 'keyword', + }, + 'file.selinux.domain': { + category: 'file', + description: "The object's SELinux domain or type.", + name: 'file.selinux.domain', + type: 'keyword', + }, + 'file.selinux.level': { + category: 'file', + description: "The object's SELinux level.", + example: 's0', + name: 'file.selinux.level', + type: 'keyword', + }, + 'user.audit.id': { + category: 'user', + description: 'Audit user ID.', + name: 'user.audit.id', + type: 'keyword', + }, + 'user.audit.name': { + category: 'user', + description: 'Audit user name.', + name: 'user.audit.name', + type: 'keyword', + }, + 'user.effective.id': { + category: 'user', + description: 'Effective user ID.', + name: 'user.effective.id', + type: 'keyword', + }, + 'user.effective.name': { + category: 'user', + description: 'Effective user name.', + name: 'user.effective.name', + type: 'keyword', + }, + 'user.effective.group.id': { + category: 'user', + description: 'Effective group ID.', + name: 'user.effective.group.id', + type: 'keyword', + }, + 'user.effective.group.name': { + category: 'user', + description: 'Effective group name.', + name: 'user.effective.group.name', + type: 'keyword', + }, + 'user.filesystem.id': { + category: 'user', + description: 'Filesystem user ID.', + name: 'user.filesystem.id', + type: 'keyword', + }, + 'user.filesystem.name': { + category: 'user', + description: 'Filesystem user name.', + name: 'user.filesystem.name', + type: 'keyword', + }, + 'user.filesystem.group.id': { + category: 'user', + description: 'Filesystem group ID.', + name: 'user.filesystem.group.id', + type: 'keyword', + }, + 'user.filesystem.group.name': { + category: 'user', + description: 'Filesystem group name.', + name: 'user.filesystem.group.name', + type: 'keyword', + }, + 'user.saved.id': { + category: 'user', + description: 'Saved user ID.', + name: 'user.saved.id', + type: 'keyword', + }, + 'user.saved.name': { + category: 'user', + description: 'Saved user name.', + name: 'user.saved.name', + type: 'keyword', + }, + 'user.saved.group.id': { + category: 'user', + description: 'Saved group ID.', + name: 'user.saved.group.id', + type: 'keyword', + }, + 'user.saved.group.name': { + category: 'user', + description: 'Saved group name.', + name: 'user.saved.group.name', + type: 'keyword', + }, + 'user.auid': { + category: 'user', + name: 'user.auid', + type: 'alias', + }, + 'user.uid': { + category: 'user', + name: 'user.uid', + type: 'alias', + }, + 'user.euid': { + category: 'user', + name: 'user.euid', + type: 'alias', + }, + 'user.fsuid': { + category: 'user', + name: 'user.fsuid', + type: 'alias', + }, + 'user.suid': { + category: 'user', + name: 'user.suid', + type: 'alias', + }, + 'user.gid': { + category: 'user', + name: 'user.gid', + type: 'alias', + }, + 'user.egid': { + category: 'user', + name: 'user.egid', + type: 'alias', + }, + 'user.sgid': { + category: 'user', + name: 'user.sgid', + type: 'alias', + }, + 'user.fsgid': { + category: 'user', + name: 'user.fsgid', + type: 'alias', + }, + 'user.name_map.auid': { + category: 'user', + name: 'user.name_map.auid', + type: 'alias', + }, + 'user.name_map.uid': { + category: 'user', + name: 'user.name_map.uid', + type: 'alias', + }, + 'user.name_map.euid': { + category: 'user', + name: 'user.name_map.euid', + type: 'alias', + }, + 'user.name_map.fsuid': { + category: 'user', + name: 'user.name_map.fsuid', + type: 'alias', + }, + 'user.name_map.suid': { + category: 'user', + name: 'user.name_map.suid', + type: 'alias', + }, + 'user.name_map.gid': { + category: 'user', + name: 'user.name_map.gid', + type: 'alias', + }, + 'user.name_map.egid': { + category: 'user', + name: 'user.name_map.egid', + type: 'alias', + }, + 'user.name_map.sgid': { + category: 'user', + name: 'user.name_map.sgid', + type: 'alias', + }, + 'user.name_map.fsgid': { + category: 'user', + name: 'user.name_map.fsgid', + type: 'alias', + }, + 'user.selinux.user': { + category: 'user', + description: 'account submitted for authentication', + name: 'user.selinux.user', + type: 'keyword', + }, + 'user.selinux.role': { + category: 'user', + description: "user's SELinux role", + name: 'user.selinux.role', + type: 'keyword', + }, + 'user.selinux.domain': { + category: 'user', + description: "The actor's SELinux domain or type.", + name: 'user.selinux.domain', + type: 'keyword', + }, + 'user.selinux.level': { + category: 'user', + description: "The actor's SELinux level.", + example: 's0', + name: 'user.selinux.level', + type: 'keyword', + }, + 'user.selinux.category': { + category: 'user', + description: "The actor's SELinux category or compartments.", + name: 'user.selinux.category', + type: 'keyword', + }, + 'process.cwd': { + category: 'process', + description: 'The current working directory.', + name: 'process.cwd', + type: 'alias', + }, + 'source.path': { + category: 'source', + description: 'This is the path associated with a unix socket.', + name: 'source.path', + type: 'keyword', + }, + 'destination.path': { + category: 'destination', + description: 'This is the path associated with a unix socket.', + name: 'destination.path', + type: 'keyword', + }, + 'auditd.message_type': { + category: 'auditd', + description: 'The audit message type (e.g. syscall or apparmor_denied). ', + example: 'syscall', + name: 'auditd.message_type', + type: 'keyword', + }, + 'auditd.sequence': { + category: 'auditd', + description: + 'The sequence number of the event as assigned by the kernel. Sequence numbers are stored as a uint32 in the kernel and can rollover. ', + name: 'auditd.sequence', + type: 'long', + }, + 'auditd.session': { + category: 'auditd', + description: + 'The session ID assigned to a login. All events related to a login session will have the same value. ', + name: 'auditd.session', + type: 'keyword', + }, + 'auditd.result': { + category: 'auditd', + description: 'The result of the audited operation (success/fail).', + example: 'success or fail', + name: 'auditd.result', + type: 'keyword', + }, + 'auditd.summary.actor.primary': { + category: 'auditd', + description: + "The primary identity of the actor. This is the actor's original login ID. It will not change even if the user changes to another account. ", + name: 'auditd.summary.actor.primary', + type: 'keyword', + }, + 'auditd.summary.actor.secondary': { + category: 'auditd', + description: + 'The secondary identity of the actor. This is typically the same as the primary, except for when the user has used `su`.', + name: 'auditd.summary.actor.secondary', + type: 'keyword', + }, + 'auditd.summary.object.type': { + category: 'auditd', + description: 'A description of the what the "thing" is (e.g. file, socket, user-session). ', + name: 'auditd.summary.object.type', + type: 'keyword', + }, + 'auditd.summary.object.primary': { + category: 'auditd', + description: '', + name: 'auditd.summary.object.primary', + type: 'keyword', + }, + 'auditd.summary.object.secondary': { + category: 'auditd', + description: '', + name: 'auditd.summary.object.secondary', + type: 'keyword', + }, + 'auditd.summary.how': { + category: 'auditd', + description: + 'This describes how the action was performed. Usually this is the exe or command that was being executed that triggered the event. ', + name: 'auditd.summary.how', + type: 'keyword', + }, + 'auditd.paths.inode': { + category: 'auditd', + description: 'inode number', + name: 'auditd.paths.inode', + type: 'keyword', + }, + 'auditd.paths.dev': { + category: 'auditd', + description: 'device name as found in /dev', + name: 'auditd.paths.dev', + type: 'keyword', + }, + 'auditd.paths.obj_user': { + category: 'auditd', + description: '', + name: 'auditd.paths.obj_user', + type: 'keyword', + }, + 'auditd.paths.obj_role': { + category: 'auditd', + description: '', + name: 'auditd.paths.obj_role', + type: 'keyword', + }, + 'auditd.paths.obj_domain': { + category: 'auditd', + description: '', + name: 'auditd.paths.obj_domain', + type: 'keyword', + }, + 'auditd.paths.obj_level': { + category: 'auditd', + description: '', + name: 'auditd.paths.obj_level', + type: 'keyword', + }, + 'auditd.paths.objtype': { + category: 'auditd', + description: '', + name: 'auditd.paths.objtype', + type: 'keyword', + }, + 'auditd.paths.ouid': { + category: 'auditd', + description: 'file owner user ID', + name: 'auditd.paths.ouid', + type: 'keyword', + }, + 'auditd.paths.rdev': { + category: 'auditd', + description: 'the device identifier (special files only)', + name: 'auditd.paths.rdev', + type: 'keyword', + }, + 'auditd.paths.nametype': { + category: 'auditd', + description: 'kind of file operation being referenced', + name: 'auditd.paths.nametype', + type: 'keyword', + }, + 'auditd.paths.ogid': { + category: 'auditd', + description: 'file owner group ID', + name: 'auditd.paths.ogid', + type: 'keyword', + }, + 'auditd.paths.item': { + category: 'auditd', + description: 'which item is being recorded', + name: 'auditd.paths.item', + type: 'keyword', + }, + 'auditd.paths.mode': { + category: 'auditd', + description: 'mode flags on a file', + name: 'auditd.paths.mode', + type: 'keyword', + }, + 'auditd.paths.name': { + category: 'auditd', + description: 'file name in avcs', + name: 'auditd.paths.name', + type: 'keyword', + }, + 'auditd.data.action': { + category: 'auditd', + description: 'netfilter packet disposition', + name: 'auditd.data.action', + type: 'keyword', + }, + 'auditd.data.minor': { + category: 'auditd', + description: 'device minor number', + name: 'auditd.data.minor', + type: 'keyword', + }, + 'auditd.data.acct': { + category: 'auditd', + description: "a user's account name", + name: 'auditd.data.acct', + type: 'keyword', + }, + 'auditd.data.addr': { + category: 'auditd', + description: 'the remote address that the user is connecting from', + name: 'auditd.data.addr', + type: 'keyword', + }, + 'auditd.data.cipher': { + category: 'auditd', + description: 'name of crypto cipher selected', + name: 'auditd.data.cipher', + type: 'keyword', + }, + 'auditd.data.id': { + category: 'auditd', + description: 'during account changes', + name: 'auditd.data.id', + type: 'keyword', + }, + 'auditd.data.entries': { + category: 'auditd', + description: 'number of entries in the netfilter table', + name: 'auditd.data.entries', + type: 'keyword', + }, + 'auditd.data.kind': { + category: 'auditd', + description: 'server or client in crypto operation', + name: 'auditd.data.kind', + type: 'keyword', + }, + 'auditd.data.ksize': { + category: 'auditd', + description: 'key size for crypto operation', + name: 'auditd.data.ksize', + type: 'keyword', + }, + 'auditd.data.spid': { + category: 'auditd', + description: 'sent process ID', + name: 'auditd.data.spid', + type: 'keyword', + }, + 'auditd.data.arch': { + category: 'auditd', + description: 'the elf architecture flags', + name: 'auditd.data.arch', + type: 'keyword', + }, + 'auditd.data.argc': { + category: 'auditd', + description: 'the number of arguments to an execve syscall', + name: 'auditd.data.argc', + type: 'keyword', + }, + 'auditd.data.major': { + category: 'auditd', + description: 'device major number', + name: 'auditd.data.major', + type: 'keyword', + }, + 'auditd.data.unit': { + category: 'auditd', + description: 'systemd unit', + name: 'auditd.data.unit', + type: 'keyword', + }, + 'auditd.data.table': { + category: 'auditd', + description: 'netfilter table name', + name: 'auditd.data.table', + type: 'keyword', + }, + 'auditd.data.terminal': { + category: 'auditd', + description: 'terminal name the user is running programs on', + name: 'auditd.data.terminal', + type: 'keyword', + }, + 'auditd.data.grantors': { + category: 'auditd', + description: 'pam modules approving the action', + name: 'auditd.data.grantors', + type: 'keyword', + }, + 'auditd.data.direction': { + category: 'auditd', + description: 'direction of crypto operation', + name: 'auditd.data.direction', + type: 'keyword', + }, + 'auditd.data.op': { + category: 'auditd', + description: 'the operation being performed that is audited', + name: 'auditd.data.op', + type: 'keyword', + }, + 'auditd.data.tty': { + category: 'auditd', + description: 'tty udevice the user is running programs on', + name: 'auditd.data.tty', + type: 'keyword', + }, + 'auditd.data.syscall': { + category: 'auditd', + description: 'syscall number in effect when the event occurred', + name: 'auditd.data.syscall', + type: 'keyword', + }, + 'auditd.data.data': { + category: 'auditd', + description: 'TTY text', + name: 'auditd.data.data', + type: 'keyword', + }, + 'auditd.data.family': { + category: 'auditd', + description: 'netfilter protocol', + name: 'auditd.data.family', + type: 'keyword', + }, + 'auditd.data.mac': { + category: 'auditd', + description: 'crypto MAC algorithm selected', + name: 'auditd.data.mac', + type: 'keyword', + }, + 'auditd.data.pfs': { + category: 'auditd', + description: 'perfect forward secrecy method', + name: 'auditd.data.pfs', + type: 'keyword', + }, + 'auditd.data.items': { + category: 'auditd', + description: 'the number of path records in the event', + name: 'auditd.data.items', + type: 'keyword', + }, + 'auditd.data.a0': { + category: 'auditd', + description: '', + name: 'auditd.data.a0', + type: 'keyword', + }, + 'auditd.data.a1': { + category: 'auditd', + description: '', + name: 'auditd.data.a1', + type: 'keyword', + }, + 'auditd.data.a2': { + category: 'auditd', + description: '', + name: 'auditd.data.a2', + type: 'keyword', + }, + 'auditd.data.a3': { + category: 'auditd', + description: '', + name: 'auditd.data.a3', + type: 'keyword', + }, + 'auditd.data.hostname': { + category: 'auditd', + description: 'the hostname that the user is connecting from', + name: 'auditd.data.hostname', + type: 'keyword', + }, + 'auditd.data.lport': { + category: 'auditd', + description: 'local network port', + name: 'auditd.data.lport', + type: 'keyword', + }, + 'auditd.data.rport': { + category: 'auditd', + description: 'remote port number', + name: 'auditd.data.rport', + type: 'keyword', + }, + 'auditd.data.exit': { + category: 'auditd', + description: 'syscall exit code', + name: 'auditd.data.exit', + type: 'keyword', + }, + 'auditd.data.fp': { + category: 'auditd', + description: 'crypto key finger print', + name: 'auditd.data.fp', + type: 'keyword', + }, + 'auditd.data.laddr': { + category: 'auditd', + description: 'local network address', + name: 'auditd.data.laddr', + type: 'keyword', + }, + 'auditd.data.sport': { + category: 'auditd', + description: 'local port number', + name: 'auditd.data.sport', + type: 'keyword', + }, + 'auditd.data.capability': { + category: 'auditd', + description: 'posix capabilities', + name: 'auditd.data.capability', + type: 'keyword', + }, + 'auditd.data.nargs': { + category: 'auditd', + description: 'the number of arguments to a socket call', + name: 'auditd.data.nargs', + type: 'keyword', + }, + 'auditd.data.new-enabled': { + category: 'auditd', + description: 'new TTY audit enabled setting', + name: 'auditd.data.new-enabled', + type: 'keyword', + }, + 'auditd.data.audit_backlog_limit': { + category: 'auditd', + description: "audit system's backlog queue size", + name: 'auditd.data.audit_backlog_limit', + type: 'keyword', + }, + 'auditd.data.dir': { + category: 'auditd', + description: 'directory name', + name: 'auditd.data.dir', + type: 'keyword', + }, + 'auditd.data.cap_pe': { + category: 'auditd', + description: 'process effective capability map', + name: 'auditd.data.cap_pe', + type: 'keyword', + }, + 'auditd.data.model': { + category: 'auditd', + description: 'security model being used for virt', + name: 'auditd.data.model', + type: 'keyword', + }, + 'auditd.data.new_pp': { + category: 'auditd', + description: 'new process permitted capability map', + name: 'auditd.data.new_pp', + type: 'keyword', + }, + 'auditd.data.old-enabled': { + category: 'auditd', + description: 'present TTY audit enabled setting', + name: 'auditd.data.old-enabled', + type: 'keyword', + }, + 'auditd.data.oauid': { + category: 'auditd', + description: "object's login user ID", + name: 'auditd.data.oauid', + type: 'keyword', + }, + 'auditd.data.old': { + category: 'auditd', + description: 'old value', + name: 'auditd.data.old', + type: 'keyword', + }, + 'auditd.data.banners': { + category: 'auditd', + description: 'banners used on printed page', + name: 'auditd.data.banners', + type: 'keyword', + }, + 'auditd.data.feature': { + category: 'auditd', + description: 'kernel feature being changed', + name: 'auditd.data.feature', + type: 'keyword', + }, + 'auditd.data.vm-ctx': { + category: 'auditd', + description: "the vm's context string", + name: 'auditd.data.vm-ctx', + type: 'keyword', + }, + 'auditd.data.opid': { + category: 'auditd', + description: "object's process ID", + name: 'auditd.data.opid', + type: 'keyword', + }, + 'auditd.data.seperms': { + category: 'auditd', + description: 'SELinux permissions being used', + name: 'auditd.data.seperms', + type: 'keyword', + }, + 'auditd.data.seresult': { + category: 'auditd', + description: 'SELinux AVC decision granted/denied', + name: 'auditd.data.seresult', + type: 'keyword', + }, + 'auditd.data.new-rng': { + category: 'auditd', + description: 'device name of rng being added from a vm', + name: 'auditd.data.new-rng', + type: 'keyword', + }, + 'auditd.data.old-net': { + category: 'auditd', + description: 'present MAC address assigned to vm', + name: 'auditd.data.old-net', + type: 'keyword', + }, + 'auditd.data.sigev_signo': { + category: 'auditd', + description: 'signal number', + name: 'auditd.data.sigev_signo', + type: 'keyword', + }, + 'auditd.data.ino': { + category: 'auditd', + description: 'inode number', + name: 'auditd.data.ino', + type: 'keyword', + }, + 'auditd.data.old_enforcing': { + category: 'auditd', + description: 'old MAC enforcement status', + name: 'auditd.data.old_enforcing', + type: 'keyword', + }, + 'auditd.data.old-vcpu': { + category: 'auditd', + description: 'present number of CPU cores', + name: 'auditd.data.old-vcpu', + type: 'keyword', + }, + 'auditd.data.range': { + category: 'auditd', + description: "user's SE Linux range", + name: 'auditd.data.range', + type: 'keyword', + }, + 'auditd.data.res': { + category: 'auditd', + description: 'result of the audited operation(success/fail)', + name: 'auditd.data.res', + type: 'keyword', + }, + 'auditd.data.added': { + category: 'auditd', + description: 'number of new files detected', + name: 'auditd.data.added', + type: 'keyword', + }, + 'auditd.data.fam': { + category: 'auditd', + description: 'socket address family', + name: 'auditd.data.fam', + type: 'keyword', + }, + 'auditd.data.nlnk-pid': { + category: 'auditd', + description: 'pid of netlink packet sender', + name: 'auditd.data.nlnk-pid', + type: 'keyword', + }, + 'auditd.data.subj': { + category: 'auditd', + description: "lspp subject's context string", + name: 'auditd.data.subj', + type: 'keyword', + }, + 'auditd.data.a[0-3]': { + category: 'auditd', + description: 'the arguments to a syscall', + name: 'auditd.data.a[0-3]', + type: 'keyword', + }, + 'auditd.data.cgroup': { + category: 'auditd', + description: 'path to cgroup in sysfs', + name: 'auditd.data.cgroup', + type: 'keyword', + }, + 'auditd.data.kernel': { + category: 'auditd', + description: "kernel's version number", + name: 'auditd.data.kernel', + type: 'keyword', + }, + 'auditd.data.ocomm': { + category: 'auditd', + description: "object's command line name", + name: 'auditd.data.ocomm', + type: 'keyword', + }, + 'auditd.data.new-net': { + category: 'auditd', + description: 'MAC address being assigned to vm', + name: 'auditd.data.new-net', + type: 'keyword', + }, + 'auditd.data.permissive': { + category: 'auditd', + description: 'SELinux is in permissive mode', + name: 'auditd.data.permissive', + type: 'keyword', + }, + 'auditd.data.class': { + category: 'auditd', + description: 'resource class assigned to vm', + name: 'auditd.data.class', + type: 'keyword', + }, + 'auditd.data.compat': { + category: 'auditd', + description: 'is_compat_task result', + name: 'auditd.data.compat', + type: 'keyword', + }, + 'auditd.data.fi': { + category: 'auditd', + description: 'file assigned inherited capability map', + name: 'auditd.data.fi', + type: 'keyword', + }, + 'auditd.data.changed': { + category: 'auditd', + description: 'number of changed files', + name: 'auditd.data.changed', + type: 'keyword', + }, + 'auditd.data.msg': { + category: 'auditd', + description: 'the payload of the audit record', + name: 'auditd.data.msg', + type: 'keyword', + }, + 'auditd.data.dport': { + category: 'auditd', + description: 'remote port number', + name: 'auditd.data.dport', + type: 'keyword', + }, + 'auditd.data.new-seuser': { + category: 'auditd', + description: 'new SELinux user', + name: 'auditd.data.new-seuser', + type: 'keyword', + }, + 'auditd.data.invalid_context': { + category: 'auditd', + description: 'SELinux context', + name: 'auditd.data.invalid_context', + type: 'keyword', + }, + 'auditd.data.dmac': { + category: 'auditd', + description: 'remote MAC address', + name: 'auditd.data.dmac', + type: 'keyword', + }, + 'auditd.data.ipx-net': { + category: 'auditd', + description: 'IPX network number', + name: 'auditd.data.ipx-net', + type: 'keyword', + }, + 'auditd.data.iuid': { + category: 'auditd', + description: "ipc object's user ID", + name: 'auditd.data.iuid', + type: 'keyword', + }, + 'auditd.data.macproto': { + category: 'auditd', + description: 'ethernet packet type ID field', + name: 'auditd.data.macproto', + type: 'keyword', + }, + 'auditd.data.obj': { + category: 'auditd', + description: 'lspp object context string', + name: 'auditd.data.obj', + type: 'keyword', + }, + 'auditd.data.ipid': { + category: 'auditd', + description: 'IP datagram fragment identifier', + name: 'auditd.data.ipid', + type: 'keyword', + }, + 'auditd.data.new-fs': { + category: 'auditd', + description: 'file system being added to vm', + name: 'auditd.data.new-fs', + type: 'keyword', + }, + 'auditd.data.vm-pid': { + category: 'auditd', + description: "vm's process ID", + name: 'auditd.data.vm-pid', + type: 'keyword', + }, + 'auditd.data.cap_pi': { + category: 'auditd', + description: 'process inherited capability map', + name: 'auditd.data.cap_pi', + type: 'keyword', + }, + 'auditd.data.old-auid': { + category: 'auditd', + description: 'previous auid value', + name: 'auditd.data.old-auid', + type: 'keyword', + }, + 'auditd.data.oses': { + category: 'auditd', + description: "object's session ID", + name: 'auditd.data.oses', + type: 'keyword', + }, + 'auditd.data.fd': { + category: 'auditd', + description: 'file descriptor number', + name: 'auditd.data.fd', + type: 'keyword', + }, + 'auditd.data.igid': { + category: 'auditd', + description: "ipc object's group ID", + name: 'auditd.data.igid', + type: 'keyword', + }, + 'auditd.data.new-disk': { + category: 'auditd', + description: 'disk being added to vm', + name: 'auditd.data.new-disk', + type: 'keyword', + }, + 'auditd.data.parent': { + category: 'auditd', + description: 'the inode number of the parent file', + name: 'auditd.data.parent', + type: 'keyword', + }, + 'auditd.data.len': { + category: 'auditd', + description: 'length', + name: 'auditd.data.len', + type: 'keyword', + }, + 'auditd.data.oflag': { + category: 'auditd', + description: 'open syscall flags', + name: 'auditd.data.oflag', + type: 'keyword', + }, + 'auditd.data.uuid': { + category: 'auditd', + description: 'a UUID', + name: 'auditd.data.uuid', + type: 'keyword', + }, + 'auditd.data.code': { + category: 'auditd', + description: 'seccomp action code', + name: 'auditd.data.code', + type: 'keyword', + }, + 'auditd.data.nlnk-grp': { + category: 'auditd', + description: 'netlink group number', + name: 'auditd.data.nlnk-grp', + type: 'keyword', + }, + 'auditd.data.cap_fp': { + category: 'auditd', + description: 'file permitted capability map', + name: 'auditd.data.cap_fp', + type: 'keyword', + }, + 'auditd.data.new-mem': { + category: 'auditd', + description: 'new amount of memory in KB', + name: 'auditd.data.new-mem', + type: 'keyword', + }, + 'auditd.data.seperm': { + category: 'auditd', + description: 'SELinux permission being decided on', + name: 'auditd.data.seperm', + type: 'keyword', + }, + 'auditd.data.enforcing': { + category: 'auditd', + description: 'new MAC enforcement status', + name: 'auditd.data.enforcing', + type: 'keyword', + }, + 'auditd.data.new-chardev': { + category: 'auditd', + description: 'new character device being assigned to vm', + name: 'auditd.data.new-chardev', + type: 'keyword', + }, + 'auditd.data.old-rng': { + category: 'auditd', + description: 'device name of rng being removed from a vm', + name: 'auditd.data.old-rng', + type: 'keyword', + }, + 'auditd.data.outif': { + category: 'auditd', + description: 'out interface number', + name: 'auditd.data.outif', + type: 'keyword', + }, + 'auditd.data.cmd': { + category: 'auditd', + description: 'command being executed', + name: 'auditd.data.cmd', + type: 'keyword', + }, + 'auditd.data.hook': { + category: 'auditd', + description: 'netfilter hook that packet came from', + name: 'auditd.data.hook', + type: 'keyword', + }, + 'auditd.data.new-level': { + category: 'auditd', + description: 'new run level', + name: 'auditd.data.new-level', + type: 'keyword', + }, + 'auditd.data.sauid': { + category: 'auditd', + description: 'sent login user ID', + name: 'auditd.data.sauid', + type: 'keyword', + }, + 'auditd.data.sig': { + category: 'auditd', + description: 'signal number', + name: 'auditd.data.sig', + type: 'keyword', + }, + 'auditd.data.audit_backlog_wait_time': { + category: 'auditd', + description: "audit system's backlog wait time", + name: 'auditd.data.audit_backlog_wait_time', + type: 'keyword', + }, + 'auditd.data.printer': { + category: 'auditd', + description: 'printer name', + name: 'auditd.data.printer', + type: 'keyword', + }, + 'auditd.data.old-mem': { + category: 'auditd', + description: 'present amount of memory in KB', + name: 'auditd.data.old-mem', + type: 'keyword', + }, + 'auditd.data.perm': { + category: 'auditd', + description: 'the file permission being used', + name: 'auditd.data.perm', + type: 'keyword', + }, + 'auditd.data.old_pi': { + category: 'auditd', + description: 'old process inherited capability map', + name: 'auditd.data.old_pi', + type: 'keyword', + }, + 'auditd.data.state': { + category: 'auditd', + description: 'audit daemon configuration resulting state', + name: 'auditd.data.state', + type: 'keyword', + }, + 'auditd.data.format': { + category: 'auditd', + description: "audit log's format", + name: 'auditd.data.format', + type: 'keyword', + }, + 'auditd.data.new_gid': { + category: 'auditd', + description: 'new group ID being assigned', + name: 'auditd.data.new_gid', + type: 'keyword', + }, + 'auditd.data.tcontext': { + category: 'auditd', + description: "the target's or object's context string", + name: 'auditd.data.tcontext', + type: 'keyword', + }, + 'auditd.data.maj': { + category: 'auditd', + description: 'device major number', + name: 'auditd.data.maj', + type: 'keyword', + }, + 'auditd.data.watch': { + category: 'auditd', + description: 'file name in a watch record', + name: 'auditd.data.watch', + type: 'keyword', + }, + 'auditd.data.device': { + category: 'auditd', + description: 'device name', + name: 'auditd.data.device', + type: 'keyword', + }, + 'auditd.data.grp': { + category: 'auditd', + description: 'group name', + name: 'auditd.data.grp', + type: 'keyword', + }, + 'auditd.data.bool': { + category: 'auditd', + description: 'name of SELinux boolean', + name: 'auditd.data.bool', + type: 'keyword', + }, + 'auditd.data.icmp_type': { + category: 'auditd', + description: 'type of icmp message', + name: 'auditd.data.icmp_type', + type: 'keyword', + }, + 'auditd.data.new_lock': { + category: 'auditd', + description: 'new value of feature lock', + name: 'auditd.data.new_lock', + type: 'keyword', + }, + 'auditd.data.old_prom': { + category: 'auditd', + description: 'network promiscuity flag', + name: 'auditd.data.old_prom', + type: 'keyword', + }, + 'auditd.data.acl': { + category: 'auditd', + description: 'access mode of resource assigned to vm', + name: 'auditd.data.acl', + type: 'keyword', + }, + 'auditd.data.ip': { + category: 'auditd', + description: 'network address of a printer', + name: 'auditd.data.ip', + type: 'keyword', + }, + 'auditd.data.new_pi': { + category: 'auditd', + description: 'new process inherited capability map', + name: 'auditd.data.new_pi', + type: 'keyword', + }, + 'auditd.data.default-context': { + category: 'auditd', + description: 'default MAC context', + name: 'auditd.data.default-context', + type: 'keyword', + }, + 'auditd.data.inode_gid': { + category: 'auditd', + description: "group ID of the inode's owner", + name: 'auditd.data.inode_gid', + type: 'keyword', + }, + 'auditd.data.new-log_passwd': { + category: 'auditd', + description: 'new value for TTY password logging', + name: 'auditd.data.new-log_passwd', + type: 'keyword', + }, + 'auditd.data.new_pe': { + category: 'auditd', + description: 'new process effective capability map', + name: 'auditd.data.new_pe', + type: 'keyword', + }, + 'auditd.data.selected-context': { + category: 'auditd', + description: 'new MAC context assigned to session', + name: 'auditd.data.selected-context', + type: 'keyword', + }, + 'auditd.data.cap_fver': { + category: 'auditd', + description: 'file system capabilities version number', + name: 'auditd.data.cap_fver', + type: 'keyword', + }, + 'auditd.data.file': { + category: 'auditd', + description: 'file name', + name: 'auditd.data.file', + type: 'keyword', + }, + 'auditd.data.net': { + category: 'auditd', + description: 'network MAC address', + name: 'auditd.data.net', + type: 'keyword', + }, + 'auditd.data.virt': { + category: 'auditd', + description: 'kind of virtualization being referenced', + name: 'auditd.data.virt', + type: 'keyword', + }, + 'auditd.data.cap_pp': { + category: 'auditd', + description: 'process permitted capability map', + name: 'auditd.data.cap_pp', + type: 'keyword', + }, + 'auditd.data.old-range': { + category: 'auditd', + description: 'present SELinux range', + name: 'auditd.data.old-range', + type: 'keyword', + }, + 'auditd.data.resrc': { + category: 'auditd', + description: 'resource being assigned', + name: 'auditd.data.resrc', + type: 'keyword', + }, + 'auditd.data.new-range': { + category: 'auditd', + description: 'new SELinux range', + name: 'auditd.data.new-range', + type: 'keyword', + }, + 'auditd.data.obj_gid': { + category: 'auditd', + description: 'group ID of object', + name: 'auditd.data.obj_gid', + type: 'keyword', + }, + 'auditd.data.proto': { + category: 'auditd', + description: 'network protocol', + name: 'auditd.data.proto', + type: 'keyword', + }, + 'auditd.data.old-disk': { + category: 'auditd', + description: 'disk being removed from vm', + name: 'auditd.data.old-disk', + type: 'keyword', + }, + 'auditd.data.audit_failure': { + category: 'auditd', + description: "audit system's failure mode", + name: 'auditd.data.audit_failure', + type: 'keyword', + }, + 'auditd.data.inif': { + category: 'auditd', + description: 'in interface number', + name: 'auditd.data.inif', + type: 'keyword', + }, + 'auditd.data.vm': { + category: 'auditd', + description: 'virtual machine name', + name: 'auditd.data.vm', + type: 'keyword', + }, + 'auditd.data.flags': { + category: 'auditd', + description: 'mmap syscall flags', + name: 'auditd.data.flags', + type: 'keyword', + }, + 'auditd.data.nlnk-fam': { + category: 'auditd', + description: 'netlink protocol number', + name: 'auditd.data.nlnk-fam', + type: 'keyword', + }, + 'auditd.data.old-fs': { + category: 'auditd', + description: 'file system being removed from vm', + name: 'auditd.data.old-fs', + type: 'keyword', + }, + 'auditd.data.old-ses': { + category: 'auditd', + description: 'previous ses value', + name: 'auditd.data.old-ses', + type: 'keyword', + }, + 'auditd.data.seqno': { + category: 'auditd', + description: 'sequence number', + name: 'auditd.data.seqno', + type: 'keyword', + }, + 'auditd.data.fver': { + category: 'auditd', + description: 'file system capabilities version number', + name: 'auditd.data.fver', + type: 'keyword', + }, + 'auditd.data.qbytes': { + category: 'auditd', + description: 'ipc objects quantity of bytes', + name: 'auditd.data.qbytes', + type: 'keyword', + }, + 'auditd.data.seuser': { + category: 'auditd', + description: "user's SE Linux user acct", + name: 'auditd.data.seuser', + type: 'keyword', + }, + 'auditd.data.cap_fe': { + category: 'auditd', + description: 'file assigned effective capability map', + name: 'auditd.data.cap_fe', + type: 'keyword', + }, + 'auditd.data.new-vcpu': { + category: 'auditd', + description: 'new number of CPU cores', + name: 'auditd.data.new-vcpu', + type: 'keyword', + }, + 'auditd.data.old-level': { + category: 'auditd', + description: 'old run level', + name: 'auditd.data.old-level', + type: 'keyword', + }, + 'auditd.data.old_pp': { + category: 'auditd', + description: 'old process permitted capability map', + name: 'auditd.data.old_pp', + type: 'keyword', + }, + 'auditd.data.daddr': { + category: 'auditd', + description: 'remote IP address', + name: 'auditd.data.daddr', + type: 'keyword', + }, + 'auditd.data.old-role': { + category: 'auditd', + description: 'present SELinux role', + name: 'auditd.data.old-role', + type: 'keyword', + }, + 'auditd.data.ioctlcmd': { + category: 'auditd', + description: 'The request argument to the ioctl syscall', + name: 'auditd.data.ioctlcmd', + type: 'keyword', + }, + 'auditd.data.smac': { + category: 'auditd', + description: 'local MAC address', + name: 'auditd.data.smac', + type: 'keyword', + }, + 'auditd.data.apparmor': { + category: 'auditd', + description: 'apparmor event information', + name: 'auditd.data.apparmor', + type: 'keyword', + }, + 'auditd.data.fe': { + category: 'auditd', + description: 'file assigned effective capability map', + name: 'auditd.data.fe', + type: 'keyword', + }, + 'auditd.data.perm_mask': { + category: 'auditd', + description: 'file permission mask that triggered a watch event', + name: 'auditd.data.perm_mask', + type: 'keyword', + }, + 'auditd.data.ses': { + category: 'auditd', + description: 'login session ID', + name: 'auditd.data.ses', + type: 'keyword', + }, + 'auditd.data.cap_fi': { + category: 'auditd', + description: 'file inherited capability map', + name: 'auditd.data.cap_fi', + type: 'keyword', + }, + 'auditd.data.obj_uid': { + category: 'auditd', + description: 'user ID of object', + name: 'auditd.data.obj_uid', + type: 'keyword', + }, + 'auditd.data.reason': { + category: 'auditd', + description: 'text string denoting a reason for the action', + name: 'auditd.data.reason', + type: 'keyword', + }, + 'auditd.data.list': { + category: 'auditd', + description: "the audit system's filter list number", + name: 'auditd.data.list', + type: 'keyword', + }, + 'auditd.data.old_lock': { + category: 'auditd', + description: 'present value of feature lock', + name: 'auditd.data.old_lock', + type: 'keyword', + }, + 'auditd.data.bus': { + category: 'auditd', + description: 'name of subsystem bus a vm resource belongs to', + name: 'auditd.data.bus', + type: 'keyword', + }, + 'auditd.data.old_pe': { + category: 'auditd', + description: 'old process effective capability map', + name: 'auditd.data.old_pe', + type: 'keyword', + }, + 'auditd.data.new-role': { + category: 'auditd', + description: 'new SELinux role', + name: 'auditd.data.new-role', + type: 'keyword', + }, + 'auditd.data.prom': { + category: 'auditd', + description: 'network promiscuity flag', + name: 'auditd.data.prom', + type: 'keyword', + }, + 'auditd.data.uri': { + category: 'auditd', + description: 'URI pointing to a printer', + name: 'auditd.data.uri', + type: 'keyword', + }, + 'auditd.data.audit_enabled': { + category: 'auditd', + description: "audit systems's enable/disable status", + name: 'auditd.data.audit_enabled', + type: 'keyword', + }, + 'auditd.data.old-log_passwd': { + category: 'auditd', + description: 'present value for TTY password logging', + name: 'auditd.data.old-log_passwd', + type: 'keyword', + }, + 'auditd.data.old-seuser': { + category: 'auditd', + description: 'present SELinux user', + name: 'auditd.data.old-seuser', + type: 'keyword', + }, + 'auditd.data.per': { + category: 'auditd', + description: 'linux personality', + name: 'auditd.data.per', + type: 'keyword', + }, + 'auditd.data.scontext': { + category: 'auditd', + description: "the subject's context string", + name: 'auditd.data.scontext', + type: 'keyword', + }, + 'auditd.data.tclass': { + category: 'auditd', + description: "target's object classification", + name: 'auditd.data.tclass', + type: 'keyword', + }, + 'auditd.data.ver': { + category: 'auditd', + description: "audit daemon's version number", + name: 'auditd.data.ver', + type: 'keyword', + }, + 'auditd.data.new': { + category: 'auditd', + description: 'value being set in feature', + name: 'auditd.data.new', + type: 'keyword', + }, + 'auditd.data.val': { + category: 'auditd', + description: 'generic value associated with the operation', + name: 'auditd.data.val', + type: 'keyword', + }, + 'auditd.data.img-ctx': { + category: 'auditd', + description: "the vm's disk image context string", + name: 'auditd.data.img-ctx', + type: 'keyword', + }, + 'auditd.data.old-chardev': { + category: 'auditd', + description: 'present character device assigned to vm', + name: 'auditd.data.old-chardev', + type: 'keyword', + }, + 'auditd.data.old_val': { + category: 'auditd', + description: 'current value of SELinux boolean', + name: 'auditd.data.old_val', + type: 'keyword', + }, + 'auditd.data.success': { + category: 'auditd', + description: 'whether the syscall was successful or not', + name: 'auditd.data.success', + type: 'keyword', + }, + 'auditd.data.inode_uid': { + category: 'auditd', + description: "user ID of the inode's owner", + name: 'auditd.data.inode_uid', + type: 'keyword', + }, + 'auditd.data.removed': { + category: 'auditd', + description: 'number of deleted files', + name: 'auditd.data.removed', + type: 'keyword', + }, + 'auditd.data.socket.port': { + category: 'auditd', + description: 'The port number.', + name: 'auditd.data.socket.port', + type: 'keyword', + }, + 'auditd.data.socket.saddr': { + category: 'auditd', + description: 'The raw socket address structure.', + name: 'auditd.data.socket.saddr', + type: 'keyword', + }, + 'auditd.data.socket.addr': { + category: 'auditd', + description: 'The remote address.', + name: 'auditd.data.socket.addr', + type: 'keyword', + }, + 'auditd.data.socket.family': { + category: 'auditd', + description: 'The socket family (unix, ipv4, ipv6, netlink).', + example: 'unix', + name: 'auditd.data.socket.family', + type: 'keyword', + }, + 'auditd.data.socket.path': { + category: 'auditd', + description: 'This is the path associated with a unix socket.', + name: 'auditd.data.socket.path', + type: 'keyword', + }, + 'auditd.messages': { + category: 'auditd', + description: + 'An ordered list of the raw messages received from the kernel that were used to construct this document. This field is present if an error occurred processing the data or if `include_raw_message` is set in the config. ', + name: 'auditd.messages', + type: 'alias', + }, + 'auditd.warnings': { + category: 'auditd', + description: + 'The warnings generated by the Beat during the construction of the event. These are disabled by default and are used for development and debug purposes only. ', + name: 'auditd.warnings', + type: 'alias', + }, + 'geoip.continent_name': { + category: 'geoip', + description: 'The name of the continent. ', + name: 'geoip.continent_name', + type: 'keyword', + }, + 'geoip.city_name': { + category: 'geoip', + description: 'The name of the city. ', + name: 'geoip.city_name', + type: 'keyword', + }, + 'geoip.region_name': { + category: 'geoip', + description: 'The name of the region. ', + name: 'geoip.region_name', + type: 'keyword', + }, + 'geoip.country_iso_code': { + category: 'geoip', + description: 'Country ISO code. ', + name: 'geoip.country_iso_code', + type: 'keyword', + }, + 'geoip.location': { + category: 'geoip', + description: 'The longitude and latitude. ', + name: 'geoip.location', + type: 'geo_point', + }, + 'hash.blake2b_256': { + category: 'hash', + description: 'BLAKE2b-256 hash of the file.', + name: 'hash.blake2b_256', + type: 'keyword', + }, + 'hash.blake2b_384': { + category: 'hash', + description: 'BLAKE2b-384 hash of the file.', + name: 'hash.blake2b_384', + type: 'keyword', + }, + 'hash.blake2b_512': { + category: 'hash', + description: 'BLAKE2b-512 hash of the file.', + name: 'hash.blake2b_512', + type: 'keyword', + }, + 'hash.sha224': { + category: 'hash', + description: 'SHA224 hash of the file.', + name: 'hash.sha224', + type: 'keyword', + }, + 'hash.sha384': { + category: 'hash', + description: 'SHA384 hash of the file.', + name: 'hash.sha384', + type: 'keyword', + }, + 'hash.sha3_224': { + category: 'hash', + description: 'SHA3_224 hash of the file.', + name: 'hash.sha3_224', + type: 'keyword', + }, + 'hash.sha3_256': { + category: 'hash', + description: 'SHA3_256 hash of the file.', + name: 'hash.sha3_256', + type: 'keyword', + }, + 'hash.sha3_384': { + category: 'hash', + description: 'SHA3_384 hash of the file.', + name: 'hash.sha3_384', + type: 'keyword', + }, + 'hash.sha3_512': { + category: 'hash', + description: 'SHA3_512 hash of the file.', + name: 'hash.sha3_512', + type: 'keyword', + }, + 'hash.sha512_224': { + category: 'hash', + description: 'SHA512/224 hash of the file.', + name: 'hash.sha512_224', + type: 'keyword', + }, + 'hash.sha512_256': { + category: 'hash', + description: 'SHA512/256 hash of the file.', + name: 'hash.sha512_256', + type: 'keyword', + }, + 'hash.xxh64': { + category: 'hash', + description: 'XX64 hash of the file.', + name: 'hash.xxh64', + type: 'keyword', + }, + 'event.origin': { + category: 'event', + description: + 'Origin of the event. This can be a file path (e.g. `/var/log/log.1`), or the name of the system component that supplied the data (e.g. `netlink`). ', + name: 'event.origin', + type: 'keyword', + }, + 'user.entity_id': { + category: 'user', + description: + 'ID uniquely identifying the user on a host. It is computed as a SHA-256 hash of the host ID, user ID, and user name. ', + name: 'user.entity_id', + type: 'keyword', + }, + 'user.terminal': { + category: 'user', + description: 'Terminal of the user. ', + name: 'user.terminal', + type: 'keyword', + }, + 'process.hash.blake2b_256': { + category: 'process', + description: 'BLAKE2b-256 hash of the executable.', + name: 'process.hash.blake2b_256', + type: 'keyword', + }, + 'process.hash.blake2b_384': { + category: 'process', + description: 'BLAKE2b-384 hash of the executable.', + name: 'process.hash.blake2b_384', + type: 'keyword', + }, + 'process.hash.blake2b_512': { + category: 'process', + description: 'BLAKE2b-512 hash of the executable.', + name: 'process.hash.blake2b_512', + type: 'keyword', + }, + 'process.hash.sha224': { + category: 'process', + description: 'SHA224 hash of the executable.', + name: 'process.hash.sha224', + type: 'keyword', + }, + 'process.hash.sha384': { + category: 'process', + description: 'SHA384 hash of the executable.', + name: 'process.hash.sha384', + type: 'keyword', + }, + 'process.hash.sha3_224': { + category: 'process', + description: 'SHA3_224 hash of the executable.', + name: 'process.hash.sha3_224', + type: 'keyword', + }, + 'process.hash.sha3_256': { + category: 'process', + description: 'SHA3_256 hash of the executable.', + name: 'process.hash.sha3_256', + type: 'keyword', + }, + 'process.hash.sha3_384': { + category: 'process', + description: 'SHA3_384 hash of the executable.', + name: 'process.hash.sha3_384', + type: 'keyword', + }, + 'process.hash.sha3_512': { + category: 'process', + description: 'SHA3_512 hash of the executable.', + name: 'process.hash.sha3_512', + type: 'keyword', + }, + 'process.hash.sha512_224': { + category: 'process', + description: 'SHA512/224 hash of the executable.', + name: 'process.hash.sha512_224', + type: 'keyword', + }, + 'process.hash.sha512_256': { + category: 'process', + description: 'SHA512/256 hash of the executable.', + name: 'process.hash.sha512_256', + type: 'keyword', + }, + 'process.hash.xxh64': { + category: 'process', + description: 'XX64 hash of the executable.', + name: 'process.hash.xxh64', + type: 'keyword', + }, + 'socket.entity_id': { + category: 'socket', + description: + 'ID uniquely identifying the socket. It is computed as a SHA-256 hash of the host ID, socket inode, local IP, local port, remote IP, and remote port. ', + name: 'socket.entity_id', + type: 'keyword', + }, + 'system.audit.host.uptime': { + category: 'system', + description: 'Uptime in nanoseconds. ', + name: 'system.audit.host.uptime', + type: 'long', + format: 'duration', + }, + 'system.audit.host.boottime': { + category: 'system', + description: 'Boot time. ', + name: 'system.audit.host.boottime', + type: 'date', + }, + 'system.audit.host.containerized': { + category: 'system', + description: 'Set if host is a container. ', + name: 'system.audit.host.containerized', + type: 'boolean', + }, + 'system.audit.host.timezone.name': { + category: 'system', + description: 'Name of the timezone of the host, e.g. BST. ', + name: 'system.audit.host.timezone.name', + type: 'keyword', + }, + 'system.audit.host.timezone.offset.sec': { + category: 'system', + description: 'Timezone offset in seconds. ', + name: 'system.audit.host.timezone.offset.sec', + type: 'long', + }, + 'system.audit.host.hostname': { + category: 'system', + description: 'Hostname. ', + name: 'system.audit.host.hostname', + type: 'keyword', + }, + 'system.audit.host.id': { + category: 'system', + description: 'Host ID. ', + name: 'system.audit.host.id', + type: 'keyword', + }, + 'system.audit.host.architecture': { + category: 'system', + description: 'Host architecture (e.g. x86_64). ', + name: 'system.audit.host.architecture', + type: 'keyword', + }, + 'system.audit.host.mac': { + category: 'system', + description: 'MAC addresses. ', + name: 'system.audit.host.mac', + type: 'keyword', + }, + 'system.audit.host.ip': { + category: 'system', + description: 'IP addresses. ', + name: 'system.audit.host.ip', + type: 'ip', + }, + 'system.audit.host.os.codename': { + category: 'system', + description: 'OS codename, if any (e.g. stretch). ', + name: 'system.audit.host.os.codename', + type: 'keyword', + }, + 'system.audit.host.os.platform': { + category: 'system', + description: 'OS platform (e.g. centos, ubuntu, windows). ', + name: 'system.audit.host.os.platform', + type: 'keyword', + }, + 'system.audit.host.os.name': { + category: 'system', + description: 'OS name (e.g. Mac OS X). ', + name: 'system.audit.host.os.name', + type: 'keyword', + }, + 'system.audit.host.os.family': { + category: 'system', + description: 'OS family (e.g. redhat, debian, freebsd, windows). ', + name: 'system.audit.host.os.family', + type: 'keyword', + }, + 'system.audit.host.os.version': { + category: 'system', + description: 'OS version. ', + name: 'system.audit.host.os.version', + type: 'keyword', + }, + 'system.audit.host.os.kernel': { + category: 'system', + description: "The operating system's kernel version. ", + name: 'system.audit.host.os.kernel', + type: 'keyword', + }, + 'system.audit.package.entity_id': { + category: 'system', + description: + 'ID uniquely identifying the package. It is computed as a SHA-256 hash of the host ID, package name, and package version. ', + name: 'system.audit.package.entity_id', + type: 'keyword', + }, + 'system.audit.package.name': { + category: 'system', + description: 'Package name. ', + name: 'system.audit.package.name', + type: 'keyword', + }, + 'system.audit.package.version': { + category: 'system', + description: 'Package version. ', + name: 'system.audit.package.version', + type: 'keyword', + }, + 'system.audit.package.release': { + category: 'system', + description: 'Package release. ', + name: 'system.audit.package.release', + type: 'keyword', + }, + 'system.audit.package.arch': { + category: 'system', + description: 'Package architecture. ', + name: 'system.audit.package.arch', + type: 'keyword', + }, + 'system.audit.package.license': { + category: 'system', + description: 'Package license. ', + name: 'system.audit.package.license', + type: 'keyword', + }, + 'system.audit.package.installtime': { + category: 'system', + description: 'Package install time. ', + name: 'system.audit.package.installtime', + type: 'date', + }, + 'system.audit.package.size': { + category: 'system', + description: 'Package size. ', + name: 'system.audit.package.size', + type: 'long', + }, + 'system.audit.package.summary': { + category: 'system', + description: 'Package summary. ', + name: 'system.audit.package.summary', + }, + 'system.audit.package.url': { + category: 'system', + description: 'Package URL. ', + name: 'system.audit.package.url', + type: 'keyword', + }, + 'system.audit.user.name': { + category: 'system', + description: 'User name. ', + name: 'system.audit.user.name', + type: 'keyword', + }, + 'system.audit.user.uid': { + category: 'system', + description: 'User ID. ', + name: 'system.audit.user.uid', + type: 'keyword', + }, + 'system.audit.user.gid': { + category: 'system', + description: 'Group ID. ', + name: 'system.audit.user.gid', + type: 'keyword', + }, + 'system.audit.user.dir': { + category: 'system', + description: "User's home directory. ", + name: 'system.audit.user.dir', + type: 'keyword', + }, + 'system.audit.user.shell': { + category: 'system', + description: 'Program to run at login. ', + name: 'system.audit.user.shell', + type: 'keyword', + }, + 'system.audit.user.user_information': { + category: 'system', + description: 'General user information. On Linux, this is the gecos field. ', + name: 'system.audit.user.user_information', + type: 'keyword', + }, + 'system.audit.user.group.name': { + category: 'system', + description: 'Group name. ', + name: 'system.audit.user.group.name', + type: 'keyword', + }, + 'system.audit.user.group.gid': { + category: 'system', + description: 'Group ID. ', + name: 'system.audit.user.group.gid', + type: 'integer', + }, + 'system.audit.user.password.type': { + category: 'system', + description: + "A user's password type. Possible values are `shadow_password` (the password hash is in the shadow file), `password_disabled`, `no_password` (this is dangerous as anyone can log in), and `crypt_password` (when the password field in /etc/passwd seems to contain an encrypted password). ", + name: 'system.audit.user.password.type', + type: 'keyword', + }, + 'system.audit.user.password.last_changed': { + category: 'system', + description: "The day the user's password was last changed. ", + name: 'system.audit.user.password.last_changed', + type: 'date', + }, + 'log.file.path': { + category: 'log', + description: + 'The file from which the line was read. This field contains the absolute path to the file. For example: `/var/log/system.log`. ', + name: 'log.file.path', + type: 'keyword', + }, + 'log.source.address': { + category: 'log', + description: 'Source address from which the log event was read / sent from. ', + name: 'log.source.address', + type: 'keyword', + }, + 'log.offset': { + category: 'log', + description: 'The file offset the reported line starts at. ', + name: 'log.offset', + type: 'long', + }, + stream: { + category: 'base', + description: "Log stream when reading container logs, can be 'stdout' or 'stderr' ", + name: 'stream', + type: 'keyword', + }, + 'input.type': { + category: 'input', + description: + 'The input type from which the event was generated. This field is set to the value specified for the `type` option in the input section of the Filebeat config file. ', + name: 'input.type', + }, + 'syslog.facility': { + category: 'syslog', + description: 'The facility extracted from the priority. ', + name: 'syslog.facility', + type: 'long', + }, + 'syslog.priority': { + category: 'syslog', + description: 'The priority of the syslog event. ', + name: 'syslog.priority', + type: 'long', + }, + 'syslog.severity_label': { + category: 'syslog', + description: 'The human readable severity. ', + name: 'syslog.severity_label', + type: 'keyword', + }, + 'syslog.facility_label': { + category: 'syslog', + description: 'The human readable facility. ', + name: 'syslog.facility_label', + type: 'keyword', + }, + 'process.program': { + category: 'process', + description: 'The name of the program. ', + name: 'process.program', + type: 'keyword', + }, + 'log.flags': { + category: 'log', + description: 'This field contains the flags of the event. ', + name: 'log.flags', + }, + 'http.response.content_length': { + category: 'http', + name: 'http.response.content_length', + type: 'alias', + }, + 'user_agent.os.full_name': { + category: 'user_agent', + name: 'user_agent.os.full_name', + type: 'keyword', + }, + 'fileset.name': { + category: 'fileset', + description: 'The Filebeat fileset that generated this event. ', + name: 'fileset.name', + type: 'keyword', + }, + 'fileset.module': { + category: 'fileset', + name: 'fileset.module', + type: 'alias', + }, + read_timestamp: { + category: 'base', + name: 'read_timestamp', + type: 'alias', + }, + 'docker.attrs': { + category: 'docker', + description: + "docker.attrs contains labels and environment variables written by docker's JSON File logging driver. These fields are only available when they are configured in the logging driver options. ", + name: 'docker.attrs', + type: 'object', + }, + 'icmp.code': { + category: 'icmp', + description: 'ICMP code. ', + name: 'icmp.code', + type: 'keyword', + }, + 'icmp.type': { + category: 'icmp', + description: 'ICMP type. ', + name: 'icmp.type', + type: 'keyword', + }, + 'igmp.type': { + category: 'igmp', + description: 'IGMP type. ', + name: 'igmp.type', + type: 'keyword', + }, + 'azure.eventhub': { + category: 'azure', + description: 'Name of the eventhub. ', + name: 'azure.eventhub', + type: 'keyword', + }, + 'azure.offset': { + category: 'azure', + description: 'The offset. ', + name: 'azure.offset', + type: 'long', + }, + 'azure.enqueued_time': { + category: 'azure', + description: 'The enqueued time. ', + name: 'azure.enqueued_time', + type: 'date', + }, + 'azure.partition_id': { + category: 'azure', + description: 'The partition id. ', + name: 'azure.partition_id', + type: 'long', + }, + 'azure.consumer_group': { + category: 'azure', + description: 'The consumer group. ', + name: 'azure.consumer_group', + type: 'keyword', + }, + 'azure.sequence_number': { + category: 'azure', + description: 'The sequence number. ', + name: 'azure.sequence_number', + type: 'long', + }, + 'kafka.topic': { + category: 'kafka', + description: 'Kafka topic ', + name: 'kafka.topic', + type: 'keyword', + }, + 'kafka.partition': { + category: 'kafka', + description: 'Kafka partition number ', + name: 'kafka.partition', + type: 'long', + }, + 'kafka.offset': { + category: 'kafka', + description: 'Kafka offset of this message ', + name: 'kafka.offset', + type: 'long', + }, + 'kafka.key': { + category: 'kafka', + description: 'Kafka key, corresponding to the Kafka value stored in the message ', + name: 'kafka.key', + type: 'keyword', + }, + 'kafka.block_timestamp': { + category: 'kafka', + description: 'Kafka outer (compressed) block timestamp ', + name: 'kafka.block_timestamp', + type: 'date', + }, + 'kafka.headers': { + category: 'kafka', + description: + 'An array of Kafka header strings for this message, in the form ": ". ', + name: 'kafka.headers', + type: 'array', + }, + 'apache2.access.remote_ip': { + category: 'apache2', + name: 'apache2.access.remote_ip', + type: 'alias', + }, + 'apache2.access.ssl.protocol': { + category: 'apache2', + name: 'apache2.access.ssl.protocol', + type: 'alias', + }, + 'apache2.access.ssl.cipher': { + category: 'apache2', + name: 'apache2.access.ssl.cipher', + type: 'alias', + }, + 'apache2.access.body_sent.bytes': { + category: 'apache2', + name: 'apache2.access.body_sent.bytes', + type: 'alias', + }, + 'apache2.access.user_name': { + category: 'apache2', + name: 'apache2.access.user_name', + type: 'alias', + }, + 'apache2.access.method': { + category: 'apache2', + name: 'apache2.access.method', + type: 'alias', + }, + 'apache2.access.url': { + category: 'apache2', + name: 'apache2.access.url', + type: 'alias', + }, + 'apache2.access.http_version': { + category: 'apache2', + name: 'apache2.access.http_version', + type: 'alias', + }, + 'apache2.access.response_code': { + category: 'apache2', + name: 'apache2.access.response_code', + type: 'alias', + }, + 'apache2.access.referrer': { + category: 'apache2', + name: 'apache2.access.referrer', + type: 'alias', + }, + 'apache2.access.agent': { + category: 'apache2', + name: 'apache2.access.agent', + type: 'alias', + }, + 'apache2.access.user_agent.device': { + category: 'apache2', + name: 'apache2.access.user_agent.device', + type: 'alias', + }, + 'apache2.access.user_agent.name': { + category: 'apache2', + name: 'apache2.access.user_agent.name', + type: 'alias', + }, + 'apache2.access.user_agent.os': { + category: 'apache2', + name: 'apache2.access.user_agent.os', + type: 'alias', + }, + 'apache2.access.user_agent.os_name': { + category: 'apache2', + name: 'apache2.access.user_agent.os_name', + type: 'alias', + }, + 'apache2.access.user_agent.original': { + category: 'apache2', + name: 'apache2.access.user_agent.original', + type: 'alias', + }, + 'apache2.access.geoip.continent_name': { + category: 'apache2', + name: 'apache2.access.geoip.continent_name', + type: 'alias', + }, + 'apache2.access.geoip.country_iso_code': { + category: 'apache2', + name: 'apache2.access.geoip.country_iso_code', + type: 'alias', + }, + 'apache2.access.geoip.location': { + category: 'apache2', + name: 'apache2.access.geoip.location', + type: 'alias', + }, + 'apache2.access.geoip.region_name': { + category: 'apache2', + name: 'apache2.access.geoip.region_name', + type: 'alias', + }, + 'apache2.access.geoip.city_name': { + category: 'apache2', + name: 'apache2.access.geoip.city_name', + type: 'alias', + }, + 'apache2.access.geoip.region_iso_code': { + category: 'apache2', + name: 'apache2.access.geoip.region_iso_code', + type: 'alias', + }, + 'apache2.error.level': { + category: 'apache2', + name: 'apache2.error.level', + type: 'alias', + }, + 'apache2.error.message': { + category: 'apache2', + name: 'apache2.error.message', + type: 'alias', + }, + 'apache2.error.pid': { + category: 'apache2', + name: 'apache2.error.pid', + type: 'alias', + }, + 'apache2.error.tid': { + category: 'apache2', + name: 'apache2.error.tid', + type: 'alias', + }, + 'apache2.error.module': { + category: 'apache2', + name: 'apache2.error.module', + type: 'alias', + }, + 'apache.access.ssl.protocol': { + category: 'apache', + description: 'SSL protocol version. ', + name: 'apache.access.ssl.protocol', + type: 'keyword', + }, + 'apache.access.ssl.cipher': { + category: 'apache', + description: 'SSL cipher name. ', + name: 'apache.access.ssl.cipher', + type: 'keyword', + }, + 'apache.error.module': { + category: 'apache', + description: 'The module producing the logged message. ', + name: 'apache.error.module', + type: 'keyword', + }, + 'user.audit.group.id': { + category: 'user', + description: 'Unique identifier for the group on the system/platform. ', + name: 'user.audit.group.id', + type: 'keyword', + }, + 'user.audit.group.name': { + category: 'user', + description: 'Name of the group. ', + name: 'user.audit.group.name', + type: 'keyword', + }, + 'user.owner.id': { + category: 'user', + description: 'One or multiple unique identifiers of the user. ', + name: 'user.owner.id', + type: 'keyword', + }, + 'user.owner.name': { + category: 'user', + description: 'Short name or login of the user. ', + example: 'albert', + name: 'user.owner.name', + type: 'keyword', + }, + 'user.owner.group.id': { + category: 'user', + description: 'Unique identifier for the group on the system/platform. ', + name: 'user.owner.group.id', + type: 'keyword', + }, + 'user.owner.group.name': { + category: 'user', + description: 'Name of the group. ', + name: 'user.owner.group.name', + type: 'keyword', + }, + 'auditd.log.old_auid': { + category: 'auditd', + description: + 'For login events this is the old audit ID used for the user prior to this login. ', + name: 'auditd.log.old_auid', + }, + 'auditd.log.new_auid': { + category: 'auditd', + description: + 'For login events this is the new audit ID. The audit ID can be used to trace future events to the user even if their identity changes (like becoming root). ', + name: 'auditd.log.new_auid', + }, + 'auditd.log.old_ses': { + category: 'auditd', + description: + 'For login events this is the old session ID used for the user prior to this login. ', + name: 'auditd.log.old_ses', + }, + 'auditd.log.new_ses': { + category: 'auditd', + description: + 'For login events this is the new session ID. It can be used to tie a user to future events by session ID. ', + name: 'auditd.log.new_ses', + }, + 'auditd.log.sequence': { + category: 'auditd', + description: 'The audit event sequence number. ', + name: 'auditd.log.sequence', + type: 'long', + }, + 'auditd.log.items': { + category: 'auditd', + description: 'The number of items in an event. ', + name: 'auditd.log.items', + }, + 'auditd.log.item': { + category: 'auditd', + description: + 'The item field indicates which item out of the total number of items. This number is zero-based; a value of 0 means it is the first item. ', + name: 'auditd.log.item', + }, + 'auditd.log.tty': { + category: 'auditd', + name: 'auditd.log.tty', + type: 'keyword', + }, + 'auditd.log.a0': { + category: 'auditd', + description: 'The first argument to the system call. ', + name: 'auditd.log.a0', + }, + 'auditd.log.addr': { + category: 'auditd', + name: 'auditd.log.addr', + type: 'ip', + }, + 'auditd.log.rport': { + category: 'auditd', + name: 'auditd.log.rport', + type: 'long', + }, + 'auditd.log.laddr': { + category: 'auditd', + name: 'auditd.log.laddr', + type: 'ip', + }, + 'auditd.log.lport': { + category: 'auditd', + name: 'auditd.log.lport', + type: 'long', + }, + 'auditd.log.acct': { + category: 'auditd', + name: 'auditd.log.acct', + type: 'alias', + }, + 'auditd.log.pid': { + category: 'auditd', + name: 'auditd.log.pid', + type: 'alias', + }, + 'auditd.log.ppid': { + category: 'auditd', + name: 'auditd.log.ppid', + type: 'alias', + }, + 'auditd.log.res': { + category: 'auditd', + name: 'auditd.log.res', + type: 'alias', + }, + 'auditd.log.record_type': { + category: 'auditd', + name: 'auditd.log.record_type', + type: 'alias', + }, + 'auditd.log.geoip.continent_name': { + category: 'auditd', + name: 'auditd.log.geoip.continent_name', + type: 'alias', + }, + 'auditd.log.geoip.country_iso_code': { + category: 'auditd', + name: 'auditd.log.geoip.country_iso_code', + type: 'alias', + }, + 'auditd.log.geoip.location': { + category: 'auditd', + name: 'auditd.log.geoip.location', + type: 'alias', + }, + 'auditd.log.geoip.region_name': { + category: 'auditd', + name: 'auditd.log.geoip.region_name', + type: 'alias', + }, + 'auditd.log.geoip.city_name': { + category: 'auditd', + name: 'auditd.log.geoip.city_name', + type: 'alias', + }, + 'auditd.log.geoip.region_iso_code': { + category: 'auditd', + name: 'auditd.log.geoip.region_iso_code', + type: 'alias', + }, + 'auditd.log.arch': { + category: 'auditd', + name: 'auditd.log.arch', + type: 'alias', + }, + 'auditd.log.gid': { + category: 'auditd', + name: 'auditd.log.gid', + type: 'alias', + }, + 'auditd.log.uid': { + category: 'auditd', + name: 'auditd.log.uid', + type: 'alias', + }, + 'auditd.log.agid': { + category: 'auditd', + name: 'auditd.log.agid', + type: 'alias', + }, + 'auditd.log.auid': { + category: 'auditd', + name: 'auditd.log.auid', + type: 'alias', + }, + 'auditd.log.fsgid': { + category: 'auditd', + name: 'auditd.log.fsgid', + type: 'alias', + }, + 'auditd.log.fsuid': { + category: 'auditd', + name: 'auditd.log.fsuid', + type: 'alias', + }, + 'auditd.log.egid': { + category: 'auditd', + name: 'auditd.log.egid', + type: 'alias', + }, + 'auditd.log.euid': { + category: 'auditd', + name: 'auditd.log.euid', + type: 'alias', + }, + 'auditd.log.sgid': { + category: 'auditd', + name: 'auditd.log.sgid', + type: 'alias', + }, + 'auditd.log.suid': { + category: 'auditd', + name: 'auditd.log.suid', + type: 'alias', + }, + 'auditd.log.ogid': { + category: 'auditd', + name: 'auditd.log.ogid', + type: 'alias', + }, + 'auditd.log.ouid': { + category: 'auditd', + name: 'auditd.log.ouid', + type: 'alias', + }, + 'auditd.log.comm': { + category: 'auditd', + name: 'auditd.log.comm', + type: 'alias', + }, + 'auditd.log.exe': { + category: 'auditd', + name: 'auditd.log.exe', + type: 'alias', + }, + 'auditd.log.terminal': { + category: 'auditd', + name: 'auditd.log.terminal', + type: 'alias', + }, + 'auditd.log.msg': { + category: 'auditd', + name: 'auditd.log.msg', + type: 'alias', + }, + 'auditd.log.src': { + category: 'auditd', + name: 'auditd.log.src', + type: 'alias', + }, + 'auditd.log.dst': { + category: 'auditd', + name: 'auditd.log.dst', + type: 'alias', + }, + 'elasticsearch.component': { + category: 'elasticsearch', + description: 'Elasticsearch component from where the log event originated', + example: 'o.e.c.m.MetaDataCreateIndexService', + name: 'elasticsearch.component', + type: 'keyword', + }, + 'elasticsearch.cluster.uuid': { + category: 'elasticsearch', + description: 'UUID of the cluster', + example: 'GmvrbHlNTiSVYiPf8kxg9g', + name: 'elasticsearch.cluster.uuid', + type: 'keyword', + }, + 'elasticsearch.cluster.name': { + category: 'elasticsearch', + description: 'Name of the cluster', + example: 'docker-cluster', + name: 'elasticsearch.cluster.name', + type: 'keyword', + }, + 'elasticsearch.node.id': { + category: 'elasticsearch', + description: 'ID of the node', + example: 'DSiWcTyeThWtUXLB9J0BMw', + name: 'elasticsearch.node.id', + type: 'keyword', + }, + 'elasticsearch.node.name': { + category: 'elasticsearch', + description: 'Name of the node', + example: 'vWNJsZ3', + name: 'elasticsearch.node.name', + type: 'keyword', + }, + 'elasticsearch.index.name': { + category: 'elasticsearch', + description: 'Index name', + example: 'filebeat-test-input', + name: 'elasticsearch.index.name', + type: 'keyword', + }, + 'elasticsearch.index.id': { + category: 'elasticsearch', + description: 'Index id', + example: 'aOGgDwbURfCV57AScqbCgw', + name: 'elasticsearch.index.id', + type: 'keyword', + }, + 'elasticsearch.shard.id': { + category: 'elasticsearch', + description: 'Id of the shard', + example: '0', + name: 'elasticsearch.shard.id', + type: 'keyword', + }, + 'elasticsearch.audit.layer': { + category: 'elasticsearch', + description: 'The layer from which this event originated: rest, transport or ip_filter', + example: 'rest', + name: 'elasticsearch.audit.layer', + type: 'keyword', + }, + 'elasticsearch.audit.event_type': { + category: 'elasticsearch', + description: + 'The type of event that occurred: anonymous_access_denied, authentication_failed, access_denied, access_granted, connection_granted, connection_denied, tampered_request, run_as_granted, run_as_denied', + example: 'access_granted', + name: 'elasticsearch.audit.event_type', + type: 'keyword', + }, + 'elasticsearch.audit.origin.type': { + category: 'elasticsearch', + description: + 'Where the request originated: rest (request originated from a REST API request), transport (request was received on the transport channel), local_node (the local node issued the request)', + example: 'local_node', + name: 'elasticsearch.audit.origin.type', + type: 'keyword', + }, + 'elasticsearch.audit.realm': { + category: 'elasticsearch', + description: 'The authentication realm the authentication was validated against', + name: 'elasticsearch.audit.realm', + type: 'keyword', + }, + 'elasticsearch.audit.user.realm': { + category: 'elasticsearch', + description: "The user's authentication realm, if authenticated", + name: 'elasticsearch.audit.user.realm', + type: 'keyword', + }, + 'elasticsearch.audit.user.roles': { + category: 'elasticsearch', + description: 'Roles to which the principal belongs', + example: '["kibana_admin","beats_admin"]', + name: 'elasticsearch.audit.user.roles', + type: 'keyword', + }, + 'elasticsearch.audit.action': { + category: 'elasticsearch', + description: 'The name of the action that was executed', + example: 'cluster:monitor/main', + name: 'elasticsearch.audit.action', + type: 'keyword', + }, + 'elasticsearch.audit.url.params': { + category: 'elasticsearch', + description: 'REST URI parameters', + example: '{username=jacknich2}', + name: 'elasticsearch.audit.url.params', + }, + 'elasticsearch.audit.indices': { + category: 'elasticsearch', + description: 'Indices accessed by action', + example: '["foo-2019.01.04","foo-2019.01.03","foo-2019.01.06"]', + name: 'elasticsearch.audit.indices', + type: 'keyword', + }, + 'elasticsearch.audit.request.id': { + category: 'elasticsearch', + description: 'Unique ID of request', + example: 'WzL_kb6VSvOhAq0twPvHOQ', + name: 'elasticsearch.audit.request.id', + type: 'keyword', + }, + 'elasticsearch.audit.request.name': { + category: 'elasticsearch', + description: 'The type of request that was executed', + example: 'ClearScrollRequest', + name: 'elasticsearch.audit.request.name', + type: 'keyword', + }, + 'elasticsearch.audit.request_body': { + category: 'elasticsearch', + name: 'elasticsearch.audit.request_body', + type: 'alias', + }, + 'elasticsearch.audit.origin_address': { + category: 'elasticsearch', + name: 'elasticsearch.audit.origin_address', + type: 'alias', + }, + 'elasticsearch.audit.uri': { + category: 'elasticsearch', + name: 'elasticsearch.audit.uri', + type: 'alias', + }, + 'elasticsearch.audit.principal': { + category: 'elasticsearch', + name: 'elasticsearch.audit.principal', + type: 'alias', + }, + 'elasticsearch.audit.message': { + category: 'elasticsearch', + name: 'elasticsearch.audit.message', + type: 'text', + }, + 'elasticsearch.deprecation': { + category: 'elasticsearch', + description: '', + name: 'elasticsearch.deprecation', + type: 'group', + }, + 'elasticsearch.gc.phase.name': { + category: 'elasticsearch', + description: 'Name of the GC collection phase. ', + name: 'elasticsearch.gc.phase.name', + type: 'keyword', + }, + 'elasticsearch.gc.phase.duration_sec': { + category: 'elasticsearch', + description: 'Collection phase duration according to the Java virtual machine. ', + name: 'elasticsearch.gc.phase.duration_sec', + type: 'float', + }, + 'elasticsearch.gc.phase.scrub_symbol_table_time_sec': { + category: 'elasticsearch', + description: 'Pause time in seconds cleaning up symbol tables. ', + name: 'elasticsearch.gc.phase.scrub_symbol_table_time_sec', + type: 'float', + }, + 'elasticsearch.gc.phase.scrub_string_table_time_sec': { + category: 'elasticsearch', + description: 'Pause time in seconds cleaning up string tables. ', + name: 'elasticsearch.gc.phase.scrub_string_table_time_sec', + type: 'float', + }, + 'elasticsearch.gc.phase.weak_refs_processing_time_sec': { + category: 'elasticsearch', + description: 'Time spent processing weak references in seconds. ', + name: 'elasticsearch.gc.phase.weak_refs_processing_time_sec', + type: 'float', + }, + 'elasticsearch.gc.phase.parallel_rescan_time_sec': { + category: 'elasticsearch', + description: 'Time spent in seconds marking live objects while application is stopped. ', + name: 'elasticsearch.gc.phase.parallel_rescan_time_sec', + type: 'float', + }, + 'elasticsearch.gc.phase.class_unload_time_sec': { + category: 'elasticsearch', + description: 'Time spent unloading unused classes in seconds. ', + name: 'elasticsearch.gc.phase.class_unload_time_sec', + type: 'float', + }, + 'elasticsearch.gc.phase.cpu_time.user_sec': { + category: 'elasticsearch', + description: 'CPU time spent outside the kernel. ', + name: 'elasticsearch.gc.phase.cpu_time.user_sec', + type: 'float', + }, + 'elasticsearch.gc.phase.cpu_time.sys_sec': { + category: 'elasticsearch', + description: 'CPU time spent inside the kernel. ', + name: 'elasticsearch.gc.phase.cpu_time.sys_sec', + type: 'float', + }, + 'elasticsearch.gc.phase.cpu_time.real_sec': { + category: 'elasticsearch', + description: 'Total elapsed CPU time spent to complete the collection from start to finish. ', + name: 'elasticsearch.gc.phase.cpu_time.real_sec', + type: 'float', + }, + 'elasticsearch.gc.jvm_runtime_sec': { + category: 'elasticsearch', + description: 'The time from JVM start up in seconds, as a floating point number. ', + name: 'elasticsearch.gc.jvm_runtime_sec', + type: 'float', + }, + 'elasticsearch.gc.threads_total_stop_time_sec': { + category: 'elasticsearch', + description: 'Garbage collection threads total stop time seconds. ', + name: 'elasticsearch.gc.threads_total_stop_time_sec', + type: 'float', + }, + 'elasticsearch.gc.stopping_threads_time_sec': { + category: 'elasticsearch', + description: 'Time took to stop threads seconds. ', + name: 'elasticsearch.gc.stopping_threads_time_sec', + type: 'float', + }, + 'elasticsearch.gc.tags': { + category: 'elasticsearch', + description: 'GC logging tags. ', + name: 'elasticsearch.gc.tags', + type: 'keyword', + }, + 'elasticsearch.gc.heap.size_kb': { + category: 'elasticsearch', + description: 'Total heap size in kilobytes. ', + name: 'elasticsearch.gc.heap.size_kb', + type: 'integer', + }, + 'elasticsearch.gc.heap.used_kb': { + category: 'elasticsearch', + description: 'Used heap in kilobytes. ', + name: 'elasticsearch.gc.heap.used_kb', + type: 'integer', + }, + 'elasticsearch.gc.old_gen.size_kb': { + category: 'elasticsearch', + description: 'Total size of old generation in kilobytes. ', + name: 'elasticsearch.gc.old_gen.size_kb', + type: 'integer', + }, + 'elasticsearch.gc.old_gen.used_kb': { + category: 'elasticsearch', + description: 'Old generation occupancy in kilobytes. ', + name: 'elasticsearch.gc.old_gen.used_kb', + type: 'integer', + }, + 'elasticsearch.gc.young_gen.size_kb': { + category: 'elasticsearch', + description: 'Total size of young generation in kilobytes. ', + name: 'elasticsearch.gc.young_gen.size_kb', + type: 'integer', + }, + 'elasticsearch.gc.young_gen.used_kb': { + category: 'elasticsearch', + description: 'Young generation occupancy in kilobytes. ', + name: 'elasticsearch.gc.young_gen.used_kb', + type: 'integer', + }, + 'elasticsearch.server.stacktrace': { + category: 'elasticsearch', + name: 'elasticsearch.server.stacktrace', + }, + 'elasticsearch.server.gc.young.one': { + category: 'elasticsearch', + description: '', + example: '', + name: 'elasticsearch.server.gc.young.one', + type: 'long', + }, + 'elasticsearch.server.gc.young.two': { + category: 'elasticsearch', + description: '', + example: '', + name: 'elasticsearch.server.gc.young.two', + type: 'long', + }, + 'elasticsearch.server.gc.overhead_seq': { + category: 'elasticsearch', + description: 'Sequence number', + example: 3449992, + name: 'elasticsearch.server.gc.overhead_seq', + type: 'long', + }, + 'elasticsearch.server.gc.collection_duration.ms': { + category: 'elasticsearch', + description: 'Time spent in GC, in milliseconds', + example: 1600, + name: 'elasticsearch.server.gc.collection_duration.ms', + type: 'float', + }, + 'elasticsearch.server.gc.observation_duration.ms': { + category: 'elasticsearch', + description: 'Total time over which collection was observed, in milliseconds', + example: 1800, + name: 'elasticsearch.server.gc.observation_duration.ms', + type: 'float', + }, + 'elasticsearch.slowlog.logger': { + category: 'elasticsearch', + description: 'Logger name', + example: 'index.search.slowlog.fetch', + name: 'elasticsearch.slowlog.logger', + type: 'keyword', + }, + 'elasticsearch.slowlog.took': { + category: 'elasticsearch', + description: 'Time it took to execute the query', + example: '300ms', + name: 'elasticsearch.slowlog.took', + type: 'keyword', + }, + 'elasticsearch.slowlog.types': { + category: 'elasticsearch', + description: 'Types', + example: '', + name: 'elasticsearch.slowlog.types', + type: 'keyword', + }, + 'elasticsearch.slowlog.stats': { + category: 'elasticsearch', + description: 'Stats groups', + example: 'group1', + name: 'elasticsearch.slowlog.stats', + type: 'keyword', + }, + 'elasticsearch.slowlog.search_type': { + category: 'elasticsearch', + description: 'Search type', + example: 'QUERY_THEN_FETCH', + name: 'elasticsearch.slowlog.search_type', + type: 'keyword', + }, + 'elasticsearch.slowlog.source_query': { + category: 'elasticsearch', + description: 'Slow query', + example: '{"query":{"match_all":{"boost":1.0}}}', + name: 'elasticsearch.slowlog.source_query', + type: 'keyword', + }, + 'elasticsearch.slowlog.extra_source': { + category: 'elasticsearch', + description: 'Extra source information', + example: '', + name: 'elasticsearch.slowlog.extra_source', + type: 'keyword', + }, + 'elasticsearch.slowlog.total_hits': { + category: 'elasticsearch', + description: 'Total hits', + example: 42, + name: 'elasticsearch.slowlog.total_hits', + type: 'keyword', + }, + 'elasticsearch.slowlog.total_shards': { + category: 'elasticsearch', + description: 'Total queried shards', + example: 22, + name: 'elasticsearch.slowlog.total_shards', + type: 'keyword', + }, + 'elasticsearch.slowlog.routing': { + category: 'elasticsearch', + description: 'Routing', + example: 's01HZ2QBk9jw4gtgaFtn', + name: 'elasticsearch.slowlog.routing', + type: 'keyword', + }, + 'elasticsearch.slowlog.id': { + category: 'elasticsearch', + description: 'Id', + example: '', + name: 'elasticsearch.slowlog.id', + type: 'keyword', + }, + 'elasticsearch.slowlog.type': { + category: 'elasticsearch', + description: 'Type', + example: 'doc', + name: 'elasticsearch.slowlog.type', + type: 'keyword', + }, + 'elasticsearch.slowlog.source': { + category: 'elasticsearch', + description: 'Source of document that was indexed', + name: 'elasticsearch.slowlog.source', + type: 'keyword', + }, + 'haproxy.frontend_name': { + category: 'haproxy', + description: 'Name of the frontend (or listener) which received and processed the connection.', + name: 'haproxy.frontend_name', + }, + 'haproxy.backend_name': { + category: 'haproxy', + description: + 'Name of the backend (or listener) which was selected to manage the connection to the server.', + name: 'haproxy.backend_name', + }, + 'haproxy.server_name': { + category: 'haproxy', + description: 'Name of the last server to which the connection was sent.', + name: 'haproxy.server_name', + }, + 'haproxy.total_waiting_time_ms': { + category: 'haproxy', + description: 'Total time in milliseconds spent waiting in the various queues', + name: 'haproxy.total_waiting_time_ms', + type: 'long', + }, + 'haproxy.connection_wait_time_ms': { + category: 'haproxy', + description: + 'Total time in milliseconds spent waiting for the connection to establish to the final server', + name: 'haproxy.connection_wait_time_ms', + type: 'long', + }, + 'haproxy.bytes_read': { + category: 'haproxy', + description: 'Total number of bytes transmitted to the client when the log is emitted.', + name: 'haproxy.bytes_read', + type: 'long', + }, + 'haproxy.time_queue': { + category: 'haproxy', + description: 'Total time in milliseconds spent waiting in the various queues.', + name: 'haproxy.time_queue', + type: 'long', + }, + 'haproxy.time_backend_connect': { + category: 'haproxy', + description: + 'Total time in milliseconds spent waiting for the connection to establish to the final server, including retries.', + name: 'haproxy.time_backend_connect', + type: 'long', + }, + 'haproxy.server_queue': { + category: 'haproxy', + description: + 'Total number of requests which were processed before this one in the server queue.', + name: 'haproxy.server_queue', + type: 'long', + }, + 'haproxy.backend_queue': { + category: 'haproxy', + description: + "Total number of requests which were processed before this one in the backend's global queue.", + name: 'haproxy.backend_queue', + type: 'long', + }, + 'haproxy.bind_name': { + category: 'haproxy', + description: 'Name of the listening address which received the connection.', + name: 'haproxy.bind_name', + }, + 'haproxy.error_message': { + category: 'haproxy', + description: 'Error message logged by HAProxy in case of error.', + name: 'haproxy.error_message', + type: 'text', + }, + 'haproxy.source': { + category: 'haproxy', + description: 'The HAProxy source of the log', + name: 'haproxy.source', + type: 'keyword', + }, + 'haproxy.termination_state': { + category: 'haproxy', + description: 'Condition the session was in when the session ended.', + name: 'haproxy.termination_state', + }, + 'haproxy.mode': { + category: 'haproxy', + description: 'mode that the frontend is operating (TCP or HTTP)', + name: 'haproxy.mode', + type: 'keyword', + }, + 'haproxy.connections.active': { + category: 'haproxy', + description: + 'Total number of concurrent connections on the process when the session was logged.', + name: 'haproxy.connections.active', + type: 'long', + }, + 'haproxy.connections.frontend': { + category: 'haproxy', + description: + 'Total number of concurrent connections on the frontend when the session was logged.', + name: 'haproxy.connections.frontend', + type: 'long', + }, + 'haproxy.connections.backend': { + category: 'haproxy', + description: + 'Total number of concurrent connections handled by the backend when the session was logged.', + name: 'haproxy.connections.backend', + type: 'long', + }, + 'haproxy.connections.server': { + category: 'haproxy', + description: + 'Total number of concurrent connections still active on the server when the session was logged.', + name: 'haproxy.connections.server', + type: 'long', + }, + 'haproxy.connections.retries': { + category: 'haproxy', + description: + 'Number of connection retries experienced by this session when trying to connect to the server.', + name: 'haproxy.connections.retries', + type: 'long', + }, + 'haproxy.client.ip': { + category: 'haproxy', + name: 'haproxy.client.ip', + type: 'alias', + }, + 'haproxy.client.port': { + category: 'haproxy', + name: 'haproxy.client.port', + type: 'alias', + }, + 'haproxy.process_name': { + category: 'haproxy', + name: 'haproxy.process_name', + type: 'alias', + }, + 'haproxy.pid': { + category: 'haproxy', + name: 'haproxy.pid', + type: 'alias', + }, + 'haproxy.destination.port': { + category: 'haproxy', + name: 'haproxy.destination.port', + type: 'alias', + }, + 'haproxy.destination.ip': { + category: 'haproxy', + name: 'haproxy.destination.ip', + type: 'alias', + }, + 'haproxy.geoip.continent_name': { + category: 'haproxy', + name: 'haproxy.geoip.continent_name', + type: 'alias', + }, + 'haproxy.geoip.country_iso_code': { + category: 'haproxy', + name: 'haproxy.geoip.country_iso_code', + type: 'alias', + }, + 'haproxy.geoip.location': { + category: 'haproxy', + name: 'haproxy.geoip.location', + type: 'alias', + }, + 'haproxy.geoip.region_name': { + category: 'haproxy', + name: 'haproxy.geoip.region_name', + type: 'alias', + }, + 'haproxy.geoip.city_name': { + category: 'haproxy', + name: 'haproxy.geoip.city_name', + type: 'alias', + }, + 'haproxy.geoip.region_iso_code': { + category: 'haproxy', + name: 'haproxy.geoip.region_iso_code', + type: 'alias', + }, + 'haproxy.http.response.captured_cookie': { + category: 'haproxy', + description: + 'Optional "name=value" entry indicating that the client had this cookie in the response. ', + name: 'haproxy.http.response.captured_cookie', + }, + 'haproxy.http.response.captured_headers': { + category: 'haproxy', + description: + 'List of headers captured in the response due to the presence of the "capture response header" statement in the frontend. ', + name: 'haproxy.http.response.captured_headers', + type: 'keyword', + }, + 'haproxy.http.response.status_code': { + category: 'haproxy', + name: 'haproxy.http.response.status_code', + type: 'alias', + }, + 'haproxy.http.request.captured_cookie': { + category: 'haproxy', + description: + 'Optional "name=value" entry indicating that the server has returned a cookie with its request. ', + name: 'haproxy.http.request.captured_cookie', + }, + 'haproxy.http.request.captured_headers': { + category: 'haproxy', + description: + 'List of headers captured in the request due to the presence of the "capture request header" statement in the frontend. ', + name: 'haproxy.http.request.captured_headers', + type: 'keyword', + }, + 'haproxy.http.request.raw_request_line': { + category: 'haproxy', + description: + 'Complete HTTP request line, including the method, request and HTTP version string.', + name: 'haproxy.http.request.raw_request_line', + type: 'keyword', + }, + 'haproxy.http.request.time_wait_without_data_ms': { + category: 'haproxy', + description: + 'Total time in milliseconds spent waiting for the server to send a full HTTP response, not counting data.', + name: 'haproxy.http.request.time_wait_without_data_ms', + type: 'long', + }, + 'haproxy.http.request.time_wait_ms': { + category: 'haproxy', + description: + 'Total time in milliseconds spent waiting for a full HTTP request from the client (not counting body) after the first byte was received.', + name: 'haproxy.http.request.time_wait_ms', + type: 'long', + }, + 'haproxy.tcp.connection_waiting_time_ms': { + category: 'haproxy', + description: 'Total time in milliseconds elapsed between the accept and the last close', + name: 'haproxy.tcp.connection_waiting_time_ms', + type: 'long', + }, + 'icinga.debug.facility': { + category: 'icinga', + description: 'Specifies what component of Icinga logged the message. ', + name: 'icinga.debug.facility', + type: 'keyword', + }, + 'icinga.debug.severity': { + category: 'icinga', + name: 'icinga.debug.severity', + type: 'alias', + }, + 'icinga.debug.message': { + category: 'icinga', + name: 'icinga.debug.message', + type: 'alias', + }, + 'icinga.main.facility': { + category: 'icinga', + description: 'Specifies what component of Icinga logged the message. ', + name: 'icinga.main.facility', + type: 'keyword', + }, + 'icinga.main.severity': { + category: 'icinga', + name: 'icinga.main.severity', + type: 'alias', + }, + 'icinga.main.message': { + category: 'icinga', + name: 'icinga.main.message', + type: 'alias', + }, + 'icinga.startup.facility': { + category: 'icinga', + description: 'Specifies what component of Icinga logged the message. ', + name: 'icinga.startup.facility', + type: 'keyword', + }, + 'icinga.startup.severity': { + category: 'icinga', + name: 'icinga.startup.severity', + type: 'alias', + }, + 'icinga.startup.message': { + category: 'icinga', + name: 'icinga.startup.message', + type: 'alias', + }, + 'iis.access.sub_status': { + category: 'iis', + description: 'The HTTP substatus code. ', + name: 'iis.access.sub_status', + type: 'long', + }, + 'iis.access.win32_status': { + category: 'iis', + description: 'The Windows status code. ', + name: 'iis.access.win32_status', + type: 'long', + }, + 'iis.access.site_name': { + category: 'iis', + description: 'The site name and instance number. ', + name: 'iis.access.site_name', + type: 'keyword', + }, + 'iis.access.server_name': { + category: 'iis', + description: 'The name of the server on which the log file entry was generated. ', + name: 'iis.access.server_name', + type: 'keyword', + }, + 'iis.access.cookie': { + category: 'iis', + description: 'The content of the cookie sent or received, if any. ', + name: 'iis.access.cookie', + type: 'keyword', + }, + 'iis.access.body_received.bytes': { + category: 'iis', + name: 'iis.access.body_received.bytes', + type: 'alias', + }, + 'iis.access.body_sent.bytes': { + category: 'iis', + name: 'iis.access.body_sent.bytes', + type: 'alias', + }, + 'iis.access.server_ip': { + category: 'iis', + name: 'iis.access.server_ip', + type: 'alias', + }, + 'iis.access.method': { + category: 'iis', + name: 'iis.access.method', + type: 'alias', + }, + 'iis.access.url': { + category: 'iis', + name: 'iis.access.url', + type: 'alias', + }, + 'iis.access.query_string': { + category: 'iis', + name: 'iis.access.query_string', + type: 'alias', + }, + 'iis.access.port': { + category: 'iis', + name: 'iis.access.port', + type: 'alias', + }, + 'iis.access.user_name': { + category: 'iis', + name: 'iis.access.user_name', + type: 'alias', + }, + 'iis.access.remote_ip': { + category: 'iis', + name: 'iis.access.remote_ip', + type: 'alias', + }, + 'iis.access.referrer': { + category: 'iis', + name: 'iis.access.referrer', + type: 'alias', + }, + 'iis.access.response_code': { + category: 'iis', + name: 'iis.access.response_code', + type: 'alias', + }, + 'iis.access.http_version': { + category: 'iis', + name: 'iis.access.http_version', + type: 'alias', + }, + 'iis.access.hostname': { + category: 'iis', + name: 'iis.access.hostname', + type: 'alias', + }, + 'iis.access.user_agent.device': { + category: 'iis', + name: 'iis.access.user_agent.device', + type: 'alias', + }, + 'iis.access.user_agent.name': { + category: 'iis', + name: 'iis.access.user_agent.name', + type: 'alias', + }, + 'iis.access.user_agent.os': { + category: 'iis', + name: 'iis.access.user_agent.os', + type: 'alias', + }, + 'iis.access.user_agent.os_name': { + category: 'iis', + name: 'iis.access.user_agent.os_name', + type: 'alias', + }, + 'iis.access.user_agent.original': { + category: 'iis', + name: 'iis.access.user_agent.original', + type: 'alias', + }, + 'iis.access.geoip.continent_name': { + category: 'iis', + name: 'iis.access.geoip.continent_name', + type: 'alias', + }, + 'iis.access.geoip.country_iso_code': { + category: 'iis', + name: 'iis.access.geoip.country_iso_code', + type: 'alias', + }, + 'iis.access.geoip.location': { + category: 'iis', + name: 'iis.access.geoip.location', + type: 'alias', + }, + 'iis.access.geoip.region_name': { + category: 'iis', + name: 'iis.access.geoip.region_name', + type: 'alias', + }, + 'iis.access.geoip.city_name': { + category: 'iis', + name: 'iis.access.geoip.city_name', + type: 'alias', + }, + 'iis.access.geoip.region_iso_code': { + category: 'iis', + name: 'iis.access.geoip.region_iso_code', + type: 'alias', + }, + 'iis.error.reason_phrase': { + category: 'iis', + description: 'The HTTP reason phrase. ', + name: 'iis.error.reason_phrase', + type: 'keyword', + }, + 'iis.error.queue_name': { + category: 'iis', + description: 'The IIS application pool name. ', + name: 'iis.error.queue_name', + type: 'keyword', + }, + 'iis.error.remote_ip': { + category: 'iis', + name: 'iis.error.remote_ip', + type: 'alias', + }, + 'iis.error.remote_port': { + category: 'iis', + name: 'iis.error.remote_port', + type: 'alias', + }, + 'iis.error.server_ip': { + category: 'iis', + name: 'iis.error.server_ip', + type: 'alias', + }, + 'iis.error.server_port': { + category: 'iis', + name: 'iis.error.server_port', + type: 'alias', + }, + 'iis.error.http_version': { + category: 'iis', + name: 'iis.error.http_version', + type: 'alias', + }, + 'iis.error.method': { + category: 'iis', + name: 'iis.error.method', + type: 'alias', + }, + 'iis.error.url': { + category: 'iis', + name: 'iis.error.url', + type: 'alias', + }, + 'iis.error.response_code': { + category: 'iis', + name: 'iis.error.response_code', + type: 'alias', + }, + 'iis.error.geoip.continent_name': { + category: 'iis', + name: 'iis.error.geoip.continent_name', + type: 'alias', + }, + 'iis.error.geoip.country_iso_code': { + category: 'iis', + name: 'iis.error.geoip.country_iso_code', + type: 'alias', + }, + 'iis.error.geoip.location': { + category: 'iis', + name: 'iis.error.geoip.location', + type: 'alias', + }, + 'iis.error.geoip.region_name': { + category: 'iis', + name: 'iis.error.geoip.region_name', + type: 'alias', + }, + 'iis.error.geoip.city_name': { + category: 'iis', + name: 'iis.error.geoip.city_name', + type: 'alias', + }, + 'iis.error.geoip.region_iso_code': { + category: 'iis', + name: 'iis.error.geoip.region_iso_code', + type: 'alias', + }, + 'kafka.log.level': { + category: 'kafka', + name: 'kafka.log.level', + type: 'alias', + }, + 'kafka.log.message': { + category: 'kafka', + name: 'kafka.log.message', + type: 'alias', + }, + 'kafka.log.component': { + category: 'kafka', + description: 'Component the log is coming from. ', + name: 'kafka.log.component', + type: 'keyword', + }, + 'kafka.log.class': { + category: 'kafka', + description: 'Java class the log is coming from. ', + name: 'kafka.log.class', + type: 'keyword', + }, + 'kafka.log.thread': { + category: 'kafka', + description: 'Thread name the log is coming from. ', + name: 'kafka.log.thread', + type: 'keyword', + }, + 'kafka.log.trace.class': { + category: 'kafka', + description: 'Java class the trace is coming from. ', + name: 'kafka.log.trace.class', + type: 'keyword', + }, + 'kafka.log.trace.message': { + category: 'kafka', + description: 'Message part of the trace. ', + name: 'kafka.log.trace.message', + type: 'text', + }, + 'kibana.log.tags': { + category: 'kibana', + description: 'Kibana logging tags. ', + name: 'kibana.log.tags', + type: 'keyword', + }, + 'kibana.log.state': { + category: 'kibana', + description: 'Current state of Kibana. ', + name: 'kibana.log.state', + type: 'keyword', + }, + 'kibana.log.meta': { + category: 'kibana', + name: 'kibana.log.meta', + type: 'object', + }, + 'kibana.log.kibana.log.meta.req.headers.referer': { + category: 'kibana', + name: 'kibana.log.kibana.log.meta.req.headers.referer', + type: 'alias', + }, + 'kibana.log.kibana.log.meta.req.referer': { + category: 'kibana', + name: 'kibana.log.kibana.log.meta.req.referer', + type: 'alias', + }, + 'kibana.log.kibana.log.meta.req.headers.user-agent': { + category: 'kibana', + name: 'kibana.log.kibana.log.meta.req.headers.user-agent', + type: 'alias', + }, + 'kibana.log.kibana.log.meta.req.remoteAddress': { + category: 'kibana', + name: 'kibana.log.kibana.log.meta.req.remoteAddress', + type: 'alias', + }, + 'kibana.log.kibana.log.meta.req.url': { + category: 'kibana', + name: 'kibana.log.kibana.log.meta.req.url', + type: 'alias', + }, + 'kibana.log.kibana.log.meta.statusCode': { + category: 'kibana', + name: 'kibana.log.kibana.log.meta.statusCode', + type: 'alias', + }, + 'kibana.log.kibana.log.meta.method': { + category: 'kibana', + name: 'kibana.log.kibana.log.meta.method', + type: 'alias', + }, + 'logstash.log.module': { + category: 'logstash', + description: 'The module or class where the event originate. ', + name: 'logstash.log.module', + type: 'keyword', + }, + 'logstash.log.thread': { + category: 'logstash', + description: 'Information about the running thread where the log originate. ', + name: 'logstash.log.thread', + type: 'keyword', + }, + 'logstash.log.log_event': { + category: 'logstash', + description: 'key and value debugging information. ', + name: 'logstash.log.log_event', + type: 'object', + }, + 'logstash.log.pipeline_id': { + category: 'logstash', + description: 'The ID of the pipeline. ', + example: 'main', + name: 'logstash.log.pipeline_id', + type: 'keyword', + }, + 'logstash.log.message': { + category: 'logstash', + name: 'logstash.log.message', + type: 'alias', + }, + 'logstash.log.level': { + category: 'logstash', + name: 'logstash.log.level', + type: 'alias', + }, + 'logstash.slowlog.module': { + category: 'logstash', + description: 'The module or class where the event originate. ', + name: 'logstash.slowlog.module', + type: 'keyword', + }, + 'logstash.slowlog.thread': { + category: 'logstash', + description: 'Information about the running thread where the log originate. ', + name: 'logstash.slowlog.thread', + type: 'keyword', + }, + 'logstash.slowlog.event': { + category: 'logstash', + description: 'Raw dump of the original event ', + name: 'logstash.slowlog.event', + type: 'keyword', + }, + 'logstash.slowlog.plugin_name': { + category: 'logstash', + description: 'Name of the plugin ', + name: 'logstash.slowlog.plugin_name', + type: 'keyword', + }, + 'logstash.slowlog.plugin_type': { + category: 'logstash', + description: 'Type of the plugin: Inputs, Filters, Outputs or Codecs. ', + name: 'logstash.slowlog.plugin_type', + type: 'keyword', + }, + 'logstash.slowlog.took_in_millis': { + category: 'logstash', + description: 'Execution time for the plugin in milliseconds. ', + name: 'logstash.slowlog.took_in_millis', + type: 'long', + }, + 'logstash.slowlog.plugin_params': { + category: 'logstash', + description: 'String value of the plugin configuration ', + name: 'logstash.slowlog.plugin_params', + type: 'keyword', + }, + 'logstash.slowlog.plugin_params_object': { + category: 'logstash', + description: 'key -> value of the configuration used by the plugin. ', + name: 'logstash.slowlog.plugin_params_object', + type: 'object', + }, + 'logstash.slowlog.level': { + category: 'logstash', + name: 'logstash.slowlog.level', + type: 'alias', + }, + 'logstash.slowlog.took_in_nanos': { + category: 'logstash', + name: 'logstash.slowlog.took_in_nanos', + type: 'alias', + }, + 'mongodb.log.component': { + category: 'mongodb', + description: 'Functional categorization of message ', + example: 'COMMAND', + name: 'mongodb.log.component', + type: 'keyword', + }, + 'mongodb.log.context': { + category: 'mongodb', + description: 'Context of message ', + example: 'initandlisten', + name: 'mongodb.log.context', + type: 'keyword', + }, + 'mongodb.log.severity': { + category: 'mongodb', + name: 'mongodb.log.severity', + type: 'alias', + }, + 'mongodb.log.message': { + category: 'mongodb', + name: 'mongodb.log.message', + type: 'alias', + }, + 'mysql.thread_id': { + category: 'mysql', + description: 'The connection or thread ID for the query. ', + name: 'mysql.thread_id', + type: 'long', + }, + 'mysql.error.thread_id': { + category: 'mysql', + name: 'mysql.error.thread_id', + type: 'alias', + }, + 'mysql.error.level': { + category: 'mysql', + name: 'mysql.error.level', + type: 'alias', + }, + 'mysql.error.message': { + category: 'mysql', + name: 'mysql.error.message', + type: 'alias', + }, + 'mysql.slowlog.lock_time.sec': { + category: 'mysql', + description: + 'The amount of time the query waited for the lock to be available. The value is in seconds, as a floating point number. ', + name: 'mysql.slowlog.lock_time.sec', + type: 'float', + }, + 'mysql.slowlog.rows_sent': { + category: 'mysql', + description: 'The number of rows returned by the query. ', + name: 'mysql.slowlog.rows_sent', + type: 'long', + }, + 'mysql.slowlog.rows_examined': { + category: 'mysql', + description: 'The number of rows scanned by the query. ', + name: 'mysql.slowlog.rows_examined', + type: 'long', + }, + 'mysql.slowlog.rows_affected': { + category: 'mysql', + description: 'The number of rows modified by the query. ', + name: 'mysql.slowlog.rows_affected', + type: 'long', + }, + 'mysql.slowlog.bytes_sent': { + category: 'mysql', + description: 'The number of bytes sent to client. ', + name: 'mysql.slowlog.bytes_sent', + type: 'long', + format: 'bytes', + }, + 'mysql.slowlog.bytes_received': { + category: 'mysql', + description: 'The number of bytes received from client. ', + name: 'mysql.slowlog.bytes_received', + type: 'long', + format: 'bytes', + }, + 'mysql.slowlog.query': { + category: 'mysql', + description: 'The slow query. ', + name: 'mysql.slowlog.query', + }, + 'mysql.slowlog.id': { + category: 'mysql', + name: 'mysql.slowlog.id', + type: 'alias', + }, + 'mysql.slowlog.schema': { + category: 'mysql', + description: 'The schema where the slow query was executed. ', + name: 'mysql.slowlog.schema', + type: 'keyword', + }, + 'mysql.slowlog.current_user': { + category: 'mysql', + description: + 'Current authenticated user, used to determine access privileges. Can differ from the value for user. ', + name: 'mysql.slowlog.current_user', + type: 'keyword', + }, + 'mysql.slowlog.last_errno': { + category: 'mysql', + description: 'Last SQL error seen. ', + name: 'mysql.slowlog.last_errno', + type: 'keyword', + }, + 'mysql.slowlog.killed': { + category: 'mysql', + description: 'Code of the reason if the query was killed. ', + name: 'mysql.slowlog.killed', + type: 'keyword', + }, + 'mysql.slowlog.query_cache_hit': { + category: 'mysql', + description: 'Whether the query cache was hit. ', + name: 'mysql.slowlog.query_cache_hit', + type: 'boolean', + }, + 'mysql.slowlog.tmp_table': { + category: 'mysql', + description: 'Whether a temporary table was used to resolve the query. ', + name: 'mysql.slowlog.tmp_table', + type: 'boolean', + }, + 'mysql.slowlog.tmp_table_on_disk': { + category: 'mysql', + description: 'Whether the query needed temporary tables on disk. ', + name: 'mysql.slowlog.tmp_table_on_disk', + type: 'boolean', + }, + 'mysql.slowlog.tmp_tables': { + category: 'mysql', + description: 'Number of temporary tables created for this query ', + name: 'mysql.slowlog.tmp_tables', + type: 'long', + }, + 'mysql.slowlog.tmp_disk_tables': { + category: 'mysql', + description: 'Number of temporary tables created on disk for this query. ', + name: 'mysql.slowlog.tmp_disk_tables', + type: 'long', + }, + 'mysql.slowlog.tmp_table_sizes': { + category: 'mysql', + description: 'Size of temporary tables created for this query.', + name: 'mysql.slowlog.tmp_table_sizes', + type: 'long', + format: 'bytes', + }, + 'mysql.slowlog.filesort': { + category: 'mysql', + description: 'Whether filesort optimization was used. ', + name: 'mysql.slowlog.filesort', + type: 'boolean', + }, + 'mysql.slowlog.filesort_on_disk': { + category: 'mysql', + description: 'Whether filesort optimization was used and it needed temporary tables on disk. ', + name: 'mysql.slowlog.filesort_on_disk', + type: 'boolean', + }, + 'mysql.slowlog.priority_queue': { + category: 'mysql', + description: 'Whether a priority queue was used for filesort. ', + name: 'mysql.slowlog.priority_queue', + type: 'boolean', + }, + 'mysql.slowlog.full_scan': { + category: 'mysql', + description: 'Whether a full table scan was needed for the slow query. ', + name: 'mysql.slowlog.full_scan', + type: 'boolean', + }, + 'mysql.slowlog.full_join': { + category: 'mysql', + description: + 'Whether a full join was needed for the slow query (no indexes were used for joins). ', + name: 'mysql.slowlog.full_join', + type: 'boolean', + }, + 'mysql.slowlog.merge_passes': { + category: 'mysql', + description: 'Number of merge passes executed for the query. ', + name: 'mysql.slowlog.merge_passes', + type: 'long', + }, + 'mysql.slowlog.sort_merge_passes': { + category: 'mysql', + description: 'Number of merge passes that the sort algorithm has had to do. ', + name: 'mysql.slowlog.sort_merge_passes', + type: 'long', + }, + 'mysql.slowlog.sort_range_count': { + category: 'mysql', + description: 'Number of sorts that were done using ranges. ', + name: 'mysql.slowlog.sort_range_count', + type: 'long', + }, + 'mysql.slowlog.sort_rows': { + category: 'mysql', + description: 'Number of sorted rows. ', + name: 'mysql.slowlog.sort_rows', + type: 'long', + }, + 'mysql.slowlog.sort_scan_count': { + category: 'mysql', + description: 'Number of sorts that were done by scanning the table. ', + name: 'mysql.slowlog.sort_scan_count', + type: 'long', + }, + 'mysql.slowlog.log_slow_rate_type': { + category: 'mysql', + description: + 'Type of slow log rate limit, it can be `session` if the rate limit is applied per session, or `query` if it applies per query. ', + name: 'mysql.slowlog.log_slow_rate_type', + type: 'keyword', + }, + 'mysql.slowlog.log_slow_rate_limit': { + category: 'mysql', + description: + 'Slow log rate limit, a value of 100 means that one in a hundred queries or sessions are being logged. ', + name: 'mysql.slowlog.log_slow_rate_limit', + type: 'keyword', + }, + 'mysql.slowlog.read_first': { + category: 'mysql', + description: 'The number of times the first entry in an index was read. ', + name: 'mysql.slowlog.read_first', + type: 'long', + }, + 'mysql.slowlog.read_last': { + category: 'mysql', + description: 'The number of times the last key in an index was read. ', + name: 'mysql.slowlog.read_last', + type: 'long', + }, + 'mysql.slowlog.read_key': { + category: 'mysql', + description: 'The number of requests to read a row based on a key. ', + name: 'mysql.slowlog.read_key', + type: 'long', + }, + 'mysql.slowlog.read_next': { + category: 'mysql', + description: 'The number of requests to read the next row in key order. ', + name: 'mysql.slowlog.read_next', + type: 'long', + }, + 'mysql.slowlog.read_prev': { + category: 'mysql', + description: 'The number of requests to read the previous row in key order. ', + name: 'mysql.slowlog.read_prev', + type: 'long', + }, + 'mysql.slowlog.read_rnd': { + category: 'mysql', + description: 'The number of requests to read a row based on a fixed position. ', + name: 'mysql.slowlog.read_rnd', + type: 'long', + }, + 'mysql.slowlog.read_rnd_next': { + category: 'mysql', + description: 'The number of requests to read the next row in the data file. ', + name: 'mysql.slowlog.read_rnd_next', + type: 'long', + }, + 'mysql.slowlog.innodb.trx_id': { + category: 'mysql', + description: 'Transaction ID ', + name: 'mysql.slowlog.innodb.trx_id', + type: 'keyword', + }, + 'mysql.slowlog.innodb.io_r_ops': { + category: 'mysql', + description: 'Number of page read operations. ', + name: 'mysql.slowlog.innodb.io_r_ops', + type: 'long', + }, + 'mysql.slowlog.innodb.io_r_bytes': { + category: 'mysql', + description: 'Bytes read during page read operations. ', + name: 'mysql.slowlog.innodb.io_r_bytes', + type: 'long', + format: 'bytes', + }, + 'mysql.slowlog.innodb.io_r_wait.sec': { + category: 'mysql', + description: 'How long it took to read all needed data from storage. ', + name: 'mysql.slowlog.innodb.io_r_wait.sec', + type: 'long', + }, + 'mysql.slowlog.innodb.rec_lock_wait.sec': { + category: 'mysql', + description: 'How long the query waited for locks. ', + name: 'mysql.slowlog.innodb.rec_lock_wait.sec', + type: 'long', + }, + 'mysql.slowlog.innodb.queue_wait.sec': { + category: 'mysql', + description: + 'How long the query waited to enter the InnoDB queue and to be executed once in the queue. ', + name: 'mysql.slowlog.innodb.queue_wait.sec', + type: 'long', + }, + 'mysql.slowlog.innodb.pages_distinct': { + category: 'mysql', + description: 'Approximated count of pages accessed to execute the query. ', + name: 'mysql.slowlog.innodb.pages_distinct', + type: 'long', + }, + 'mysql.slowlog.user': { + category: 'mysql', + name: 'mysql.slowlog.user', + type: 'alias', + }, + 'mysql.slowlog.host': { + category: 'mysql', + name: 'mysql.slowlog.host', + type: 'alias', + }, + 'mysql.slowlog.ip': { + category: 'mysql', + name: 'mysql.slowlog.ip', + type: 'alias', + }, + 'nats.log.client.id': { + category: 'nats', + description: 'The id of the client ', + name: 'nats.log.client.id', + type: 'integer', + }, + 'nats.log.msg.bytes': { + category: 'nats', + description: 'Size of the payload in bytes ', + name: 'nats.log.msg.bytes', + type: 'long', + format: 'bytes', + }, + 'nats.log.msg.type': { + category: 'nats', + description: 'The protocol message type ', + name: 'nats.log.msg.type', + type: 'keyword', + }, + 'nats.log.msg.subject': { + category: 'nats', + description: 'Subject name this message was received on ', + name: 'nats.log.msg.subject', + type: 'keyword', + }, + 'nats.log.msg.sid': { + category: 'nats', + description: 'The unique alphanumeric subscription ID of the subject ', + name: 'nats.log.msg.sid', + type: 'integer', + }, + 'nats.log.msg.reply_to': { + category: 'nats', + description: 'The inbox subject on which the publisher is listening for responses ', + name: 'nats.log.msg.reply_to', + type: 'keyword', + }, + 'nats.log.msg.max_messages': { + category: 'nats', + description: 'An optional number of messages to wait for before automatically unsubscribing ', + name: 'nats.log.msg.max_messages', + type: 'integer', + }, + 'nats.log.msg.error.message': { + category: 'nats', + description: 'Details about the error occurred ', + name: 'nats.log.msg.error.message', + type: 'text', + }, + 'nats.log.msg.queue_group': { + category: 'nats', + description: 'The queue group which subscriber will join ', + name: 'nats.log.msg.queue_group', + type: 'text', + }, + 'nginx.access.remote_ip_list': { + category: 'nginx', + description: + 'An array of remote IP addresses. It is a list because it is common to include, besides the client IP address, IP addresses from headers like `X-Forwarded-For`. Real source IP is restored to `source.ip`. ', + name: 'nginx.access.remote_ip_list', + type: 'array', + }, + 'nginx.access.body_sent.bytes': { + category: 'nginx', + name: 'nginx.access.body_sent.bytes', + type: 'alias', + }, + 'nginx.access.user_name': { + category: 'nginx', + name: 'nginx.access.user_name', + type: 'alias', + }, + 'nginx.access.method': { + category: 'nginx', + name: 'nginx.access.method', + type: 'alias', + }, + 'nginx.access.url': { + category: 'nginx', + name: 'nginx.access.url', + type: 'alias', + }, + 'nginx.access.http_version': { + category: 'nginx', + name: 'nginx.access.http_version', + type: 'alias', + }, + 'nginx.access.response_code': { + category: 'nginx', + name: 'nginx.access.response_code', + type: 'alias', + }, + 'nginx.access.referrer': { + category: 'nginx', + name: 'nginx.access.referrer', + type: 'alias', + }, + 'nginx.access.agent': { + category: 'nginx', + name: 'nginx.access.agent', + type: 'alias', + }, + 'nginx.access.user_agent.device': { + category: 'nginx', + name: 'nginx.access.user_agent.device', + type: 'alias', + }, + 'nginx.access.user_agent.name': { + category: 'nginx', + name: 'nginx.access.user_agent.name', + type: 'alias', + }, + 'nginx.access.user_agent.os': { + category: 'nginx', + name: 'nginx.access.user_agent.os', + type: 'alias', + }, + 'nginx.access.user_agent.os_name': { + category: 'nginx', + name: 'nginx.access.user_agent.os_name', + type: 'alias', + }, + 'nginx.access.user_agent.original': { + category: 'nginx', + name: 'nginx.access.user_agent.original', + type: 'alias', + }, + 'nginx.access.geoip.continent_name': { + category: 'nginx', + name: 'nginx.access.geoip.continent_name', + type: 'alias', + }, + 'nginx.access.geoip.country_iso_code': { + category: 'nginx', + name: 'nginx.access.geoip.country_iso_code', + type: 'alias', + }, + 'nginx.access.geoip.location': { + category: 'nginx', + name: 'nginx.access.geoip.location', + type: 'alias', + }, + 'nginx.access.geoip.region_name': { + category: 'nginx', + name: 'nginx.access.geoip.region_name', + type: 'alias', + }, + 'nginx.access.geoip.city_name': { + category: 'nginx', + name: 'nginx.access.geoip.city_name', + type: 'alias', + }, + 'nginx.access.geoip.region_iso_code': { + category: 'nginx', + name: 'nginx.access.geoip.region_iso_code', + type: 'alias', + }, + 'nginx.error.connection_id': { + category: 'nginx', + description: 'Connection identifier. ', + name: 'nginx.error.connection_id', + type: 'long', + }, + 'nginx.error.level': { + category: 'nginx', + name: 'nginx.error.level', + type: 'alias', + }, + 'nginx.error.pid': { + category: 'nginx', + name: 'nginx.error.pid', + type: 'alias', + }, + 'nginx.error.tid': { + category: 'nginx', + name: 'nginx.error.tid', + type: 'alias', + }, + 'nginx.error.message': { + category: 'nginx', + name: 'nginx.error.message', + type: 'alias', + }, + 'nginx.ingress_controller.remote_ip_list': { + category: 'nginx', + description: + 'An array of remote IP addresses. It is a list because it is common to include, besides the client IP address, IP addresses from headers like `X-Forwarded-For`. Real source IP is restored to `source.ip`. ', + name: 'nginx.ingress_controller.remote_ip_list', + type: 'array', + }, + 'nginx.ingress_controller.http.request.length': { + category: 'nginx', + description: 'The request length (including request line, header, and request body) ', + name: 'nginx.ingress_controller.http.request.length', + type: 'long', + format: 'bytes', + }, + 'nginx.ingress_controller.http.request.time': { + category: 'nginx', + description: 'Time elapsed since the first bytes were read from the client ', + name: 'nginx.ingress_controller.http.request.time', + type: 'double', + format: 'duration', + }, + 'nginx.ingress_controller.upstream.name': { + category: 'nginx', + description: 'The name of the upstream. ', + name: 'nginx.ingress_controller.upstream.name', + type: 'keyword', + }, + 'nginx.ingress_controller.upstream.alternative_name': { + category: 'nginx', + description: 'The name of the alternative upstream. ', + name: 'nginx.ingress_controller.upstream.alternative_name', + type: 'keyword', + }, + 'nginx.ingress_controller.upstream.response.length': { + category: 'nginx', + description: 'The length of the response obtained from the upstream server ', + name: 'nginx.ingress_controller.upstream.response.length', + type: 'long', + format: 'bytes', + }, + 'nginx.ingress_controller.upstream.response.time': { + category: 'nginx', + description: + 'The time spent on receiving the response from the upstream server as seconds with millisecond resolution ', + name: 'nginx.ingress_controller.upstream.response.time', + type: 'double', + format: 'duration', + }, + 'nginx.ingress_controller.upstream.response.status_code': { + category: 'nginx', + description: 'The status code of the response obtained from the upstream server ', + name: 'nginx.ingress_controller.upstream.response.status_code', + type: 'long', + }, + 'nginx.ingress_controller.http.request.id': { + category: 'nginx', + description: 'The randomly generated ID of the request ', + name: 'nginx.ingress_controller.http.request.id', + type: 'keyword', + }, + 'nginx.ingress_controller.upstream.ip': { + category: 'nginx', + description: + 'The IP address of the upstream server. If several servers were contacted during request processing, their addresses are separated by commas. ', + name: 'nginx.ingress_controller.upstream.ip', + type: 'ip', + }, + 'nginx.ingress_controller.upstream.port': { + category: 'nginx', + description: 'The port of the upstream server. ', + name: 'nginx.ingress_controller.upstream.port', + type: 'long', + }, + 'nginx.ingress_controller.body_sent.bytes': { + category: 'nginx', + name: 'nginx.ingress_controller.body_sent.bytes', + type: 'alias', + }, + 'nginx.ingress_controller.user_name': { + category: 'nginx', + name: 'nginx.ingress_controller.user_name', + type: 'alias', + }, + 'nginx.ingress_controller.method': { + category: 'nginx', + name: 'nginx.ingress_controller.method', + type: 'alias', + }, + 'nginx.ingress_controller.url': { + category: 'nginx', + name: 'nginx.ingress_controller.url', + type: 'alias', + }, + 'nginx.ingress_controller.http_version': { + category: 'nginx', + name: 'nginx.ingress_controller.http_version', + type: 'alias', + }, + 'nginx.ingress_controller.response_code': { + category: 'nginx', + name: 'nginx.ingress_controller.response_code', + type: 'alias', + }, + 'nginx.ingress_controller.referrer': { + category: 'nginx', + name: 'nginx.ingress_controller.referrer', + type: 'alias', + }, + 'nginx.ingress_controller.agent': { + category: 'nginx', + name: 'nginx.ingress_controller.agent', + type: 'alias', + }, + 'nginx.ingress_controller.user_agent.device': { + category: 'nginx', + name: 'nginx.ingress_controller.user_agent.device', + type: 'alias', + }, + 'nginx.ingress_controller.user_agent.name': { + category: 'nginx', + name: 'nginx.ingress_controller.user_agent.name', + type: 'alias', + }, + 'nginx.ingress_controller.user_agent.os': { + category: 'nginx', + name: 'nginx.ingress_controller.user_agent.os', + type: 'alias', + }, + 'nginx.ingress_controller.user_agent.os_name': { + category: 'nginx', + name: 'nginx.ingress_controller.user_agent.os_name', + type: 'alias', + }, + 'nginx.ingress_controller.user_agent.original': { + category: 'nginx', + name: 'nginx.ingress_controller.user_agent.original', + type: 'alias', + }, + 'nginx.ingress_controller.geoip.continent_name': { + category: 'nginx', + name: 'nginx.ingress_controller.geoip.continent_name', + type: 'alias', + }, + 'nginx.ingress_controller.geoip.country_iso_code': { + category: 'nginx', + name: 'nginx.ingress_controller.geoip.country_iso_code', + type: 'alias', + }, + 'nginx.ingress_controller.geoip.location': { + category: 'nginx', + name: 'nginx.ingress_controller.geoip.location', + type: 'alias', + }, + 'nginx.ingress_controller.geoip.region_name': { + category: 'nginx', + name: 'nginx.ingress_controller.geoip.region_name', + type: 'alias', + }, + 'nginx.ingress_controller.geoip.city_name': { + category: 'nginx', + name: 'nginx.ingress_controller.geoip.city_name', + type: 'alias', + }, + 'nginx.ingress_controller.geoip.region_iso_code': { + category: 'nginx', + name: 'nginx.ingress_controller.geoip.region_iso_code', + type: 'alias', + }, + 'osquery.result.name': { + category: 'osquery', + description: 'The name of the query that generated this event. ', + name: 'osquery.result.name', + type: 'keyword', + }, + 'osquery.result.action': { + category: 'osquery', + description: + 'For incremental data, marks whether the entry was added or removed. It can be one of "added", "removed", or "snapshot". ', + name: 'osquery.result.action', + type: 'keyword', + }, + 'osquery.result.host_identifier': { + category: 'osquery', + description: + 'The identifier for the host on which the osquery agent is running. Normally the hostname. ', + name: 'osquery.result.host_identifier', + type: 'keyword', + }, + 'osquery.result.unix_time': { + category: 'osquery', + description: + 'Unix timestamp of the event, in seconds since the epoch. Used for computing the `@timestamp` column. ', + name: 'osquery.result.unix_time', + type: 'long', + }, + 'osquery.result.calendar_time': { + category: 'osquery', + description: 'String representation of the collection time, as formatted by osquery. ', + name: 'osquery.result.calendar_time', + type: 'keyword', + }, + 'postgresql.log.timestamp': { + category: 'postgresql', + description: 'The timestamp from the log line. ', + name: 'postgresql.log.timestamp', + }, + 'postgresql.log.core_id': { + category: 'postgresql', + description: 'Core id ', + name: 'postgresql.log.core_id', + type: 'long', + }, + 'postgresql.log.database': { + category: 'postgresql', + description: 'Name of database ', + example: 'mydb', + name: 'postgresql.log.database', + }, + 'postgresql.log.query': { + category: 'postgresql', + description: 'Query statement. ', + example: 'SELECT * FROM users;', + name: 'postgresql.log.query', + }, + 'postgresql.log.query_step': { + category: 'postgresql', + description: + 'Statement step when using extended query protocol (one of statement, parse, bind or execute) ', + example: 'parse', + name: 'postgresql.log.query_step', + }, + 'postgresql.log.query_name': { + category: 'postgresql', + description: + 'Name given to a query when using extended query protocol. If it is "", or not present, this field is ignored. ', + example: 'pdo_stmt_00000001', + name: 'postgresql.log.query_name', + }, + 'postgresql.log.error.code': { + category: 'postgresql', + description: 'Error code returned by Postgres (if any)', + name: 'postgresql.log.error.code', + type: 'long', + }, + 'postgresql.log.timezone': { + category: 'postgresql', + name: 'postgresql.log.timezone', + type: 'alias', + }, + 'postgresql.log.thread_id': { + category: 'postgresql', + name: 'postgresql.log.thread_id', + type: 'alias', + }, + 'postgresql.log.user': { + category: 'postgresql', + name: 'postgresql.log.user', + type: 'alias', + }, + 'postgresql.log.level': { + category: 'postgresql', + name: 'postgresql.log.level', + type: 'alias', + }, + 'postgresql.log.message': { + category: 'postgresql', + name: 'postgresql.log.message', + type: 'alias', + }, + 'redis.log.role': { + category: 'redis', + description: + 'The role of the Redis instance. Can be one of `master`, `slave`, `child` (for RDF/AOF writing child), or `sentinel`. ', + name: 'redis.log.role', + type: 'keyword', + }, + 'redis.log.pid': { + category: 'redis', + name: 'redis.log.pid', + type: 'alias', + }, + 'redis.log.level': { + category: 'redis', + name: 'redis.log.level', + type: 'alias', + }, + 'redis.log.message': { + category: 'redis', + name: 'redis.log.message', + type: 'alias', + }, + 'redis.slowlog.cmd': { + category: 'redis', + description: 'The command executed. ', + name: 'redis.slowlog.cmd', + type: 'keyword', + }, + 'redis.slowlog.duration.us': { + category: 'redis', + description: 'How long it took to execute the command in microseconds. ', + name: 'redis.slowlog.duration.us', + type: 'long', + }, + 'redis.slowlog.id': { + category: 'redis', + description: 'The ID of the query. ', + name: 'redis.slowlog.id', + type: 'long', + }, + 'redis.slowlog.key': { + category: 'redis', + description: 'The key on which the command was executed. ', + name: 'redis.slowlog.key', + type: 'keyword', + }, + 'redis.slowlog.args': { + category: 'redis', + description: 'The arguments with which the command was called. ', + name: 'redis.slowlog.args', + type: 'keyword', + }, + 'santa.action': { + category: 'santa', + description: 'Action', + example: 'EXEC', + name: 'santa.action', + type: 'keyword', + }, + 'santa.decision': { + category: 'santa', + description: 'Decision that santad took.', + example: 'ALLOW', + name: 'santa.decision', + type: 'keyword', + }, + 'santa.reason': { + category: 'santa', + description: 'Reason for the decsision.', + example: 'CERT', + name: 'santa.reason', + type: 'keyword', + }, + 'santa.mode': { + category: 'santa', + description: 'Operating mode of Santa.', + example: 'M', + name: 'santa.mode', + type: 'keyword', + }, + 'santa.disk.volume': { + category: 'santa', + description: 'The volume name.', + name: 'santa.disk.volume', + }, + 'santa.disk.bus': { + category: 'santa', + description: 'The disk bus protocol.', + name: 'santa.disk.bus', + }, + 'santa.disk.serial': { + category: 'santa', + description: 'The disk serial number.', + name: 'santa.disk.serial', + }, + 'santa.disk.bsdname': { + category: 'santa', + description: 'The disk BSD name.', + example: 'disk1s3', + name: 'santa.disk.bsdname', + }, + 'santa.disk.model': { + category: 'santa', + description: 'The disk model.', + example: 'APPLE SSD SM0512L', + name: 'santa.disk.model', + }, + 'santa.disk.fs': { + category: 'santa', + description: 'The disk volume kind (filesystem type).', + example: 'apfs', + name: 'santa.disk.fs', + }, + 'santa.disk.mount': { + category: 'santa', + description: 'The disk volume path.', + name: 'santa.disk.mount', + }, + 'santa.certificate.common_name': { + category: 'santa', + description: 'Common name from code signing certificate.', + name: 'santa.certificate.common_name', + type: 'keyword', + }, + 'santa.certificate.sha256': { + category: 'santa', + description: 'SHA256 hash of code signing certificate.', + name: 'santa.certificate.sha256', + type: 'keyword', + }, + 'system.auth.timestamp': { + category: 'system', + name: 'system.auth.timestamp', + type: 'alias', + }, + 'system.auth.hostname': { + category: 'system', + name: 'system.auth.hostname', + type: 'alias', + }, + 'system.auth.program': { + category: 'system', + name: 'system.auth.program', + type: 'alias', + }, + 'system.auth.pid': { + category: 'system', + name: 'system.auth.pid', + type: 'alias', + }, + 'system.auth.message': { + category: 'system', + name: 'system.auth.message', + type: 'alias', + }, + 'system.auth.user': { + category: 'system', + name: 'system.auth.user', + type: 'alias', + }, + 'system.auth.ssh.method': { + category: 'system', + description: 'The SSH authentication method. Can be one of "password" or "publickey". ', + name: 'system.auth.ssh.method', + }, + 'system.auth.ssh.signature': { + category: 'system', + description: 'The signature of the client public key. ', + name: 'system.auth.ssh.signature', + }, + 'system.auth.ssh.dropped_ip': { + category: 'system', + description: 'The client IP from SSH connections that are open and immediately dropped. ', + name: 'system.auth.ssh.dropped_ip', + type: 'ip', + }, + 'system.auth.ssh.event': { + category: 'system', + description: 'The SSH event as found in the logs (Accepted, Invalid, Failed, etc.) ', + example: 'Accepted', + name: 'system.auth.ssh.event', + }, + 'system.auth.ssh.ip': { + category: 'system', + name: 'system.auth.ssh.ip', + type: 'alias', + }, + 'system.auth.ssh.port': { + category: 'system', + name: 'system.auth.ssh.port', + type: 'alias', + }, + 'system.auth.ssh.geoip.continent_name': { + category: 'system', + name: 'system.auth.ssh.geoip.continent_name', + type: 'alias', + }, + 'system.auth.ssh.geoip.country_iso_code': { + category: 'system', + name: 'system.auth.ssh.geoip.country_iso_code', + type: 'alias', + }, + 'system.auth.ssh.geoip.location': { + category: 'system', + name: 'system.auth.ssh.geoip.location', + type: 'alias', + }, + 'system.auth.ssh.geoip.region_name': { + category: 'system', + name: 'system.auth.ssh.geoip.region_name', + type: 'alias', + }, + 'system.auth.ssh.geoip.city_name': { + category: 'system', + name: 'system.auth.ssh.geoip.city_name', + type: 'alias', + }, + 'system.auth.ssh.geoip.region_iso_code': { + category: 'system', + name: 'system.auth.ssh.geoip.region_iso_code', + type: 'alias', + }, + 'system.auth.sudo.error': { + category: 'system', + description: 'The error message in case the sudo command failed. ', + example: 'user NOT in sudoers', + name: 'system.auth.sudo.error', + }, + 'system.auth.sudo.tty': { + category: 'system', + description: 'The TTY where the sudo command is executed. ', + name: 'system.auth.sudo.tty', + }, + 'system.auth.sudo.pwd': { + category: 'system', + description: 'The current directory where the sudo command is executed. ', + name: 'system.auth.sudo.pwd', + }, + 'system.auth.sudo.user': { + category: 'system', + description: 'The target user to which the sudo command is switching. ', + example: 'root', + name: 'system.auth.sudo.user', + }, + 'system.auth.sudo.command': { + category: 'system', + description: 'The command executed via sudo. ', + name: 'system.auth.sudo.command', + }, + 'system.auth.useradd.home': { + category: 'system', + description: 'The home folder for the new user.', + name: 'system.auth.useradd.home', + }, + 'system.auth.useradd.shell': { + category: 'system', + description: 'The default shell for the new user.', + name: 'system.auth.useradd.shell', + }, + 'system.auth.useradd.name': { + category: 'system', + name: 'system.auth.useradd.name', + type: 'alias', + }, + 'system.auth.useradd.uid': { + category: 'system', + name: 'system.auth.useradd.uid', + type: 'alias', + }, + 'system.auth.useradd.gid': { + category: 'system', + name: 'system.auth.useradd.gid', + type: 'alias', + }, + 'system.auth.groupadd.name': { + category: 'system', + name: 'system.auth.groupadd.name', + type: 'alias', + }, + 'system.auth.groupadd.gid': { + category: 'system', + name: 'system.auth.groupadd.gid', + type: 'alias', + }, + 'system.syslog.timestamp': { + category: 'system', + name: 'system.syslog.timestamp', + type: 'alias', + }, + 'system.syslog.hostname': { + category: 'system', + name: 'system.syslog.hostname', + type: 'alias', + }, + 'system.syslog.program': { + category: 'system', + name: 'system.syslog.program', + type: 'alias', + }, + 'system.syslog.pid': { + category: 'system', + name: 'system.syslog.pid', + type: 'alias', + }, + 'system.syslog.message': { + category: 'system', + name: 'system.syslog.message', + type: 'alias', + }, + 'traefik.access.user_identifier': { + category: 'traefik', + description: 'Is the RFC 1413 identity of the client ', + name: 'traefik.access.user_identifier', + type: 'keyword', + }, + 'traefik.access.request_count': { + category: 'traefik', + description: 'The number of requests ', + name: 'traefik.access.request_count', + type: 'long', + }, + 'traefik.access.frontend_name': { + category: 'traefik', + description: 'The name of the frontend used ', + name: 'traefik.access.frontend_name', + type: 'keyword', + }, + 'traefik.access.backend_url': { + category: 'traefik', + description: 'The url of the backend where request is forwarded', + name: 'traefik.access.backend_url', + type: 'keyword', + }, + 'traefik.access.body_sent.bytes': { + category: 'traefik', + name: 'traefik.access.body_sent.bytes', + type: 'alias', + }, + 'traefik.access.remote_ip': { + category: 'traefik', + name: 'traefik.access.remote_ip', + type: 'alias', + }, + 'traefik.access.user_name': { + category: 'traefik', + name: 'traefik.access.user_name', + type: 'alias', + }, + 'traefik.access.method': { + category: 'traefik', + name: 'traefik.access.method', + type: 'alias', + }, + 'traefik.access.url': { + category: 'traefik', + name: 'traefik.access.url', + type: 'alias', + }, + 'traefik.access.http_version': { + category: 'traefik', + name: 'traefik.access.http_version', + type: 'alias', + }, + 'traefik.access.response_code': { + category: 'traefik', + name: 'traefik.access.response_code', + type: 'alias', + }, + 'traefik.access.referrer': { + category: 'traefik', + name: 'traefik.access.referrer', + type: 'alias', + }, + 'traefik.access.agent': { + category: 'traefik', + name: 'traefik.access.agent', + type: 'alias', + }, + 'traefik.access.user_agent.device': { + category: 'traefik', + name: 'traefik.access.user_agent.device', + type: 'alias', + }, + 'traefik.access.user_agent.name': { + category: 'traefik', + name: 'traefik.access.user_agent.name', + type: 'alias', + }, + 'traefik.access.user_agent.os': { + category: 'traefik', + name: 'traefik.access.user_agent.os', + type: 'alias', + }, + 'traefik.access.user_agent.os_name': { + category: 'traefik', + name: 'traefik.access.user_agent.os_name', + type: 'alias', + }, + 'traefik.access.user_agent.original': { + category: 'traefik', + name: 'traefik.access.user_agent.original', + type: 'alias', + }, + 'traefik.access.geoip.continent_name': { + category: 'traefik', + name: 'traefik.access.geoip.continent_name', + type: 'alias', + }, + 'traefik.access.geoip.country_iso_code': { + category: 'traefik', + name: 'traefik.access.geoip.country_iso_code', + type: 'alias', + }, + 'traefik.access.geoip.location': { + category: 'traefik', + name: 'traefik.access.geoip.location', + type: 'alias', + }, + 'traefik.access.geoip.region_name': { + category: 'traefik', + name: 'traefik.access.geoip.region_name', + type: 'alias', + }, + 'traefik.access.geoip.city_name': { + category: 'traefik', + name: 'traefik.access.geoip.city_name', + type: 'alias', + }, + 'traefik.access.geoip.region_iso_code': { + category: 'traefik', + name: 'traefik.access.geoip.region_iso_code', + type: 'alias', + }, + 'activemq.caller': { + category: 'activemq', + description: 'Name of the caller issuing the logging request (class or resource). ', + name: 'activemq.caller', + type: 'keyword', + }, + 'activemq.thread': { + category: 'activemq', + description: 'Thread that generated the logging event. ', + name: 'activemq.thread', + type: 'keyword', + }, + 'activemq.user': { + category: 'activemq', + description: 'User that generated the logging event. ', + name: 'activemq.user', + type: 'keyword', + }, + 'activemq.audit': { + category: 'activemq', + description: 'Fields from ActiveMQ audit logs. ', + name: 'activemq.audit', + type: 'group', + }, + 'activemq.log.stack_trace': { + category: 'activemq', + name: 'activemq.log.stack_trace', + type: 'keyword', + }, + 'aws.cloudtrail.event_version': { + category: 'aws', + description: 'The CloudTrail version of the log event format. ', + name: 'aws.cloudtrail.event_version', + type: 'keyword', + }, + 'aws.cloudtrail.user_identity.type': { + category: 'aws', + description: 'The type of the identity ', + name: 'aws.cloudtrail.user_identity.type', + type: 'keyword', + }, + 'aws.cloudtrail.user_identity.arn': { + category: 'aws', + description: 'The Amazon Resource Name (ARN) of the principal that made the call.', + name: 'aws.cloudtrail.user_identity.arn', + type: 'keyword', + }, + 'aws.cloudtrail.user_identity.access_key_id': { + category: 'aws', + description: 'The access key ID that was used to sign the request.', + name: 'aws.cloudtrail.user_identity.access_key_id', + type: 'keyword', + }, + 'aws.cloudtrail.user_identity.session_context.mfa_authenticated': { + category: 'aws', + description: + 'The value is true if the root user or IAM user whose credentials were used for the request also was authenticated with an MFA device; otherwise, false.', + name: 'aws.cloudtrail.user_identity.session_context.mfa_authenticated', + type: 'keyword', + }, + 'aws.cloudtrail.user_identity.session_context.creation_date': { + category: 'aws', + description: 'The date and time when the temporary security credentials were issued.', + name: 'aws.cloudtrail.user_identity.session_context.creation_date', + type: 'date', + }, + 'aws.cloudtrail.user_identity.session_context.session_issuer.type': { + category: 'aws', + description: + 'The source of the temporary security credentials, such as Root, IAMUser, or Role.', + name: 'aws.cloudtrail.user_identity.session_context.session_issuer.type', + type: 'keyword', + }, + 'aws.cloudtrail.user_identity.session_context.session_issuer.principal_id': { + category: 'aws', + description: 'The internal ID of the entity that was used to get credentials.', + name: 'aws.cloudtrail.user_identity.session_context.session_issuer.principal_id', + type: 'keyword', + }, + 'aws.cloudtrail.user_identity.session_context.session_issuer.arn': { + category: 'aws', + description: + 'The ARN of the source (account, IAM user, or role) that was used to get temporary security credentials.', + name: 'aws.cloudtrail.user_identity.session_context.session_issuer.arn', + type: 'keyword', + }, + 'aws.cloudtrail.user_identity.session_context.session_issuer.account_id': { + category: 'aws', + description: 'The account that owns the entity that was used to get credentials.', + name: 'aws.cloudtrail.user_identity.session_context.session_issuer.account_id', + type: 'keyword', + }, + 'aws.cloudtrail.user_identity.invoked_by': { + category: 'aws', + description: + 'The name of the AWS service that made the request, such as Amazon EC2 Auto Scaling or AWS Elastic Beanstalk.', + name: 'aws.cloudtrail.user_identity.invoked_by', + type: 'keyword', + }, + 'aws.cloudtrail.error_code': { + category: 'aws', + description: 'The AWS service error if the request returns an error.', + name: 'aws.cloudtrail.error_code', + type: 'keyword', + }, + 'aws.cloudtrail.error_message': { + category: 'aws', + description: 'If the request returns an error, the description of the error.', + name: 'aws.cloudtrail.error_message', + type: 'keyword', + }, + 'aws.cloudtrail.request_parameters': { + category: 'aws', + description: 'The parameters, if any, that were sent with the request.', + name: 'aws.cloudtrail.request_parameters', + type: 'keyword', + }, + 'aws.cloudtrail.response_elements': { + category: 'aws', + description: + 'The response element for actions that make changes (create, update, or delete actions).', + name: 'aws.cloudtrail.response_elements', + type: 'keyword', + }, + 'aws.cloudtrail.additional_eventdata': { + category: 'aws', + description: 'Additional data about the event that was not part of the request or response.', + name: 'aws.cloudtrail.additional_eventdata', + type: 'keyword', + }, + 'aws.cloudtrail.request_id': { + category: 'aws', + description: + 'The value that identifies the request. The service being called generates this value.', + name: 'aws.cloudtrail.request_id', + type: 'keyword', + }, + 'aws.cloudtrail.event_type': { + category: 'aws', + description: 'Identifies the type of event that generated the event record.', + name: 'aws.cloudtrail.event_type', + type: 'keyword', + }, + 'aws.cloudtrail.api_version': { + category: 'aws', + description: 'Identifies the API version associated with the AwsApiCall eventType value.', + name: 'aws.cloudtrail.api_version', + type: 'keyword', + }, + 'aws.cloudtrail.management_event': { + category: 'aws', + description: 'A Boolean value that identifies whether the event is a management event.', + name: 'aws.cloudtrail.management_event', + type: 'keyword', + }, + 'aws.cloudtrail.read_only': { + category: 'aws', + description: 'Identifies whether this operation is a read-only operation.', + name: 'aws.cloudtrail.read_only', + type: 'keyword', + }, + 'aws.cloudtrail.resources.arn': { + category: 'aws', + description: 'Resource ARNs', + name: 'aws.cloudtrail.resources.arn', + type: 'keyword', + }, + 'aws.cloudtrail.resources.account_id': { + category: 'aws', + description: 'Account ID of the resource owner', + name: 'aws.cloudtrail.resources.account_id', + type: 'keyword', + }, + 'aws.cloudtrail.resources.type': { + category: 'aws', + description: 'Resource type identifier in the format: AWS::aws-service-name::data-type-name', + name: 'aws.cloudtrail.resources.type', + type: 'keyword', + }, + 'aws.cloudtrail.recipient_account_id': { + category: 'aws', + description: 'Represents the account ID that received this event.', + name: 'aws.cloudtrail.recipient_account_id', + type: 'keyword', + }, + 'aws.cloudtrail.service_event_details': { + category: 'aws', + description: 'Identifies the service event, including what triggered the event and the result.', + name: 'aws.cloudtrail.service_event_details', + type: 'keyword', + }, + 'aws.cloudtrail.shared_event_id': { + category: 'aws', + description: + 'GUID generated by CloudTrail to uniquely identify CloudTrail events from the same AWS action that is sent to different AWS accounts.', + name: 'aws.cloudtrail.shared_event_id', + type: 'keyword', + }, + 'aws.cloudtrail.vpc_endpoint_id': { + category: 'aws', + description: + 'Identifies the VPC endpoint in which requests were made from a VPC to another AWS service, such as Amazon S3.', + name: 'aws.cloudtrail.vpc_endpoint_id', + type: 'keyword', + }, + 'aws.cloudtrail.console_login.additional_eventdata.mobile_version': { + category: 'aws', + description: 'Identifies whether ConsoleLogin was from mobile version', + name: 'aws.cloudtrail.console_login.additional_eventdata.mobile_version', + type: 'boolean', + }, + 'aws.cloudtrail.console_login.additional_eventdata.login_to': { + category: 'aws', + description: 'URL for ConsoleLogin', + name: 'aws.cloudtrail.console_login.additional_eventdata.login_to', + type: 'keyword', + }, + 'aws.cloudtrail.console_login.additional_eventdata.mfa_used': { + category: 'aws', + description: 'Identifies whether multi factor authentication was used during ConsoleLogin', + name: 'aws.cloudtrail.console_login.additional_eventdata.mfa_used', + type: 'boolean', + }, + 'aws.cloudtrail.flattened.additional_eventdata': { + category: 'aws', + description: 'Additional data about the event that was not part of the request or response. ', + name: 'aws.cloudtrail.flattened.additional_eventdata', + type: 'flattened', + }, + 'aws.cloudtrail.flattened.request_parameters': { + category: 'aws', + description: 'The parameters, if any, that were sent with the request.', + name: 'aws.cloudtrail.flattened.request_parameters', + type: 'flattened', + }, + 'aws.cloudtrail.flattened.response_elements': { + category: 'aws', + description: + 'The response element for actions that make changes (create, update, or delete actions).', + name: 'aws.cloudtrail.flattened.response_elements', + type: 'flattened', + }, + 'aws.cloudtrail.flattened.service_event_details': { + category: 'aws', + description: 'Identifies the service event, including what triggered the event and the result.', + name: 'aws.cloudtrail.flattened.service_event_details', + type: 'flattened', + }, + 'aws.cloudwatch.message': { + category: 'aws', + description: 'CloudWatch log message. ', + name: 'aws.cloudwatch.message', + type: 'text', + }, + 'aws.ec2.ip_address': { + category: 'aws', + description: 'The internet address of the requester. ', + name: 'aws.ec2.ip_address', + type: 'keyword', + }, + 'aws.elb.name': { + category: 'aws', + description: 'The name of the load balancer. ', + name: 'aws.elb.name', + type: 'keyword', + }, + 'aws.elb.type': { + category: 'aws', + description: 'The type of the load balancer for v2 Load Balancers. ', + name: 'aws.elb.type', + type: 'keyword', + }, + 'aws.elb.target_group.arn': { + category: 'aws', + description: 'The ARN of the target group handling the request. ', + name: 'aws.elb.target_group.arn', + type: 'keyword', + }, + 'aws.elb.listener': { + category: 'aws', + description: 'The ELB listener that received the connection. ', + name: 'aws.elb.listener', + type: 'keyword', + }, + 'aws.elb.protocol': { + category: 'aws', + description: 'The protocol of the load balancer (http or tcp). ', + name: 'aws.elb.protocol', + type: 'keyword', + }, + 'aws.elb.request_processing_time.sec': { + category: 'aws', + description: + 'The total time in seconds since the connection or request is received until it is sent to a registered backend. ', + name: 'aws.elb.request_processing_time.sec', + type: 'float', + }, + 'aws.elb.backend_processing_time.sec': { + category: 'aws', + description: + 'The total time in seconds since the connection is sent to the backend till the backend starts responding. ', + name: 'aws.elb.backend_processing_time.sec', + type: 'float', + }, + 'aws.elb.response_processing_time.sec': { + category: 'aws', + description: + 'The total time in seconds since the response is received from the backend till it is sent to the client. ', + name: 'aws.elb.response_processing_time.sec', + type: 'float', + }, + 'aws.elb.connection_time.ms': { + category: 'aws', + description: + 'The total time of the connection in milliseconds, since it is opened till it is closed. ', + name: 'aws.elb.connection_time.ms', + type: 'long', + }, + 'aws.elb.tls_handshake_time.ms': { + category: 'aws', + description: + 'The total time for the TLS handshake to complete in milliseconds once the connection has been established. ', + name: 'aws.elb.tls_handshake_time.ms', + type: 'long', + }, + 'aws.elb.backend.ip': { + category: 'aws', + description: 'The IP address of the backend processing this connection. ', + name: 'aws.elb.backend.ip', + type: 'keyword', + }, + 'aws.elb.backend.port': { + category: 'aws', + description: 'The port in the backend processing this connection. ', + name: 'aws.elb.backend.port', + type: 'keyword', + }, + 'aws.elb.backend.http.response.status_code': { + category: 'aws', + description: + 'The status code from the backend (status code sent to the client from ELB is stored in `http.response.status_code` ', + name: 'aws.elb.backend.http.response.status_code', + type: 'keyword', + }, + 'aws.elb.ssl_cipher': { + category: 'aws', + description: 'The SSL cipher used in TLS/SSL connections. ', + name: 'aws.elb.ssl_cipher', + type: 'keyword', + }, + 'aws.elb.ssl_protocol': { + category: 'aws', + description: 'The SSL protocol used in TLS/SSL connections. ', + name: 'aws.elb.ssl_protocol', + type: 'keyword', + }, + 'aws.elb.chosen_cert.arn': { + category: 'aws', + description: + 'The ARN of the chosen certificate presented to the client in TLS/SSL connections. ', + name: 'aws.elb.chosen_cert.arn', + type: 'keyword', + }, + 'aws.elb.chosen_cert.serial': { + category: 'aws', + description: + 'The serial number of the chosen certificate presented to the client in TLS/SSL connections. ', + name: 'aws.elb.chosen_cert.serial', + type: 'keyword', + }, + 'aws.elb.incoming_tls_alert': { + category: 'aws', + description: + 'The integer value of TLS alerts received by the load balancer from the client, if present. ', + name: 'aws.elb.incoming_tls_alert', + type: 'keyword', + }, + 'aws.elb.tls_named_group': { + category: 'aws', + description: 'The TLS named group. ', + name: 'aws.elb.tls_named_group', + type: 'keyword', + }, + 'aws.elb.trace_id': { + category: 'aws', + description: 'The contents of the `X-Amzn-Trace-Id` header. ', + name: 'aws.elb.trace_id', + type: 'keyword', + }, + 'aws.elb.matched_rule_priority': { + category: 'aws', + description: 'The priority value of the rule that matched the request, if a rule matched. ', + name: 'aws.elb.matched_rule_priority', + type: 'keyword', + }, + 'aws.elb.action_executed': { + category: 'aws', + description: + 'The action executed when processing the request (forward, fixed-response, authenticate...). It can contain several values. ', + name: 'aws.elb.action_executed', + type: 'keyword', + }, + 'aws.elb.redirect_url': { + category: 'aws', + description: 'The URL used if a redirection action was executed. ', + name: 'aws.elb.redirect_url', + type: 'keyword', + }, + 'aws.elb.error.reason': { + category: 'aws', + description: 'The error reason if the executed action failed. ', + name: 'aws.elb.error.reason', + type: 'keyword', + }, + 'aws.s3access.bucket_owner': { + category: 'aws', + description: 'The canonical user ID of the owner of the source bucket. ', + name: 'aws.s3access.bucket_owner', + type: 'keyword', + }, + 'aws.s3access.bucket': { + category: 'aws', + description: 'The name of the bucket that the request was processed against. ', + name: 'aws.s3access.bucket', + type: 'keyword', + }, + 'aws.s3access.remote_ip': { + category: 'aws', + description: 'The apparent internet address of the requester. ', + name: 'aws.s3access.remote_ip', + type: 'ip', + }, + 'aws.s3access.requester': { + category: 'aws', + description: 'The canonical user ID of the requester, or a - for unauthenticated requests. ', + name: 'aws.s3access.requester', + type: 'keyword', + }, + 'aws.s3access.request_id': { + category: 'aws', + description: 'A string generated by Amazon S3 to uniquely identify each request. ', + name: 'aws.s3access.request_id', + type: 'keyword', + }, + 'aws.s3access.operation': { + category: 'aws', + description: + 'The operation listed here is declared as SOAP.operation, REST.HTTP_method.resource_type, WEBSITE.HTTP_method.resource_type, or BATCH.DELETE.OBJECT. ', + name: 'aws.s3access.operation', + type: 'keyword', + }, + 'aws.s3access.key': { + category: 'aws', + description: + 'The "key" part of the request, URL encoded, or "-" if the operation does not take a key parameter. ', + name: 'aws.s3access.key', + type: 'keyword', + }, + 'aws.s3access.request_uri': { + category: 'aws', + description: 'The Request-URI part of the HTTP request message. ', + name: 'aws.s3access.request_uri', + type: 'keyword', + }, + 'aws.s3access.http_status': { + category: 'aws', + description: 'The numeric HTTP status code of the response. ', + name: 'aws.s3access.http_status', + type: 'long', + }, + 'aws.s3access.error_code': { + category: 'aws', + description: 'The Amazon S3 Error Code, or "-" if no error occurred. ', + name: 'aws.s3access.error_code', + type: 'keyword', + }, + 'aws.s3access.bytes_sent': { + category: 'aws', + description: + 'The number of response bytes sent, excluding HTTP protocol overhead, or "-" if zero. ', + name: 'aws.s3access.bytes_sent', + type: 'long', + }, + 'aws.s3access.object_size': { + category: 'aws', + description: 'The total size of the object in question. ', + name: 'aws.s3access.object_size', + type: 'long', + }, + 'aws.s3access.total_time': { + category: 'aws', + description: + "The number of milliseconds the request was in flight from the server's perspective. ", + name: 'aws.s3access.total_time', + type: 'long', + }, + 'aws.s3access.turn_around_time': { + category: 'aws', + description: 'The number of milliseconds that Amazon S3 spent processing your request. ', + name: 'aws.s3access.turn_around_time', + type: 'long', + }, + 'aws.s3access.referrer': { + category: 'aws', + description: 'The value of the HTTP Referrer header, if present. ', + name: 'aws.s3access.referrer', + type: 'keyword', + }, + 'aws.s3access.user_agent': { + category: 'aws', + description: 'The value of the HTTP User-Agent header. ', + name: 'aws.s3access.user_agent', + type: 'keyword', + }, + 'aws.s3access.version_id': { + category: 'aws', + description: + 'The version ID in the request, or "-" if the operation does not take a versionId parameter. ', + name: 'aws.s3access.version_id', + type: 'keyword', + }, + 'aws.s3access.host_id': { + category: 'aws', + description: 'The x-amz-id-2 or Amazon S3 extended request ID. ', + name: 'aws.s3access.host_id', + type: 'keyword', + }, + 'aws.s3access.signature_version': { + category: 'aws', + description: + 'The signature version, SigV2 or SigV4, that was used to authenticate the request or a - for unauthenticated requests. ', + name: 'aws.s3access.signature_version', + type: 'keyword', + }, + 'aws.s3access.cipher_suite': { + category: 'aws', + description: + 'The Secure Sockets Layer (SSL) cipher that was negotiated for HTTPS request or a - for HTTP. ', + name: 'aws.s3access.cipher_suite', + type: 'keyword', + }, + 'aws.s3access.authentication_type': { + category: 'aws', + description: + 'The type of request authentication used, AuthHeader for authentication headers, QueryString for query string (pre-signed URL) or a - for unauthenticated requests. ', + name: 'aws.s3access.authentication_type', + type: 'keyword', + }, + 'aws.s3access.host_header': { + category: 'aws', + description: 'The endpoint used to connect to Amazon S3. ', + name: 'aws.s3access.host_header', + type: 'keyword', + }, + 'aws.s3access.tls_version': { + category: 'aws', + description: 'The Transport Layer Security (TLS) version negotiated by the client. ', + name: 'aws.s3access.tls_version', + type: 'keyword', + }, + 'aws.vpcflow.version': { + category: 'aws', + description: + 'The VPC Flow Logs version. If you use the default format, the version is 2. If you specify a custom format, the version is 3. ', + name: 'aws.vpcflow.version', + type: 'keyword', + }, + 'aws.vpcflow.account_id': { + category: 'aws', + description: 'The AWS account ID for the flow log. ', + name: 'aws.vpcflow.account_id', + type: 'keyword', + }, + 'aws.vpcflow.interface_id': { + category: 'aws', + description: 'The ID of the network interface for which the traffic is recorded. ', + name: 'aws.vpcflow.interface_id', + type: 'keyword', + }, + 'aws.vpcflow.action': { + category: 'aws', + description: 'The action that is associated with the traffic, ACCEPT or REJECT. ', + name: 'aws.vpcflow.action', + type: 'keyword', + }, + 'aws.vpcflow.log_status': { + category: 'aws', + description: 'The logging status of the flow log, OK, NODATA or SKIPDATA. ', + name: 'aws.vpcflow.log_status', + type: 'keyword', + }, + 'aws.vpcflow.instance_id': { + category: 'aws', + description: + "The ID of the instance that's associated with network interface for which the traffic is recorded, if the instance is owned by you. ", + name: 'aws.vpcflow.instance_id', + type: 'keyword', + }, + 'aws.vpcflow.pkt_srcaddr': { + category: 'aws', + description: 'The packet-level (original) source IP address of the traffic. ', + name: 'aws.vpcflow.pkt_srcaddr', + type: 'ip', + }, + 'aws.vpcflow.pkt_dstaddr': { + category: 'aws', + description: 'The packet-level (original) destination IP address for the traffic. ', + name: 'aws.vpcflow.pkt_dstaddr', + type: 'ip', + }, + 'aws.vpcflow.vpc_id': { + category: 'aws', + description: + 'The ID of the VPC that contains the network interface for which the traffic is recorded. ', + name: 'aws.vpcflow.vpc_id', + type: 'keyword', + }, + 'aws.vpcflow.subnet_id': { + category: 'aws', + description: + 'The ID of the subnet that contains the network interface for which the traffic is recorded. ', + name: 'aws.vpcflow.subnet_id', + type: 'keyword', + }, + 'aws.vpcflow.tcp_flags': { + category: 'aws', + description: 'The bitmask value for the following TCP flags: 2=SYN,18=SYN-ACK,1=FIN,4=RST ', + name: 'aws.vpcflow.tcp_flags', + type: 'keyword', + }, + 'aws.vpcflow.type': { + category: 'aws', + description: 'The type of traffic: IPv4, IPv6, or EFA. ', + name: 'aws.vpcflow.type', + type: 'keyword', + }, + 'azure.subscription_id': { + category: 'azure', + description: 'Azure subscription ID ', + name: 'azure.subscription_id', + type: 'keyword', + }, + 'azure.correlation_id': { + category: 'azure', + description: 'Correlation ID ', + name: 'azure.correlation_id', + type: 'keyword', + }, + 'azure.tenant_id': { + category: 'azure', + description: 'tenant ID ', + name: 'azure.tenant_id', + type: 'keyword', + }, + 'azure.resource.id': { + category: 'azure', + description: 'Resource ID ', + name: 'azure.resource.id', + type: 'keyword', + }, + 'azure.resource.group': { + category: 'azure', + description: 'Resource group ', + name: 'azure.resource.group', + type: 'keyword', + }, + 'azure.resource.provider': { + category: 'azure', + description: 'Resource type/namespace ', + name: 'azure.resource.provider', + type: 'keyword', + }, + 'azure.resource.namespace': { + category: 'azure', + description: 'Resource type/namespace ', + name: 'azure.resource.namespace', + type: 'keyword', + }, + 'azure.resource.name': { + category: 'azure', + description: 'Name ', + name: 'azure.resource.name', + type: 'keyword', + }, + 'azure.resource.authorization_rule': { + category: 'azure', + description: 'Authorization rule ', + name: 'azure.resource.authorization_rule', + type: 'keyword', + }, + 'azure.activitylogs.identity.claims_initiated_by_user.name': { + category: 'azure', + description: 'Name ', + name: 'azure.activitylogs.identity.claims_initiated_by_user.name', + type: 'keyword', + }, + 'azure.activitylogs.identity.claims_initiated_by_user.givenname': { + category: 'azure', + description: 'Givenname ', + name: 'azure.activitylogs.identity.claims_initiated_by_user.givenname', + type: 'keyword', + }, + 'azure.activitylogs.identity.claims_initiated_by_user.surname': { + category: 'azure', + description: 'Surname ', + name: 'azure.activitylogs.identity.claims_initiated_by_user.surname', + type: 'keyword', + }, + 'azure.activitylogs.identity.claims_initiated_by_user.fullname': { + category: 'azure', + description: 'Fullname ', + name: 'azure.activitylogs.identity.claims_initiated_by_user.fullname', + type: 'keyword', + }, + 'azure.activitylogs.identity.claims_initiated_by_user.schema': { + category: 'azure', + description: 'Schema ', + name: 'azure.activitylogs.identity.claims_initiated_by_user.schema', + type: 'keyword', + }, + 'azure.activitylogs.identity.claims.*': { + category: 'azure', + description: 'Claims ', + name: 'azure.activitylogs.identity.claims.*', + type: 'object', + }, + 'azure.activitylogs.identity.authorization.scope': { + category: 'azure', + description: 'Scope ', + name: 'azure.activitylogs.identity.authorization.scope', + type: 'keyword', + }, + 'azure.activitylogs.identity.authorization.action': { + category: 'azure', + description: 'Action ', + name: 'azure.activitylogs.identity.authorization.action', + type: 'keyword', + }, + 'azure.activitylogs.identity.authorization.evidence.role_assignment_scope': { + category: 'azure', + description: 'Role assignment scope ', + name: 'azure.activitylogs.identity.authorization.evidence.role_assignment_scope', + type: 'keyword', + }, + 'azure.activitylogs.identity.authorization.evidence.role_definition_id': { + category: 'azure', + description: 'Role definition ID ', + name: 'azure.activitylogs.identity.authorization.evidence.role_definition_id', + type: 'keyword', + }, + 'azure.activitylogs.identity.authorization.evidence.role': { + category: 'azure', + description: 'Role ', + name: 'azure.activitylogs.identity.authorization.evidence.role', + type: 'keyword', + }, + 'azure.activitylogs.identity.authorization.evidence.role_assignment_id': { + category: 'azure', + description: 'Role assignment ID ', + name: 'azure.activitylogs.identity.authorization.evidence.role_assignment_id', + type: 'keyword', + }, + 'azure.activitylogs.identity.authorization.evidence.principal_id': { + category: 'azure', + description: 'Principal ID ', + name: 'azure.activitylogs.identity.authorization.evidence.principal_id', + type: 'keyword', + }, + 'azure.activitylogs.identity.authorization.evidence.principal_type': { + category: 'azure', + description: 'Principal type ', + name: 'azure.activitylogs.identity.authorization.evidence.principal_type', + type: 'keyword', + }, + 'azure.activitylogs.operation_name': { + category: 'azure', + description: 'Operation name ', + name: 'azure.activitylogs.operation_name', + type: 'keyword', + }, + 'azure.activitylogs.result_type': { + category: 'azure', + description: 'Result type ', + name: 'azure.activitylogs.result_type', + type: 'keyword', + }, + 'azure.activitylogs.result_signature': { + category: 'azure', + description: 'Result signature ', + name: 'azure.activitylogs.result_signature', + type: 'keyword', + }, + 'azure.activitylogs.category': { + category: 'azure', + description: 'Category ', + name: 'azure.activitylogs.category', + type: 'keyword', + }, + 'azure.activitylogs.event_category': { + category: 'azure', + description: 'Event Category ', + name: 'azure.activitylogs.event_category', + type: 'keyword', + }, + 'azure.activitylogs.properties.service_request_id': { + category: 'azure', + description: 'Service Request Id ', + name: 'azure.activitylogs.properties.service_request_id', + type: 'keyword', + }, + 'azure.activitylogs.properties.status_code': { + category: 'azure', + description: 'Status code ', + name: 'azure.activitylogs.properties.status_code', + type: 'keyword', + }, + 'azure.auditlogs.category': { + category: 'azure', + description: 'The category of the operation. Currently, Audit is the only supported value. ', + name: 'azure.auditlogs.category', + type: 'keyword', + }, + 'azure.auditlogs.operation_name': { + category: 'azure', + description: 'The operation name ', + name: 'azure.auditlogs.operation_name', + type: 'keyword', + }, + 'azure.auditlogs.operation_version': { + category: 'azure', + description: 'The operation version ', + name: 'azure.auditlogs.operation_version', + type: 'keyword', + }, + 'azure.auditlogs.identity': { + category: 'azure', + description: 'Identity ', + name: 'azure.auditlogs.identity', + type: 'keyword', + }, + 'azure.auditlogs.tenant_id': { + category: 'azure', + description: 'Tenant ID ', + name: 'azure.auditlogs.tenant_id', + type: 'keyword', + }, + 'azure.auditlogs.result_signature': { + category: 'azure', + description: 'Result signature ', + name: 'azure.auditlogs.result_signature', + type: 'keyword', + }, + 'azure.auditlogs.properties.result': { + category: 'azure', + description: 'Log result ', + name: 'azure.auditlogs.properties.result', + type: 'keyword', + }, + 'azure.auditlogs.properties.activity_display_name': { + category: 'azure', + description: 'Activity display name ', + name: 'azure.auditlogs.properties.activity_display_name', + type: 'keyword', + }, + 'azure.auditlogs.properties.result_reason': { + category: 'azure', + description: 'Reason for the log result ', + name: 'azure.auditlogs.properties.result_reason', + type: 'keyword', + }, + 'azure.auditlogs.properties.correlation_id': { + category: 'azure', + description: 'Correlation ID ', + name: 'azure.auditlogs.properties.correlation_id', + type: 'keyword', + }, + 'azure.auditlogs.properties.logged_by_service': { + category: 'azure', + description: 'Logged by service ', + name: 'azure.auditlogs.properties.logged_by_service', + type: 'keyword', + }, + 'azure.auditlogs.properties.operation_type': { + category: 'azure', + description: 'Operation type ', + name: 'azure.auditlogs.properties.operation_type', + type: 'keyword', + }, + 'azure.auditlogs.properties.id': { + category: 'azure', + description: 'ID ', + name: 'azure.auditlogs.properties.id', + type: 'keyword', + }, + 'azure.auditlogs.properties.activity_datetime': { + category: 'azure', + description: 'Activity timestamp ', + name: 'azure.auditlogs.properties.activity_datetime', + type: 'date', + }, + 'azure.auditlogs.properties.category': { + category: 'azure', + description: 'category ', + name: 'azure.auditlogs.properties.category', + type: 'keyword', + }, + 'azure.auditlogs.properties.target_resources.*.display_name': { + category: 'azure', + description: 'Display name ', + name: 'azure.auditlogs.properties.target_resources.*.display_name', + type: 'keyword', + }, + 'azure.auditlogs.properties.target_resources.*.id': { + category: 'azure', + description: 'ID ', + name: 'azure.auditlogs.properties.target_resources.*.id', + type: 'keyword', + }, + 'azure.auditlogs.properties.target_resources.*.type': { + category: 'azure', + description: 'Type ', + name: 'azure.auditlogs.properties.target_resources.*.type', + type: 'keyword', + }, + 'azure.auditlogs.properties.target_resources.*.ip_address': { + category: 'azure', + description: 'ip Address ', + name: 'azure.auditlogs.properties.target_resources.*.ip_address', + type: 'keyword', + }, + 'azure.auditlogs.properties.target_resources.*.user_principal_name': { + category: 'azure', + description: 'User principal name ', + name: 'azure.auditlogs.properties.target_resources.*.user_principal_name', + type: 'keyword', + }, + 'azure.auditlogs.properties.target_resources.*.modified_properties.*.new_value': { + category: 'azure', + description: 'New value ', + name: 'azure.auditlogs.properties.target_resources.*.modified_properties.*.new_value', + type: 'keyword', + }, + 'azure.auditlogs.properties.target_resources.*.modified_properties.*.display_name': { + category: 'azure', + description: 'Display value ', + name: 'azure.auditlogs.properties.target_resources.*.modified_properties.*.display_name', + type: 'keyword', + }, + 'azure.auditlogs.properties.target_resources.*.modified_properties.*.old_value': { + category: 'azure', + description: 'Old value ', + name: 'azure.auditlogs.properties.target_resources.*.modified_properties.*.old_value', + type: 'keyword', + }, + 'azure.auditlogs.properties.initiated_by.app.servicePrincipalName': { + category: 'azure', + description: 'Service principal name ', + name: 'azure.auditlogs.properties.initiated_by.app.servicePrincipalName', + type: 'keyword', + }, + 'azure.auditlogs.properties.initiated_by.app.displayName': { + category: 'azure', + description: 'Display name ', + name: 'azure.auditlogs.properties.initiated_by.app.displayName', + type: 'keyword', + }, + 'azure.auditlogs.properties.initiated_by.app.appId': { + category: 'azure', + description: 'App ID ', + name: 'azure.auditlogs.properties.initiated_by.app.appId', + type: 'keyword', + }, + 'azure.auditlogs.properties.initiated_by.app.servicePrincipalId': { + category: 'azure', + description: 'Service principal ID ', + name: 'azure.auditlogs.properties.initiated_by.app.servicePrincipalId', + type: 'keyword', + }, + 'azure.auditlogs.properties.initiated_by.user.userPrincipalName': { + category: 'azure', + description: 'User principal name ', + name: 'azure.auditlogs.properties.initiated_by.user.userPrincipalName', + type: 'keyword', + }, + 'azure.auditlogs.properties.initiated_by.user.displayName': { + category: 'azure', + description: 'Display name ', + name: 'azure.auditlogs.properties.initiated_by.user.displayName', + type: 'keyword', + }, + 'azure.auditlogs.properties.initiated_by.user.id': { + category: 'azure', + description: 'ID ', + name: 'azure.auditlogs.properties.initiated_by.user.id', + type: 'keyword', + }, + 'azure.auditlogs.properties.initiated_by.user.ipAddress': { + category: 'azure', + description: 'ip Address ', + name: 'azure.auditlogs.properties.initiated_by.user.ipAddress', + type: 'keyword', + }, + 'azure.signinlogs.operation_name': { + category: 'azure', + description: 'The operation name ', + name: 'azure.signinlogs.operation_name', + type: 'keyword', + }, + 'azure.signinlogs.operation_version': { + category: 'azure', + description: 'The operation version ', + name: 'azure.signinlogs.operation_version', + type: 'keyword', + }, + 'azure.signinlogs.tenant_id': { + category: 'azure', + description: 'Tenant ID ', + name: 'azure.signinlogs.tenant_id', + type: 'keyword', + }, + 'azure.signinlogs.result_signature': { + category: 'azure', + description: 'Result signature ', + name: 'azure.signinlogs.result_signature', + type: 'keyword', + }, + 'azure.signinlogs.result_description': { + category: 'azure', + description: 'Result description ', + name: 'azure.signinlogs.result_description', + type: 'keyword', + }, + 'azure.signinlogs.result_type': { + category: 'azure', + description: 'Result type ', + name: 'azure.signinlogs.result_type', + type: 'keyword', + }, + 'azure.signinlogs.identity': { + category: 'azure', + description: 'Identity ', + name: 'azure.signinlogs.identity', + type: 'keyword', + }, + 'azure.signinlogs.category': { + category: 'azure', + description: 'Category ', + name: 'azure.signinlogs.category', + type: 'keyword', + }, + 'azure.signinlogs.properties.id': { + category: 'azure', + description: 'ID ', + name: 'azure.signinlogs.properties.id', + type: 'keyword', + }, + 'azure.signinlogs.properties.created_at': { + category: 'azure', + description: 'Created date time ', + name: 'azure.signinlogs.properties.created_at', + type: 'date', + }, + 'azure.signinlogs.properties.user_display_name': { + category: 'azure', + description: 'User display name ', + name: 'azure.signinlogs.properties.user_display_name', + type: 'keyword', + }, + 'azure.signinlogs.properties.correlation_id': { + category: 'azure', + description: 'Correlation ID ', + name: 'azure.signinlogs.properties.correlation_id', + type: 'keyword', + }, + 'azure.signinlogs.properties.user_principal_name': { + category: 'azure', + description: 'User principal name ', + name: 'azure.signinlogs.properties.user_principal_name', + type: 'keyword', + }, + 'azure.signinlogs.properties.user_id': { + category: 'azure', + description: 'User ID ', + name: 'azure.signinlogs.properties.user_id', + type: 'keyword', + }, + 'azure.signinlogs.properties.app_id': { + category: 'azure', + description: 'App ID ', + name: 'azure.signinlogs.properties.app_id', + type: 'keyword', + }, + 'azure.signinlogs.properties.app_display_name': { + category: 'azure', + description: 'App display name ', + name: 'azure.signinlogs.properties.app_display_name', + type: 'keyword', + }, + 'azure.signinlogs.properties.ip_address': { + category: 'azure', + description: 'Ip address ', + name: 'azure.signinlogs.properties.ip_address', + type: 'keyword', + }, + 'azure.signinlogs.properties.client_app_used': { + category: 'azure', + description: 'Client app used ', + name: 'azure.signinlogs.properties.client_app_used', + type: 'keyword', + }, + 'azure.signinlogs.properties.conditional_access_status': { + category: 'azure', + description: 'Conditional access status ', + name: 'azure.signinlogs.properties.conditional_access_status', + type: 'keyword', + }, + 'azure.signinlogs.properties.original_request_id': { + category: 'azure', + description: 'Original request ID ', + name: 'azure.signinlogs.properties.original_request_id', + type: 'keyword', + }, + 'azure.signinlogs.properties.is_interactive': { + category: 'azure', + description: 'Is interactive ', + name: 'azure.signinlogs.properties.is_interactive', + type: 'keyword', + }, + 'azure.signinlogs.properties.token_issuer_name': { + category: 'azure', + description: 'Token issuer name ', + name: 'azure.signinlogs.properties.token_issuer_name', + type: 'keyword', + }, + 'azure.signinlogs.properties.token_issuer_type': { + category: 'azure', + description: 'Token issuer type ', + name: 'azure.signinlogs.properties.token_issuer_type', + type: 'keyword', + }, + 'azure.signinlogs.properties.processing_time_ms': { + category: 'azure', + description: 'Processing time in milliseconds ', + name: 'azure.signinlogs.properties.processing_time_ms', + type: 'float', + }, + 'azure.signinlogs.properties.risk_detail': { + category: 'azure', + description: 'Risk detail ', + name: 'azure.signinlogs.properties.risk_detail', + type: 'keyword', + }, + 'azure.signinlogs.properties.risk_level_aggregated': { + category: 'azure', + description: 'Risk level aggregated ', + name: 'azure.signinlogs.properties.risk_level_aggregated', + type: 'keyword', + }, + 'azure.signinlogs.properties.risk_level_during_signin': { + category: 'azure', + description: 'Risk level during signIn ', + name: 'azure.signinlogs.properties.risk_level_during_signin', + type: 'keyword', + }, + 'azure.signinlogs.properties.risk_state': { + category: 'azure', + description: 'Risk state ', + name: 'azure.signinlogs.properties.risk_state', + type: 'keyword', + }, + 'azure.signinlogs.properties.resource_display_name': { + category: 'azure', + description: 'Resource display name ', + name: 'azure.signinlogs.properties.resource_display_name', + type: 'keyword', + }, + 'azure.signinlogs.properties.status.error_code': { + category: 'azure', + description: 'Error code ', + name: 'azure.signinlogs.properties.status.error_code', + type: 'keyword', + }, + 'azure.signinlogs.properties.device_detail.device_id': { + category: 'azure', + description: 'Device ID ', + name: 'azure.signinlogs.properties.device_detail.device_id', + type: 'keyword', + }, + 'azure.signinlogs.properties.device_detail.operating_system': { + category: 'azure', + description: 'Operating system ', + name: 'azure.signinlogs.properties.device_detail.operating_system', + type: 'keyword', + }, + 'azure.signinlogs.properties.device_detail.browser': { + category: 'azure', + description: 'Browser ', + name: 'azure.signinlogs.properties.device_detail.browser', + type: 'keyword', + }, + 'azure.signinlogs.properties.device_detail.display_name': { + category: 'azure', + description: 'Display name ', + name: 'azure.signinlogs.properties.device_detail.display_name', + type: 'keyword', + }, + 'azure.signinlogs.properties.device_detail.trust_type': { + category: 'azure', + description: 'Trust type ', + name: 'azure.signinlogs.properties.device_detail.trust_type', + type: 'keyword', + }, + 'azure.signinlogs.properties.service_principal_id': { + category: 'azure', + description: 'Status ', + name: 'azure.signinlogs.properties.service_principal_id', + type: 'keyword', + }, + 'network.interface.name': { + category: 'network', + description: 'Name of the network interface where the traffic has been observed. ', + name: 'network.interface.name', + type: 'keyword', + }, + 'rsa.internal.msg': { + category: 'rsa', + description: 'This key is used to capture the raw message that comes into the Log Decoder', + name: 'rsa.internal.msg', + type: 'keyword', + }, + 'rsa.internal.messageid': { + category: 'rsa', + name: 'rsa.internal.messageid', + type: 'keyword', + }, + 'rsa.internal.event_desc': { + category: 'rsa', + name: 'rsa.internal.event_desc', + type: 'keyword', + }, + 'rsa.internal.message': { + category: 'rsa', + description: 'This key captures the contents of instant messages', + name: 'rsa.internal.message', + type: 'keyword', + }, + 'rsa.internal.time': { + category: 'rsa', + description: + 'This is the time at which a session hits a NetWitness Decoder. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness.', + name: 'rsa.internal.time', + type: 'date', + }, + 'rsa.internal.level': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.level', + type: 'long', + }, + 'rsa.internal.msg_id': { + category: 'rsa', + description: + 'This is the Message ID1 value that identifies the exact log parser definition which parses a particular log session. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.msg_id', + type: 'keyword', + }, + 'rsa.internal.msg_vid': { + category: 'rsa', + description: + 'This is the Message ID2 value that identifies the exact log parser definition which parses a particular log session. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.msg_vid', + type: 'keyword', + }, + 'rsa.internal.data': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.data', + type: 'keyword', + }, + 'rsa.internal.obj_server': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.obj_server', + type: 'keyword', + }, + 'rsa.internal.obj_val': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.obj_val', + type: 'keyword', + }, + 'rsa.internal.resource': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.resource', + type: 'keyword', + }, + 'rsa.internal.obj_id': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.obj_id', + type: 'keyword', + }, + 'rsa.internal.statement': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.statement', + type: 'keyword', + }, + 'rsa.internal.audit_class': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.audit_class', + type: 'keyword', + }, + 'rsa.internal.entry': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.entry', + type: 'keyword', + }, + 'rsa.internal.hcode': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.hcode', + type: 'keyword', + }, + 'rsa.internal.inode': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.inode', + type: 'long', + }, + 'rsa.internal.resource_class': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.resource_class', + type: 'keyword', + }, + 'rsa.internal.dead': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.dead', + type: 'long', + }, + 'rsa.internal.feed_desc': { + category: 'rsa', + description: + 'This is used to capture the description of the feed. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.feed_desc', + type: 'keyword', + }, + 'rsa.internal.feed_name': { + category: 'rsa', + description: + 'This is used to capture the name of the feed. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.feed_name', + type: 'keyword', + }, + 'rsa.internal.cid': { + category: 'rsa', + description: + 'This is the unique identifier used to identify a NetWitness Concentrator. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.cid', + type: 'keyword', + }, + 'rsa.internal.device_class': { + category: 'rsa', + description: + 'This is the Classification of the Log Event Source under a predefined fixed set of Event Source Classifications. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.device_class', + type: 'keyword', + }, + 'rsa.internal.device_group': { + category: 'rsa', + description: + 'This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.device_group', + type: 'keyword', + }, + 'rsa.internal.device_host': { + category: 'rsa', + description: + 'This is the Hostname of the log Event Source sending the logs to NetWitness. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.device_host', + type: 'keyword', + }, + 'rsa.internal.device_ip': { + category: 'rsa', + description: + 'This is the IPv4 address of the Log Event Source sending the logs to NetWitness. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.device_ip', + type: 'ip', + }, + 'rsa.internal.device_ipv6': { + category: 'rsa', + description: + 'This is the IPv6 address of the Log Event Source sending the logs to NetWitness. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.device_ipv6', + type: 'ip', + }, + 'rsa.internal.device_type': { + category: 'rsa', + description: + 'This is the name of the log parser which parsed a given session. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.device_type', + type: 'keyword', + }, + 'rsa.internal.device_type_id': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.device_type_id', + type: 'long', + }, + 'rsa.internal.did': { + category: 'rsa', + description: + 'This is the unique identifier used to identify a NetWitness Decoder. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.did', + type: 'keyword', + }, + 'rsa.internal.entropy_req': { + category: 'rsa', + description: + 'This key is only used by the Entropy Parser, the Meta Type can be either UInt16 or Float32 based on the configuration', + name: 'rsa.internal.entropy_req', + type: 'long', + }, + 'rsa.internal.entropy_res': { + category: 'rsa', + description: + 'This key is only used by the Entropy Parser, the Meta Type can be either UInt16 or Float32 based on the configuration', + name: 'rsa.internal.entropy_res', + type: 'long', + }, + 'rsa.internal.event_name': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.event_name', + type: 'keyword', + }, + 'rsa.internal.feed_category': { + category: 'rsa', + description: + 'This is used to capture the category of the feed. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.feed_category', + type: 'keyword', + }, + 'rsa.internal.forward_ip': { + category: 'rsa', + description: + 'This key should be used to capture the IPV4 address of a relay system which forwarded the events from the original system to NetWitness.', + name: 'rsa.internal.forward_ip', + type: 'ip', + }, + 'rsa.internal.forward_ipv6': { + category: 'rsa', + description: + 'This key is used to capture the IPV6 address of a relay system which forwarded the events from the original system to NetWitness. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.forward_ipv6', + type: 'ip', + }, + 'rsa.internal.header_id': { + category: 'rsa', + description: + 'This is the Header ID value that identifies the exact log parser header definition that parses a particular log session. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.header_id', + type: 'keyword', + }, + 'rsa.internal.lc_cid': { + category: 'rsa', + description: + 'This is a unique Identifier of a Log Collector. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.lc_cid', + type: 'keyword', + }, + 'rsa.internal.lc_ctime': { + category: 'rsa', + description: + 'This is the time at which a log is collected in a NetWitness Log Collector. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.lc_ctime', + type: 'date', + }, + 'rsa.internal.mcb_req': { + category: 'rsa', + description: + 'This key is only used by the Entropy Parser, the most common byte request is simply which byte for each side (0 thru 255) was seen the most', + name: 'rsa.internal.mcb_req', + type: 'long', + }, + 'rsa.internal.mcb_res': { + category: 'rsa', + description: + 'This key is only used by the Entropy Parser, the most common byte response is simply which byte for each side (0 thru 255) was seen the most', + name: 'rsa.internal.mcb_res', + type: 'long', + }, + 'rsa.internal.mcbc_req': { + category: 'rsa', + description: + 'This key is only used by the Entropy Parser, the most common byte count is the number of times the most common byte (above) was seen in the session streams', + name: 'rsa.internal.mcbc_req', + type: 'long', + }, + 'rsa.internal.mcbc_res': { + category: 'rsa', + description: + 'This key is only used by the Entropy Parser, the most common byte count is the number of times the most common byte (above) was seen in the session streams', + name: 'rsa.internal.mcbc_res', + type: 'long', + }, + 'rsa.internal.medium': { + category: 'rsa', + description: + 'This key is used to identify if it’s a log/packet session or Layer 2 Encapsulation Type. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness. 32 = log, 33 = correlation session, < 32 is packet session', + name: 'rsa.internal.medium', + type: 'long', + }, + 'rsa.internal.node_name': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.node_name', + type: 'keyword', + }, + 'rsa.internal.nwe_callback_id': { + category: 'rsa', + description: 'This key denotes that event is endpoint related', + name: 'rsa.internal.nwe_callback_id', + type: 'keyword', + }, + 'rsa.internal.parse_error': { + category: 'rsa', + description: + 'This is a special key that stores any Meta key validation error found while parsing a log session. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.parse_error', + type: 'keyword', + }, + 'rsa.internal.payload_req': { + category: 'rsa', + description: + 'This key is only used by the Entropy Parser, the payload size metrics are the payload sizes of each session side at the time of parsing. However, in order to keep', + name: 'rsa.internal.payload_req', + type: 'long', + }, + 'rsa.internal.payload_res': { + category: 'rsa', + description: + 'This key is only used by the Entropy Parser, the payload size metrics are the payload sizes of each session side at the time of parsing. However, in order to keep', + name: 'rsa.internal.payload_res', + type: 'long', + }, + 'rsa.internal.process_vid_dst': { + category: 'rsa', + description: + 'Endpoint generates and uses a unique virtual ID to identify any similar group of process. This ID represents the target process.', + name: 'rsa.internal.process_vid_dst', + type: 'keyword', + }, + 'rsa.internal.process_vid_src': { + category: 'rsa', + description: + 'Endpoint generates and uses a unique virtual ID to identify any similar group of process. This ID represents the source process.', + name: 'rsa.internal.process_vid_src', + type: 'keyword', + }, + 'rsa.internal.rid': { + category: 'rsa', + description: + 'This is a special ID of the Remote Session created by NetWitness Decoder. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.rid', + type: 'long', + }, + 'rsa.internal.session_split': { + category: 'rsa', + description: + 'This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.session_split', + type: 'keyword', + }, + 'rsa.internal.site': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.internal.site', + type: 'keyword', + }, + 'rsa.internal.size': { + category: 'rsa', + description: + 'This is the size of the session as seen by the NetWitness Decoder. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.size', + type: 'long', + }, + 'rsa.internal.sourcefile': { + category: 'rsa', + description: + 'This is the name of the log file or PCAPs that can be imported into NetWitness. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.internal.sourcefile', + type: 'keyword', + }, + 'rsa.internal.ubc_req': { + category: 'rsa', + description: + 'This key is only used by the Entropy Parser, Unique byte count is the number of unique bytes seen in each stream. 256 would mean all byte values of 0 thru 255 were seen at least once', + name: 'rsa.internal.ubc_req', + type: 'long', + }, + 'rsa.internal.ubc_res': { + category: 'rsa', + description: + 'This key is only used by the Entropy Parser, Unique byte count is the number of unique bytes seen in each stream. 256 would mean all byte values of 0 thru 255 were seen at least once', + name: 'rsa.internal.ubc_res', + type: 'long', + }, + 'rsa.internal.word': { + category: 'rsa', + description: + 'This is used by the Word Parsing technology to capture the first 5 character of every word in an unparsed log', + name: 'rsa.internal.word', + type: 'keyword', + }, + 'rsa.time.event_time': { + category: 'rsa', + description: + 'This key is used to capture the time mentioned in a raw session that represents the actual time an event occured in a standard normalized form', + name: 'rsa.time.event_time', + type: 'date', + }, + 'rsa.time.duration_time': { + category: 'rsa', + description: 'This key is used to capture the normalized duration/lifetime in seconds.', + name: 'rsa.time.duration_time', + type: 'double', + }, + 'rsa.time.event_time_str': { + category: 'rsa', + description: + 'This key is used to capture the incomplete time mentioned in a session as a string', + name: 'rsa.time.event_time_str', + type: 'keyword', + }, + 'rsa.time.starttime': { + category: 'rsa', + description: + 'This key is used to capture the Start time mentioned in a session in a standard form', + name: 'rsa.time.starttime', + type: 'date', + }, + 'rsa.time.month': { + category: 'rsa', + name: 'rsa.time.month', + type: 'keyword', + }, + 'rsa.time.day': { + category: 'rsa', + name: 'rsa.time.day', + type: 'keyword', + }, + 'rsa.time.endtime': { + category: 'rsa', + description: + 'This key is used to capture the End time mentioned in a session in a standard form', + name: 'rsa.time.endtime', + type: 'date', + }, + 'rsa.time.timezone': { + category: 'rsa', + description: 'This key is used to capture the timezone of the Event Time', + name: 'rsa.time.timezone', + type: 'keyword', + }, + 'rsa.time.duration_str': { + category: 'rsa', + description: 'A text string version of the duration', + name: 'rsa.time.duration_str', + type: 'keyword', + }, + 'rsa.time.date': { + category: 'rsa', + name: 'rsa.time.date', + type: 'keyword', + }, + 'rsa.time.year': { + category: 'rsa', + name: 'rsa.time.year', + type: 'keyword', + }, + 'rsa.time.recorded_time': { + category: 'rsa', + description: + "The event time as recorded by the system the event is collected from. The usage scenario is a multi-tier application where the management layer of the system records it's own timestamp at the time of collection from its child nodes. Must be in timestamp format.", + name: 'rsa.time.recorded_time', + type: 'date', + }, + 'rsa.time.datetime': { + category: 'rsa', + name: 'rsa.time.datetime', + type: 'keyword', + }, + 'rsa.time.effective_time': { + category: 'rsa', + description: + 'This key is the effective time referenced by an individual event in a Standard Timestamp format', + name: 'rsa.time.effective_time', + type: 'date', + }, + 'rsa.time.expire_time': { + category: 'rsa', + description: 'This key is the timestamp that explicitly refers to an expiration.', + name: 'rsa.time.expire_time', + type: 'date', + }, + 'rsa.time.process_time': { + category: 'rsa', + description: 'Deprecated, use duration.time', + name: 'rsa.time.process_time', + type: 'keyword', + }, + 'rsa.time.hour': { + category: 'rsa', + name: 'rsa.time.hour', + type: 'keyword', + }, + 'rsa.time.min': { + category: 'rsa', + name: 'rsa.time.min', + type: 'keyword', + }, + 'rsa.time.timestamp': { + category: 'rsa', + name: 'rsa.time.timestamp', + type: 'keyword', + }, + 'rsa.time.event_queue_time': { + category: 'rsa', + description: 'This key is the Time that the event was queued.', + name: 'rsa.time.event_queue_time', + type: 'date', + }, + 'rsa.time.p_time1': { + category: 'rsa', + name: 'rsa.time.p_time1', + type: 'keyword', + }, + 'rsa.time.tzone': { + category: 'rsa', + name: 'rsa.time.tzone', + type: 'keyword', + }, + 'rsa.time.eventtime': { + category: 'rsa', + name: 'rsa.time.eventtime', + type: 'keyword', + }, + 'rsa.time.gmtdate': { + category: 'rsa', + name: 'rsa.time.gmtdate', + type: 'keyword', + }, + 'rsa.time.gmttime': { + category: 'rsa', + name: 'rsa.time.gmttime', + type: 'keyword', + }, + 'rsa.time.p_date': { + category: 'rsa', + name: 'rsa.time.p_date', + type: 'keyword', + }, + 'rsa.time.p_month': { + category: 'rsa', + name: 'rsa.time.p_month', + type: 'keyword', + }, + 'rsa.time.p_time': { + category: 'rsa', + name: 'rsa.time.p_time', + type: 'keyword', + }, + 'rsa.time.p_time2': { + category: 'rsa', + name: 'rsa.time.p_time2', + type: 'keyword', + }, + 'rsa.time.p_year': { + category: 'rsa', + name: 'rsa.time.p_year', + type: 'keyword', + }, + 'rsa.time.expire_time_str': { + category: 'rsa', + description: + 'This key is used to capture incomplete timestamp that explicitly refers to an expiration.', + name: 'rsa.time.expire_time_str', + type: 'keyword', + }, + 'rsa.time.stamp': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.time.stamp', + type: 'date', + }, + 'rsa.misc.action': { + category: 'rsa', + name: 'rsa.misc.action', + type: 'keyword', + }, + 'rsa.misc.result': { + category: 'rsa', + description: + 'This key is used to capture the outcome/result string value of an action in a session.', + name: 'rsa.misc.result', + type: 'keyword', + }, + 'rsa.misc.severity': { + category: 'rsa', + description: 'This key is used to capture the severity given the session', + name: 'rsa.misc.severity', + type: 'keyword', + }, + 'rsa.misc.event_type': { + category: 'rsa', + description: 'This key captures the event category type as specified by the event source.', + name: 'rsa.misc.event_type', + type: 'keyword', + }, + 'rsa.misc.reference_id': { + category: 'rsa', + description: 'This key is used to capture an event id from the session directly', + name: 'rsa.misc.reference_id', + type: 'keyword', + }, + 'rsa.misc.version': { + category: 'rsa', + description: + 'This key captures Version of the application or OS which is generating the event.', + name: 'rsa.misc.version', + type: 'keyword', + }, + 'rsa.misc.disposition': { + category: 'rsa', + description: 'This key captures the The end state of an action.', + name: 'rsa.misc.disposition', + type: 'keyword', + }, + 'rsa.misc.result_code': { + category: 'rsa', + description: + 'This key is used to capture the outcome/result numeric value of an action in a session', + name: 'rsa.misc.result_code', + type: 'keyword', + }, + 'rsa.misc.category': { + category: 'rsa', + description: + 'This key is used to capture the category of an event given by the vendor in the session', + name: 'rsa.misc.category', + type: 'keyword', + }, + 'rsa.misc.obj_name': { + category: 'rsa', + description: 'This is used to capture name of object', + name: 'rsa.misc.obj_name', + type: 'keyword', + }, + 'rsa.misc.obj_type': { + category: 'rsa', + description: 'This is used to capture type of object', + name: 'rsa.misc.obj_type', + type: 'keyword', + }, + 'rsa.misc.event_source': { + category: 'rsa', + description: 'This key captures Source of the event that’s not a hostname', + name: 'rsa.misc.event_source', + type: 'keyword', + }, + 'rsa.misc.log_session_id': { + category: 'rsa', + description: 'This key is used to capture a sessionid from the session directly', + name: 'rsa.misc.log_session_id', + type: 'keyword', + }, + 'rsa.misc.group': { + category: 'rsa', + description: 'This key captures the Group Name value', + name: 'rsa.misc.group', + type: 'keyword', + }, + 'rsa.misc.policy_name': { + category: 'rsa', + description: 'This key is used to capture the Policy Name only.', + name: 'rsa.misc.policy_name', + type: 'keyword', + }, + 'rsa.misc.rule_name': { + category: 'rsa', + description: 'This key captures the Rule Name', + name: 'rsa.misc.rule_name', + type: 'keyword', + }, + 'rsa.misc.context': { + category: 'rsa', + description: 'This key captures Information which adds additional context to the event.', + name: 'rsa.misc.context', + type: 'keyword', + }, + 'rsa.misc.change_new': { + category: 'rsa', + description: + 'This key is used to capture the new values of the attribute that’s changing in a session', + name: 'rsa.misc.change_new', + type: 'keyword', + }, + 'rsa.misc.space': { + category: 'rsa', + name: 'rsa.misc.space', + type: 'keyword', + }, + 'rsa.misc.client': { + category: 'rsa', + description: + 'This key is used to capture only the name of the client application requesting resources of the server. See the user.agent meta key for capture of the specific user agent identifier or browser identification string.', + name: 'rsa.misc.client', + type: 'keyword', + }, + 'rsa.misc.msgIdPart1': { + category: 'rsa', + name: 'rsa.misc.msgIdPart1', + type: 'keyword', + }, + 'rsa.misc.msgIdPart2': { + category: 'rsa', + name: 'rsa.misc.msgIdPart2', + type: 'keyword', + }, + 'rsa.misc.change_old': { + category: 'rsa', + description: + 'This key is used to capture the old value of the attribute that’s changing in a session', + name: 'rsa.misc.change_old', + type: 'keyword', + }, + 'rsa.misc.operation_id': { + category: 'rsa', + description: + 'An alert number or operation number. The values should be unique and non-repeating.', + name: 'rsa.misc.operation_id', + type: 'keyword', + }, + 'rsa.misc.event_state': { + category: 'rsa', + description: + 'This key captures the current state of the object/item referenced within the event. Describing an on-going event.', + name: 'rsa.misc.event_state', + type: 'keyword', + }, + 'rsa.misc.group_object': { + category: 'rsa', + description: 'This key captures a collection/grouping of entities. Specific usage', + name: 'rsa.misc.group_object', + type: 'keyword', + }, + 'rsa.misc.node': { + category: 'rsa', + description: + 'Common use case is the node name within a cluster. The cluster name is reflected by the host name.', + name: 'rsa.misc.node', + type: 'keyword', + }, + 'rsa.misc.rule': { + category: 'rsa', + description: 'This key captures the Rule number', + name: 'rsa.misc.rule', + type: 'keyword', + }, + 'rsa.misc.device_name': { + category: 'rsa', + description: + 'This is used to capture name of the Device associated with the node Like: a physical disk, printer, etc', + name: 'rsa.misc.device_name', + type: 'keyword', + }, + 'rsa.misc.param': { + category: 'rsa', + description: 'This key is the parameters passed as part of a command or application, etc.', + name: 'rsa.misc.param', + type: 'keyword', + }, + 'rsa.misc.change_attrib': { + category: 'rsa', + description: + 'This key is used to capture the name of the attribute that’s changing in a session', + name: 'rsa.misc.change_attrib', + type: 'keyword', + }, + 'rsa.misc.event_computer': { + category: 'rsa', + description: + 'This key is a windows only concept, where this key is used to capture fully qualified domain name in a windows log.', + name: 'rsa.misc.event_computer', + type: 'keyword', + }, + 'rsa.misc.reference_id1': { + category: 'rsa', + description: 'This key is for Linked ID to be used as an addition to "reference.id"', + name: 'rsa.misc.reference_id1', + type: 'keyword', + }, + 'rsa.misc.event_log': { + category: 'rsa', + description: 'This key captures the Name of the event log', + name: 'rsa.misc.event_log', + type: 'keyword', + }, + 'rsa.misc.OS': { + category: 'rsa', + description: 'This key captures the Name of the Operating System', + name: 'rsa.misc.OS', + type: 'keyword', + }, + 'rsa.misc.terminal': { + category: 'rsa', + description: 'This key captures the Terminal Names only', + name: 'rsa.misc.terminal', + type: 'keyword', + }, + 'rsa.misc.msgIdPart3': { + category: 'rsa', + name: 'rsa.misc.msgIdPart3', + type: 'keyword', + }, + 'rsa.misc.filter': { + category: 'rsa', + description: 'This key captures Filter used to reduce result set', + name: 'rsa.misc.filter', + type: 'keyword', + }, + 'rsa.misc.serial_number': { + category: 'rsa', + description: 'This key is the Serial number associated with a physical asset.', + name: 'rsa.misc.serial_number', + type: 'keyword', + }, + 'rsa.misc.checksum': { + category: 'rsa', + description: + 'This key is used to capture the checksum or hash of the entity such as a file or process. Checksum should be used over checksum.src or checksum.dst when it is unclear whether the entity is a source or target of an action.', + name: 'rsa.misc.checksum', + type: 'keyword', + }, + 'rsa.misc.event_user': { + category: 'rsa', + description: + 'This key is a windows only concept, where this key is used to capture combination of domain name and username in a windows log.', + name: 'rsa.misc.event_user', + type: 'keyword', + }, + 'rsa.misc.virusname': { + category: 'rsa', + description: 'This key captures the name of the virus', + name: 'rsa.misc.virusname', + type: 'keyword', + }, + 'rsa.misc.content_type': { + category: 'rsa', + description: 'This key is used to capture Content Type only.', + name: 'rsa.misc.content_type', + type: 'keyword', + }, + 'rsa.misc.group_id': { + category: 'rsa', + description: 'This key captures Group ID Number (related to the group name)', + name: 'rsa.misc.group_id', + type: 'keyword', + }, + 'rsa.misc.policy_id': { + category: 'rsa', + description: + 'This key is used to capture the Policy ID only, this should be a numeric value, use policy.name otherwise', + name: 'rsa.misc.policy_id', + type: 'keyword', + }, + 'rsa.misc.vsys': { + category: 'rsa', + description: 'This key captures Virtual System Name', + name: 'rsa.misc.vsys', + type: 'keyword', + }, + 'rsa.misc.connection_id': { + category: 'rsa', + description: 'This key captures the Connection ID', + name: 'rsa.misc.connection_id', + type: 'keyword', + }, + 'rsa.misc.reference_id2': { + category: 'rsa', + description: + 'This key is for the 2nd Linked ID. Can be either linked to "reference.id" or "reference.id1" value but should not be used unless the other two variables are in play.', + name: 'rsa.misc.reference_id2', + type: 'keyword', + }, + 'rsa.misc.sensor': { + category: 'rsa', + description: 'This key captures Name of the sensor. Typically used in IDS/IPS based devices', + name: 'rsa.misc.sensor', + type: 'keyword', + }, + 'rsa.misc.sig_id': { + category: 'rsa', + description: 'This key captures IDS/IPS Int Signature ID', + name: 'rsa.misc.sig_id', + type: 'long', + }, + 'rsa.misc.port_name': { + category: 'rsa', + description: + 'This key is used for Physical or logical port connection but does NOT include a network port. (Example: Printer port name).', + name: 'rsa.misc.port_name', + type: 'keyword', + }, + 'rsa.misc.rule_group': { + category: 'rsa', + description: 'This key captures the Rule group name', + name: 'rsa.misc.rule_group', + type: 'keyword', + }, + 'rsa.misc.risk_num': { + category: 'rsa', + description: 'This key captures a Numeric Risk value', + name: 'rsa.misc.risk_num', + type: 'double', + }, + 'rsa.misc.trigger_val': { + category: 'rsa', + description: 'This key captures the Value of the trigger or threshold condition.', + name: 'rsa.misc.trigger_val', + type: 'keyword', + }, + 'rsa.misc.log_session_id1': { + category: 'rsa', + description: + 'This key is used to capture a Linked (Related) Session ID from the session directly', + name: 'rsa.misc.log_session_id1', + type: 'keyword', + }, + 'rsa.misc.comp_version': { + category: 'rsa', + description: 'This key captures the Version level of a sub-component of a product.', + name: 'rsa.misc.comp_version', + type: 'keyword', + }, + 'rsa.misc.content_version': { + category: 'rsa', + description: 'This key captures Version level of a signature or database content.', + name: 'rsa.misc.content_version', + type: 'keyword', + }, + 'rsa.misc.hardware_id': { + category: 'rsa', + description: + 'This key is used to capture unique identifier for a device or system (NOT a Mac address)', + name: 'rsa.misc.hardware_id', + type: 'keyword', + }, + 'rsa.misc.risk': { + category: 'rsa', + description: 'This key captures the non-numeric risk value', + name: 'rsa.misc.risk', + type: 'keyword', + }, + 'rsa.misc.event_id': { + category: 'rsa', + name: 'rsa.misc.event_id', + type: 'keyword', + }, + 'rsa.misc.reason': { + category: 'rsa', + name: 'rsa.misc.reason', + type: 'keyword', + }, + 'rsa.misc.status': { + category: 'rsa', + name: 'rsa.misc.status', + type: 'keyword', + }, + 'rsa.misc.mail_id': { + category: 'rsa', + description: 'This key is used to capture the mailbox id/name', + name: 'rsa.misc.mail_id', + type: 'keyword', + }, + 'rsa.misc.rule_uid': { + category: 'rsa', + description: 'This key is the Unique Identifier for a rule.', + name: 'rsa.misc.rule_uid', + type: 'keyword', + }, + 'rsa.misc.trigger_desc': { + category: 'rsa', + description: 'This key captures the Description of the trigger or threshold condition.', + name: 'rsa.misc.trigger_desc', + type: 'keyword', + }, + 'rsa.misc.inout': { + category: 'rsa', + name: 'rsa.misc.inout', + type: 'keyword', + }, + 'rsa.misc.p_msgid': { + category: 'rsa', + name: 'rsa.misc.p_msgid', + type: 'keyword', + }, + 'rsa.misc.data_type': { + category: 'rsa', + name: 'rsa.misc.data_type', + type: 'keyword', + }, + 'rsa.misc.msgIdPart4': { + category: 'rsa', + name: 'rsa.misc.msgIdPart4', + type: 'keyword', + }, + 'rsa.misc.error': { + category: 'rsa', + description: 'This key captures All non successful Error codes or responses', + name: 'rsa.misc.error', + type: 'keyword', + }, + 'rsa.misc.index': { + category: 'rsa', + name: 'rsa.misc.index', + type: 'keyword', + }, + 'rsa.misc.listnum': { + category: 'rsa', + description: + 'This key is used to capture listname or listnumber, primarily for collecting access-list', + name: 'rsa.misc.listnum', + type: 'keyword', + }, + 'rsa.misc.ntype': { + category: 'rsa', + name: 'rsa.misc.ntype', + type: 'keyword', + }, + 'rsa.misc.observed_val': { + category: 'rsa', + description: + 'This key captures the Value observed (from the perspective of the device generating the log).', + name: 'rsa.misc.observed_val', + type: 'keyword', + }, + 'rsa.misc.policy_value': { + category: 'rsa', + description: + 'This key captures the contents of the policy. This contains details about the policy', + name: 'rsa.misc.policy_value', + type: 'keyword', + }, + 'rsa.misc.pool_name': { + category: 'rsa', + description: 'This key captures the name of a resource pool', + name: 'rsa.misc.pool_name', + type: 'keyword', + }, + 'rsa.misc.rule_template': { + category: 'rsa', + description: + 'A default set of parameters which are overlayed onto a rule (or rulename) which efffectively constitutes a template', + name: 'rsa.misc.rule_template', + type: 'keyword', + }, + 'rsa.misc.count': { + category: 'rsa', + name: 'rsa.misc.count', + type: 'keyword', + }, + 'rsa.misc.number': { + category: 'rsa', + name: 'rsa.misc.number', + type: 'keyword', + }, + 'rsa.misc.sigcat': { + category: 'rsa', + name: 'rsa.misc.sigcat', + type: 'keyword', + }, + 'rsa.misc.type': { + category: 'rsa', + name: 'rsa.misc.type', + type: 'keyword', + }, + 'rsa.misc.comments': { + category: 'rsa', + description: 'Comment information provided in the log message', + name: 'rsa.misc.comments', + type: 'keyword', + }, + 'rsa.misc.doc_number': { + category: 'rsa', + description: 'This key captures File Identification number', + name: 'rsa.misc.doc_number', + type: 'long', + }, + 'rsa.misc.expected_val': { + category: 'rsa', + description: + 'This key captures the Value expected (from the perspective of the device generating the log).', + name: 'rsa.misc.expected_val', + type: 'keyword', + }, + 'rsa.misc.job_num': { + category: 'rsa', + description: 'This key captures the Job Number', + name: 'rsa.misc.job_num', + type: 'keyword', + }, + 'rsa.misc.spi_dst': { + category: 'rsa', + description: 'Destination SPI Index', + name: 'rsa.misc.spi_dst', + type: 'keyword', + }, + 'rsa.misc.spi_src': { + category: 'rsa', + description: 'Source SPI Index', + name: 'rsa.misc.spi_src', + type: 'keyword', + }, + 'rsa.misc.code': { + category: 'rsa', + name: 'rsa.misc.code', + type: 'keyword', + }, + 'rsa.misc.agent_id': { + category: 'rsa', + description: 'This key is used to capture agent id', + name: 'rsa.misc.agent_id', + type: 'keyword', + }, + 'rsa.misc.message_body': { + category: 'rsa', + description: 'This key captures the The contents of the message body.', + name: 'rsa.misc.message_body', + type: 'keyword', + }, + 'rsa.misc.phone': { + category: 'rsa', + name: 'rsa.misc.phone', + type: 'keyword', + }, + 'rsa.misc.sig_id_str': { + category: 'rsa', + description: 'This key captures a string object of the sigid variable.', + name: 'rsa.misc.sig_id_str', + type: 'keyword', + }, + 'rsa.misc.cmd': { + category: 'rsa', + name: 'rsa.misc.cmd', + type: 'keyword', + }, + 'rsa.misc.misc': { + category: 'rsa', + name: 'rsa.misc.misc', + type: 'keyword', + }, + 'rsa.misc.name': { + category: 'rsa', + name: 'rsa.misc.name', + type: 'keyword', + }, + 'rsa.misc.cpu': { + category: 'rsa', + description: 'This key is the CPU time used in the execution of the event being recorded.', + name: 'rsa.misc.cpu', + type: 'long', + }, + 'rsa.misc.event_desc': { + category: 'rsa', + description: + 'This key is used to capture a description of an event available directly or inferred', + name: 'rsa.misc.event_desc', + type: 'keyword', + }, + 'rsa.misc.sig_id1': { + category: 'rsa', + description: 'This key captures IDS/IPS Int Signature ID. This must be linked to the sig.id', + name: 'rsa.misc.sig_id1', + type: 'long', + }, + 'rsa.misc.im_buddyid': { + category: 'rsa', + name: 'rsa.misc.im_buddyid', + type: 'keyword', + }, + 'rsa.misc.im_client': { + category: 'rsa', + name: 'rsa.misc.im_client', + type: 'keyword', + }, + 'rsa.misc.im_userid': { + category: 'rsa', + name: 'rsa.misc.im_userid', + type: 'keyword', + }, + 'rsa.misc.pid': { + category: 'rsa', + name: 'rsa.misc.pid', + type: 'keyword', + }, + 'rsa.misc.priority': { + category: 'rsa', + name: 'rsa.misc.priority', + type: 'keyword', + }, + 'rsa.misc.context_subject': { + category: 'rsa', + description: + 'This key is to be used in an audit context where the subject is the object being identified', + name: 'rsa.misc.context_subject', + type: 'keyword', + }, + 'rsa.misc.context_target': { + category: 'rsa', + name: 'rsa.misc.context_target', + type: 'keyword', + }, + 'rsa.misc.cve': { + category: 'rsa', + description: + 'This key captures CVE (Common Vulnerabilities and Exposures) - an identifier for known information security vulnerabilities.', + name: 'rsa.misc.cve', + type: 'keyword', + }, + 'rsa.misc.fcatnum': { + category: 'rsa', + description: 'This key captures Filter Category Number. Legacy Usage', + name: 'rsa.misc.fcatnum', + type: 'keyword', + }, + 'rsa.misc.library': { + category: 'rsa', + description: 'This key is used to capture library information in mainframe devices', + name: 'rsa.misc.library', + type: 'keyword', + }, + 'rsa.misc.parent_node': { + category: 'rsa', + description: 'This key captures the Parent Node Name. Must be related to node variable.', + name: 'rsa.misc.parent_node', + type: 'keyword', + }, + 'rsa.misc.risk_info': { + category: 'rsa', + description: 'Deprecated, use New Hunting Model (inv.*, ioc, boc, eoc, analysis.*)', + name: 'rsa.misc.risk_info', + type: 'keyword', + }, + 'rsa.misc.tcp_flags': { + category: 'rsa', + description: 'This key is captures the TCP flags set in any packet of session', + name: 'rsa.misc.tcp_flags', + type: 'long', + }, + 'rsa.misc.tos': { + category: 'rsa', + description: 'This key describes the type of service', + name: 'rsa.misc.tos', + type: 'long', + }, + 'rsa.misc.vm_target': { + category: 'rsa', + description: 'VMWare Target **VMWARE** only varaible.', + name: 'rsa.misc.vm_target', + type: 'keyword', + }, + 'rsa.misc.workspace': { + category: 'rsa', + description: 'This key captures Workspace Description', + name: 'rsa.misc.workspace', + type: 'keyword', + }, + 'rsa.misc.command': { + category: 'rsa', + name: 'rsa.misc.command', + type: 'keyword', + }, + 'rsa.misc.event_category': { + category: 'rsa', + name: 'rsa.misc.event_category', + type: 'keyword', + }, + 'rsa.misc.facilityname': { + category: 'rsa', + name: 'rsa.misc.facilityname', + type: 'keyword', + }, + 'rsa.misc.forensic_info': { + category: 'rsa', + name: 'rsa.misc.forensic_info', + type: 'keyword', + }, + 'rsa.misc.jobname': { + category: 'rsa', + name: 'rsa.misc.jobname', + type: 'keyword', + }, + 'rsa.misc.mode': { + category: 'rsa', + name: 'rsa.misc.mode', + type: 'keyword', + }, + 'rsa.misc.policy': { + category: 'rsa', + name: 'rsa.misc.policy', + type: 'keyword', + }, + 'rsa.misc.policy_waiver': { + category: 'rsa', + name: 'rsa.misc.policy_waiver', + type: 'keyword', + }, + 'rsa.misc.second': { + category: 'rsa', + name: 'rsa.misc.second', + type: 'keyword', + }, + 'rsa.misc.space1': { + category: 'rsa', + name: 'rsa.misc.space1', + type: 'keyword', + }, + 'rsa.misc.subcategory': { + category: 'rsa', + name: 'rsa.misc.subcategory', + type: 'keyword', + }, + 'rsa.misc.tbdstr2': { + category: 'rsa', + name: 'rsa.misc.tbdstr2', + type: 'keyword', + }, + 'rsa.misc.alert_id': { + category: 'rsa', + description: 'Deprecated, New Hunting Model (inv.*, ioc, boc, eoc, analysis.*)', + name: 'rsa.misc.alert_id', + type: 'keyword', + }, + 'rsa.misc.checksum_dst': { + category: 'rsa', + description: + 'This key is used to capture the checksum or hash of the the target entity such as a process or file.', + name: 'rsa.misc.checksum_dst', + type: 'keyword', + }, + 'rsa.misc.checksum_src': { + category: 'rsa', + description: + 'This key is used to capture the checksum or hash of the source entity such as a file or process.', + name: 'rsa.misc.checksum_src', + type: 'keyword', + }, + 'rsa.misc.fresult': { + category: 'rsa', + description: 'This key captures the Filter Result', + name: 'rsa.misc.fresult', + type: 'long', + }, + 'rsa.misc.payload_dst': { + category: 'rsa', + description: 'This key is used to capture destination payload', + name: 'rsa.misc.payload_dst', + type: 'keyword', + }, + 'rsa.misc.payload_src': { + category: 'rsa', + description: 'This key is used to capture source payload', + name: 'rsa.misc.payload_src', + type: 'keyword', + }, + 'rsa.misc.pool_id': { + category: 'rsa', + description: 'This key captures the identifier (typically numeric field) of a resource pool', + name: 'rsa.misc.pool_id', + type: 'keyword', + }, + 'rsa.misc.process_id_val': { + category: 'rsa', + description: 'This key is a failure key for Process ID when it is not an integer value', + name: 'rsa.misc.process_id_val', + type: 'keyword', + }, + 'rsa.misc.risk_num_comm': { + category: 'rsa', + description: 'This key captures Risk Number Community', + name: 'rsa.misc.risk_num_comm', + type: 'double', + }, + 'rsa.misc.risk_num_next': { + category: 'rsa', + description: 'This key captures Risk Number NextGen', + name: 'rsa.misc.risk_num_next', + type: 'double', + }, + 'rsa.misc.risk_num_sand': { + category: 'rsa', + description: 'This key captures Risk Number SandBox', + name: 'rsa.misc.risk_num_sand', + type: 'double', + }, + 'rsa.misc.risk_num_static': { + category: 'rsa', + description: 'This key captures Risk Number Static', + name: 'rsa.misc.risk_num_static', + type: 'double', + }, + 'rsa.misc.risk_suspicious': { + category: 'rsa', + description: 'Deprecated, use New Hunting Model (inv.*, ioc, boc, eoc, analysis.*)', + name: 'rsa.misc.risk_suspicious', + type: 'keyword', + }, + 'rsa.misc.risk_warning': { + category: 'rsa', + description: 'Deprecated, use New Hunting Model (inv.*, ioc, boc, eoc, analysis.*)', + name: 'rsa.misc.risk_warning', + type: 'keyword', + }, + 'rsa.misc.snmp_oid': { + category: 'rsa', + description: 'SNMP Object Identifier', + name: 'rsa.misc.snmp_oid', + type: 'keyword', + }, + 'rsa.misc.sql': { + category: 'rsa', + description: 'This key captures the SQL query', + name: 'rsa.misc.sql', + type: 'keyword', + }, + 'rsa.misc.vuln_ref': { + category: 'rsa', + description: 'This key captures the Vulnerability Reference details', + name: 'rsa.misc.vuln_ref', + type: 'keyword', + }, + 'rsa.misc.acl_id': { + category: 'rsa', + name: 'rsa.misc.acl_id', + type: 'keyword', + }, + 'rsa.misc.acl_op': { + category: 'rsa', + name: 'rsa.misc.acl_op', + type: 'keyword', + }, + 'rsa.misc.acl_pos': { + category: 'rsa', + name: 'rsa.misc.acl_pos', + type: 'keyword', + }, + 'rsa.misc.acl_table': { + category: 'rsa', + name: 'rsa.misc.acl_table', + type: 'keyword', + }, + 'rsa.misc.admin': { + category: 'rsa', + name: 'rsa.misc.admin', + type: 'keyword', + }, + 'rsa.misc.alarm_id': { + category: 'rsa', + name: 'rsa.misc.alarm_id', + type: 'keyword', + }, + 'rsa.misc.alarmname': { + category: 'rsa', + name: 'rsa.misc.alarmname', + type: 'keyword', + }, + 'rsa.misc.app_id': { + category: 'rsa', + name: 'rsa.misc.app_id', + type: 'keyword', + }, + 'rsa.misc.audit': { + category: 'rsa', + name: 'rsa.misc.audit', + type: 'keyword', + }, + 'rsa.misc.audit_object': { + category: 'rsa', + name: 'rsa.misc.audit_object', + type: 'keyword', + }, + 'rsa.misc.auditdata': { + category: 'rsa', + name: 'rsa.misc.auditdata', + type: 'keyword', + }, + 'rsa.misc.benchmark': { + category: 'rsa', + name: 'rsa.misc.benchmark', + type: 'keyword', + }, + 'rsa.misc.bypass': { + category: 'rsa', + name: 'rsa.misc.bypass', + type: 'keyword', + }, + 'rsa.misc.cache': { + category: 'rsa', + name: 'rsa.misc.cache', + type: 'keyword', + }, + 'rsa.misc.cache_hit': { + category: 'rsa', + name: 'rsa.misc.cache_hit', + type: 'keyword', + }, + 'rsa.misc.cefversion': { + category: 'rsa', + name: 'rsa.misc.cefversion', + type: 'keyword', + }, + 'rsa.misc.cfg_attr': { + category: 'rsa', + name: 'rsa.misc.cfg_attr', + type: 'keyword', + }, + 'rsa.misc.cfg_obj': { + category: 'rsa', + name: 'rsa.misc.cfg_obj', + type: 'keyword', + }, + 'rsa.misc.cfg_path': { + category: 'rsa', + name: 'rsa.misc.cfg_path', + type: 'keyword', + }, + 'rsa.misc.changes': { + category: 'rsa', + name: 'rsa.misc.changes', + type: 'keyword', + }, + 'rsa.misc.client_ip': { + category: 'rsa', + name: 'rsa.misc.client_ip', + type: 'keyword', + }, + 'rsa.misc.clustermembers': { + category: 'rsa', + name: 'rsa.misc.clustermembers', + type: 'keyword', + }, + 'rsa.misc.cn_acttimeout': { + category: 'rsa', + name: 'rsa.misc.cn_acttimeout', + type: 'keyword', + }, + 'rsa.misc.cn_asn_src': { + category: 'rsa', + name: 'rsa.misc.cn_asn_src', + type: 'keyword', + }, + 'rsa.misc.cn_bgpv4nxthop': { + category: 'rsa', + name: 'rsa.misc.cn_bgpv4nxthop', + type: 'keyword', + }, + 'rsa.misc.cn_ctr_dst_code': { + category: 'rsa', + name: 'rsa.misc.cn_ctr_dst_code', + type: 'keyword', + }, + 'rsa.misc.cn_dst_tos': { + category: 'rsa', + name: 'rsa.misc.cn_dst_tos', + type: 'keyword', + }, + 'rsa.misc.cn_dst_vlan': { + category: 'rsa', + name: 'rsa.misc.cn_dst_vlan', + type: 'keyword', + }, + 'rsa.misc.cn_engine_id': { + category: 'rsa', + name: 'rsa.misc.cn_engine_id', + type: 'keyword', + }, + 'rsa.misc.cn_engine_type': { + category: 'rsa', + name: 'rsa.misc.cn_engine_type', + type: 'keyword', + }, + 'rsa.misc.cn_f_switch': { + category: 'rsa', + name: 'rsa.misc.cn_f_switch', + type: 'keyword', + }, + 'rsa.misc.cn_flowsampid': { + category: 'rsa', + name: 'rsa.misc.cn_flowsampid', + type: 'keyword', + }, + 'rsa.misc.cn_flowsampintv': { + category: 'rsa', + name: 'rsa.misc.cn_flowsampintv', + type: 'keyword', + }, + 'rsa.misc.cn_flowsampmode': { + category: 'rsa', + name: 'rsa.misc.cn_flowsampmode', + type: 'keyword', + }, + 'rsa.misc.cn_inacttimeout': { + category: 'rsa', + name: 'rsa.misc.cn_inacttimeout', + type: 'keyword', + }, + 'rsa.misc.cn_inpermbyts': { + category: 'rsa', + name: 'rsa.misc.cn_inpermbyts', + type: 'keyword', + }, + 'rsa.misc.cn_inpermpckts': { + category: 'rsa', + name: 'rsa.misc.cn_inpermpckts', + type: 'keyword', + }, + 'rsa.misc.cn_invalid': { + category: 'rsa', + name: 'rsa.misc.cn_invalid', + type: 'keyword', + }, + 'rsa.misc.cn_ip_proto_ver': { + category: 'rsa', + name: 'rsa.misc.cn_ip_proto_ver', + type: 'keyword', + }, + 'rsa.misc.cn_ipv4_ident': { + category: 'rsa', + name: 'rsa.misc.cn_ipv4_ident', + type: 'keyword', + }, + 'rsa.misc.cn_l_switch': { + category: 'rsa', + name: 'rsa.misc.cn_l_switch', + type: 'keyword', + }, + 'rsa.misc.cn_log_did': { + category: 'rsa', + name: 'rsa.misc.cn_log_did', + type: 'keyword', + }, + 'rsa.misc.cn_log_rid': { + category: 'rsa', + name: 'rsa.misc.cn_log_rid', + type: 'keyword', + }, + 'rsa.misc.cn_max_ttl': { + category: 'rsa', + name: 'rsa.misc.cn_max_ttl', + type: 'keyword', + }, + 'rsa.misc.cn_maxpcktlen': { + category: 'rsa', + name: 'rsa.misc.cn_maxpcktlen', + type: 'keyword', + }, + 'rsa.misc.cn_min_ttl': { + category: 'rsa', + name: 'rsa.misc.cn_min_ttl', + type: 'keyword', + }, + 'rsa.misc.cn_minpcktlen': { + category: 'rsa', + name: 'rsa.misc.cn_minpcktlen', + type: 'keyword', + }, + 'rsa.misc.cn_mpls_lbl_1': { + category: 'rsa', + name: 'rsa.misc.cn_mpls_lbl_1', + type: 'keyword', + }, + 'rsa.misc.cn_mpls_lbl_10': { + category: 'rsa', + name: 'rsa.misc.cn_mpls_lbl_10', + type: 'keyword', + }, + 'rsa.misc.cn_mpls_lbl_2': { + category: 'rsa', + name: 'rsa.misc.cn_mpls_lbl_2', + type: 'keyword', + }, + 'rsa.misc.cn_mpls_lbl_3': { + category: 'rsa', + name: 'rsa.misc.cn_mpls_lbl_3', + type: 'keyword', + }, + 'rsa.misc.cn_mpls_lbl_4': { + category: 'rsa', + name: 'rsa.misc.cn_mpls_lbl_4', + type: 'keyword', + }, + 'rsa.misc.cn_mpls_lbl_5': { + category: 'rsa', + name: 'rsa.misc.cn_mpls_lbl_5', + type: 'keyword', + }, + 'rsa.misc.cn_mpls_lbl_6': { + category: 'rsa', + name: 'rsa.misc.cn_mpls_lbl_6', + type: 'keyword', + }, + 'rsa.misc.cn_mpls_lbl_7': { + category: 'rsa', + name: 'rsa.misc.cn_mpls_lbl_7', + type: 'keyword', + }, + 'rsa.misc.cn_mpls_lbl_8': { + category: 'rsa', + name: 'rsa.misc.cn_mpls_lbl_8', + type: 'keyword', + }, + 'rsa.misc.cn_mpls_lbl_9': { + category: 'rsa', + name: 'rsa.misc.cn_mpls_lbl_9', + type: 'keyword', + }, + 'rsa.misc.cn_mplstoplabel': { + category: 'rsa', + name: 'rsa.misc.cn_mplstoplabel', + type: 'keyword', + }, + 'rsa.misc.cn_mplstoplabip': { + category: 'rsa', + name: 'rsa.misc.cn_mplstoplabip', + type: 'keyword', + }, + 'rsa.misc.cn_mul_dst_byt': { + category: 'rsa', + name: 'rsa.misc.cn_mul_dst_byt', + type: 'keyword', + }, + 'rsa.misc.cn_mul_dst_pks': { + category: 'rsa', + name: 'rsa.misc.cn_mul_dst_pks', + type: 'keyword', + }, + 'rsa.misc.cn_muligmptype': { + category: 'rsa', + name: 'rsa.misc.cn_muligmptype', + type: 'keyword', + }, + 'rsa.misc.cn_sampalgo': { + category: 'rsa', + name: 'rsa.misc.cn_sampalgo', + type: 'keyword', + }, + 'rsa.misc.cn_sampint': { + category: 'rsa', + name: 'rsa.misc.cn_sampint', + type: 'keyword', + }, + 'rsa.misc.cn_seqctr': { + category: 'rsa', + name: 'rsa.misc.cn_seqctr', + type: 'keyword', + }, + 'rsa.misc.cn_spackets': { + category: 'rsa', + name: 'rsa.misc.cn_spackets', + type: 'keyword', + }, + 'rsa.misc.cn_src_tos': { + category: 'rsa', + name: 'rsa.misc.cn_src_tos', + type: 'keyword', + }, + 'rsa.misc.cn_src_vlan': { + category: 'rsa', + name: 'rsa.misc.cn_src_vlan', + type: 'keyword', + }, + 'rsa.misc.cn_sysuptime': { + category: 'rsa', + name: 'rsa.misc.cn_sysuptime', + type: 'keyword', + }, + 'rsa.misc.cn_template_id': { + category: 'rsa', + name: 'rsa.misc.cn_template_id', + type: 'keyword', + }, + 'rsa.misc.cn_totbytsexp': { + category: 'rsa', + name: 'rsa.misc.cn_totbytsexp', + type: 'keyword', + }, + 'rsa.misc.cn_totflowexp': { + category: 'rsa', + name: 'rsa.misc.cn_totflowexp', + type: 'keyword', + }, + 'rsa.misc.cn_totpcktsexp': { + category: 'rsa', + name: 'rsa.misc.cn_totpcktsexp', + type: 'keyword', + }, + 'rsa.misc.cn_unixnanosecs': { + category: 'rsa', + name: 'rsa.misc.cn_unixnanosecs', + type: 'keyword', + }, + 'rsa.misc.cn_v6flowlabel': { + category: 'rsa', + name: 'rsa.misc.cn_v6flowlabel', + type: 'keyword', + }, + 'rsa.misc.cn_v6optheaders': { + category: 'rsa', + name: 'rsa.misc.cn_v6optheaders', + type: 'keyword', + }, + 'rsa.misc.comp_class': { + category: 'rsa', + name: 'rsa.misc.comp_class', + type: 'keyword', + }, + 'rsa.misc.comp_name': { + category: 'rsa', + name: 'rsa.misc.comp_name', + type: 'keyword', + }, + 'rsa.misc.comp_rbytes': { + category: 'rsa', + name: 'rsa.misc.comp_rbytes', + type: 'keyword', + }, + 'rsa.misc.comp_sbytes': { + category: 'rsa', + name: 'rsa.misc.comp_sbytes', + type: 'keyword', + }, + 'rsa.misc.cpu_data': { + category: 'rsa', + name: 'rsa.misc.cpu_data', + type: 'keyword', + }, + 'rsa.misc.criticality': { + category: 'rsa', + name: 'rsa.misc.criticality', + type: 'keyword', + }, + 'rsa.misc.cs_agency_dst': { + category: 'rsa', + name: 'rsa.misc.cs_agency_dst', + type: 'keyword', + }, + 'rsa.misc.cs_analyzedby': { + category: 'rsa', + name: 'rsa.misc.cs_analyzedby', + type: 'keyword', + }, + 'rsa.misc.cs_av_other': { + category: 'rsa', + name: 'rsa.misc.cs_av_other', + type: 'keyword', + }, + 'rsa.misc.cs_av_primary': { + category: 'rsa', + name: 'rsa.misc.cs_av_primary', + type: 'keyword', + }, + 'rsa.misc.cs_av_secondary': { + category: 'rsa', + name: 'rsa.misc.cs_av_secondary', + type: 'keyword', + }, + 'rsa.misc.cs_bgpv6nxthop': { + category: 'rsa', + name: 'rsa.misc.cs_bgpv6nxthop', + type: 'keyword', + }, + 'rsa.misc.cs_bit9status': { + category: 'rsa', + name: 'rsa.misc.cs_bit9status', + type: 'keyword', + }, + 'rsa.misc.cs_context': { + category: 'rsa', + name: 'rsa.misc.cs_context', + type: 'keyword', + }, + 'rsa.misc.cs_control': { + category: 'rsa', + name: 'rsa.misc.cs_control', + type: 'keyword', + }, + 'rsa.misc.cs_data': { + category: 'rsa', + name: 'rsa.misc.cs_data', + type: 'keyword', + }, + 'rsa.misc.cs_datecret': { + category: 'rsa', + name: 'rsa.misc.cs_datecret', + type: 'keyword', + }, + 'rsa.misc.cs_dst_tld': { + category: 'rsa', + name: 'rsa.misc.cs_dst_tld', + type: 'keyword', + }, + 'rsa.misc.cs_eth_dst_ven': { + category: 'rsa', + name: 'rsa.misc.cs_eth_dst_ven', + type: 'keyword', + }, + 'rsa.misc.cs_eth_src_ven': { + category: 'rsa', + name: 'rsa.misc.cs_eth_src_ven', + type: 'keyword', + }, + 'rsa.misc.cs_event_uuid': { + category: 'rsa', + name: 'rsa.misc.cs_event_uuid', + type: 'keyword', + }, + 'rsa.misc.cs_filetype': { + category: 'rsa', + name: 'rsa.misc.cs_filetype', + type: 'keyword', + }, + 'rsa.misc.cs_fld': { + category: 'rsa', + name: 'rsa.misc.cs_fld', + type: 'keyword', + }, + 'rsa.misc.cs_if_desc': { + category: 'rsa', + name: 'rsa.misc.cs_if_desc', + type: 'keyword', + }, + 'rsa.misc.cs_if_name': { + category: 'rsa', + name: 'rsa.misc.cs_if_name', + type: 'keyword', + }, + 'rsa.misc.cs_ip_next_hop': { + category: 'rsa', + name: 'rsa.misc.cs_ip_next_hop', + type: 'keyword', + }, + 'rsa.misc.cs_ipv4dstpre': { + category: 'rsa', + name: 'rsa.misc.cs_ipv4dstpre', + type: 'keyword', + }, + 'rsa.misc.cs_ipv4srcpre': { + category: 'rsa', + name: 'rsa.misc.cs_ipv4srcpre', + type: 'keyword', + }, + 'rsa.misc.cs_lifetime': { + category: 'rsa', + name: 'rsa.misc.cs_lifetime', + type: 'keyword', + }, + 'rsa.misc.cs_log_medium': { + category: 'rsa', + name: 'rsa.misc.cs_log_medium', + type: 'keyword', + }, + 'rsa.misc.cs_loginname': { + category: 'rsa', + name: 'rsa.misc.cs_loginname', + type: 'keyword', + }, + 'rsa.misc.cs_modulescore': { + category: 'rsa', + name: 'rsa.misc.cs_modulescore', + type: 'keyword', + }, + 'rsa.misc.cs_modulesign': { + category: 'rsa', + name: 'rsa.misc.cs_modulesign', + type: 'keyword', + }, + 'rsa.misc.cs_opswatresult': { + category: 'rsa', + name: 'rsa.misc.cs_opswatresult', + type: 'keyword', + }, + 'rsa.misc.cs_payload': { + category: 'rsa', + name: 'rsa.misc.cs_payload', + type: 'keyword', + }, + 'rsa.misc.cs_registrant': { + category: 'rsa', + name: 'rsa.misc.cs_registrant', + type: 'keyword', + }, + 'rsa.misc.cs_registrar': { + category: 'rsa', + name: 'rsa.misc.cs_registrar', + type: 'keyword', + }, + 'rsa.misc.cs_represult': { + category: 'rsa', + name: 'rsa.misc.cs_represult', + type: 'keyword', + }, + 'rsa.misc.cs_rpayload': { + category: 'rsa', + name: 'rsa.misc.cs_rpayload', + type: 'keyword', + }, + 'rsa.misc.cs_sampler_name': { + category: 'rsa', + name: 'rsa.misc.cs_sampler_name', + type: 'keyword', + }, + 'rsa.misc.cs_sourcemodule': { + category: 'rsa', + name: 'rsa.misc.cs_sourcemodule', + type: 'keyword', + }, + 'rsa.misc.cs_streams': { + category: 'rsa', + name: 'rsa.misc.cs_streams', + type: 'keyword', + }, + 'rsa.misc.cs_targetmodule': { + category: 'rsa', + name: 'rsa.misc.cs_targetmodule', + type: 'keyword', + }, + 'rsa.misc.cs_v6nxthop': { + category: 'rsa', + name: 'rsa.misc.cs_v6nxthop', + type: 'keyword', + }, + 'rsa.misc.cs_whois_server': { + category: 'rsa', + name: 'rsa.misc.cs_whois_server', + type: 'keyword', + }, + 'rsa.misc.cs_yararesult': { + category: 'rsa', + name: 'rsa.misc.cs_yararesult', + type: 'keyword', + }, + 'rsa.misc.description': { + category: 'rsa', + name: 'rsa.misc.description', + type: 'keyword', + }, + 'rsa.misc.devvendor': { + category: 'rsa', + name: 'rsa.misc.devvendor', + type: 'keyword', + }, + 'rsa.misc.distance': { + category: 'rsa', + name: 'rsa.misc.distance', + type: 'keyword', + }, + 'rsa.misc.dstburb': { + category: 'rsa', + name: 'rsa.misc.dstburb', + type: 'keyword', + }, + 'rsa.misc.edomain': { + category: 'rsa', + name: 'rsa.misc.edomain', + type: 'keyword', + }, + 'rsa.misc.edomaub': { + category: 'rsa', + name: 'rsa.misc.edomaub', + type: 'keyword', + }, + 'rsa.misc.euid': { + category: 'rsa', + name: 'rsa.misc.euid', + type: 'keyword', + }, + 'rsa.misc.facility': { + category: 'rsa', + name: 'rsa.misc.facility', + type: 'keyword', + }, + 'rsa.misc.finterface': { + category: 'rsa', + name: 'rsa.misc.finterface', + type: 'keyword', + }, + 'rsa.misc.flags': { + category: 'rsa', + name: 'rsa.misc.flags', + type: 'keyword', + }, + 'rsa.misc.gaddr': { + category: 'rsa', + name: 'rsa.misc.gaddr', + type: 'keyword', + }, + 'rsa.misc.id3': { + category: 'rsa', + name: 'rsa.misc.id3', + type: 'keyword', + }, + 'rsa.misc.im_buddyname': { + category: 'rsa', + name: 'rsa.misc.im_buddyname', + type: 'keyword', + }, + 'rsa.misc.im_croomid': { + category: 'rsa', + name: 'rsa.misc.im_croomid', + type: 'keyword', + }, + 'rsa.misc.im_croomtype': { + category: 'rsa', + name: 'rsa.misc.im_croomtype', + type: 'keyword', + }, + 'rsa.misc.im_members': { + category: 'rsa', + name: 'rsa.misc.im_members', + type: 'keyword', + }, + 'rsa.misc.im_username': { + category: 'rsa', + name: 'rsa.misc.im_username', + type: 'keyword', + }, + 'rsa.misc.ipkt': { + category: 'rsa', + name: 'rsa.misc.ipkt', + type: 'keyword', + }, + 'rsa.misc.ipscat': { + category: 'rsa', + name: 'rsa.misc.ipscat', + type: 'keyword', + }, + 'rsa.misc.ipspri': { + category: 'rsa', + name: 'rsa.misc.ipspri', + type: 'keyword', + }, + 'rsa.misc.latitude': { + category: 'rsa', + name: 'rsa.misc.latitude', + type: 'keyword', + }, + 'rsa.misc.linenum': { + category: 'rsa', + name: 'rsa.misc.linenum', + type: 'keyword', + }, + 'rsa.misc.list_name': { + category: 'rsa', + name: 'rsa.misc.list_name', + type: 'keyword', + }, + 'rsa.misc.load_data': { + category: 'rsa', + name: 'rsa.misc.load_data', + type: 'keyword', + }, + 'rsa.misc.location_floor': { + category: 'rsa', + name: 'rsa.misc.location_floor', + type: 'keyword', + }, + 'rsa.misc.location_mark': { + category: 'rsa', + name: 'rsa.misc.location_mark', + type: 'keyword', + }, + 'rsa.misc.log_id': { + category: 'rsa', + name: 'rsa.misc.log_id', + type: 'keyword', + }, + 'rsa.misc.log_type': { + category: 'rsa', + name: 'rsa.misc.log_type', + type: 'keyword', + }, + 'rsa.misc.logid': { + category: 'rsa', + name: 'rsa.misc.logid', + type: 'keyword', + }, + 'rsa.misc.logip': { + category: 'rsa', + name: 'rsa.misc.logip', + type: 'keyword', + }, + 'rsa.misc.logname': { + category: 'rsa', + name: 'rsa.misc.logname', + type: 'keyword', + }, + 'rsa.misc.longitude': { + category: 'rsa', + name: 'rsa.misc.longitude', + type: 'keyword', + }, + 'rsa.misc.lport': { + category: 'rsa', + name: 'rsa.misc.lport', + type: 'keyword', + }, + 'rsa.misc.mbug_data': { + category: 'rsa', + name: 'rsa.misc.mbug_data', + type: 'keyword', + }, + 'rsa.misc.misc_name': { + category: 'rsa', + name: 'rsa.misc.misc_name', + type: 'keyword', + }, + 'rsa.misc.msg_type': { + category: 'rsa', + name: 'rsa.misc.msg_type', + type: 'keyword', + }, + 'rsa.misc.msgid': { + category: 'rsa', + name: 'rsa.misc.msgid', + type: 'keyword', + }, + 'rsa.misc.netsessid': { + category: 'rsa', + name: 'rsa.misc.netsessid', + type: 'keyword', + }, + 'rsa.misc.num': { + category: 'rsa', + name: 'rsa.misc.num', + type: 'keyword', + }, + 'rsa.misc.number1': { + category: 'rsa', + name: 'rsa.misc.number1', + type: 'keyword', + }, + 'rsa.misc.number2': { + category: 'rsa', + name: 'rsa.misc.number2', + type: 'keyword', + }, + 'rsa.misc.nwwn': { + category: 'rsa', + name: 'rsa.misc.nwwn', + type: 'keyword', + }, + 'rsa.misc.object': { + category: 'rsa', + name: 'rsa.misc.object', + type: 'keyword', + }, + 'rsa.misc.operation': { + category: 'rsa', + name: 'rsa.misc.operation', + type: 'keyword', + }, + 'rsa.misc.opkt': { + category: 'rsa', + name: 'rsa.misc.opkt', + type: 'keyword', + }, + 'rsa.misc.orig_from': { + category: 'rsa', + name: 'rsa.misc.orig_from', + type: 'keyword', + }, + 'rsa.misc.owner_id': { + category: 'rsa', + name: 'rsa.misc.owner_id', + type: 'keyword', + }, + 'rsa.misc.p_action': { + category: 'rsa', + name: 'rsa.misc.p_action', + type: 'keyword', + }, + 'rsa.misc.p_filter': { + category: 'rsa', + name: 'rsa.misc.p_filter', + type: 'keyword', + }, + 'rsa.misc.p_group_object': { + category: 'rsa', + name: 'rsa.misc.p_group_object', + type: 'keyword', + }, + 'rsa.misc.p_id': { + category: 'rsa', + name: 'rsa.misc.p_id', + type: 'keyword', + }, + 'rsa.misc.p_msgid1': { + category: 'rsa', + name: 'rsa.misc.p_msgid1', + type: 'keyword', + }, + 'rsa.misc.p_msgid2': { + category: 'rsa', + name: 'rsa.misc.p_msgid2', + type: 'keyword', + }, + 'rsa.misc.p_result1': { + category: 'rsa', + name: 'rsa.misc.p_result1', + type: 'keyword', + }, + 'rsa.misc.password_chg': { + category: 'rsa', + name: 'rsa.misc.password_chg', + type: 'keyword', + }, + 'rsa.misc.password_expire': { + category: 'rsa', + name: 'rsa.misc.password_expire', + type: 'keyword', + }, + 'rsa.misc.permgranted': { + category: 'rsa', + name: 'rsa.misc.permgranted', + type: 'keyword', + }, + 'rsa.misc.permwanted': { + category: 'rsa', + name: 'rsa.misc.permwanted', + type: 'keyword', + }, + 'rsa.misc.pgid': { + category: 'rsa', + name: 'rsa.misc.pgid', + type: 'keyword', + }, + 'rsa.misc.policyUUID': { + category: 'rsa', + name: 'rsa.misc.policyUUID', + type: 'keyword', + }, + 'rsa.misc.prog_asp_num': { + category: 'rsa', + name: 'rsa.misc.prog_asp_num', + type: 'keyword', + }, + 'rsa.misc.program': { + category: 'rsa', + name: 'rsa.misc.program', + type: 'keyword', + }, + 'rsa.misc.real_data': { + category: 'rsa', + name: 'rsa.misc.real_data', + type: 'keyword', + }, + 'rsa.misc.rec_asp_device': { + category: 'rsa', + name: 'rsa.misc.rec_asp_device', + type: 'keyword', + }, + 'rsa.misc.rec_asp_num': { + category: 'rsa', + name: 'rsa.misc.rec_asp_num', + type: 'keyword', + }, + 'rsa.misc.rec_library': { + category: 'rsa', + name: 'rsa.misc.rec_library', + type: 'keyword', + }, + 'rsa.misc.recordnum': { + category: 'rsa', + name: 'rsa.misc.recordnum', + type: 'keyword', + }, + 'rsa.misc.ruid': { + category: 'rsa', + name: 'rsa.misc.ruid', + type: 'keyword', + }, + 'rsa.misc.sburb': { + category: 'rsa', + name: 'rsa.misc.sburb', + type: 'keyword', + }, + 'rsa.misc.sdomain_fld': { + category: 'rsa', + name: 'rsa.misc.sdomain_fld', + type: 'keyword', + }, + 'rsa.misc.sec': { + category: 'rsa', + name: 'rsa.misc.sec', + type: 'keyword', + }, + 'rsa.misc.sensorname': { + category: 'rsa', + name: 'rsa.misc.sensorname', + type: 'keyword', + }, + 'rsa.misc.seqnum': { + category: 'rsa', + name: 'rsa.misc.seqnum', + type: 'keyword', + }, + 'rsa.misc.session': { + category: 'rsa', + name: 'rsa.misc.session', + type: 'keyword', + }, + 'rsa.misc.sessiontype': { + category: 'rsa', + name: 'rsa.misc.sessiontype', + type: 'keyword', + }, + 'rsa.misc.sigUUID': { + category: 'rsa', + name: 'rsa.misc.sigUUID', + type: 'keyword', + }, + 'rsa.misc.spi': { + category: 'rsa', + name: 'rsa.misc.spi', + type: 'keyword', + }, + 'rsa.misc.srcburb': { + category: 'rsa', + name: 'rsa.misc.srcburb', + type: 'keyword', + }, + 'rsa.misc.srcdom': { + category: 'rsa', + name: 'rsa.misc.srcdom', + type: 'keyword', + }, + 'rsa.misc.srcservice': { + category: 'rsa', + name: 'rsa.misc.srcservice', + type: 'keyword', + }, + 'rsa.misc.state': { + category: 'rsa', + name: 'rsa.misc.state', + type: 'keyword', + }, + 'rsa.misc.status1': { + category: 'rsa', + name: 'rsa.misc.status1', + type: 'keyword', + }, + 'rsa.misc.svcno': { + category: 'rsa', + name: 'rsa.misc.svcno', + type: 'keyword', + }, + 'rsa.misc.system': { + category: 'rsa', + name: 'rsa.misc.system', + type: 'keyword', + }, + 'rsa.misc.tbdstr1': { + category: 'rsa', + name: 'rsa.misc.tbdstr1', + type: 'keyword', + }, + 'rsa.misc.tgtdom': { + category: 'rsa', + name: 'rsa.misc.tgtdom', + type: 'keyword', + }, + 'rsa.misc.tgtdomain': { + category: 'rsa', + name: 'rsa.misc.tgtdomain', + type: 'keyword', + }, + 'rsa.misc.threshold': { + category: 'rsa', + name: 'rsa.misc.threshold', + type: 'keyword', + }, + 'rsa.misc.type1': { + category: 'rsa', + name: 'rsa.misc.type1', + type: 'keyword', + }, + 'rsa.misc.udb_class': { + category: 'rsa', + name: 'rsa.misc.udb_class', + type: 'keyword', + }, + 'rsa.misc.url_fld': { + category: 'rsa', + name: 'rsa.misc.url_fld', + type: 'keyword', + }, + 'rsa.misc.user_div': { + category: 'rsa', + name: 'rsa.misc.user_div', + type: 'keyword', + }, + 'rsa.misc.userid': { + category: 'rsa', + name: 'rsa.misc.userid', + type: 'keyword', + }, + 'rsa.misc.username_fld': { + category: 'rsa', + name: 'rsa.misc.username_fld', + type: 'keyword', + }, + 'rsa.misc.utcstamp': { + category: 'rsa', + name: 'rsa.misc.utcstamp', + type: 'keyword', + }, + 'rsa.misc.v_instafname': { + category: 'rsa', + name: 'rsa.misc.v_instafname', + type: 'keyword', + }, + 'rsa.misc.virt_data': { + category: 'rsa', + name: 'rsa.misc.virt_data', + type: 'keyword', + }, + 'rsa.misc.vpnid': { + category: 'rsa', + name: 'rsa.misc.vpnid', + type: 'keyword', + }, + 'rsa.misc.autorun_type': { + category: 'rsa', + description: 'This is used to capture Auto Run type', + name: 'rsa.misc.autorun_type', + type: 'keyword', + }, + 'rsa.misc.cc_number': { + category: 'rsa', + description: 'Valid Credit Card Numbers only', + name: 'rsa.misc.cc_number', + type: 'long', + }, + 'rsa.misc.content': { + category: 'rsa', + description: 'This key captures the content type from protocol headers', + name: 'rsa.misc.content', + type: 'keyword', + }, + 'rsa.misc.ein_number': { + category: 'rsa', + description: 'Employee Identification Numbers only', + name: 'rsa.misc.ein_number', + type: 'long', + }, + 'rsa.misc.found': { + category: 'rsa', + description: 'This is used to capture the results of regex match', + name: 'rsa.misc.found', + type: 'keyword', + }, + 'rsa.misc.language': { + category: 'rsa', + description: 'This is used to capture list of languages the client support and what it prefers', + name: 'rsa.misc.language', + type: 'keyword', + }, + 'rsa.misc.lifetime': { + category: 'rsa', + description: 'This key is used to capture the session lifetime in seconds.', + name: 'rsa.misc.lifetime', + type: 'long', + }, + 'rsa.misc.link': { + category: 'rsa', + description: + 'This key is used to link the sessions together. This key should never be used to parse Meta data from a session (Logs/Packets) Directly, this is a Reserved key in NetWitness', + name: 'rsa.misc.link', + type: 'keyword', + }, + 'rsa.misc.match': { + category: 'rsa', + description: 'This key is for regex match name from search.ini', + name: 'rsa.misc.match', + type: 'keyword', + }, + 'rsa.misc.param_dst': { + category: 'rsa', + description: 'This key captures the command line/launch argument of the target process or file', + name: 'rsa.misc.param_dst', + type: 'keyword', + }, + 'rsa.misc.param_src': { + category: 'rsa', + description: 'This key captures source parameter', + name: 'rsa.misc.param_src', + type: 'keyword', + }, + 'rsa.misc.search_text': { + category: 'rsa', + description: 'This key captures the Search Text used', + name: 'rsa.misc.search_text', + type: 'keyword', + }, + 'rsa.misc.sig_name': { + category: 'rsa', + description: 'This key is used to capture the Signature Name only.', + name: 'rsa.misc.sig_name', + type: 'keyword', + }, + 'rsa.misc.snmp_value': { + category: 'rsa', + description: 'SNMP set request value', + name: 'rsa.misc.snmp_value', + type: 'keyword', + }, + 'rsa.misc.streams': { + category: 'rsa', + description: 'This key captures number of streams in session', + name: 'rsa.misc.streams', + type: 'long', + }, + 'rsa.db.index': { + category: 'rsa', + description: 'This key captures IndexID of the index.', + name: 'rsa.db.index', + type: 'keyword', + }, + 'rsa.db.instance': { + category: 'rsa', + description: 'This key is used to capture the database server instance name', + name: 'rsa.db.instance', + type: 'keyword', + }, + 'rsa.db.database': { + category: 'rsa', + description: + 'This key is used to capture the name of a database or an instance as seen in a session', + name: 'rsa.db.database', + type: 'keyword', + }, + 'rsa.db.transact_id': { + category: 'rsa', + description: 'This key captures the SQL transantion ID of the current session', + name: 'rsa.db.transact_id', + type: 'keyword', + }, + 'rsa.db.permissions': { + category: 'rsa', + description: 'This key captures permission or privilege level assigned to a resource.', + name: 'rsa.db.permissions', + type: 'keyword', + }, + 'rsa.db.table_name': { + category: 'rsa', + description: 'This key is used to capture the table name', + name: 'rsa.db.table_name', + type: 'keyword', + }, + 'rsa.db.db_id': { + category: 'rsa', + description: 'This key is used to capture the unique identifier for a database', + name: 'rsa.db.db_id', + type: 'keyword', + }, + 'rsa.db.db_pid': { + category: 'rsa', + description: 'This key captures the process id of a connection with database server', + name: 'rsa.db.db_pid', + type: 'long', + }, + 'rsa.db.lread': { + category: 'rsa', + description: 'This key is used for the number of logical reads', + name: 'rsa.db.lread', + type: 'long', + }, + 'rsa.db.lwrite': { + category: 'rsa', + description: 'This key is used for the number of logical writes', + name: 'rsa.db.lwrite', + type: 'long', + }, + 'rsa.db.pread': { + category: 'rsa', + description: 'This key is used for the number of physical writes', + name: 'rsa.db.pread', + type: 'long', + }, + 'rsa.network.alias_host': { + category: 'rsa', + description: + 'This key should be used when the source or destination context of a hostname is not clear.Also it captures the Device Hostname. Any Hostname that isnt ad.computer.', + name: 'rsa.network.alias_host', + type: 'keyword', + }, + 'rsa.network.domain': { + category: 'rsa', + name: 'rsa.network.domain', + type: 'keyword', + }, + 'rsa.network.host_dst': { + category: 'rsa', + description: 'This key should only be used when it’s a Destination Hostname', + name: 'rsa.network.host_dst', + type: 'keyword', + }, + 'rsa.network.network_service': { + category: 'rsa', + description: 'This is used to capture layer 7 protocols/service names', + name: 'rsa.network.network_service', + type: 'keyword', + }, + 'rsa.network.interface': { + category: 'rsa', + description: + 'This key should be used when the source or destination context of an interface is not clear', + name: 'rsa.network.interface', + type: 'keyword', + }, + 'rsa.network.network_port': { + category: 'rsa', + description: + 'Deprecated, use port. NOTE: There is a type discrepancy as currently used, TM: Int32, INDEX: UInt64 (why neither chose the correct UInt16?!)', + name: 'rsa.network.network_port', + type: 'long', + }, + 'rsa.network.eth_host': { + category: 'rsa', + description: 'Deprecated, use alias.mac', + name: 'rsa.network.eth_host', + type: 'keyword', + }, + 'rsa.network.sinterface': { + category: 'rsa', + description: 'This key should only be used when it’s a Source Interface', + name: 'rsa.network.sinterface', + type: 'keyword', + }, + 'rsa.network.dinterface': { + category: 'rsa', + description: 'This key should only be used when it’s a Destination Interface', + name: 'rsa.network.dinterface', + type: 'keyword', + }, + 'rsa.network.vlan': { + category: 'rsa', + description: 'This key should only be used to capture the ID of the Virtual LAN', + name: 'rsa.network.vlan', + type: 'long', + }, + 'rsa.network.zone_src': { + category: 'rsa', + description: 'This key should only be used when it’s a Source Zone.', + name: 'rsa.network.zone_src', + type: 'keyword', + }, + 'rsa.network.zone': { + category: 'rsa', + description: + 'This key should be used when the source or destination context of a Zone is not clear', + name: 'rsa.network.zone', + type: 'keyword', + }, + 'rsa.network.zone_dst': { + category: 'rsa', + description: 'This key should only be used when it’s a Destination Zone.', + name: 'rsa.network.zone_dst', + type: 'keyword', + }, + 'rsa.network.gateway': { + category: 'rsa', + description: 'This key is used to capture the IP Address of the gateway', + name: 'rsa.network.gateway', + type: 'keyword', + }, + 'rsa.network.icmp_type': { + category: 'rsa', + description: 'This key is used to capture the ICMP type only', + name: 'rsa.network.icmp_type', + type: 'long', + }, + 'rsa.network.mask': { + category: 'rsa', + description: 'This key is used to capture the device network IPmask.', + name: 'rsa.network.mask', + type: 'keyword', + }, + 'rsa.network.icmp_code': { + category: 'rsa', + description: 'This key is used to capture the ICMP code only', + name: 'rsa.network.icmp_code', + type: 'long', + }, + 'rsa.network.protocol_detail': { + category: 'rsa', + description: 'This key should be used to capture additional protocol information', + name: 'rsa.network.protocol_detail', + type: 'keyword', + }, + 'rsa.network.dmask': { + category: 'rsa', + description: 'This key is used for Destionation Device network mask', + name: 'rsa.network.dmask', + type: 'keyword', + }, + 'rsa.network.port': { + category: 'rsa', + description: + 'This key should only be used to capture a Network Port when the directionality is not clear', + name: 'rsa.network.port', + type: 'long', + }, + 'rsa.network.smask': { + category: 'rsa', + description: 'This key is used for capturing source Network Mask', + name: 'rsa.network.smask', + type: 'keyword', + }, + 'rsa.network.netname': { + category: 'rsa', + description: + 'This key is used to capture the network name associated with an IP range. This is configured by the end user.', + name: 'rsa.network.netname', + type: 'keyword', + }, + 'rsa.network.paddr': { + category: 'rsa', + description: 'Deprecated', + name: 'rsa.network.paddr', + type: 'ip', + }, + 'rsa.network.faddr': { + category: 'rsa', + name: 'rsa.network.faddr', + type: 'keyword', + }, + 'rsa.network.lhost': { + category: 'rsa', + name: 'rsa.network.lhost', + type: 'keyword', + }, + 'rsa.network.origin': { + category: 'rsa', + name: 'rsa.network.origin', + type: 'keyword', + }, + 'rsa.network.remote_domain_id': { + category: 'rsa', + name: 'rsa.network.remote_domain_id', + type: 'keyword', + }, + 'rsa.network.addr': { + category: 'rsa', + name: 'rsa.network.addr', + type: 'keyword', + }, + 'rsa.network.dns_a_record': { + category: 'rsa', + name: 'rsa.network.dns_a_record', + type: 'keyword', + }, + 'rsa.network.dns_ptr_record': { + category: 'rsa', + name: 'rsa.network.dns_ptr_record', + type: 'keyword', + }, + 'rsa.network.fhost': { + category: 'rsa', + name: 'rsa.network.fhost', + type: 'keyword', + }, + 'rsa.network.fport': { + category: 'rsa', + name: 'rsa.network.fport', + type: 'keyword', + }, + 'rsa.network.laddr': { + category: 'rsa', + name: 'rsa.network.laddr', + type: 'keyword', + }, + 'rsa.network.linterface': { + category: 'rsa', + name: 'rsa.network.linterface', + type: 'keyword', + }, + 'rsa.network.phost': { + category: 'rsa', + name: 'rsa.network.phost', + type: 'keyword', + }, + 'rsa.network.ad_computer_dst': { + category: 'rsa', + description: 'Deprecated, use host.dst', + name: 'rsa.network.ad_computer_dst', + type: 'keyword', + }, + 'rsa.network.eth_type': { + category: 'rsa', + description: 'This key is used to capture Ethernet Type, Used for Layer 3 Protocols Only', + name: 'rsa.network.eth_type', + type: 'long', + }, + 'rsa.network.ip_proto': { + category: 'rsa', + description: + 'This key should be used to capture the Protocol number, all the protocol nubers are converted into string in UI', + name: 'rsa.network.ip_proto', + type: 'long', + }, + 'rsa.network.dns_cname_record': { + category: 'rsa', + name: 'rsa.network.dns_cname_record', + type: 'keyword', + }, + 'rsa.network.dns_id': { + category: 'rsa', + name: 'rsa.network.dns_id', + type: 'keyword', + }, + 'rsa.network.dns_opcode': { + category: 'rsa', + name: 'rsa.network.dns_opcode', + type: 'keyword', + }, + 'rsa.network.dns_resp': { + category: 'rsa', + name: 'rsa.network.dns_resp', + type: 'keyword', + }, + 'rsa.network.dns_type': { + category: 'rsa', + name: 'rsa.network.dns_type', + type: 'keyword', + }, + 'rsa.network.domain1': { + category: 'rsa', + name: 'rsa.network.domain1', + type: 'keyword', + }, + 'rsa.network.host_type': { + category: 'rsa', + name: 'rsa.network.host_type', + type: 'keyword', + }, + 'rsa.network.packet_length': { + category: 'rsa', + name: 'rsa.network.packet_length', + type: 'keyword', + }, + 'rsa.network.host_orig': { + category: 'rsa', + description: + 'This is used to capture the original hostname in case of a Forwarding Agent or a Proxy in between.', + name: 'rsa.network.host_orig', + type: 'keyword', + }, + 'rsa.network.rpayload': { + category: 'rsa', + description: + 'This key is used to capture the total number of payload bytes seen in the retransmitted packets.', + name: 'rsa.network.rpayload', + type: 'keyword', + }, + 'rsa.network.vlan_name': { + category: 'rsa', + description: 'This key should only be used to capture the name of the Virtual LAN', + name: 'rsa.network.vlan_name', + type: 'keyword', + }, + 'rsa.investigations.ec_activity': { + category: 'rsa', + description: 'This key captures the particular event activity(Ex:Logoff)', + name: 'rsa.investigations.ec_activity', + type: 'keyword', + }, + 'rsa.investigations.ec_theme': { + category: 'rsa', + description: 'This key captures the Theme of a particular Event(Ex:Authentication)', + name: 'rsa.investigations.ec_theme', + type: 'keyword', + }, + 'rsa.investigations.ec_subject': { + category: 'rsa', + description: 'This key captures the Subject of a particular Event(Ex:User)', + name: 'rsa.investigations.ec_subject', + type: 'keyword', + }, + 'rsa.investigations.ec_outcome': { + category: 'rsa', + description: 'This key captures the outcome of a particular Event(Ex:Success)', + name: 'rsa.investigations.ec_outcome', + type: 'keyword', + }, + 'rsa.investigations.event_cat': { + category: 'rsa', + description: 'This key captures the Event category number', + name: 'rsa.investigations.event_cat', + type: 'long', + }, + 'rsa.investigations.event_cat_name': { + category: 'rsa', + description: 'This key captures the event category name corresponding to the event cat code', + name: 'rsa.investigations.event_cat_name', + type: 'keyword', + }, + 'rsa.investigations.event_vcat': { + category: 'rsa', + description: + 'This is a vendor supplied category. This should be used in situations where the vendor has adopted their own event_category taxonomy.', + name: 'rsa.investigations.event_vcat', + type: 'keyword', + }, + 'rsa.investigations.analysis_file': { + category: 'rsa', + description: + 'This is used to capture all indicators used in a File Analysis. This key should be used to capture an analysis of a file', + name: 'rsa.investigations.analysis_file', + type: 'keyword', + }, + 'rsa.investigations.analysis_service': { + category: 'rsa', + description: + 'This is used to capture all indicators used in a Service Analysis. This key should be used to capture an analysis of a service', + name: 'rsa.investigations.analysis_service', + type: 'keyword', + }, + 'rsa.investigations.analysis_session': { + category: 'rsa', + description: + 'This is used to capture all indicators used for a Session Analysis. This key should be used to capture an analysis of a session', + name: 'rsa.investigations.analysis_session', + type: 'keyword', + }, + 'rsa.investigations.boc': { + category: 'rsa', + description: 'This is used to capture behaviour of compromise', + name: 'rsa.investigations.boc', + type: 'keyword', + }, + 'rsa.investigations.eoc': { + category: 'rsa', + description: 'This is used to capture Enablers of Compromise', + name: 'rsa.investigations.eoc', + type: 'keyword', + }, + 'rsa.investigations.inv_category': { + category: 'rsa', + description: 'This used to capture investigation category', + name: 'rsa.investigations.inv_category', + type: 'keyword', + }, + 'rsa.investigations.inv_context': { + category: 'rsa', + description: 'This used to capture investigation context', + name: 'rsa.investigations.inv_context', + type: 'keyword', + }, + 'rsa.investigations.ioc': { + category: 'rsa', + description: 'This is key capture indicator of compromise', + name: 'rsa.investigations.ioc', + type: 'keyword', + }, + 'rsa.counters.dclass_c1': { + category: 'rsa', + description: + 'This is a generic counter key that should be used with the label dclass.c1.str only', + name: 'rsa.counters.dclass_c1', + type: 'long', + }, + 'rsa.counters.dclass_c2': { + category: 'rsa', + description: + 'This is a generic counter key that should be used with the label dclass.c2.str only', + name: 'rsa.counters.dclass_c2', + type: 'long', + }, + 'rsa.counters.event_counter': { + category: 'rsa', + description: 'This is used to capture the number of times an event repeated', + name: 'rsa.counters.event_counter', + type: 'long', + }, + 'rsa.counters.dclass_r1': { + category: 'rsa', + description: + 'This is a generic ratio key that should be used with the label dclass.r1.str only', + name: 'rsa.counters.dclass_r1', + type: 'keyword', + }, + 'rsa.counters.dclass_c3': { + category: 'rsa', + description: + 'This is a generic counter key that should be used with the label dclass.c3.str only', + name: 'rsa.counters.dclass_c3', + type: 'long', + }, + 'rsa.counters.dclass_c1_str': { + category: 'rsa', + description: + 'This is a generic counter string key that should be used with the label dclass.c1 only', + name: 'rsa.counters.dclass_c1_str', + type: 'keyword', + }, + 'rsa.counters.dclass_c2_str': { + category: 'rsa', + description: + 'This is a generic counter string key that should be used with the label dclass.c2 only', + name: 'rsa.counters.dclass_c2_str', + type: 'keyword', + }, + 'rsa.counters.dclass_r1_str': { + category: 'rsa', + description: + 'This is a generic ratio string key that should be used with the label dclass.r1 only', + name: 'rsa.counters.dclass_r1_str', + type: 'keyword', + }, + 'rsa.counters.dclass_r2': { + category: 'rsa', + description: + 'This is a generic ratio key that should be used with the label dclass.r2.str only', + name: 'rsa.counters.dclass_r2', + type: 'keyword', + }, + 'rsa.counters.dclass_c3_str': { + category: 'rsa', + description: + 'This is a generic counter string key that should be used with the label dclass.c3 only', + name: 'rsa.counters.dclass_c3_str', + type: 'keyword', + }, + 'rsa.counters.dclass_r3': { + category: 'rsa', + description: + 'This is a generic ratio key that should be used with the label dclass.r3.str only', + name: 'rsa.counters.dclass_r3', + type: 'keyword', + }, + 'rsa.counters.dclass_r2_str': { + category: 'rsa', + description: + 'This is a generic ratio string key that should be used with the label dclass.r2 only', + name: 'rsa.counters.dclass_r2_str', + type: 'keyword', + }, + 'rsa.counters.dclass_r3_str': { + category: 'rsa', + description: + 'This is a generic ratio string key that should be used with the label dclass.r3 only', + name: 'rsa.counters.dclass_r3_str', + type: 'keyword', + }, + 'rsa.identity.auth_method': { + category: 'rsa', + description: 'This key is used to capture authentication methods used only', + name: 'rsa.identity.auth_method', + type: 'keyword', + }, + 'rsa.identity.user_role': { + category: 'rsa', + description: 'This key is used to capture the Role of a user only', + name: 'rsa.identity.user_role', + type: 'keyword', + }, + 'rsa.identity.dn': { + category: 'rsa', + description: 'X.500 (LDAP) Distinguished Name', + name: 'rsa.identity.dn', + type: 'keyword', + }, + 'rsa.identity.logon_type': { + category: 'rsa', + description: 'This key is used to capture the type of logon method used.', + name: 'rsa.identity.logon_type', + type: 'keyword', + }, + 'rsa.identity.profile': { + category: 'rsa', + description: 'This key is used to capture the user profile', + name: 'rsa.identity.profile', + type: 'keyword', + }, + 'rsa.identity.accesses': { + category: 'rsa', + description: 'This key is used to capture actual privileges used in accessing an object', + name: 'rsa.identity.accesses', + type: 'keyword', + }, + 'rsa.identity.realm': { + category: 'rsa', + description: 'Radius realm or similar grouping of accounts', + name: 'rsa.identity.realm', + type: 'keyword', + }, + 'rsa.identity.user_sid_dst': { + category: 'rsa', + description: 'This key captures Destination User Session ID', + name: 'rsa.identity.user_sid_dst', + type: 'keyword', + }, + 'rsa.identity.dn_src': { + category: 'rsa', + description: + 'An X.500 (LDAP) Distinguished name that is used in a context that indicates a Source dn', + name: 'rsa.identity.dn_src', + type: 'keyword', + }, + 'rsa.identity.org': { + category: 'rsa', + description: 'This key captures the User organization', + name: 'rsa.identity.org', + type: 'keyword', + }, + 'rsa.identity.dn_dst': { + category: 'rsa', + description: + 'An X.500 (LDAP) Distinguished name that used in a context that indicates a Destination dn', + name: 'rsa.identity.dn_dst', + type: 'keyword', + }, + 'rsa.identity.firstname': { + category: 'rsa', + description: + 'This key is for First Names only, this is used for Healthcare predominantly to capture Patients information', + name: 'rsa.identity.firstname', + type: 'keyword', + }, + 'rsa.identity.lastname': { + category: 'rsa', + description: + 'This key is for Last Names only, this is used for Healthcare predominantly to capture Patients information', + name: 'rsa.identity.lastname', + type: 'keyword', + }, + 'rsa.identity.user_dept': { + category: 'rsa', + description: "User's Department Names only", + name: 'rsa.identity.user_dept', + type: 'keyword', + }, + 'rsa.identity.user_sid_src': { + category: 'rsa', + description: 'This key captures Source User Session ID', + name: 'rsa.identity.user_sid_src', + type: 'keyword', + }, + 'rsa.identity.federated_sp': { + category: 'rsa', + description: + 'This key is the Federated Service Provider. This is the application requesting authentication.', + name: 'rsa.identity.federated_sp', + type: 'keyword', + }, + 'rsa.identity.federated_idp': { + category: 'rsa', + description: + 'This key is the federated Identity Provider. This is the server providing the authentication.', + name: 'rsa.identity.federated_idp', + type: 'keyword', + }, + 'rsa.identity.logon_type_desc': { + category: 'rsa', + description: + "This key is used to capture the textual description of an integer logon type as stored in the meta key 'logon.type'.", + name: 'rsa.identity.logon_type_desc', + type: 'keyword', + }, + 'rsa.identity.middlename': { + category: 'rsa', + description: + 'This key is for Middle Names only, this is used for Healthcare predominantly to capture Patients information', + name: 'rsa.identity.middlename', + type: 'keyword', + }, + 'rsa.identity.password': { + category: 'rsa', + description: 'This key is for Passwords seen in any session, plain text or encrypted', + name: 'rsa.identity.password', + type: 'keyword', + }, + 'rsa.identity.host_role': { + category: 'rsa', + description: 'This key should only be used to capture the role of a Host Machine', + name: 'rsa.identity.host_role', + type: 'keyword', + }, + 'rsa.identity.ldap': { + category: 'rsa', + description: + 'This key is for Uninterpreted LDAP values. Ldap Values that don’t have a clear query or response context', + name: 'rsa.identity.ldap', + type: 'keyword', + }, + 'rsa.identity.ldap_query': { + category: 'rsa', + description: 'This key is the Search criteria from an LDAP search', + name: 'rsa.identity.ldap_query', + type: 'keyword', + }, + 'rsa.identity.ldap_response': { + category: 'rsa', + description: 'This key is to capture Results from an LDAP search', + name: 'rsa.identity.ldap_response', + type: 'keyword', + }, + 'rsa.identity.owner': { + category: 'rsa', + description: + 'This is used to capture username the process or service is running as, the author of the task', + name: 'rsa.identity.owner', + type: 'keyword', + }, + 'rsa.identity.service_account': { + category: 'rsa', + description: + 'This key is a windows specific key, used for capturing name of the account a service (referenced in the event) is running under. Legacy Usage', + name: 'rsa.identity.service_account', + type: 'keyword', + }, + 'rsa.email.email_dst': { + category: 'rsa', + description: + 'This key is used to capture the Destination email address only, when the destination context is not clear use email', + name: 'rsa.email.email_dst', + type: 'keyword', + }, + 'rsa.email.email_src': { + category: 'rsa', + description: + 'This key is used to capture the source email address only, when the source context is not clear use email', + name: 'rsa.email.email_src', + type: 'keyword', + }, + 'rsa.email.subject': { + category: 'rsa', + description: 'This key is used to capture the subject string from an Email only.', + name: 'rsa.email.subject', + type: 'keyword', + }, + 'rsa.email.email': { + category: 'rsa', + description: + 'This key is used to capture a generic email address where the source or destination context is not clear', + name: 'rsa.email.email', + type: 'keyword', + }, + 'rsa.email.trans_from': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.email.trans_from', + type: 'keyword', + }, + 'rsa.email.trans_to': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.email.trans_to', + type: 'keyword', + }, + 'rsa.file.privilege': { + category: 'rsa', + description: 'Deprecated, use permissions', + name: 'rsa.file.privilege', + type: 'keyword', + }, + 'rsa.file.attachment': { + category: 'rsa', + description: 'This key captures the attachment file name', + name: 'rsa.file.attachment', + type: 'keyword', + }, + 'rsa.file.filesystem': { + category: 'rsa', + name: 'rsa.file.filesystem', + type: 'keyword', + }, + 'rsa.file.binary': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.file.binary', + type: 'keyword', + }, + 'rsa.file.filename_dst': { + category: 'rsa', + description: 'This is used to capture name of the file targeted by the action', + name: 'rsa.file.filename_dst', + type: 'keyword', + }, + 'rsa.file.filename_src': { + category: 'rsa', + description: + 'This is used to capture name of the parent filename, the file which performed the action', + name: 'rsa.file.filename_src', + type: 'keyword', + }, + 'rsa.file.filename_tmp': { + category: 'rsa', + name: 'rsa.file.filename_tmp', + type: 'keyword', + }, + 'rsa.file.directory_dst': { + category: 'rsa', + description: + 'This key is used to capture the directory of the target process or file', + name: 'rsa.file.directory_dst', + type: 'keyword', + }, + 'rsa.file.directory_src': { + category: 'rsa', + description: 'This key is used to capture the directory of the source process or file', + name: 'rsa.file.directory_src', + type: 'keyword', + }, + 'rsa.file.file_entropy': { + category: 'rsa', + description: 'This is used to capture entropy vale of a file', + name: 'rsa.file.file_entropy', + type: 'double', + }, + 'rsa.file.file_vendor': { + category: 'rsa', + description: 'This is used to capture Company name of file located in version_info', + name: 'rsa.file.file_vendor', + type: 'keyword', + }, + 'rsa.file.task_name': { + category: 'rsa', + description: 'This is used to capture name of the task', + name: 'rsa.file.task_name', + type: 'keyword', + }, + 'rsa.web.fqdn': { + category: 'rsa', + description: 'Fully Qualified Domain Names', + name: 'rsa.web.fqdn', + type: 'keyword', + }, + 'rsa.web.web_cookie': { + category: 'rsa', + description: 'This key is used to capture the Web cookies specifically.', + name: 'rsa.web.web_cookie', + type: 'keyword', + }, + 'rsa.web.alias_host': { + category: 'rsa', + name: 'rsa.web.alias_host', + type: 'keyword', + }, + 'rsa.web.reputation_num': { + category: 'rsa', + description: 'Reputation Number of an entity. Typically used for Web Domains', + name: 'rsa.web.reputation_num', + type: 'double', + }, + 'rsa.web.web_ref_domain': { + category: 'rsa', + description: "Web referer's domain", + name: 'rsa.web.web_ref_domain', + type: 'keyword', + }, + 'rsa.web.web_ref_query': { + category: 'rsa', + description: "This key captures Web referer's query portion of the URL", + name: 'rsa.web.web_ref_query', + type: 'keyword', + }, + 'rsa.web.remote_domain': { + category: 'rsa', + name: 'rsa.web.remote_domain', + type: 'keyword', + }, + 'rsa.web.web_ref_page': { + category: 'rsa', + description: "This key captures Web referer's page information", + name: 'rsa.web.web_ref_page', + type: 'keyword', + }, + 'rsa.web.web_ref_root': { + category: 'rsa', + description: "Web referer's root URL path", + name: 'rsa.web.web_ref_root', + type: 'keyword', + }, + 'rsa.web.cn_asn_dst': { + category: 'rsa', + name: 'rsa.web.cn_asn_dst', + type: 'keyword', + }, + 'rsa.web.cn_rpackets': { + category: 'rsa', + name: 'rsa.web.cn_rpackets', + type: 'keyword', + }, + 'rsa.web.urlpage': { + category: 'rsa', + name: 'rsa.web.urlpage', + type: 'keyword', + }, + 'rsa.web.urlroot': { + category: 'rsa', + name: 'rsa.web.urlroot', + type: 'keyword', + }, + 'rsa.web.p_url': { + category: 'rsa', + name: 'rsa.web.p_url', + type: 'keyword', + }, + 'rsa.web.p_user_agent': { + category: 'rsa', + name: 'rsa.web.p_user_agent', + type: 'keyword', + }, + 'rsa.web.p_web_cookie': { + category: 'rsa', + name: 'rsa.web.p_web_cookie', + type: 'keyword', + }, + 'rsa.web.p_web_method': { + category: 'rsa', + name: 'rsa.web.p_web_method', + type: 'keyword', + }, + 'rsa.web.p_web_referer': { + category: 'rsa', + name: 'rsa.web.p_web_referer', + type: 'keyword', + }, + 'rsa.web.web_extension_tmp': { + category: 'rsa', + name: 'rsa.web.web_extension_tmp', + type: 'keyword', + }, + 'rsa.web.web_page': { + category: 'rsa', + name: 'rsa.web.web_page', + type: 'keyword', + }, + 'rsa.threat.threat_category': { + category: 'rsa', + description: 'This key captures Threat Name/Threat Category/Categorization of alert', + name: 'rsa.threat.threat_category', + type: 'keyword', + }, + 'rsa.threat.threat_desc': { + category: 'rsa', + description: + 'This key is used to capture the threat description from the session directly or inferred', + name: 'rsa.threat.threat_desc', + type: 'keyword', + }, + 'rsa.threat.alert': { + category: 'rsa', + description: 'This key is used to capture name of the alert', + name: 'rsa.threat.alert', + type: 'keyword', + }, + 'rsa.threat.threat_source': { + category: 'rsa', + description: 'This key is used to capture source of the threat', + name: 'rsa.threat.threat_source', + type: 'keyword', + }, + 'rsa.crypto.crypto': { + category: 'rsa', + description: 'This key is used to capture the Encryption Type or Encryption Key only', + name: 'rsa.crypto.crypto', + type: 'keyword', + }, + 'rsa.crypto.cipher_src': { + category: 'rsa', + description: 'This key is for Source (Client) Cipher', + name: 'rsa.crypto.cipher_src', + type: 'keyword', + }, + 'rsa.crypto.cert_subject': { + category: 'rsa', + description: 'This key is used to capture the Certificate organization only', + name: 'rsa.crypto.cert_subject', + type: 'keyword', + }, + 'rsa.crypto.peer': { + category: 'rsa', + description: "This key is for Encryption peer's IP Address", + name: 'rsa.crypto.peer', + type: 'keyword', + }, + 'rsa.crypto.cipher_size_src': { + category: 'rsa', + description: 'This key captures Source (Client) Cipher Size', + name: 'rsa.crypto.cipher_size_src', + type: 'long', + }, + 'rsa.crypto.ike': { + category: 'rsa', + description: 'IKE negotiation phase.', + name: 'rsa.crypto.ike', + type: 'keyword', + }, + 'rsa.crypto.scheme': { + category: 'rsa', + description: 'This key captures the Encryption scheme used', + name: 'rsa.crypto.scheme', + type: 'keyword', + }, + 'rsa.crypto.peer_id': { + category: 'rsa', + description: 'This key is for Encryption peer’s identity', + name: 'rsa.crypto.peer_id', + type: 'keyword', + }, + 'rsa.crypto.sig_type': { + category: 'rsa', + description: 'This key captures the Signature Type', + name: 'rsa.crypto.sig_type', + type: 'keyword', + }, + 'rsa.crypto.cert_issuer': { + category: 'rsa', + name: 'rsa.crypto.cert_issuer', + type: 'keyword', + }, + 'rsa.crypto.cert_host_name': { + category: 'rsa', + description: 'Deprecated key defined only in table map.', + name: 'rsa.crypto.cert_host_name', + type: 'keyword', + }, + 'rsa.crypto.cert_error': { + category: 'rsa', + description: 'This key captures the Certificate Error String', + name: 'rsa.crypto.cert_error', + type: 'keyword', + }, + 'rsa.crypto.cipher_dst': { + category: 'rsa', + description: 'This key is for Destination (Server) Cipher', + name: 'rsa.crypto.cipher_dst', + type: 'keyword', + }, + 'rsa.crypto.cipher_size_dst': { + category: 'rsa', + description: 'This key captures Destination (Server) Cipher Size', + name: 'rsa.crypto.cipher_size_dst', + type: 'long', + }, + 'rsa.crypto.ssl_ver_src': { + category: 'rsa', + description: 'Deprecated, use version', + name: 'rsa.crypto.ssl_ver_src', + type: 'keyword', + }, + 'rsa.crypto.d_certauth': { + category: 'rsa', + name: 'rsa.crypto.d_certauth', + type: 'keyword', + }, + 'rsa.crypto.s_certauth': { + category: 'rsa', + name: 'rsa.crypto.s_certauth', + type: 'keyword', + }, + 'rsa.crypto.ike_cookie1': { + category: 'rsa', + description: 'ID of the negotiation — sent for ISAKMP Phase One', + name: 'rsa.crypto.ike_cookie1', + type: 'keyword', + }, + 'rsa.crypto.ike_cookie2': { + category: 'rsa', + description: 'ID of the negotiation — sent for ISAKMP Phase Two', + name: 'rsa.crypto.ike_cookie2', + type: 'keyword', + }, + 'rsa.crypto.cert_checksum': { + category: 'rsa', + name: 'rsa.crypto.cert_checksum', + type: 'keyword', + }, + 'rsa.crypto.cert_host_cat': { + category: 'rsa', + description: 'This key is used for the hostname category value of a certificate', + name: 'rsa.crypto.cert_host_cat', + type: 'keyword', + }, + 'rsa.crypto.cert_serial': { + category: 'rsa', + description: 'This key is used to capture the Certificate serial number only', + name: 'rsa.crypto.cert_serial', + type: 'keyword', + }, + 'rsa.crypto.cert_status': { + category: 'rsa', + description: 'This key captures Certificate validation status', + name: 'rsa.crypto.cert_status', + type: 'keyword', + }, + 'rsa.crypto.ssl_ver_dst': { + category: 'rsa', + description: 'Deprecated, use version', + name: 'rsa.crypto.ssl_ver_dst', + type: 'keyword', + }, + 'rsa.crypto.cert_keysize': { + category: 'rsa', + name: 'rsa.crypto.cert_keysize', + type: 'keyword', + }, + 'rsa.crypto.cert_username': { + category: 'rsa', + name: 'rsa.crypto.cert_username', + type: 'keyword', + }, + 'rsa.crypto.https_insact': { + category: 'rsa', + name: 'rsa.crypto.https_insact', + type: 'keyword', + }, + 'rsa.crypto.https_valid': { + category: 'rsa', + name: 'rsa.crypto.https_valid', + type: 'keyword', + }, + 'rsa.crypto.cert_ca': { + category: 'rsa', + description: 'This key is used to capture the Certificate signing authority only', + name: 'rsa.crypto.cert_ca', + type: 'keyword', + }, + 'rsa.crypto.cert_common': { + category: 'rsa', + description: 'This key is used to capture the Certificate common name only', + name: 'rsa.crypto.cert_common', + type: 'keyword', + }, + 'rsa.wireless.wlan_ssid': { + category: 'rsa', + description: 'This key is used to capture the ssid of a Wireless Session', + name: 'rsa.wireless.wlan_ssid', + type: 'keyword', + }, + 'rsa.wireless.access_point': { + category: 'rsa', + description: 'This key is used to capture the access point name.', + name: 'rsa.wireless.access_point', + type: 'keyword', + }, + 'rsa.wireless.wlan_channel': { + category: 'rsa', + description: 'This is used to capture the channel names', + name: 'rsa.wireless.wlan_channel', + type: 'long', + }, + 'rsa.wireless.wlan_name': { + category: 'rsa', + description: 'This key captures either WLAN number/name', + name: 'rsa.wireless.wlan_name', + type: 'keyword', + }, + 'rsa.storage.disk_volume': { + category: 'rsa', + description: 'A unique name assigned to logical units (volumes) within a physical disk', + name: 'rsa.storage.disk_volume', + type: 'keyword', + }, + 'rsa.storage.lun': { + category: 'rsa', + description: 'Logical Unit Number.This key is a very useful concept in Storage.', + name: 'rsa.storage.lun', + type: 'keyword', + }, + 'rsa.storage.pwwn': { + category: 'rsa', + description: 'This uniquely identifies a port on a HBA.', + name: 'rsa.storage.pwwn', + type: 'keyword', + }, + 'rsa.physical.org_dst': { + category: 'rsa', + description: + 'This is used to capture the destination organization based on the GEOPIP Maxmind database.', + name: 'rsa.physical.org_dst', + type: 'keyword', + }, + 'rsa.physical.org_src': { + category: 'rsa', + description: + 'This is used to capture the source organization based on the GEOPIP Maxmind database.', + name: 'rsa.physical.org_src', + type: 'keyword', + }, + 'rsa.healthcare.patient_fname': { + category: 'rsa', + description: + 'This key is for First Names only, this is used for Healthcare predominantly to capture Patients information', + name: 'rsa.healthcare.patient_fname', + type: 'keyword', + }, + 'rsa.healthcare.patient_id': { + category: 'rsa', + description: 'This key captures the unique ID for a patient', + name: 'rsa.healthcare.patient_id', + type: 'keyword', + }, + 'rsa.healthcare.patient_lname': { + category: 'rsa', + description: + 'This key is for Last Names only, this is used for Healthcare predominantly to capture Patients information', + name: 'rsa.healthcare.patient_lname', + type: 'keyword', + }, + 'rsa.healthcare.patient_mname': { + category: 'rsa', + description: + 'This key is for Middle Names only, this is used for Healthcare predominantly to capture Patients information', + name: 'rsa.healthcare.patient_mname', + type: 'keyword', + }, + 'rsa.endpoint.host_state': { + category: 'rsa', + description: + 'This key is used to capture the current state of the machine, such as blacklisted, infected, firewall disabled and so on', + name: 'rsa.endpoint.host_state', + type: 'keyword', + }, + 'rsa.endpoint.registry_key': { + category: 'rsa', + description: 'This key captures the path to the registry key', + name: 'rsa.endpoint.registry_key', + type: 'keyword', + }, + 'rsa.endpoint.registry_value': { + category: 'rsa', + description: 'This key captures values or decorators used within a registry entry', + name: 'rsa.endpoint.registry_value', + type: 'keyword', + }, + 'forcepoint.virus_id': { + category: 'forcepoint', + description: 'Virus ID ', + name: 'forcepoint.virus_id', + type: 'keyword', + }, + 'checkpoint.app_risk': { + category: 'checkpoint', + description: 'Application risk.', + name: 'checkpoint.app_risk', + type: 'keyword', + }, + 'checkpoint.app_severity': { + category: 'checkpoint', + description: 'Application threat severity.', + name: 'checkpoint.app_severity', + type: 'keyword', + }, + 'checkpoint.app_sig_id': { + category: 'checkpoint', + description: 'The signature ID which the application was detected by.', + name: 'checkpoint.app_sig_id', + type: 'keyword', + }, + 'checkpoint.auth_method': { + category: 'checkpoint', + description: 'Password authentication protocol used.', + name: 'checkpoint.auth_method', + type: 'keyword', + }, + 'checkpoint.category': { + category: 'checkpoint', + description: 'Category.', + name: 'checkpoint.category', + type: 'keyword', + }, + 'checkpoint.confidence_level': { + category: 'checkpoint', + description: 'Confidence level determined.', + name: 'checkpoint.confidence_level', + type: 'integer', + }, + 'checkpoint.connectivity_state': { + category: 'checkpoint', + description: 'Connectivity state.', + name: 'checkpoint.connectivity_state', + type: 'keyword', + }, + 'checkpoint.cookie': { + category: 'checkpoint', + description: 'IKE cookie.', + name: 'checkpoint.cookie', + type: 'keyword', + }, + 'checkpoint.dst_phone_number': { + category: 'checkpoint', + description: 'Destination IP-Phone.', + name: 'checkpoint.dst_phone_number', + type: 'keyword', + }, + 'checkpoint.email_control': { + category: 'checkpoint', + description: 'Engine name.', + name: 'checkpoint.email_control', + type: 'keyword', + }, + 'checkpoint.email_id': { + category: 'checkpoint', + description: 'Internal email ID.', + name: 'checkpoint.email_id', + type: 'keyword', + }, + 'checkpoint.email_recipients_num': { + category: 'checkpoint', + description: 'Number of recipients.', + name: 'checkpoint.email_recipients_num', + type: 'long', + }, + 'checkpoint.email_session_id': { + category: 'checkpoint', + description: 'Internal email session ID.', + name: 'checkpoint.email_session_id', + type: 'keyword', + }, + 'checkpoint.email_spool_id': { + category: 'checkpoint', + description: 'Internal email spool ID.', + name: 'checkpoint.email_spool_id', + type: 'keyword', + }, + 'checkpoint.email_subject': { + category: 'checkpoint', + description: 'Email subject.', + name: 'checkpoint.email_subject', + type: 'keyword', + }, + 'checkpoint.event_count': { + category: 'checkpoint', + description: 'Number of events associated with the log.', + name: 'checkpoint.event_count', + type: 'long', + }, + 'checkpoint.frequency': { + category: 'checkpoint', + description: 'Scan frequency.', + name: 'checkpoint.frequency', + type: 'keyword', + }, + 'checkpoint.icmp_type': { + category: 'checkpoint', + description: 'ICMP type.', + name: 'checkpoint.icmp_type', + type: 'long', + }, + 'checkpoint.icmp_code': { + category: 'checkpoint', + description: 'ICMP code.', + name: 'checkpoint.icmp_code', + type: 'long', + }, + 'checkpoint.identity_type': { + category: 'checkpoint', + description: 'Identity type.', + name: 'checkpoint.identity_type', + type: 'keyword', + }, + 'checkpoint.incident_extension': { + category: 'checkpoint', + description: 'Format of original data.', + name: 'checkpoint.incident_extension', + type: 'keyword', + }, + 'checkpoint.integrity_av_invoke_type': { + category: 'checkpoint', + description: 'Scan invoke type.', + name: 'checkpoint.integrity_av_invoke_type', + type: 'keyword', + }, + 'checkpoint.malware_family': { + category: 'checkpoint', + description: 'Malware family.', + name: 'checkpoint.malware_family', + type: 'keyword', + }, + 'checkpoint.peer_gateway': { + category: 'checkpoint', + description: 'Main IP of the peer Security Gateway.', + name: 'checkpoint.peer_gateway', + type: 'ip', + }, + 'checkpoint.performance_impact': { + category: 'checkpoint', + description: 'Protection performance impact.', + name: 'checkpoint.performance_impact', + type: 'integer', + }, + 'checkpoint.protection_id': { + category: 'checkpoint', + description: 'Protection malware ID.', + name: 'checkpoint.protection_id', + type: 'keyword', + }, + 'checkpoint.protection_name': { + category: 'checkpoint', + description: 'Specific signature name of the attack.', + name: 'checkpoint.protection_name', + type: 'keyword', + }, + 'checkpoint.protection_type': { + category: 'checkpoint', + description: 'Type of protection used to detect the attack.', + name: 'checkpoint.protection_type', + type: 'keyword', + }, + 'checkpoint.scan_result': { + category: 'checkpoint', + description: 'Scan result.', + name: 'checkpoint.scan_result', + type: 'keyword', + }, + 'checkpoint.sensor_mode': { + category: 'checkpoint', + description: 'Sensor mode.', + name: 'checkpoint.sensor_mode', + type: 'keyword', + }, + 'checkpoint.severity': { + category: 'checkpoint', + description: 'Threat severity.', + name: 'checkpoint.severity', + type: 'keyword', + }, + 'checkpoint.spyware_name': { + category: 'checkpoint', + description: 'Spyware name.', + name: 'checkpoint.spyware_name', + type: 'keyword', + }, + 'checkpoint.spyware_status': { + category: 'checkpoint', + description: 'Spyware status.', + name: 'checkpoint.spyware_status', + type: 'keyword', + }, + 'checkpoint.subs_exp': { + category: 'checkpoint', + description: 'The expiration date of the subscription.', + name: 'checkpoint.subs_exp', + type: 'date', + }, + 'checkpoint.tcp_flags': { + category: 'checkpoint', + description: 'TCP packet flags.', + name: 'checkpoint.tcp_flags', + type: 'keyword', + }, + 'checkpoint.termination_reason': { + category: 'checkpoint', + description: 'Termination reason.', + name: 'checkpoint.termination_reason', + type: 'keyword', + }, + 'checkpoint.update_status': { + category: 'checkpoint', + description: 'Update status.', + name: 'checkpoint.update_status', + type: 'keyword', + }, + 'checkpoint.user_status': { + category: 'checkpoint', + description: 'User response.', + name: 'checkpoint.user_status', + type: 'keyword', + }, + 'checkpoint.uuid': { + category: 'checkpoint', + description: 'External ID.', + name: 'checkpoint.uuid', + type: 'keyword', + }, + 'checkpoint.virus_name': { + category: 'checkpoint', + description: 'Virus name.', + name: 'checkpoint.virus_name', + type: 'keyword', + }, + 'checkpoint.voip_log_type': { + category: 'checkpoint', + description: 'VoIP log types.', + name: 'checkpoint.voip_log_type', + type: 'keyword', + }, + 'cef.extensions.cp_app_risk': { + category: 'cef', + name: 'cef.extensions.cp_app_risk', + type: 'keyword', + }, + 'cef.extensions.cp_severity': { + category: 'cef', + name: 'cef.extensions.cp_severity', + type: 'keyword', + }, + 'cef.extensions.ifname': { + category: 'cef', + name: 'cef.extensions.ifname', + type: 'keyword', + }, + 'cef.extensions.inzone': { + category: 'cef', + name: 'cef.extensions.inzone', + type: 'keyword', + }, + 'cef.extensions.layer_uuid': { + category: 'cef', + name: 'cef.extensions.layer_uuid', + type: 'keyword', + }, + 'cef.extensions.layer_name': { + category: 'cef', + name: 'cef.extensions.layer_name', + type: 'keyword', + }, + 'cef.extensions.logid': { + category: 'cef', + name: 'cef.extensions.logid', + type: 'keyword', + }, + 'cef.extensions.loguid': { + category: 'cef', + name: 'cef.extensions.loguid', + type: 'keyword', + }, + 'cef.extensions.match_id': { + category: 'cef', + name: 'cef.extensions.match_id', + type: 'keyword', + }, + 'cef.extensions.nat_addtnl_rulenum': { + category: 'cef', + name: 'cef.extensions.nat_addtnl_rulenum', + type: 'keyword', + }, + 'cef.extensions.nat_rulenum': { + category: 'cef', + name: 'cef.extensions.nat_rulenum', + type: 'keyword', + }, + 'cef.extensions.origin': { + category: 'cef', + name: 'cef.extensions.origin', + type: 'keyword', + }, + 'cef.extensions.originsicname': { + category: 'cef', + name: 'cef.extensions.originsicname', + type: 'keyword', + }, + 'cef.extensions.outzone': { + category: 'cef', + name: 'cef.extensions.outzone', + type: 'keyword', + }, + 'cef.extensions.parent_rule': { + category: 'cef', + name: 'cef.extensions.parent_rule', + type: 'keyword', + }, + 'cef.extensions.product': { + category: 'cef', + name: 'cef.extensions.product', + type: 'keyword', + }, + 'cef.extensions.rule_action': { + category: 'cef', + name: 'cef.extensions.rule_action', + type: 'keyword', + }, + 'cef.extensions.rule_uid': { + category: 'cef', + name: 'cef.extensions.rule_uid', + type: 'keyword', + }, + 'cef.extensions.sequencenum': { + category: 'cef', + name: 'cef.extensions.sequencenum', + type: 'keyword', + }, + 'cef.extensions.service_id': { + category: 'cef', + name: 'cef.extensions.service_id', + type: 'keyword', + }, + 'cef.extensions.version': { + category: 'cef', + name: 'cef.extensions.version', + type: 'keyword', + }, + 'checkpoint.calc_desc': { + category: 'checkpoint', + description: 'Log description. ', + name: 'checkpoint.calc_desc', + type: 'keyword', + }, + 'checkpoint.dst_country': { + category: 'checkpoint', + description: 'Destination country. ', + name: 'checkpoint.dst_country', + type: 'keyword', + }, + 'checkpoint.dst_user_name': { + category: 'checkpoint', + description: 'Connected user name on the destination IP. ', + name: 'checkpoint.dst_user_name', + type: 'keyword', + }, + 'checkpoint.sys_message': { + category: 'checkpoint', + description: 'System messages ', + name: 'checkpoint.sys_message', + type: 'keyword', + }, + 'checkpoint.logid': { + category: 'checkpoint', + description: 'System messages ', + name: 'checkpoint.logid', + type: 'keyword', + }, + 'checkpoint.failure_impact': { + category: 'checkpoint', + description: 'The impact of update service failure. ', + name: 'checkpoint.failure_impact', + type: 'keyword', + }, + 'checkpoint.id': { + category: 'checkpoint', + description: 'Override application ID. ', + name: 'checkpoint.id', + type: 'integer', + }, + 'checkpoint.information': { + category: 'checkpoint', + description: 'Policy installation status for a specific blade. ', + name: 'checkpoint.information', + type: 'keyword', + }, + 'checkpoint.layer_name': { + category: 'checkpoint', + description: 'Layer name. ', + name: 'checkpoint.layer_name', + type: 'keyword', + }, + 'checkpoint.layer_uuid': { + category: 'checkpoint', + description: 'Layer UUID. ', + name: 'checkpoint.layer_uuid', + type: 'keyword', + }, + 'checkpoint.log_id': { + category: 'checkpoint', + description: 'Unique identity for logs. ', + name: 'checkpoint.log_id', + type: 'integer', + }, + 'checkpoint.origin_sic_name': { + category: 'checkpoint', + description: 'Machine SIC. ', + name: 'checkpoint.origin_sic_name', + type: 'keyword', + }, + 'checkpoint.policy_mgmt': { + category: 'checkpoint', + description: 'Name of the Management Server that manages this Security Gateway. ', + name: 'checkpoint.policy_mgmt', + type: 'keyword', + }, + 'checkpoint.policy_name': { + category: 'checkpoint', + description: 'Name of the last policy that this Security Gateway fetched. ', + name: 'checkpoint.policy_name', + type: 'keyword', + }, + 'checkpoint.protocol': { + category: 'checkpoint', + description: 'Protocol detected on the connection. ', + name: 'checkpoint.protocol', + type: 'keyword', + }, + 'checkpoint.proxy_src_ip': { + category: 'checkpoint', + description: 'Sender source IP (even when using proxy). ', + name: 'checkpoint.proxy_src_ip', + type: 'ip', + }, + 'checkpoint.rule': { + category: 'checkpoint', + description: 'Matched rule number. ', + name: 'checkpoint.rule', + type: 'integer', + }, + 'checkpoint.rule_action': { + category: 'checkpoint', + description: 'Action of the matched rule in the access policy. ', + name: 'checkpoint.rule_action', + type: 'keyword', + }, + 'checkpoint.scan_direction': { + category: 'checkpoint', + description: 'Scan direction. ', + name: 'checkpoint.scan_direction', + type: 'keyword', + }, + 'checkpoint.session_id': { + category: 'checkpoint', + description: 'Log uuid. ', + name: 'checkpoint.session_id', + type: 'keyword', + }, + 'checkpoint.source_os': { + category: 'checkpoint', + description: 'OS which generated the attack. ', + name: 'checkpoint.source_os', + type: 'keyword', + }, + 'checkpoint.src_country': { + category: 'checkpoint', + description: 'Country name, derived from connection source IP address. ', + name: 'checkpoint.src_country', + type: 'keyword', + }, + 'checkpoint.src_user_name': { + category: 'checkpoint', + description: 'User name connected to source IP ', + name: 'checkpoint.src_user_name', + type: 'keyword', + }, + 'checkpoint.ticket_id': { + category: 'checkpoint', + description: 'Unique ID per file. ', + name: 'checkpoint.ticket_id', + type: 'keyword', + }, + 'checkpoint.tls_server_host_name': { + category: 'checkpoint', + description: 'SNI/CN from encrypted TLS connection used by URLF for categorization. ', + name: 'checkpoint.tls_server_host_name', + type: 'keyword', + }, + 'checkpoint.verdict': { + category: 'checkpoint', + description: 'TE engine verdict Possible values: Malicious/Benign/Error. ', + name: 'checkpoint.verdict', + type: 'keyword', + }, + 'checkpoint.user': { + category: 'checkpoint', + description: 'Source user name. ', + name: 'checkpoint.user', + type: 'keyword', + }, + 'checkpoint.vendor_list': { + category: 'checkpoint', + description: 'The vendor name that provided the verdict for a malicious URL. ', + name: 'checkpoint.vendor_list', + type: 'keyword', + }, + 'checkpoint.web_server_type': { + category: 'checkpoint', + description: 'Web server detected in the HTTP response. ', + name: 'checkpoint.web_server_type', + type: 'keyword', + }, + 'checkpoint.client_name': { + category: 'checkpoint', + description: 'Client Application or Software Blade that detected the event. ', + name: 'checkpoint.client_name', + type: 'keyword', + }, + 'checkpoint.client_version': { + category: 'checkpoint', + description: 'Build version of SandBlast Agent client installed on the computer. ', + name: 'checkpoint.client_version', + type: 'keyword', + }, + 'checkpoint.extension_version': { + category: 'checkpoint', + description: 'Build version of the SandBlast Agent browser extension. ', + name: 'checkpoint.extension_version', + type: 'keyword', + }, + 'checkpoint.host_time': { + category: 'checkpoint', + description: 'Local time on the endpoint computer. ', + name: 'checkpoint.host_time', + type: 'keyword', + }, + 'checkpoint.installed_products': { + category: 'checkpoint', + description: 'List of installed Endpoint Software Blades. ', + name: 'checkpoint.installed_products', + type: 'keyword', + }, + 'checkpoint.cc': { + category: 'checkpoint', + description: 'The Carbon Copy address of the email. ', + name: 'checkpoint.cc', + type: 'keyword', + }, + 'checkpoint.parent_process_username': { + category: 'checkpoint', + description: 'Owner username of the parent process of the process that triggered the attack. ', + name: 'checkpoint.parent_process_username', + type: 'keyword', + }, + 'checkpoint.process_username': { + category: 'checkpoint', + description: 'Owner username of the process that triggered the attack. ', + name: 'checkpoint.process_username', + type: 'keyword', + }, + 'checkpoint.audit_status': { + category: 'checkpoint', + description: 'Audit Status. Can be Success or Failure. ', + name: 'checkpoint.audit_status', + type: 'keyword', + }, + 'checkpoint.objecttable': { + category: 'checkpoint', + description: 'Table of affected objects. ', + name: 'checkpoint.objecttable', + type: 'keyword', + }, + 'checkpoint.objecttype': { + category: 'checkpoint', + description: 'The type of the affected object. ', + name: 'checkpoint.objecttype', + type: 'keyword', + }, + 'checkpoint.operation_number': { + category: 'checkpoint', + description: 'The operation nuber. ', + name: 'checkpoint.operation_number', + type: 'keyword', + }, + 'checkpoint.suppressed_logs': { + category: 'checkpoint', + description: + 'Aggregated connections for five minutes on the same source, destination and port. ', + name: 'checkpoint.suppressed_logs', + type: 'integer', + }, + 'checkpoint.blade_name': { + category: 'checkpoint', + description: 'Blade name. ', + name: 'checkpoint.blade_name', + type: 'keyword', + }, + 'checkpoint.status': { + category: 'checkpoint', + description: 'Ok/Warning/Error. ', + name: 'checkpoint.status', + type: 'keyword', + }, + 'checkpoint.short_desc': { + category: 'checkpoint', + description: 'Short description of the process that was executed. ', + name: 'checkpoint.short_desc', + type: 'keyword', + }, + 'checkpoint.long_desc': { + category: 'checkpoint', + description: 'More information on the process (usually describing error reason in failure). ', + name: 'checkpoint.long_desc', + type: 'keyword', + }, + 'checkpoint.scan_hosts_hour': { + category: 'checkpoint', + description: 'Number of unique hosts during the last hour. ', + name: 'checkpoint.scan_hosts_hour', + type: 'integer', + }, + 'checkpoint.scan_hosts_day': { + category: 'checkpoint', + description: 'Number of unique hosts during the last day. ', + name: 'checkpoint.scan_hosts_day', + type: 'integer', + }, + 'checkpoint.scan_hosts_week': { + category: 'checkpoint', + description: 'Number of unique hosts during the last week. ', + name: 'checkpoint.scan_hosts_week', + type: 'integer', + }, + 'checkpoint.unique_detected_hour': { + category: 'checkpoint', + description: 'Detected virus for a specific host during the last hour. ', + name: 'checkpoint.unique_detected_hour', + type: 'integer', + }, + 'checkpoint.unique_detected_day': { + category: 'checkpoint', + description: 'Detected virus for a specific host during the last day. ', + name: 'checkpoint.unique_detected_day', + type: 'integer', + }, + 'checkpoint.unique_detected_week': { + category: 'checkpoint', + description: 'Detected virus for a specific host during the last week. ', + name: 'checkpoint.unique_detected_week', + type: 'integer', + }, + 'checkpoint.scan_mail': { + category: 'checkpoint', + description: 'Number of emails that were scanned by "AB malicious activity" engine. ', + name: 'checkpoint.scan_mail', + type: 'integer', + }, + 'checkpoint.additional_ip': { + category: 'checkpoint', + description: 'DNS host name. ', + name: 'checkpoint.additional_ip', + type: 'keyword', + }, + 'checkpoint.description': { + category: 'checkpoint', + description: 'Additional explanation how the security gateway enforced the connection. ', + name: 'checkpoint.description', + type: 'keyword', + }, + 'checkpoint.email_spam_category': { + category: 'checkpoint', + description: 'Email categories. Possible values: spam/not spam/phishing. ', + name: 'checkpoint.email_spam_category', + type: 'keyword', + }, + 'checkpoint.email_control_analysis': { + category: 'checkpoint', + description: 'Message classification, received from spam vendor engine. ', + name: 'checkpoint.email_control_analysis', + type: 'keyword', + }, + 'checkpoint.scan_results': { + category: 'checkpoint', + description: '"Infected"/description of a failure. ', + name: 'checkpoint.scan_results', + type: 'keyword', + }, + 'checkpoint.original_queue_id': { + category: 'checkpoint', + description: 'Original postfix email queue id. ', + name: 'checkpoint.original_queue_id', + type: 'keyword', + }, + 'checkpoint.risk': { + category: 'checkpoint', + description: 'Risk level we got from the engine. ', + name: 'checkpoint.risk', + type: 'keyword', + }, + 'checkpoint.observable_name': { + category: 'checkpoint', + description: 'IOC observable signature name. ', + name: 'checkpoint.observable_name', + type: 'keyword', + }, + 'checkpoint.observable_id': { + category: 'checkpoint', + description: 'IOC observable signature id. ', + name: 'checkpoint.observable_id', + type: 'keyword', + }, + 'checkpoint.observable_comment': { + category: 'checkpoint', + description: 'IOC observable signature description. ', + name: 'checkpoint.observable_comment', + type: 'keyword', + }, + 'checkpoint.indicator_name': { + category: 'checkpoint', + description: 'IOC indicator name. ', + name: 'checkpoint.indicator_name', + type: 'keyword', + }, + 'checkpoint.indicator_description': { + category: 'checkpoint', + description: 'IOC indicator description. ', + name: 'checkpoint.indicator_description', + type: 'keyword', + }, + 'checkpoint.indicator_reference': { + category: 'checkpoint', + description: 'IOC indicator reference. ', + name: 'checkpoint.indicator_reference', + type: 'keyword', + }, + 'checkpoint.indicator_uuid': { + category: 'checkpoint', + description: 'IOC indicator uuid. ', + name: 'checkpoint.indicator_uuid', + type: 'keyword', + }, + 'checkpoint.app_desc': { + category: 'checkpoint', + description: 'Application description. ', + name: 'checkpoint.app_desc', + type: 'keyword', + }, + 'checkpoint.app_id': { + category: 'checkpoint', + description: 'Application ID. ', + name: 'checkpoint.app_id', + type: 'integer', + }, + 'checkpoint.certificate_resource': { + category: 'checkpoint', + description: 'HTTPS resource Possible values: SNI or domain name (DN). ', + name: 'checkpoint.certificate_resource', + type: 'keyword', + }, + 'checkpoint.certificate_validation': { + category: 'checkpoint', + description: + 'Precise error, describing HTTPS certificate failure under "HTTPS categorize websites" feature. ', + name: 'checkpoint.certificate_validation', + type: 'keyword', + }, + 'checkpoint.browse_time': { + category: 'checkpoint', + description: 'Application session browse time. ', + name: 'checkpoint.browse_time', + type: 'keyword', + }, + 'checkpoint.limit_requested': { + category: 'checkpoint', + description: 'Indicates whether data limit was requested for the session. ', + name: 'checkpoint.limit_requested', + type: 'integer', + }, + 'checkpoint.limit_applied': { + category: 'checkpoint', + description: 'Indicates whether the session was actually date limited. ', + name: 'checkpoint.limit_applied', + type: 'integer', + }, + 'checkpoint.dropped_total': { + category: 'checkpoint', + description: 'Amount of dropped packets (both incoming and outgoing). ', + name: 'checkpoint.dropped_total', + type: 'integer', + }, + 'checkpoint.client_type_os': { + category: 'checkpoint', + description: 'Client OS detected in the HTTP request. ', + name: 'checkpoint.client_type_os', + type: 'keyword', + }, + 'checkpoint.name': { + category: 'checkpoint', + description: 'Application name. ', + name: 'checkpoint.name', + type: 'keyword', + }, + 'checkpoint.properties': { + category: 'checkpoint', + description: 'Application categories. ', + name: 'checkpoint.properties', + type: 'keyword', + }, + 'checkpoint.sig_id': { + category: 'checkpoint', + description: "Application's signature ID which how it was detected by. ", + name: 'checkpoint.sig_id', + type: 'keyword', + }, + 'checkpoint.desc': { + category: 'checkpoint', + description: 'Override application description. ', + name: 'checkpoint.desc', + type: 'keyword', + }, + 'checkpoint.referrer_self_uid': { + category: 'checkpoint', + description: 'UUID of the current log. ', + name: 'checkpoint.referrer_self_uid', + type: 'keyword', + }, + 'checkpoint.referrer_parent_uid': { + category: 'checkpoint', + description: 'Log UUID of the referring application. ', + name: 'checkpoint.referrer_parent_uid', + type: 'keyword', + }, + 'checkpoint.needs_browse_time': { + category: 'checkpoint', + description: 'Browse time required for the connection. ', + name: 'checkpoint.needs_browse_time', + type: 'integer', + }, + 'checkpoint.cluster_info': { + category: 'checkpoint', + description: + 'Cluster information. Possible options: Failover reason/cluster state changes/CP cluster or 3rd party. ', + name: 'checkpoint.cluster_info', + type: 'keyword', + }, + 'checkpoint.sync': { + category: 'checkpoint', + description: 'Sync status and the reason (stable, at risk). ', + name: 'checkpoint.sync', + type: 'keyword', + }, + 'checkpoint.file_direction': { + category: 'checkpoint', + description: 'File direction. Possible options: upload/download. ', + name: 'checkpoint.file_direction', + type: 'keyword', + }, + 'checkpoint.invalid_file_size': { + category: 'checkpoint', + description: 'File_size field is valid only if this field is set to 0. ', + name: 'checkpoint.invalid_file_size', + type: 'integer', + }, + 'checkpoint.top_archive_file_name': { + category: 'checkpoint', + description: 'In case of archive file: the file that was sent/received. ', + name: 'checkpoint.top_archive_file_name', + type: 'keyword', + }, + 'checkpoint.data_type_name': { + category: 'checkpoint', + description: 'Data type in rulebase that was matched. ', + name: 'checkpoint.data_type_name', + type: 'keyword', + }, + 'checkpoint.specific_data_type_name': { + category: 'checkpoint', + description: 'Compound/Group scenario, data type that was matched. ', + name: 'checkpoint.specific_data_type_name', + type: 'keyword', + }, + 'checkpoint.word_list': { + category: 'checkpoint', + description: 'Words matched by data type. ', + name: 'checkpoint.word_list', + type: 'keyword', + }, + 'checkpoint.info': { + category: 'checkpoint', + description: 'Special log message. ', + name: 'checkpoint.info', + type: 'keyword', + }, + 'checkpoint.outgoing_url': { + category: 'checkpoint', + description: 'URL related to this log (for HTTP). ', + name: 'checkpoint.outgoing_url', + type: 'keyword', + }, + 'checkpoint.dlp_rule_name': { + category: 'checkpoint', + description: 'Matched rule name. ', + name: 'checkpoint.dlp_rule_name', + type: 'keyword', + }, + 'checkpoint.dlp_recipients': { + category: 'checkpoint', + description: 'Mail recipients. ', + name: 'checkpoint.dlp_recipients', + type: 'keyword', + }, + 'checkpoint.dlp_subject': { + category: 'checkpoint', + description: 'Mail subject. ', + name: 'checkpoint.dlp_subject', + type: 'keyword', + }, + 'checkpoint.dlp_word_list': { + category: 'checkpoint', + description: 'Phrases matched by data type. ', + name: 'checkpoint.dlp_word_list', + type: 'keyword', + }, + 'checkpoint.dlp_template_score': { + category: 'checkpoint', + description: 'Template data type match score. ', + name: 'checkpoint.dlp_template_score', + type: 'keyword', + }, + 'checkpoint.message_size': { + category: 'checkpoint', + description: 'Mail/post size. ', + name: 'checkpoint.message_size', + type: 'integer', + }, + 'checkpoint.dlp_incident_uid': { + category: 'checkpoint', + description: 'Unique ID of the matched rule. ', + name: 'checkpoint.dlp_incident_uid', + type: 'keyword', + }, + 'checkpoint.dlp_related_incident_uid': { + category: 'checkpoint', + description: 'Other ID related to this one. ', + name: 'checkpoint.dlp_related_incident_uid', + type: 'keyword', + }, + 'checkpoint.dlp_data_type_name': { + category: 'checkpoint', + description: 'Matched data type. ', + name: 'checkpoint.dlp_data_type_name', + type: 'keyword', + }, + 'checkpoint.dlp_data_type_uid': { + category: 'checkpoint', + description: 'Unique ID of the matched data type. ', + name: 'checkpoint.dlp_data_type_uid', + type: 'keyword', + }, + 'checkpoint.dlp_violation_description': { + category: 'checkpoint', + description: 'Violation descriptions described in the rulebase. ', + name: 'checkpoint.dlp_violation_description', + type: 'keyword', + }, + 'checkpoint.dlp_relevant_data_types': { + category: 'checkpoint', + description: 'In case of Compound/Group: the inner data types that were matched. ', + name: 'checkpoint.dlp_relevant_data_types', + type: 'keyword', + }, + 'checkpoint.dlp_action_reason': { + category: 'checkpoint', + description: 'Action chosen reason. ', + name: 'checkpoint.dlp_action_reason', + type: 'keyword', + }, + 'checkpoint.dlp_categories': { + category: 'checkpoint', + description: 'Data type category. ', + name: 'checkpoint.dlp_categories', + type: 'keyword', + }, + 'checkpoint.dlp_transint': { + category: 'checkpoint', + description: 'HTTP/SMTP/FTP. ', + name: 'checkpoint.dlp_transint', + type: 'keyword', + }, + 'checkpoint.duplicate': { + category: 'checkpoint', + description: + 'Log marked as duplicated, when mail is split and the Security Gateway sees it twice. ', + name: 'checkpoint.duplicate', + type: 'keyword', + }, + 'checkpoint.matched_file': { + category: 'checkpoint', + description: 'Unique ID of the matched data type. ', + name: 'checkpoint.matched_file', + type: 'keyword', + }, + 'checkpoint.matched_file_text_segments': { + category: 'checkpoint', + description: 'Fingerprint: number of text segments matched by this traffic. ', + name: 'checkpoint.matched_file_text_segments', + type: 'integer', + }, + 'checkpoint.matched_file_percentage': { + category: 'checkpoint', + description: 'Fingerprint: match percentage of the traffic. ', + name: 'checkpoint.matched_file_percentage', + type: 'integer', + }, + 'checkpoint.dlp_additional_action': { + category: 'checkpoint', + description: 'Watermark/None. ', + name: 'checkpoint.dlp_additional_action', + type: 'keyword', + }, + 'checkpoint.dlp_watermark_profile': { + category: 'checkpoint', + description: 'Watermark which was applied. ', + name: 'checkpoint.dlp_watermark_profile', + type: 'keyword', + }, + 'checkpoint.dlp_repository_id': { + category: 'checkpoint', + description: 'ID of scanned repository. ', + name: 'checkpoint.dlp_repository_id', + type: 'keyword', + }, + 'checkpoint.dlp_repository_root_path': { + category: 'checkpoint', + description: 'Repository path. ', + name: 'checkpoint.dlp_repository_root_path', + type: 'keyword', + }, + 'checkpoint.scan_id': { + category: 'checkpoint', + description: 'Sequential number of scan. ', + name: 'checkpoint.scan_id', + type: 'keyword', + }, + 'checkpoint.special_properties': { + category: 'checkpoint', + description: + "If this field is set to '1' the log will not be shown (in use for monitoring scan progress). ", + name: 'checkpoint.special_properties', + type: 'integer', + }, + 'checkpoint.dlp_repository_total_size': { + category: 'checkpoint', + description: 'Repository size. ', + name: 'checkpoint.dlp_repository_total_size', + type: 'integer', + }, + 'checkpoint.dlp_repository_files_number': { + category: 'checkpoint', + description: 'Number of files in repository. ', + name: 'checkpoint.dlp_repository_files_number', + type: 'integer', + }, + 'checkpoint.dlp_repository_scanned_files_number': { + category: 'checkpoint', + description: 'Number of scanned files in repository. ', + name: 'checkpoint.dlp_repository_scanned_files_number', + type: 'integer', + }, + 'checkpoint.duration': { + category: 'checkpoint', + description: 'Scan duration. ', + name: 'checkpoint.duration', + type: 'keyword', + }, + 'checkpoint.dlp_fingerprint_long_status': { + category: 'checkpoint', + description: 'Scan status - long format. ', + name: 'checkpoint.dlp_fingerprint_long_status', + type: 'keyword', + }, + 'checkpoint.dlp_fingerprint_short_status': { + category: 'checkpoint', + description: 'Scan status - short format. ', + name: 'checkpoint.dlp_fingerprint_short_status', + type: 'keyword', + }, + 'checkpoint.dlp_repository_directories_number': { + category: 'checkpoint', + description: 'Number of directories in repository. ', + name: 'checkpoint.dlp_repository_directories_number', + type: 'integer', + }, + 'checkpoint.dlp_repository_unreachable_directories_number': { + category: 'checkpoint', + description: 'Number of directories the Security Gateway was unable to read. ', + name: 'checkpoint.dlp_repository_unreachable_directories_number', + type: 'integer', + }, + 'checkpoint.dlp_fingerprint_files_number': { + category: 'checkpoint', + description: 'Number of successfully scanned files in repository. ', + name: 'checkpoint.dlp_fingerprint_files_number', + type: 'integer', + }, + 'checkpoint.dlp_repository_skipped_files_number': { + category: 'checkpoint', + description: 'Skipped number of files because of configuration. ', + name: 'checkpoint.dlp_repository_skipped_files_number', + type: 'integer', + }, + 'checkpoint.dlp_repository_scanned_directories_number': { + category: 'checkpoint', + description: 'Amount of directories scanned. ', + name: 'checkpoint.dlp_repository_scanned_directories_number', + type: 'integer', + }, + 'checkpoint.number_of_errors': { + category: 'checkpoint', + description: 'Number of files that were not scanned due to an error. ', + name: 'checkpoint.number_of_errors', + type: 'integer', + }, + 'checkpoint.next_scheduled_scan_date': { + category: 'checkpoint', + description: 'Next scan scheduled time according to time object. ', + name: 'checkpoint.next_scheduled_scan_date', + type: 'keyword', + }, + 'checkpoint.dlp_repository_scanned_total_size': { + category: 'checkpoint', + description: 'Size scanned. ', + name: 'checkpoint.dlp_repository_scanned_total_size', + type: 'integer', + }, + 'checkpoint.dlp_repository_reached_directories_number': { + category: 'checkpoint', + description: 'Number of scanned directories in repository. ', + name: 'checkpoint.dlp_repository_reached_directories_number', + type: 'integer', + }, + 'checkpoint.dlp_repository_not_scanned_directories_percentage': { + category: 'checkpoint', + description: 'Percentage of directories the Security Gateway was unable to read. ', + name: 'checkpoint.dlp_repository_not_scanned_directories_percentage', + type: 'integer', + }, + 'checkpoint.speed': { + category: 'checkpoint', + description: 'Current scan speed. ', + name: 'checkpoint.speed', + type: 'integer', + }, + 'checkpoint.dlp_repository_scan_progress': { + category: 'checkpoint', + description: 'Scan percentage. ', + name: 'checkpoint.dlp_repository_scan_progress', + type: 'integer', + }, + 'checkpoint.sub_policy_name': { + category: 'checkpoint', + description: 'Layer name. ', + name: 'checkpoint.sub_policy_name', + type: 'keyword', + }, + 'checkpoint.sub_policy_uid': { + category: 'checkpoint', + description: 'Layer uid. ', + name: 'checkpoint.sub_policy_uid', + type: 'keyword', + }, + 'checkpoint.fw_message': { + category: 'checkpoint', + description: 'Used for various firewall errors. ', + name: 'checkpoint.fw_message', + type: 'keyword', + }, + 'checkpoint.message': { + category: 'checkpoint', + description: 'ISP link has failed. ', + name: 'checkpoint.message', + type: 'keyword', + }, + 'checkpoint.isp_link': { + category: 'checkpoint', + description: 'Name of ISP link. ', + name: 'checkpoint.isp_link', + type: 'keyword', + }, + 'checkpoint.fw_subproduct': { + category: 'checkpoint', + description: 'Can be vpn/non vpn. ', + name: 'checkpoint.fw_subproduct', + type: 'keyword', + }, + 'checkpoint.sctp_error': { + category: 'checkpoint', + description: 'Error information, what caused sctp to fail on out_of_state. ', + name: 'checkpoint.sctp_error', + type: 'keyword', + }, + 'checkpoint.chunk_type': { + category: 'checkpoint', + description: 'Chunck of the sctp stream. ', + name: 'checkpoint.chunk_type', + type: 'keyword', + }, + 'checkpoint.sctp_association_state': { + category: 'checkpoint', + description: 'The bad state you were trying to update to. ', + name: 'checkpoint.sctp_association_state', + type: 'keyword', + }, + 'checkpoint.tcp_packet_out_of_state': { + category: 'checkpoint', + description: 'State violation. ', + name: 'checkpoint.tcp_packet_out_of_state', + type: 'keyword', + }, + 'checkpoint.connectivity_level': { + category: 'checkpoint', + description: 'Log for a new connection in wire mode. ', + name: 'checkpoint.connectivity_level', + type: 'keyword', + }, + 'checkpoint.ip_option': { + category: 'checkpoint', + description: 'IP option that was dropped. ', + name: 'checkpoint.ip_option', + type: 'integer', + }, + 'checkpoint.tcp_state': { + category: 'checkpoint', + description: 'Log reinting a tcp state change. ', + name: 'checkpoint.tcp_state', + type: 'keyword', + }, + 'checkpoint.expire_time': { + category: 'checkpoint', + description: 'Connection closing time. ', + name: 'checkpoint.expire_time', + type: 'keyword', + }, + 'checkpoint.rpc_prog': { + category: 'checkpoint', + description: 'Log for new RPC state - prog values. ', + name: 'checkpoint.rpc_prog', + type: 'integer', + }, + 'checkpoint.dce-rpc_interface_uuid': { + category: 'checkpoint', + description: 'Log for new RPC state - UUID values ', + name: 'checkpoint.dce-rpc_interface_uuid', + type: 'keyword', + }, + 'checkpoint.elapsed': { + category: 'checkpoint', + description: 'Time passed since start time. ', + name: 'checkpoint.elapsed', + type: 'keyword', + }, + 'checkpoint.icmp': { + category: 'checkpoint', + description: 'Number of packets, received by the client. ', + name: 'checkpoint.icmp', + type: 'keyword', + }, + 'checkpoint.capture_uuid': { + category: 'checkpoint', + description: 'UUID generated for the capture. Used when enabling the capture when logging. ', + name: 'checkpoint.capture_uuid', + type: 'keyword', + }, + 'checkpoint.diameter_app_ID': { + category: 'checkpoint', + description: 'The ID of diameter application. ', + name: 'checkpoint.diameter_app_ID', + type: 'integer', + }, + 'checkpoint.diameter_cmd_code': { + category: 'checkpoint', + description: 'Diameter not allowed application command id. ', + name: 'checkpoint.diameter_cmd_code', + type: 'integer', + }, + 'checkpoint.diameter_msg_type': { + category: 'checkpoint', + description: 'Diameter message type. ', + name: 'checkpoint.diameter_msg_type', + type: 'keyword', + }, + 'checkpoint.cp_message': { + category: 'checkpoint', + description: 'Used to log a general message. ', + name: 'checkpoint.cp_message', + type: 'integer', + }, + 'checkpoint.log_delay': { + category: 'checkpoint', + description: 'Time left before deleting template. ', + name: 'checkpoint.log_delay', + type: 'integer', + }, + 'checkpoint.attack_status': { + category: 'checkpoint', + description: 'In case of a malicious event on an endpoint computer, the status of the attack. ', + name: 'checkpoint.attack_status', + type: 'keyword', + }, + 'checkpoint.impacted_files': { + category: 'checkpoint', + description: + 'In case of an infection on an endpoint computer, the list of files that the malware impacted. ', + name: 'checkpoint.impacted_files', + type: 'keyword', + }, + 'checkpoint.remediated_files': { + category: 'checkpoint', + description: + 'In case of an infection and a successful cleaning of that infection, this is a list of remediated files on the computer. ', + name: 'checkpoint.remediated_files', + type: 'keyword', + }, + 'checkpoint.triggered_by': { + category: 'checkpoint', + description: + 'The name of the mechanism that triggered the Software Blade to enforce a protection. ', + name: 'checkpoint.triggered_by', + type: 'keyword', + }, + 'checkpoint.https_inspection_rule_id': { + category: 'checkpoint', + description: 'ID of the matched rule. ', + name: 'checkpoint.https_inspection_rule_id', + type: 'keyword', + }, + 'checkpoint.https_inspection_rule_name': { + category: 'checkpoint', + description: 'Name of the matched rule. ', + name: 'checkpoint.https_inspection_rule_name', + type: 'keyword', + }, + 'checkpoint.app_properties': { + category: 'checkpoint', + description: 'List of all found categories. ', + name: 'checkpoint.app_properties', + type: 'keyword', + }, + 'checkpoint.https_validation': { + category: 'checkpoint', + description: 'Precise error, describing HTTPS inspection failure. ', + name: 'checkpoint.https_validation', + type: 'keyword', + }, + 'checkpoint.https_inspection_action': { + category: 'checkpoint', + description: 'HTTPS inspection action (Inspect/Bypass/Error). ', + name: 'checkpoint.https_inspection_action', + type: 'keyword', + }, + 'checkpoint.icap_service_id': { + category: 'checkpoint', + description: 'Service ID, can work with multiple servers, treated as services. ', + name: 'checkpoint.icap_service_id', + type: 'integer', + }, + 'checkpoint.icap_server_name': { + category: 'checkpoint', + description: 'Server name. ', + name: 'checkpoint.icap_server_name', + type: 'keyword', + }, + 'checkpoint.internal_error': { + category: 'checkpoint', + description: 'Internal error, for troubleshooting ', + name: 'checkpoint.internal_error', + type: 'keyword', + }, + 'checkpoint.icap_more_info': { + category: 'checkpoint', + description: 'Free text for verdict. ', + name: 'checkpoint.icap_more_info', + type: 'integer', + }, + 'checkpoint.reply_status': { + category: 'checkpoint', + description: 'ICAP reply status code, e.g. 200 or 204. ', + name: 'checkpoint.reply_status', + type: 'integer', + }, + 'checkpoint.icap_server_service': { + category: 'checkpoint', + description: 'Service name, as given in the ICAP URI ', + name: 'checkpoint.icap_server_service', + type: 'keyword', + }, + 'checkpoint.mirror_and_decrypt_type': { + category: 'checkpoint', + description: + 'Information about decrypt and forward. Possible values: Mirror only, Decrypt and mirror, Partial mirroring (HTTPS inspection Bypass). ', + name: 'checkpoint.mirror_and_decrypt_type', + type: 'keyword', + }, + 'checkpoint.interface_name': { + category: 'checkpoint', + description: 'Designated interface for mirror And decrypt. ', + name: 'checkpoint.interface_name', + type: 'keyword', + }, + 'checkpoint.session_uid': { + category: 'checkpoint', + description: 'HTTP session-id. ', + name: 'checkpoint.session_uid', + type: 'keyword', + }, + 'checkpoint.broker_publisher': { + category: 'checkpoint', + description: 'IP address of the broker publisher who shared the session information. ', + name: 'checkpoint.broker_publisher', + type: 'ip', + }, + 'checkpoint.src_user_dn': { + category: 'checkpoint', + description: 'User distinguished name connected to source IP. ', + name: 'checkpoint.src_user_dn', + type: 'keyword', + }, + 'checkpoint.proxy_user_name': { + category: 'checkpoint', + description: 'User name connected to proxy IP. ', + name: 'checkpoint.proxy_user_name', + type: 'keyword', + }, + 'checkpoint.proxy_machine_name': { + category: 'checkpoint', + description: 'Machine name connected to proxy IP. ', + name: 'checkpoint.proxy_machine_name', + type: 'integer', + }, + 'checkpoint.proxy_user_dn': { + category: 'checkpoint', + description: 'User distinguished name connected to proxy IP. ', + name: 'checkpoint.proxy_user_dn', + type: 'keyword', + }, + 'checkpoint.query': { + category: 'checkpoint', + description: 'DNS query. ', + name: 'checkpoint.query', + type: 'keyword', + }, + 'checkpoint.dns_query': { + category: 'checkpoint', + description: 'DNS query. ', + name: 'checkpoint.dns_query', + type: 'keyword', + }, + 'checkpoint.inspection_item': { + category: 'checkpoint', + description: 'Blade element performed inspection. ', + name: 'checkpoint.inspection_item', + type: 'keyword', + }, + 'checkpoint.inspection_category': { + category: 'checkpoint', + description: 'Inspection category: protocol anomaly, signature etc. ', + name: 'checkpoint.inspection_category', + type: 'keyword', + }, + 'checkpoint.inspection_profile': { + category: 'checkpoint', + description: 'Profile which the activated protection belongs to. ', + name: 'checkpoint.inspection_profile', + type: 'keyword', + }, + 'checkpoint.summary': { + category: 'checkpoint', + description: 'Summary message of a non-compliant DNS traffic drops or detects. ', + name: 'checkpoint.summary', + type: 'keyword', + }, + 'checkpoint.question_rdata': { + category: 'checkpoint', + description: 'List of question records domains. ', + name: 'checkpoint.question_rdata', + type: 'keyword', + }, + 'checkpoint.answer_rdata': { + category: 'checkpoint', + description: 'List of answer resource records to the questioned domains. ', + name: 'checkpoint.answer_rdata', + type: 'keyword', + }, + 'checkpoint.authority_rdata': { + category: 'checkpoint', + description: 'List of authoritative servers. ', + name: 'checkpoint.authority_rdata', + type: 'keyword', + }, + 'checkpoint.additional_rdata': { + category: 'checkpoint', + description: 'List of additional resource records. ', + name: 'checkpoint.additional_rdata', + type: 'keyword', + }, + 'checkpoint.files_names': { + category: 'checkpoint', + description: 'List of files requested by FTP. ', + name: 'checkpoint.files_names', + type: 'keyword', + }, + 'checkpoint.ftp_user': { + category: 'checkpoint', + description: 'FTP username. ', + name: 'checkpoint.ftp_user', + type: 'keyword', + }, + 'checkpoint.mime_from': { + category: 'checkpoint', + description: "Sender's address. ", + name: 'checkpoint.mime_from', + type: 'keyword', + }, + 'checkpoint.mime_to': { + category: 'checkpoint', + description: 'List of receiver address. ', + name: 'checkpoint.mime_to', + type: 'keyword', + }, + 'checkpoint.bcc': { + category: 'checkpoint', + description: 'List of BCC addresses. ', + name: 'checkpoint.bcc', + type: 'keyword', + }, + 'checkpoint.content_type': { + category: 'checkpoint', + description: + 'Mail content type. Possible values: application/msword, text/html, image/gif etc. ', + name: 'checkpoint.content_type', + type: 'keyword', + }, + 'checkpoint.user_agent': { + category: 'checkpoint', + description: 'String identifying requesting software user agent. ', + name: 'checkpoint.user_agent', + type: 'keyword', + }, + 'checkpoint.referrer': { + category: 'checkpoint', + description: 'Referrer HTTP request header, previous web page address. ', + name: 'checkpoint.referrer', + type: 'keyword', + }, + 'checkpoint.http_location': { + category: 'checkpoint', + description: 'Response header, indicates the URL to redirect a page to. ', + name: 'checkpoint.http_location', + type: 'keyword', + }, + 'checkpoint.content_disposition': { + category: 'checkpoint', + description: 'Indicates how the content is expected to be displayed inline in the browser. ', + name: 'checkpoint.content_disposition', + type: 'keyword', + }, + 'checkpoint.via': { + category: 'checkpoint', + description: + 'Via header is added by proxies for tracking purposes to avoid sending reqests in loop. ', + name: 'checkpoint.via', + type: 'keyword', + }, + 'checkpoint.http_server': { + category: 'checkpoint', + description: + 'Server HTTP header value, contains information about the software used by the origin server, which handles the request. ', + name: 'checkpoint.http_server', + type: 'keyword', + }, + 'checkpoint.content_length': { + category: 'checkpoint', + description: 'Indicates the size of the entity-body of the HTTP header. ', + name: 'checkpoint.content_length', + type: 'keyword', + }, + 'checkpoint.authorization': { + category: 'checkpoint', + description: 'Authorization HTTP header value. ', + name: 'checkpoint.authorization', + type: 'keyword', + }, + 'checkpoint.http_host': { + category: 'checkpoint', + description: 'Domain name of the server that the HTTP request is sent to. ', + name: 'checkpoint.http_host', + type: 'keyword', + }, + 'checkpoint.inspection_settings_log': { + category: 'checkpoint', + description: 'Indicats that the log was released by inspection settings. ', + name: 'checkpoint.inspection_settings_log', + type: 'keyword', + }, + 'checkpoint.cvpn_resource': { + category: 'checkpoint', + description: 'Mobile Access application. ', + name: 'checkpoint.cvpn_resource', + type: 'keyword', + }, + 'checkpoint.cvpn_category': { + category: 'checkpoint', + description: 'Mobile Access application type. ', + name: 'checkpoint.cvpn_category', + type: 'keyword', + }, + 'checkpoint.url': { + category: 'checkpoint', + description: 'Translated URL. ', + name: 'checkpoint.url', + type: 'keyword', + }, + 'checkpoint.reject_id': { + category: 'checkpoint', + description: + 'A reject ID that corresponds to the one presented in the Mobile Access error page. ', + name: 'checkpoint.reject_id', + type: 'keyword', + }, + 'checkpoint.fs-proto': { + category: 'checkpoint', + description: 'The file share protocol used in mobile acess file share application. ', + name: 'checkpoint.fs-proto', + type: 'keyword', + }, + 'checkpoint.app_package': { + category: 'checkpoint', + description: 'Unique identifier of the application on the protected mobile device. ', + name: 'checkpoint.app_package', + type: 'keyword', + }, + 'checkpoint.appi_name': { + category: 'checkpoint', + description: 'Name of application downloaded on the protected mobile device. ', + name: 'checkpoint.appi_name', + type: 'keyword', + }, + 'checkpoint.app_repackaged': { + category: 'checkpoint', + description: + 'Indicates whether the original application was repackage not by the official developer. ', + name: 'checkpoint.app_repackaged', + type: 'keyword', + }, + 'checkpoint.app_sid_id': { + category: 'checkpoint', + description: 'Unique SHA identifier of a mobile application. ', + name: 'checkpoint.app_sid_id', + type: 'keyword', + }, + 'checkpoint.app_version': { + category: 'checkpoint', + description: 'Version of the application downloaded on the protected mobile device. ', + name: 'checkpoint.app_version', + type: 'keyword', + }, + 'checkpoint.developer_certificate_name': { + category: 'checkpoint', + description: + "Name of the developer's certificate that was used to sign the mobile application. ", + name: 'checkpoint.developer_certificate_name', + type: 'keyword', + }, + 'checkpoint.email_message_id': { + category: 'checkpoint', + description: 'Email session id (uniqe ID of the mail). ', + name: 'checkpoint.email_message_id', + type: 'keyword', + }, + 'checkpoint.email_queue_id': { + category: 'checkpoint', + description: 'Postfix email queue id. ', + name: 'checkpoint.email_queue_id', + type: 'keyword', + }, + 'checkpoint.email_queue_name': { + category: 'checkpoint', + description: 'Postfix email queue name. ', + name: 'checkpoint.email_queue_name', + type: 'keyword', + }, + 'checkpoint.file_name': { + category: 'checkpoint', + description: 'Malicious file name. ', + name: 'checkpoint.file_name', + type: 'keyword', + }, + 'checkpoint.failure_reason': { + category: 'checkpoint', + description: 'MTA failure description. ', + name: 'checkpoint.failure_reason', + type: 'keyword', + }, + 'checkpoint.email_headers': { + category: 'checkpoint', + description: 'String containing all the email headers. ', + name: 'checkpoint.email_headers', + type: 'keyword', + }, + 'checkpoint.arrival_time': { + category: 'checkpoint', + description: 'Email arrival timestamp. ', + name: 'checkpoint.arrival_time', + type: 'keyword', + }, + 'checkpoint.email_status': { + category: 'checkpoint', + description: + "Describes the email's state. Possible options: delivered, deferred, skipped, bounced, hold, new, scan_started, scan_ended ", + name: 'checkpoint.email_status', + type: 'keyword', + }, + 'checkpoint.status_update': { + category: 'checkpoint', + description: 'Last time log was updated. ', + name: 'checkpoint.status_update', + type: 'keyword', + }, + 'checkpoint.delivery_time': { + category: 'checkpoint', + description: 'Timestamp of when email was delivered (MTA finished handling the email. ', + name: 'checkpoint.delivery_time', + type: 'keyword', + }, + 'checkpoint.links_num': { + category: 'checkpoint', + description: 'Number of links in the mail. ', + name: 'checkpoint.links_num', + type: 'integer', + }, + 'checkpoint.attachments_num': { + category: 'checkpoint', + description: 'Number of attachments in the mail. ', + name: 'checkpoint.attachments_num', + type: 'integer', + }, + 'checkpoint.email_content': { + category: 'checkpoint', + description: + 'Mail contents. Possible options: attachments/links & attachments/links/text only. ', + name: 'checkpoint.email_content', + type: 'keyword', + }, + 'checkpoint.allocated_ports': { + category: 'checkpoint', + description: 'Amount of allocated ports. ', + name: 'checkpoint.allocated_ports', + type: 'integer', + }, + 'checkpoint.capacity': { + category: 'checkpoint', + description: 'Capacity of the ports. ', + name: 'checkpoint.capacity', + type: 'integer', + }, + 'checkpoint.ports_usage': { + category: 'checkpoint', + description: 'Percentage of allocated ports. ', + name: 'checkpoint.ports_usage', + type: 'integer', + }, + 'checkpoint.nat_exhausted_pool': { + category: 'checkpoint', + description: '4-tuple of an exhausted pool. ', + name: 'checkpoint.nat_exhausted_pool', + type: 'keyword', + }, + 'checkpoint.nat_rulenum': { + category: 'checkpoint', + description: 'NAT rulebase first matched rule. ', + name: 'checkpoint.nat_rulenum', + type: 'integer', + }, + 'checkpoint.nat_addtnl_rulenum': { + category: 'checkpoint', + description: + 'When matching 2 automatic rules , second rule match will be shown otherwise field will be 0. ', + name: 'checkpoint.nat_addtnl_rulenum', + type: 'integer', + }, + 'checkpoint.message_info': { + category: 'checkpoint', + description: 'Used for information messages, for example:NAT connection has ended. ', + name: 'checkpoint.message_info', + type: 'keyword', + }, + 'checkpoint.nat46': { + category: 'checkpoint', + description: 'NAT 46 status, in most cases "enabled". ', + name: 'checkpoint.nat46', + type: 'keyword', + }, + 'checkpoint.end_time': { + category: 'checkpoint', + description: 'TCP connection end time. ', + name: 'checkpoint.end_time', + type: 'keyword', + }, + 'checkpoint.tcp_end_reason': { + category: 'checkpoint', + description: 'Reason for TCP connection closure. ', + name: 'checkpoint.tcp_end_reason', + type: 'keyword', + }, + 'checkpoint.cgnet': { + category: 'checkpoint', + description: 'Describes NAT allocation for specific subscriber. ', + name: 'checkpoint.cgnet', + type: 'keyword', + }, + 'checkpoint.subscriber': { + category: 'checkpoint', + description: 'Source IP before CGNAT. ', + name: 'checkpoint.subscriber', + type: 'ip', + }, + 'checkpoint.hide_ip': { + category: 'checkpoint', + description: 'Source IP which will be used after CGNAT. ', + name: 'checkpoint.hide_ip', + type: 'ip', + }, + 'checkpoint.int_start': { + category: 'checkpoint', + description: 'Subscriber start int which will be used for NAT. ', + name: 'checkpoint.int_start', + type: 'integer', + }, + 'checkpoint.int_end': { + category: 'checkpoint', + description: 'Subscriber end int which will be used for NAT. ', + name: 'checkpoint.int_end', + type: 'integer', + }, + 'checkpoint.packet_amount': { + category: 'checkpoint', + description: 'Amount of packets dropped. ', + name: 'checkpoint.packet_amount', + type: 'integer', + }, + 'checkpoint.monitor_reason': { + category: 'checkpoint', + description: 'Aggregated logs of monitored packets. ', + name: 'checkpoint.monitor_reason', + type: 'keyword', + }, + 'checkpoint.drops_amount': { + category: 'checkpoint', + description: 'Amount of multicast packets dropped. ', + name: 'checkpoint.drops_amount', + type: 'integer', + }, + 'checkpoint.securexl_message': { + category: 'checkpoint', + description: + 'Two options for a SecureXL message: 1. Missed accounting records after heavy load on logging system. 2. FW log message regarding a packet drop. ', + name: 'checkpoint.securexl_message', + type: 'keyword', + }, + 'checkpoint.conns_amount': { + category: 'checkpoint', + description: 'Connections amount of aggregated log info. ', + name: 'checkpoint.conns_amount', + type: 'integer', + }, + 'checkpoint.scope': { + category: 'checkpoint', + description: 'IP related to the attack. ', + name: 'checkpoint.scope', + type: 'keyword', + }, + 'checkpoint.analyzed_on': { + category: 'checkpoint', + description: 'Check Point ThreatCloud / emulator name. ', + name: 'checkpoint.analyzed_on', + type: 'keyword', + }, + 'checkpoint.detected_on': { + category: 'checkpoint', + description: 'System and applications version the file was emulated on. ', + name: 'checkpoint.detected_on', + type: 'keyword', + }, + 'checkpoint.dropped_file_name': { + category: 'checkpoint', + description: 'List of names dropped from the original file. ', + name: 'checkpoint.dropped_file_name', + type: 'keyword', + }, + 'checkpoint.dropped_file_type': { + category: 'checkpoint', + description: 'List of file types dropped from the original file. ', + name: 'checkpoint.dropped_file_type', + type: 'keyword', + }, + 'checkpoint.dropped_file_hash': { + category: 'checkpoint', + description: 'List of file hashes dropped from the original file. ', + name: 'checkpoint.dropped_file_hash', + type: 'keyword', + }, + 'checkpoint.dropped_file_verdict': { + category: 'checkpoint', + description: 'List of file verdics dropped from the original file. ', + name: 'checkpoint.dropped_file_verdict', + type: 'keyword', + }, + 'checkpoint.emulated_on': { + category: 'checkpoint', + description: 'Images the files were emulated on. ', + name: 'checkpoint.emulated_on', + type: 'keyword', + }, + 'checkpoint.extracted_file_type': { + category: 'checkpoint', + description: 'Types of extracted files in case of an archive. ', + name: 'checkpoint.extracted_file_type', + type: 'keyword', + }, + 'checkpoint.extracted_file_names': { + category: 'checkpoint', + description: 'Names of extracted files in case of an archive. ', + name: 'checkpoint.extracted_file_names', + type: 'keyword', + }, + 'checkpoint.extracted_file_hash': { + category: 'checkpoint', + description: 'Archive hash in case of extracted files. ', + name: 'checkpoint.extracted_file_hash', + type: 'keyword', + }, + 'checkpoint.extracted_file_verdict': { + category: 'checkpoint', + description: 'Verdict of extracted files in case of an archive. ', + name: 'checkpoint.extracted_file_verdict', + type: 'keyword', + }, + 'checkpoint.extracted_file_uid': { + category: 'checkpoint', + description: 'UID of extracted files in case of an archive. ', + name: 'checkpoint.extracted_file_uid', + type: 'keyword', + }, + 'checkpoint.mitre_initial_access': { + category: 'checkpoint', + description: 'The adversary is trying to break into your network. ', + name: 'checkpoint.mitre_initial_access', + type: 'keyword', + }, + 'checkpoint.mitre_execution': { + category: 'checkpoint', + description: 'The adversary is trying to run malicious code. ', + name: 'checkpoint.mitre_execution', + type: 'keyword', + }, + 'checkpoint.mitre_persistence': { + category: 'checkpoint', + description: 'The adversary is trying to maintain his foothold. ', + name: 'checkpoint.mitre_persistence', + type: 'keyword', + }, + 'checkpoint.mitre_privilege_escalation': { + category: 'checkpoint', + description: 'The adversary is trying to gain higher-level permissions. ', + name: 'checkpoint.mitre_privilege_escalation', + type: 'keyword', + }, + 'checkpoint.mitre_defense_evasion': { + category: 'checkpoint', + description: 'The adversary is trying to avoid being detected. ', + name: 'checkpoint.mitre_defense_evasion', + type: 'keyword', + }, + 'checkpoint.mitre_credential_access': { + category: 'checkpoint', + description: 'The adversary is trying to steal account names and passwords. ', + name: 'checkpoint.mitre_credential_access', + type: 'keyword', + }, + 'checkpoint.mitre_discovery': { + category: 'checkpoint', + description: 'The adversary is trying to expose information about your environment. ', + name: 'checkpoint.mitre_discovery', + type: 'keyword', + }, + 'checkpoint.mitre_lateral_movement': { + category: 'checkpoint', + description: 'The adversary is trying to explore your environment. ', + name: 'checkpoint.mitre_lateral_movement', + type: 'keyword', + }, + 'checkpoint.mitre_collection': { + category: 'checkpoint', + description: 'The adversary is trying to collect data of interest to achieve his goal. ', + name: 'checkpoint.mitre_collection', + type: 'keyword', + }, + 'checkpoint.mitre_command_and_control': { + category: 'checkpoint', + description: + 'The adversary is trying to communicate with compromised systems in order to control them. ', + name: 'checkpoint.mitre_command_and_control', + type: 'keyword', + }, + 'checkpoint.mitre_exfiltration': { + category: 'checkpoint', + description: 'The adversary is trying to steal data. ', + name: 'checkpoint.mitre_exfiltration', + type: 'keyword', + }, + 'checkpoint.mitre_impact': { + category: 'checkpoint', + description: + 'The adversary is trying to manipulate, interrupt, or destroy your systems and data. ', + name: 'checkpoint.mitre_impact', + type: 'keyword', + }, + 'checkpoint.parent_file_hash': { + category: 'checkpoint', + description: "Archive's hash in case of extracted files. ", + name: 'checkpoint.parent_file_hash', + type: 'keyword', + }, + 'checkpoint.parent_file_name': { + category: 'checkpoint', + description: "Archive's name in case of extracted files. ", + name: 'checkpoint.parent_file_name', + type: 'keyword', + }, + 'checkpoint.parent_file_uid': { + category: 'checkpoint', + description: "Archive's UID in case of extracted files. ", + name: 'checkpoint.parent_file_uid', + type: 'keyword', + }, + 'checkpoint.similiar_iocs': { + category: 'checkpoint', + description: 'Other IoCs similar to the ones found, related to the malicious file. ', + name: 'checkpoint.similiar_iocs', + type: 'keyword', + }, + 'checkpoint.similar_hashes': { + category: 'checkpoint', + description: 'Hashes found similar to the malicious file. ', + name: 'checkpoint.similar_hashes', + type: 'keyword', + }, + 'checkpoint.similar_strings': { + category: 'checkpoint', + description: 'Strings found similar to the malicious file. ', + name: 'checkpoint.similar_strings', + type: 'keyword', + }, + 'checkpoint.similar_communication': { + category: 'checkpoint', + description: 'Network action found similar to the malicious file. ', + name: 'checkpoint.similar_communication', + type: 'keyword', + }, + 'checkpoint.te_verdict_determined_by': { + category: 'checkpoint', + description: 'Emulators determined file verdict. ', + name: 'checkpoint.te_verdict_determined_by', + type: 'keyword', + }, + 'checkpoint.packet_capture_unique_id': { + category: 'checkpoint', + description: 'Identifier of the packet capture files. ', + name: 'checkpoint.packet_capture_unique_id', + type: 'keyword', + }, + 'checkpoint.total_attachments': { + category: 'checkpoint', + description: 'The number of attachments in an email. ', + name: 'checkpoint.total_attachments', + type: 'integer', + }, + 'checkpoint.additional_info': { + category: 'checkpoint', + description: 'ID of original file/mail which are sent by admin. ', + name: 'checkpoint.additional_info', + type: 'keyword', + }, + 'checkpoint.content_risk': { + category: 'checkpoint', + description: 'File risk. ', + name: 'checkpoint.content_risk', + type: 'integer', + }, + 'checkpoint.operation': { + category: 'checkpoint', + description: 'Operation made by Threat Extraction. ', + name: 'checkpoint.operation', + type: 'keyword', + }, + 'checkpoint.scrubbed_content': { + category: 'checkpoint', + description: 'Active content that was found. ', + name: 'checkpoint.scrubbed_content', + type: 'keyword', + }, + 'checkpoint.scrub_time': { + category: 'checkpoint', + description: 'Extraction process duration. ', + name: 'checkpoint.scrub_time', + type: 'keyword', + }, + 'checkpoint.scrub_download_time': { + category: 'checkpoint', + description: 'File download time from resource. ', + name: 'checkpoint.scrub_download_time', + type: 'keyword', + }, + 'checkpoint.scrub_total_time': { + category: 'checkpoint', + description: 'Threat extraction total file handling time. ', + name: 'checkpoint.scrub_total_time', + type: 'keyword', + }, + 'checkpoint.scrub_activity': { + category: 'checkpoint', + description: 'The result of the extraction ', + name: 'checkpoint.scrub_activity', + type: 'keyword', + }, + 'checkpoint.watermark': { + category: 'checkpoint', + description: 'Reports whether watermark is added to the cleaned file. ', + name: 'checkpoint.watermark', + type: 'keyword', + }, + 'checkpoint.source_object': { + category: 'checkpoint', + description: 'Matched object name on source column. ', + name: 'checkpoint.source_object', + type: 'integer', + }, + 'checkpoint.destination_object': { + category: 'checkpoint', + description: 'Matched object name on destination column. ', + name: 'checkpoint.destination_object', + type: 'keyword', + }, + 'checkpoint.drop_reason': { + category: 'checkpoint', + description: 'Drop reason description. ', + name: 'checkpoint.drop_reason', + type: 'keyword', + }, + 'checkpoint.hit': { + category: 'checkpoint', + description: 'Number of hits on a rule. ', + name: 'checkpoint.hit', + type: 'integer', + }, + 'checkpoint.rulebase_id': { + category: 'checkpoint', + description: 'Layer number. ', + name: 'checkpoint.rulebase_id', + type: 'integer', + }, + 'checkpoint.first_hit_time': { + category: 'checkpoint', + description: 'First hit time in current interval. ', + name: 'checkpoint.first_hit_time', + type: 'integer', + }, + 'checkpoint.last_hit_time': { + category: 'checkpoint', + description: 'Last hit time in current interval. ', + name: 'checkpoint.last_hit_time', + type: 'integer', + }, + 'checkpoint.rematch_info': { + category: 'checkpoint', + description: + 'Information sent when old connections cannot be matched during policy installation. ', + name: 'checkpoint.rematch_info', + type: 'keyword', + }, + 'checkpoint.last_rematch_time': { + category: 'checkpoint', + description: 'Connection rematched time. ', + name: 'checkpoint.last_rematch_time', + type: 'keyword', + }, + 'checkpoint.action_reason': { + category: 'checkpoint', + description: 'Connection drop reason. ', + name: 'checkpoint.action_reason', + type: 'integer', + }, + 'checkpoint.c_bytes': { + category: 'checkpoint', + description: 'Boolean value indicates whether bytes sent from the client side are used. ', + name: 'checkpoint.c_bytes', + type: 'integer', + }, + 'checkpoint.context_num': { + category: 'checkpoint', + description: 'Serial number of the log for a specific connection. ', + name: 'checkpoint.context_num', + type: 'integer', + }, + 'checkpoint.match_id': { + category: 'checkpoint', + description: 'Private key of the rule ', + name: 'checkpoint.match_id', + type: 'integer', + }, + 'checkpoint.alert': { + category: 'checkpoint', + description: 'Alert level of matched rule (for connection logs). ', + name: 'checkpoint.alert', + type: 'keyword', + }, + 'checkpoint.parent_rule': { + category: 'checkpoint', + description: 'Parent rule number, in case of inline layer. ', + name: 'checkpoint.parent_rule', + type: 'integer', + }, + 'checkpoint.match_fk': { + category: 'checkpoint', + description: 'Rule number. ', + name: 'checkpoint.match_fk', + type: 'integer', + }, + 'checkpoint.dropped_outgoing': { + category: 'checkpoint', + description: 'Number of outgoing bytes dropped when using UP-limit feature. ', + name: 'checkpoint.dropped_outgoing', + type: 'integer', + }, + 'checkpoint.dropped_incoming': { + category: 'checkpoint', + description: 'Number of incoming bytes dropped when using UP-limit feature. ', + name: 'checkpoint.dropped_incoming', + type: 'integer', + }, + 'checkpoint.media_type': { + category: 'checkpoint', + description: 'Media used (audio, video, etc.) ', + name: 'checkpoint.media_type', + type: 'keyword', + }, + 'checkpoint.sip_reason': { + category: 'checkpoint', + description: "Explains why 'source_ip' isn't allowed to redirect (handover). ", + name: 'checkpoint.sip_reason', + type: 'keyword', + }, + 'checkpoint.voip_method': { + category: 'checkpoint', + description: 'Registration request. ', + name: 'checkpoint.voip_method', + type: 'keyword', + }, + 'checkpoint.registered_ip-phones': { + category: 'checkpoint', + description: 'Registered IP-Phones. ', + name: 'checkpoint.registered_ip-phones', + type: 'keyword', + }, + 'checkpoint.voip_reg_user_type': { + category: 'checkpoint', + description: 'Registered IP-Phone type. ', + name: 'checkpoint.voip_reg_user_type', + type: 'keyword', + }, + 'checkpoint.voip_call_id': { + category: 'checkpoint', + description: 'Call-ID. ', + name: 'checkpoint.voip_call_id', + type: 'keyword', + }, + 'checkpoint.voip_reg_int': { + category: 'checkpoint', + description: 'Registration port. ', + name: 'checkpoint.voip_reg_int', + type: 'integer', + }, + 'checkpoint.voip_reg_ipp': { + category: 'checkpoint', + description: 'Registration IP protocol. ', + name: 'checkpoint.voip_reg_ipp', + type: 'integer', + }, + 'checkpoint.voip_reg_period': { + category: 'checkpoint', + description: 'Registration period. ', + name: 'checkpoint.voip_reg_period', + type: 'integer', + }, + 'checkpoint.src_phone_number': { + category: 'checkpoint', + description: 'Source IP-Phone. ', + name: 'checkpoint.src_phone_number', + type: 'keyword', + }, + 'checkpoint.voip_from_user_type': { + category: 'checkpoint', + description: 'Source IP-Phone type. ', + name: 'checkpoint.voip_from_user_type', + type: 'keyword', + }, + 'checkpoint.voip_to_user_type': { + category: 'checkpoint', + description: 'Destination IP-Phone type. ', + name: 'checkpoint.voip_to_user_type', + type: 'keyword', + }, + 'checkpoint.voip_call_dir': { + category: 'checkpoint', + description: 'Call direction: in/out. ', + name: 'checkpoint.voip_call_dir', + type: 'keyword', + }, + 'checkpoint.voip_call_state': { + category: 'checkpoint', + description: 'Call state. Possible values: in/out. ', + name: 'checkpoint.voip_call_state', + type: 'keyword', + }, + 'checkpoint.voip_call_term_time': { + category: 'checkpoint', + description: 'Call termination time stamp. ', + name: 'checkpoint.voip_call_term_time', + type: 'keyword', + }, + 'checkpoint.voip_duration': { + category: 'checkpoint', + description: 'Call duration (seconds). ', + name: 'checkpoint.voip_duration', + type: 'keyword', + }, + 'checkpoint.voip_media_port': { + category: 'checkpoint', + description: 'Media int. ', + name: 'checkpoint.voip_media_port', + type: 'keyword', + }, + 'checkpoint.voip_media_ipp': { + category: 'checkpoint', + description: 'Media IP protocol. ', + name: 'checkpoint.voip_media_ipp', + type: 'keyword', + }, + 'checkpoint.voip_est_codec': { + category: 'checkpoint', + description: 'Estimated codec. ', + name: 'checkpoint.voip_est_codec', + type: 'keyword', + }, + 'checkpoint.voip_exp': { + category: 'checkpoint', + description: 'Expiration. ', + name: 'checkpoint.voip_exp', + type: 'integer', + }, + 'checkpoint.voip_attach_sz': { + category: 'checkpoint', + description: 'Attachment size. ', + name: 'checkpoint.voip_attach_sz', + type: 'integer', + }, + 'checkpoint.voip_attach_action_info': { + category: 'checkpoint', + description: 'Attachment action Info. ', + name: 'checkpoint.voip_attach_action_info', + type: 'keyword', + }, + 'checkpoint.voip_media_codec': { + category: 'checkpoint', + description: 'Estimated codec. ', + name: 'checkpoint.voip_media_codec', + type: 'keyword', + }, + 'checkpoint.voip_reject_reason': { + category: 'checkpoint', + description: 'Reject reason. ', + name: 'checkpoint.voip_reject_reason', + type: 'keyword', + }, + 'checkpoint.voip_reason_info': { + category: 'checkpoint', + description: 'Information. ', + name: 'checkpoint.voip_reason_info', + type: 'keyword', + }, + 'checkpoint.voip_config': { + category: 'checkpoint', + description: 'Configuration. ', + name: 'checkpoint.voip_config', + type: 'keyword', + }, + 'checkpoint.voip_reg_server': { + category: 'checkpoint', + description: 'Registrar server IP address. ', + name: 'checkpoint.voip_reg_server', + type: 'ip', + }, + 'checkpoint.scv_user': { + category: 'checkpoint', + description: 'Username whose packets are dropped on SCV. ', + name: 'checkpoint.scv_user', + type: 'keyword', + }, + 'checkpoint.scv_message_info': { + category: 'checkpoint', + description: 'Drop reason. ', + name: 'checkpoint.scv_message_info', + type: 'keyword', + }, + 'checkpoint.ppp': { + category: 'checkpoint', + description: 'Authentication status. ', + name: 'checkpoint.ppp', + type: 'keyword', + }, + 'checkpoint.scheme': { + category: 'checkpoint', + description: 'Describes the scheme used for the log. ', + name: 'checkpoint.scheme', + type: 'keyword', + }, + 'checkpoint.machine': { + category: 'checkpoint', + description: 'L2TP machine which triggered the log and the log refers to it. ', + name: 'checkpoint.machine', + type: 'keyword', + }, + 'checkpoint.vpn_feature_name': { + category: 'checkpoint', + description: 'L2TP /IKE / Link Selection. ', + name: 'checkpoint.vpn_feature_name', + type: 'keyword', + }, + 'checkpoint.reject_category': { + category: 'checkpoint', + description: 'Authentication failure reason. ', + name: 'checkpoint.reject_category', + type: 'keyword', + }, + 'checkpoint.peer_ip_probing_status_update': { + category: 'checkpoint', + description: 'IP address response status. ', + name: 'checkpoint.peer_ip_probing_status_update', + type: 'keyword', + }, + 'checkpoint.peer_ip': { + category: 'checkpoint', + description: 'IP address which the client connects to. ', + name: 'checkpoint.peer_ip', + type: 'keyword', + }, + 'checkpoint.link_probing_status_update': { + category: 'checkpoint', + description: 'IP address response status. ', + name: 'checkpoint.link_probing_status_update', + type: 'keyword', + }, + 'checkpoint.source_interface': { + category: 'checkpoint', + description: 'External Interface name for source interface or Null if not found. ', + name: 'checkpoint.source_interface', + type: 'keyword', + }, + 'checkpoint.next_hop_ip': { + category: 'checkpoint', + description: 'Next hop IP address. ', + name: 'checkpoint.next_hop_ip', + type: 'keyword', + }, + 'checkpoint.srckeyid': { + category: 'checkpoint', + description: 'Initiator Spi ID. ', + name: 'checkpoint.srckeyid', + type: 'keyword', + }, + 'checkpoint.dstkeyid': { + category: 'checkpoint', + description: 'Responder Spi ID. ', + name: 'checkpoint.dstkeyid', + type: 'keyword', + }, + 'checkpoint.encryption_failure': { + category: 'checkpoint', + description: 'Message indicating why the encryption failed. ', + name: 'checkpoint.encryption_failure', + type: 'keyword', + }, + 'checkpoint.ike_ids': { + category: 'checkpoint', + description: 'All QM ids. ', + name: 'checkpoint.ike_ids', + type: 'keyword', + }, + 'checkpoint.community': { + category: 'checkpoint', + description: 'Community name for the IPSec key and the use of the IKEv. ', + name: 'checkpoint.community', + type: 'keyword', + }, + 'checkpoint.ike': { + category: 'checkpoint', + description: 'IKEMode (PHASE1, PHASE2, etc..). ', + name: 'checkpoint.ike', + type: 'keyword', + }, + 'checkpoint.cookieI': { + category: 'checkpoint', + description: 'Initiator cookie. ', + name: 'checkpoint.cookieI', + type: 'keyword', + }, + 'checkpoint.cookieR': { + category: 'checkpoint', + description: 'Responder cookie. ', + name: 'checkpoint.cookieR', + type: 'keyword', + }, + 'checkpoint.msgid': { + category: 'checkpoint', + description: 'Message ID. ', + name: 'checkpoint.msgid', + type: 'keyword', + }, + 'checkpoint.methods': { + category: 'checkpoint', + description: 'IPSEc methods. ', + name: 'checkpoint.methods', + type: 'keyword', + }, + 'checkpoint.connection_uid': { + category: 'checkpoint', + description: 'Calculation of md5 of the IP and user name as UID. ', + name: 'checkpoint.connection_uid', + type: 'keyword', + }, + 'checkpoint.site_name': { + category: 'checkpoint', + description: 'Site name. ', + name: 'checkpoint.site_name', + type: 'keyword', + }, + 'checkpoint.esod_rule_name': { + category: 'checkpoint', + description: 'Unknown rule name. ', + name: 'checkpoint.esod_rule_name', + type: 'keyword', + }, + 'checkpoint.esod_rule_action': { + category: 'checkpoint', + description: 'Unknown rule action. ', + name: 'checkpoint.esod_rule_action', + type: 'keyword', + }, + 'checkpoint.esod_rule_type': { + category: 'checkpoint', + description: 'Unknown rule type. ', + name: 'checkpoint.esod_rule_type', + type: 'keyword', + }, + 'checkpoint.esod_noncompliance_reason': { + category: 'checkpoint', + description: 'Non-compliance reason. ', + name: 'checkpoint.esod_noncompliance_reason', + type: 'keyword', + }, + 'checkpoint.esod_associated_policies': { + category: 'checkpoint', + description: 'Associated policies. ', + name: 'checkpoint.esod_associated_policies', + type: 'keyword', + }, + 'checkpoint.spyware_type': { + category: 'checkpoint', + description: 'Spyware type. ', + name: 'checkpoint.spyware_type', + type: 'keyword', + }, + 'checkpoint.anti_virus_type': { + category: 'checkpoint', + description: 'Anti virus type. ', + name: 'checkpoint.anti_virus_type', + type: 'keyword', + }, + 'checkpoint.end_user_firewall_type': { + category: 'checkpoint', + description: 'End user firewall type. ', + name: 'checkpoint.end_user_firewall_type', + type: 'keyword', + }, + 'checkpoint.esod_scan_status': { + category: 'checkpoint', + description: 'Scan failed. ', + name: 'checkpoint.esod_scan_status', + type: 'keyword', + }, + 'checkpoint.esod_access_status': { + category: 'checkpoint', + description: 'Access denied. ', + name: 'checkpoint.esod_access_status', + type: 'keyword', + }, + 'checkpoint.client_type': { + category: 'checkpoint', + description: 'Endpoint Connect. ', + name: 'checkpoint.client_type', + type: 'keyword', + }, + 'checkpoint.precise_error': { + category: 'checkpoint', + description: 'HTTP parser error. ', + name: 'checkpoint.precise_error', + type: 'keyword', + }, + 'checkpoint.method': { + category: 'checkpoint', + description: 'HTTP method. ', + name: 'checkpoint.method', + type: 'keyword', + }, + 'checkpoint.trusted_domain': { + category: 'checkpoint', + description: 'In case of phishing event, the domain, which the attacker was impersonating. ', + name: 'checkpoint.trusted_domain', + type: 'keyword', + }, + 'cisco.asa.message_id': { + category: 'cisco', + description: 'The Cisco ASA message identifier. ', + name: 'cisco.asa.message_id', + type: 'keyword', + }, + 'cisco.asa.suffix': { + category: 'cisco', + description: 'Optional suffix after %ASA identifier. ', + example: 'session', + name: 'cisco.asa.suffix', + type: 'keyword', + }, + 'cisco.asa.source_interface': { + category: 'cisco', + description: 'Source interface for the flow or event. ', + name: 'cisco.asa.source_interface', + type: 'keyword', + }, + 'cisco.asa.destination_interface': { + category: 'cisco', + description: 'Destination interface for the flow or event. ', + name: 'cisco.asa.destination_interface', + type: 'keyword', + }, + 'cisco.asa.rule_name': { + category: 'cisco', + description: 'Name of the Access Control List rule that matched this event. ', + name: 'cisco.asa.rule_name', + type: 'keyword', + }, + 'cisco.asa.source_username': { + category: 'cisco', + description: 'Name of the user that is the source for this event. ', + name: 'cisco.asa.source_username', + type: 'keyword', + }, + 'cisco.asa.destination_username': { + category: 'cisco', + description: 'Name of the user that is the destination for this event. ', + name: 'cisco.asa.destination_username', + type: 'keyword', + }, + 'cisco.asa.mapped_source_ip': { + category: 'cisco', + description: 'The translated source IP address. ', + name: 'cisco.asa.mapped_source_ip', + type: 'ip', + }, + 'cisco.asa.mapped_source_host': { + category: 'cisco', + description: 'The translated source host. ', + name: 'cisco.asa.mapped_source_host', + type: 'keyword', + }, + 'cisco.asa.mapped_source_port': { + category: 'cisco', + description: 'The translated source port. ', + name: 'cisco.asa.mapped_source_port', + type: 'long', + }, + 'cisco.asa.mapped_destination_ip': { + category: 'cisco', + description: 'The translated destination IP address. ', + name: 'cisco.asa.mapped_destination_ip', + type: 'ip', + }, + 'cisco.asa.mapped_destination_host': { + category: 'cisco', + description: 'The translated destination host. ', + name: 'cisco.asa.mapped_destination_host', + type: 'keyword', + }, + 'cisco.asa.mapped_destination_port': { + category: 'cisco', + description: 'The translated destination port. ', + name: 'cisco.asa.mapped_destination_port', + type: 'long', + }, + 'cisco.asa.threat_level': { + category: 'cisco', + description: + 'Threat level for malware / botnet traffic. One of very-low, low, moderate, high or very-high. ', + name: 'cisco.asa.threat_level', + type: 'keyword', + }, + 'cisco.asa.threat_category': { + category: 'cisco', + description: + 'Category for the malware / botnet traffic. For example: virus, botnet, trojan, etc. ', + name: 'cisco.asa.threat_category', + type: 'keyword', + }, + 'cisco.asa.connection_id': { + category: 'cisco', + description: 'Unique identifier for a flow. ', + name: 'cisco.asa.connection_id', + type: 'keyword', + }, + 'cisco.asa.icmp_type': { + category: 'cisco', + description: 'ICMP type. ', + name: 'cisco.asa.icmp_type', + type: 'short', + }, + 'cisco.asa.icmp_code': { + category: 'cisco', + description: 'ICMP code. ', + name: 'cisco.asa.icmp_code', + type: 'short', + }, + 'cisco.asa.connection_type': { + category: 'cisco', + description: 'The VPN connection type ', + name: 'cisco.asa.connection_type', + type: 'keyword', + }, + 'cisco.asa.dap_records': { + category: 'cisco', + description: 'The assigned DAP records ', + name: 'cisco.asa.dap_records', + type: 'keyword', + }, + 'cisco.ftd.message_id': { + category: 'cisco', + description: 'The Cisco FTD message identifier. ', + name: 'cisco.ftd.message_id', + type: 'keyword', + }, + 'cisco.ftd.suffix': { + category: 'cisco', + description: 'Optional suffix after %FTD identifier. ', + example: 'session', + name: 'cisco.ftd.suffix', + type: 'keyword', + }, + 'cisco.ftd.source_interface': { + category: 'cisco', + description: 'Source interface for the flow or event. ', + name: 'cisco.ftd.source_interface', + type: 'keyword', + }, + 'cisco.ftd.destination_interface': { + category: 'cisco', + description: 'Destination interface for the flow or event. ', + name: 'cisco.ftd.destination_interface', + type: 'keyword', + }, + 'cisco.ftd.rule_name': { + category: 'cisco', + description: 'Name of the Access Control List rule that matched this event. ', + name: 'cisco.ftd.rule_name', + type: 'keyword', + }, + 'cisco.ftd.source_username': { + category: 'cisco', + description: 'Name of the user that is the source for this event. ', + name: 'cisco.ftd.source_username', + type: 'keyword', + }, + 'cisco.ftd.destination_username': { + category: 'cisco', + description: 'Name of the user that is the destination for this event. ', + name: 'cisco.ftd.destination_username', + type: 'keyword', + }, + 'cisco.ftd.mapped_source_ip': { + category: 'cisco', + description: 'The translated source IP address. Use ECS source.nat.ip. ', + name: 'cisco.ftd.mapped_source_ip', + type: 'ip', + }, + 'cisco.ftd.mapped_source_host': { + category: 'cisco', + description: 'The translated source host. ', + name: 'cisco.ftd.mapped_source_host', + type: 'keyword', + }, + 'cisco.ftd.mapped_source_port': { + category: 'cisco', + description: 'The translated source port. Use ECS source.nat.port. ', + name: 'cisco.ftd.mapped_source_port', + type: 'long', + }, + 'cisco.ftd.mapped_destination_ip': { + category: 'cisco', + description: 'The translated destination IP address. Use ECS destination.nat.ip. ', + name: 'cisco.ftd.mapped_destination_ip', + type: 'ip', + }, + 'cisco.ftd.mapped_destination_host': { + category: 'cisco', + description: 'The translated destination host. ', + name: 'cisco.ftd.mapped_destination_host', + type: 'keyword', + }, + 'cisco.ftd.mapped_destination_port': { + category: 'cisco', + description: 'The translated destination port. Use ECS destination.nat.port. ', + name: 'cisco.ftd.mapped_destination_port', + type: 'long', + }, + 'cisco.ftd.threat_level': { + category: 'cisco', + description: + 'Threat level for malware / botnet traffic. One of very-low, low, moderate, high or very-high. ', + name: 'cisco.ftd.threat_level', + type: 'keyword', + }, + 'cisco.ftd.threat_category': { + category: 'cisco', + description: + 'Category for the malware / botnet traffic. For example: virus, botnet, trojan, etc. ', + name: 'cisco.ftd.threat_category', + type: 'keyword', + }, + 'cisco.ftd.connection_id': { + category: 'cisco', + description: 'Unique identifier for a flow. ', + name: 'cisco.ftd.connection_id', + type: 'keyword', + }, + 'cisco.ftd.icmp_type': { + category: 'cisco', + description: 'ICMP type. ', + name: 'cisco.ftd.icmp_type', + type: 'short', + }, + 'cisco.ftd.icmp_code': { + category: 'cisco', + description: 'ICMP code. ', + name: 'cisco.ftd.icmp_code', + type: 'short', + }, + 'cisco.ftd.security': { + category: 'cisco', + description: 'Raw fields for Security Events.', + name: 'cisco.ftd.security', + type: 'object', + }, + 'cisco.ftd.connection_type': { + category: 'cisco', + description: 'The VPN connection type ', + name: 'cisco.ftd.connection_type', + type: 'keyword', + }, + 'cisco.ftd.dap_records': { + category: 'cisco', + description: 'The assigned DAP records ', + name: 'cisco.ftd.dap_records', + type: 'keyword', + }, + 'cisco.ios.access_list': { + category: 'cisco', + description: 'Name of the IP access list. ', + name: 'cisco.ios.access_list', + type: 'keyword', + }, + 'cisco.ios.facility': { + category: 'cisco', + description: + 'The facility to which the message refers (for example, SNMP, SYS, and so forth). A facility can be a hardware device, a protocol, or a module of the system software. It denotes the source or the cause of the system message. ', + example: 'SEC', + name: 'cisco.ios.facility', + type: 'keyword', + }, + 'coredns.id': { + category: 'coredns', + description: 'id of the DNS transaction ', + name: 'coredns.id', + type: 'keyword', + }, + 'coredns.query.size': { + category: 'coredns', + description: 'size of the DNS query ', + name: 'coredns.query.size', + type: 'integer', + format: 'bytes', + }, + 'coredns.query.class': { + category: 'coredns', + description: 'DNS query class ', + name: 'coredns.query.class', + type: 'keyword', + }, + 'coredns.query.name': { + category: 'coredns', + description: 'DNS query name ', + name: 'coredns.query.name', + type: 'keyword', + }, + 'coredns.query.type': { + category: 'coredns', + description: 'DNS query type ', + name: 'coredns.query.type', + type: 'keyword', + }, + 'coredns.response.code': { + category: 'coredns', + description: 'DNS response code ', + name: 'coredns.response.code', + type: 'keyword', + }, + 'coredns.response.flags': { + category: 'coredns', + description: 'DNS response flags ', + name: 'coredns.response.flags', + type: 'keyword', + }, + 'coredns.response.size': { + category: 'coredns', + description: 'size of the DNS response ', + name: 'coredns.response.size', + type: 'integer', + format: 'bytes', + }, + 'coredns.dnssec_ok': { + category: 'coredns', + description: 'dnssec flag ', + name: 'coredns.dnssec_ok', + type: 'boolean', + }, + 'crowdstrike.metadata.eventType': { + category: 'crowdstrike', + description: + 'DetectionSummaryEvent, FirewallMatchEvent, IncidentSummaryEvent, RemoteResponseSessionStartEvent, RemoteResponseSessionEndEvent, AuthActivityAuditEvent, or UserActivityAuditEvent ', + name: 'crowdstrike.metadata.eventType', + type: 'keyword', + }, + 'crowdstrike.metadata.eventCreationTime': { + category: 'crowdstrike', + description: 'The time this event occurred on the endpoint in UTC UNIX_MS format. ', + name: 'crowdstrike.metadata.eventCreationTime', + type: 'date', + }, + 'crowdstrike.metadata.offset': { + category: 'crowdstrike', + description: + 'Offset number that tracks the location of the event in stream. This is used to identify unique detection events. ', + name: 'crowdstrike.metadata.offset', + type: 'integer', + }, + 'crowdstrike.metadata.customerIDString': { + category: 'crowdstrike', + description: 'Customer identifier ', + name: 'crowdstrike.metadata.customerIDString', + type: 'keyword', + }, + 'crowdstrike.metadata.version': { + category: 'crowdstrike', + description: 'Schema version ', + name: 'crowdstrike.metadata.version', + type: 'keyword', + }, + 'crowdstrike.event.ProcessStartTime': { + category: 'crowdstrike', + description: 'The process start time in UTC UNIX_MS format. ', + name: 'crowdstrike.event.ProcessStartTime', + type: 'date', + }, + 'crowdstrike.event.ProcessEndTime': { + category: 'crowdstrike', + description: 'The process termination time in UTC UNIX_MS format. ', + name: 'crowdstrike.event.ProcessEndTime', + type: 'date', + }, + 'crowdstrike.event.ProcessId': { + category: 'crowdstrike', + description: 'Process ID related to the detection. ', + name: 'crowdstrike.event.ProcessId', + type: 'integer', + }, + 'crowdstrike.event.ParentProcessId': { + category: 'crowdstrike', + description: 'Parent process ID related to the detection. ', + name: 'crowdstrike.event.ParentProcessId', + type: 'integer', + }, + 'crowdstrike.event.ComputerName': { + category: 'crowdstrike', + description: 'Name of the computer where the detection occurred. ', + name: 'crowdstrike.event.ComputerName', + type: 'keyword', + }, + 'crowdstrike.event.UserName': { + category: 'crowdstrike', + description: 'User name associated with the detection. ', + name: 'crowdstrike.event.UserName', + type: 'keyword', + }, + 'crowdstrike.event.DetectName': { + category: 'crowdstrike', + description: 'Name of the detection. ', + name: 'crowdstrike.event.DetectName', + type: 'keyword', + }, + 'crowdstrike.event.DetectDescription': { + category: 'crowdstrike', + description: 'Description of the detection. ', + name: 'crowdstrike.event.DetectDescription', + type: 'keyword', + }, + 'crowdstrike.event.Severity': { + category: 'crowdstrike', + description: 'Severity score of the detection. ', + name: 'crowdstrike.event.Severity', + type: 'integer', + }, + 'crowdstrike.event.SeverityName': { + category: 'crowdstrike', + description: 'Severity score text. ', + name: 'crowdstrike.event.SeverityName', + type: 'keyword', + }, + 'crowdstrike.event.FileName': { + category: 'crowdstrike', + description: 'File name of the associated process for the detection. ', + name: 'crowdstrike.event.FileName', + type: 'keyword', + }, + 'crowdstrike.event.FilePath': { + category: 'crowdstrike', + description: 'Path of the executable associated with the detection. ', + name: 'crowdstrike.event.FilePath', + type: 'keyword', + }, + 'crowdstrike.event.CommandLine': { + category: 'crowdstrike', + description: 'Executable path with command line arguments. ', + name: 'crowdstrike.event.CommandLine', + type: 'keyword', + }, + 'crowdstrike.event.SHA1String': { + category: 'crowdstrike', + description: 'SHA1 sum of the executable associated with the detection. ', + name: 'crowdstrike.event.SHA1String', + type: 'keyword', + }, + 'crowdstrike.event.SHA256String': { + category: 'crowdstrike', + description: 'SHA256 sum of the executable associated with the detection. ', + name: 'crowdstrike.event.SHA256String', + type: 'keyword', + }, + 'crowdstrike.event.MD5String': { + category: 'crowdstrike', + description: 'MD5 sum of the executable associated with the detection. ', + name: 'crowdstrike.event.MD5String', + type: 'keyword', + }, + 'crowdstrike.event.MachineDomain': { + category: 'crowdstrike', + description: 'Domain for the machine associated with the detection. ', + name: 'crowdstrike.event.MachineDomain', + type: 'keyword', + }, + 'crowdstrike.event.FalconHostLink': { + category: 'crowdstrike', + description: 'URL to view the detection in Falcon. ', + name: 'crowdstrike.event.FalconHostLink', + type: 'keyword', + }, + 'crowdstrike.event.SensorId': { + category: 'crowdstrike', + description: 'Unique ID associated with the Falcon sensor. ', + name: 'crowdstrike.event.SensorId', + type: 'keyword', + }, + 'crowdstrike.event.DetectId': { + category: 'crowdstrike', + description: 'Unique ID associated with the detection. ', + name: 'crowdstrike.event.DetectId', + type: 'keyword', + }, + 'crowdstrike.event.LocalIP': { + category: 'crowdstrike', + description: 'IP address of the host associated with the detection. ', + name: 'crowdstrike.event.LocalIP', + type: 'keyword', + }, + 'crowdstrike.event.MACAddress': { + category: 'crowdstrike', + description: 'MAC address of the host associated with the detection. ', + name: 'crowdstrike.event.MACAddress', + type: 'keyword', + }, + 'crowdstrike.event.Tactic': { + category: 'crowdstrike', + description: 'MITRE tactic category of the detection. ', + name: 'crowdstrike.event.Tactic', + type: 'keyword', + }, + 'crowdstrike.event.Technique': { + category: 'crowdstrike', + description: 'MITRE technique category of the detection. ', + name: 'crowdstrike.event.Technique', + type: 'keyword', + }, + 'crowdstrike.event.Objective': { + category: 'crowdstrike', + description: 'Method of detection. ', + name: 'crowdstrike.event.Objective', + type: 'keyword', + }, + 'crowdstrike.event.PatternDispositionDescription': { + category: 'crowdstrike', + description: 'Action taken by Falcon. ', + name: 'crowdstrike.event.PatternDispositionDescription', + type: 'keyword', + }, + 'crowdstrike.event.PatternDispositionValue': { + category: 'crowdstrike', + description: 'Unique ID associated with action taken. ', + name: 'crowdstrike.event.PatternDispositionValue', + type: 'integer', + }, + 'crowdstrike.event.PatternDispositionFlags': { + category: 'crowdstrike', + description: 'Flags indicating actions taken. ', + name: 'crowdstrike.event.PatternDispositionFlags', + type: 'object', + }, + 'crowdstrike.event.State': { + category: 'crowdstrike', + description: 'Whether the incident summary is open and ongoing or closed. ', + name: 'crowdstrike.event.State', + type: 'keyword', + }, + 'crowdstrike.event.IncidentStartTime': { + category: 'crowdstrike', + description: 'Start time for the incident in UTC UNIX format. ', + name: 'crowdstrike.event.IncidentStartTime', + type: 'date', + }, + 'crowdstrike.event.IncidentEndTime': { + category: 'crowdstrike', + description: 'End time for the incident in UTC UNIX format. ', + name: 'crowdstrike.event.IncidentEndTime', + type: 'date', + }, + 'crowdstrike.event.FineScore': { + category: 'crowdstrike', + description: 'Score for incident. ', + name: 'crowdstrike.event.FineScore', + type: 'float', + }, + 'crowdstrike.event.UserId': { + category: 'crowdstrike', + description: 'Email address or user ID associated with the event. ', + name: 'crowdstrike.event.UserId', + type: 'keyword', + }, + 'crowdstrike.event.UserIp': { + category: 'crowdstrike', + description: 'IP address associated with the user. ', + name: 'crowdstrike.event.UserIp', + type: 'keyword', + }, + 'crowdstrike.event.OperationName': { + category: 'crowdstrike', + description: 'Event subtype. ', + name: 'crowdstrike.event.OperationName', + type: 'keyword', + }, + 'crowdstrike.event.ServiceName': { + category: 'crowdstrike', + description: 'Service associated with this event. ', + name: 'crowdstrike.event.ServiceName', + type: 'keyword', + }, + 'crowdstrike.event.Success': { + category: 'crowdstrike', + description: 'Indicator of whether or not this event was successful. ', + name: 'crowdstrike.event.Success', + type: 'boolean', + }, + 'crowdstrike.event.UTCTimestamp': { + category: 'crowdstrike', + description: 'Timestamp associated with this event in UTC UNIX format. ', + name: 'crowdstrike.event.UTCTimestamp', + type: 'date', + }, + 'crowdstrike.event.AuditKeyValues': { + category: 'crowdstrike', + description: 'Fields that were changed in this event. ', + name: 'crowdstrike.event.AuditKeyValues', + type: 'nested', + }, + 'crowdstrike.event.ExecutablesWritten': { + category: 'crowdstrike', + description: 'Detected executables written to disk by a process. ', + name: 'crowdstrike.event.ExecutablesWritten', + type: 'nested', + }, + 'crowdstrike.event.SessionId': { + category: 'crowdstrike', + description: 'Session ID of the remote response session. ', + name: 'crowdstrike.event.SessionId', + type: 'keyword', + }, + 'crowdstrike.event.HostnameField': { + category: 'crowdstrike', + description: 'Host name of the machine for the remote session. ', + name: 'crowdstrike.event.HostnameField', + type: 'keyword', + }, + 'crowdstrike.event.StartTimestamp': { + category: 'crowdstrike', + description: 'Start time for the remote session in UTC UNIX format. ', + name: 'crowdstrike.event.StartTimestamp', + type: 'date', + }, + 'crowdstrike.event.EndTimestamp': { + category: 'crowdstrike', + description: 'End time for the remote session in UTC UNIX format. ', + name: 'crowdstrike.event.EndTimestamp', + type: 'date', + }, + 'crowdstrike.event.LateralMovement': { + category: 'crowdstrike', + description: 'Lateral movement field for incident. ', + name: 'crowdstrike.event.LateralMovement', + type: 'long', + }, + 'crowdstrike.event.ParentImageFileName': { + category: 'crowdstrike', + description: 'Path to the parent process. ', + name: 'crowdstrike.event.ParentImageFileName', + type: 'keyword', + }, + 'crowdstrike.event.ParentCommandLine': { + category: 'crowdstrike', + description: 'Parent process command line arguments. ', + name: 'crowdstrike.event.ParentCommandLine', + type: 'keyword', + }, + 'crowdstrike.event.GrandparentImageFileName': { + category: 'crowdstrike', + description: 'Path to the grandparent process. ', + name: 'crowdstrike.event.GrandparentImageFileName', + type: 'keyword', + }, + 'crowdstrike.event.GrandparentCommandLine': { + category: 'crowdstrike', + description: 'Grandparent process command line arguments. ', + name: 'crowdstrike.event.GrandparentCommandLine', + type: 'keyword', + }, + 'crowdstrike.event.IOCType': { + category: 'crowdstrike', + description: 'CrowdStrike type for indicator of compromise. ', + name: 'crowdstrike.event.IOCType', + type: 'keyword', + }, + 'crowdstrike.event.IOCValue': { + category: 'crowdstrike', + description: 'CrowdStrike value for indicator of compromise. ', + name: 'crowdstrike.event.IOCValue', + type: 'keyword', + }, + 'crowdstrike.event.CustomerId': { + category: 'crowdstrike', + description: 'Customer identifier. ', + name: 'crowdstrike.event.CustomerId', + type: 'keyword', + }, + 'crowdstrike.event.DeviceId': { + category: 'crowdstrike', + description: 'Device on which the event occurred. ', + name: 'crowdstrike.event.DeviceId', + type: 'keyword', + }, + 'crowdstrike.event.Ipv': { + category: 'crowdstrike', + description: 'Protocol for network request. ', + name: 'crowdstrike.event.Ipv', + type: 'keyword', + }, + 'crowdstrike.event.ConnectionDirection': { + category: 'crowdstrike', + description: 'Direction for network connection. ', + name: 'crowdstrike.event.ConnectionDirection', + type: 'keyword', + }, + 'crowdstrike.event.EventType': { + category: 'crowdstrike', + description: 'CrowdStrike provided event type. ', + name: 'crowdstrike.event.EventType', + type: 'keyword', + }, + 'crowdstrike.event.HostName': { + category: 'crowdstrike', + description: 'Host name of the local machine. ', + name: 'crowdstrike.event.HostName', + type: 'keyword', + }, + 'crowdstrike.event.ICMPCode': { + category: 'crowdstrike', + description: 'RFC2780 ICMP Code field. ', + name: 'crowdstrike.event.ICMPCode', + type: 'keyword', + }, + 'crowdstrike.event.ICMPType': { + category: 'crowdstrike', + description: 'RFC2780 ICMP Type field. ', + name: 'crowdstrike.event.ICMPType', + type: 'keyword', + }, + 'crowdstrike.event.ImageFileName': { + category: 'crowdstrike', + description: 'File name of the associated process for the detection. ', + name: 'crowdstrike.event.ImageFileName', + type: 'keyword', + }, + 'crowdstrike.event.PID': { + category: 'crowdstrike', + description: 'Associated process id for the detection. ', + name: 'crowdstrike.event.PID', + type: 'long', + }, + 'crowdstrike.event.LocalAddress': { + category: 'crowdstrike', + description: 'IP address of local machine. ', + name: 'crowdstrike.event.LocalAddress', + type: 'ip', + }, + 'crowdstrike.event.LocalPort': { + category: 'crowdstrike', + description: 'Port of local machine. ', + name: 'crowdstrike.event.LocalPort', + type: 'long', + }, + 'crowdstrike.event.RemoteAddress': { + category: 'crowdstrike', + description: 'IP address of remote machine. ', + name: 'crowdstrike.event.RemoteAddress', + type: 'ip', + }, + 'crowdstrike.event.RemotePort': { + category: 'crowdstrike', + description: 'Port of remote machine. ', + name: 'crowdstrike.event.RemotePort', + type: 'long', + }, + 'crowdstrike.event.RuleAction': { + category: 'crowdstrike', + description: 'Firewall rule action. ', + name: 'crowdstrike.event.RuleAction', + type: 'keyword', + }, + 'crowdstrike.event.RuleDescription': { + category: 'crowdstrike', + description: 'Firewall rule description. ', + name: 'crowdstrike.event.RuleDescription', + type: 'keyword', + }, + 'crowdstrike.event.RuleFamilyID': { + category: 'crowdstrike', + description: 'Firewall rule family id. ', + name: 'crowdstrike.event.RuleFamilyID', + type: 'keyword', + }, + 'crowdstrike.event.RuleGroupName': { + category: 'crowdstrike', + description: 'Firewall rule group name. ', + name: 'crowdstrike.event.RuleGroupName', + type: 'keyword', + }, + 'crowdstrike.event.RuleName': { + category: 'crowdstrike', + description: 'Firewall rule name. ', + name: 'crowdstrike.event.RuleName', + type: 'keyword', + }, + 'crowdstrike.event.RuleId': { + category: 'crowdstrike', + description: 'Firewall rule id. ', + name: 'crowdstrike.event.RuleId', + type: 'keyword', + }, + 'crowdstrike.event.MatchCount': { + category: 'crowdstrike', + description: 'Number of firewall rule matches. ', + name: 'crowdstrike.event.MatchCount', + type: 'long', + }, + 'crowdstrike.event.MatchCountSinceLastReport': { + category: 'crowdstrike', + description: 'Number of firewall rule matches since the last report. ', + name: 'crowdstrike.event.MatchCountSinceLastReport', + type: 'long', + }, + 'crowdstrike.event.Timestamp': { + category: 'crowdstrike', + description: 'Firewall rule triggered timestamp. ', + name: 'crowdstrike.event.Timestamp', + type: 'date', + }, + 'crowdstrike.event.Flags.Audit': { + category: 'crowdstrike', + description: 'CrowdStrike audit flag. ', + name: 'crowdstrike.event.Flags.Audit', + type: 'boolean', + }, + 'crowdstrike.event.Flags.Log': { + category: 'crowdstrike', + description: 'CrowdStrike log flag. ', + name: 'crowdstrike.event.Flags.Log', + type: 'boolean', + }, + 'crowdstrike.event.Flags.Monitor': { + category: 'crowdstrike', + description: 'CrowdStrike monitor flag. ', + name: 'crowdstrike.event.Flags.Monitor', + type: 'boolean', + }, + 'crowdstrike.event.Protocol': { + category: 'crowdstrike', + description: 'CrowdStrike provided protocol. ', + name: 'crowdstrike.event.Protocol', + type: 'keyword', + }, + 'crowdstrike.event.NetworkProfile': { + category: 'crowdstrike', + description: 'CrowdStrike network profile. ', + name: 'crowdstrike.event.NetworkProfile', + type: 'keyword', + }, + 'crowdstrike.event.PolicyName': { + category: 'crowdstrike', + description: 'CrowdStrike policy name. ', + name: 'crowdstrike.event.PolicyName', + type: 'keyword', + }, + 'crowdstrike.event.PolicyID': { + category: 'crowdstrike', + description: 'CrowdStrike policy id. ', + name: 'crowdstrike.event.PolicyID', + type: 'keyword', + }, + 'crowdstrike.event.Status': { + category: 'crowdstrike', + description: 'CrowdStrike status. ', + name: 'crowdstrike.event.Status', + type: 'keyword', + }, + 'crowdstrike.event.TreeID': { + category: 'crowdstrike', + description: 'CrowdStrike tree id. ', + name: 'crowdstrike.event.TreeID', + type: 'keyword', + }, + 'crowdstrike.event.Commands': { + category: 'crowdstrike', + description: 'Commands run in a remote session. ', + name: 'crowdstrike.event.Commands', + type: 'keyword', + }, + 'envoyproxy.log_type': { + category: 'envoyproxy', + description: 'Envoy log type, normally ACCESS ', + name: 'envoyproxy.log_type', + type: 'keyword', + }, + 'envoyproxy.response_flags': { + category: 'envoyproxy', + description: 'Response flags ', + name: 'envoyproxy.response_flags', + type: 'keyword', + }, + 'envoyproxy.upstream_service_time': { + category: 'envoyproxy', + description: 'Upstream service time in nanoseconds ', + name: 'envoyproxy.upstream_service_time', + type: 'long', + format: 'duration', + }, + 'envoyproxy.request_id': { + category: 'envoyproxy', + description: 'ID of the request ', + name: 'envoyproxy.request_id', + type: 'keyword', + }, + 'envoyproxy.authority': { + category: 'envoyproxy', + description: 'Envoy proxy authority field ', + name: 'envoyproxy.authority', + type: 'keyword', + }, + 'envoyproxy.proxy_type': { + category: 'envoyproxy', + description: 'Envoy proxy type, tcp or http ', + name: 'envoyproxy.proxy_type', + type: 'keyword', + }, + 'fortinet.file.hash.crc32': { + category: 'fortinet', + description: 'CRC32 Hash of file ', + name: 'fortinet.file.hash.crc32', + type: 'keyword', + }, + 'fortinet.firewall.acct_stat': { + category: 'fortinet', + description: 'Accounting state (RADIUS) ', + name: 'fortinet.firewall.acct_stat', + type: 'keyword', + }, + 'fortinet.firewall.acktime': { + category: 'fortinet', + description: 'Alarm Acknowledge Time ', + name: 'fortinet.firewall.acktime', + type: 'keyword', + }, + 'fortinet.firewall.act': { + category: 'fortinet', + description: 'Action ', + name: 'fortinet.firewall.act', + type: 'keyword', + }, + 'fortinet.firewall.action': { + category: 'fortinet', + description: 'Status of the session ', + name: 'fortinet.firewall.action', + type: 'keyword', + }, + 'fortinet.firewall.activity': { + category: 'fortinet', + description: 'HA activity message ', + name: 'fortinet.firewall.activity', + type: 'keyword', + }, + 'fortinet.firewall.addr': { + category: 'fortinet', + description: 'IP Address ', + name: 'fortinet.firewall.addr', + type: 'ip', + }, + 'fortinet.firewall.addr_type': { + category: 'fortinet', + description: 'Address Type ', + name: 'fortinet.firewall.addr_type', + type: 'keyword', + }, + 'fortinet.firewall.addrgrp': { + category: 'fortinet', + description: 'Address Group ', + name: 'fortinet.firewall.addrgrp', + type: 'keyword', + }, + 'fortinet.firewall.adgroup': { + category: 'fortinet', + description: 'AD Group Name ', + name: 'fortinet.firewall.adgroup', + type: 'keyword', + }, + 'fortinet.firewall.admin': { + category: 'fortinet', + description: 'Admin User ', + name: 'fortinet.firewall.admin', + type: 'keyword', + }, + 'fortinet.firewall.age': { + category: 'fortinet', + description: 'Time in seconds - time passed since last seen ', + name: 'fortinet.firewall.age', + type: 'integer', + }, + 'fortinet.firewall.agent': { + category: 'fortinet', + description: 'User agent - eg. agent="Mozilla/5.0" ', + name: 'fortinet.firewall.agent', + type: 'keyword', + }, + 'fortinet.firewall.alarmid': { + category: 'fortinet', + description: 'Alarm ID ', + name: 'fortinet.firewall.alarmid', + type: 'integer', + }, + 'fortinet.firewall.alert': { + category: 'fortinet', + description: 'Alert ', + name: 'fortinet.firewall.alert', + type: 'keyword', + }, + 'fortinet.firewall.analyticscksum': { + category: 'fortinet', + description: 'The checksum of the file submitted for analytics ', + name: 'fortinet.firewall.analyticscksum', + type: 'keyword', + }, + 'fortinet.firewall.analyticssubmit': { + category: 'fortinet', + description: 'The flag for analytics submission ', + name: 'fortinet.firewall.analyticssubmit', + type: 'keyword', + }, + 'fortinet.firewall.ap': { + category: 'fortinet', + description: 'Access Point ', + name: 'fortinet.firewall.ap', + type: 'keyword', + }, + 'fortinet.firewall.app-type': { + category: 'fortinet', + description: 'Address Type ', + name: 'fortinet.firewall.app-type', + type: 'keyword', + }, + 'fortinet.firewall.appact': { + category: 'fortinet', + description: 'The security action from app control ', + name: 'fortinet.firewall.appact', + type: 'keyword', + }, + 'fortinet.firewall.appid': { + category: 'fortinet', + description: 'Application ID ', + name: 'fortinet.firewall.appid', + type: 'integer', + }, + 'fortinet.firewall.applist': { + category: 'fortinet', + description: 'Application Control profile ', + name: 'fortinet.firewall.applist', + type: 'keyword', + }, + 'fortinet.firewall.apprisk': { + category: 'fortinet', + description: 'Application Risk Level ', + name: 'fortinet.firewall.apprisk', + type: 'keyword', + }, + 'fortinet.firewall.apscan': { + category: 'fortinet', + description: 'The name of the AP, which scanned and detected the rogue AP ', + name: 'fortinet.firewall.apscan', + type: 'keyword', + }, + 'fortinet.firewall.apsn': { + category: 'fortinet', + description: 'Access Point ', + name: 'fortinet.firewall.apsn', + type: 'keyword', + }, + 'fortinet.firewall.apstatus': { + category: 'fortinet', + description: 'Access Point status ', + name: 'fortinet.firewall.apstatus', + type: 'keyword', + }, + 'fortinet.firewall.aptype': { + category: 'fortinet', + description: 'Access Point type ', + name: 'fortinet.firewall.aptype', + type: 'keyword', + }, + 'fortinet.firewall.assigned': { + category: 'fortinet', + description: 'Assigned IP Address ', + name: 'fortinet.firewall.assigned', + type: 'ip', + }, + 'fortinet.firewall.assignip': { + category: 'fortinet', + description: 'Assigned IP Address ', + name: 'fortinet.firewall.assignip', + type: 'ip', + }, + 'fortinet.firewall.attachment': { + category: 'fortinet', + description: 'The flag for email attachement ', + name: 'fortinet.firewall.attachment', + type: 'keyword', + }, + 'fortinet.firewall.attack': { + category: 'fortinet', + description: 'Attack Name ', + name: 'fortinet.firewall.attack', + type: 'keyword', + }, + 'fortinet.firewall.attackcontext': { + category: 'fortinet', + description: 'The trigger patterns and the packetdata with base64 encoding ', + name: 'fortinet.firewall.attackcontext', + type: 'keyword', + }, + 'fortinet.firewall.attackcontextid': { + category: 'fortinet', + description: 'Attack context id / total ', + name: 'fortinet.firewall.attackcontextid', + type: 'keyword', + }, + 'fortinet.firewall.attackid': { + category: 'fortinet', + description: 'Attack ID ', + name: 'fortinet.firewall.attackid', + type: 'integer', + }, + 'fortinet.firewall.auditid': { + category: 'fortinet', + description: 'Audit ID ', + name: 'fortinet.firewall.auditid', + type: 'long', + }, + 'fortinet.firewall.auditscore': { + category: 'fortinet', + description: 'The Audit Score ', + name: 'fortinet.firewall.auditscore', + type: 'keyword', + }, + 'fortinet.firewall.audittime': { + category: 'fortinet', + description: 'The time of the audit ', + name: 'fortinet.firewall.audittime', + type: 'long', + }, + 'fortinet.firewall.authgrp': { + category: 'fortinet', + description: 'Authorization Group ', + name: 'fortinet.firewall.authgrp', + type: 'keyword', + }, + 'fortinet.firewall.authid': { + category: 'fortinet', + description: 'Authentication ID ', + name: 'fortinet.firewall.authid', + type: 'keyword', + }, + 'fortinet.firewall.authproto': { + category: 'fortinet', + description: 'The protocol that initiated the authentication ', + name: 'fortinet.firewall.authproto', + type: 'keyword', + }, + 'fortinet.firewall.authserver': { + category: 'fortinet', + description: 'Authentication server ', + name: 'fortinet.firewall.authserver', + type: 'keyword', + }, + 'fortinet.firewall.bandwidth': { + category: 'fortinet', + description: 'Bandwidth ', + name: 'fortinet.firewall.bandwidth', + type: 'keyword', + }, + 'fortinet.firewall.banned_rule': { + category: 'fortinet', + description: 'NAC quarantine Banned Rule Name ', + name: 'fortinet.firewall.banned_rule', + type: 'keyword', + }, + 'fortinet.firewall.banned_src': { + category: 'fortinet', + description: 'NAC quarantine Banned Source IP ', + name: 'fortinet.firewall.banned_src', + type: 'keyword', + }, + 'fortinet.firewall.banword': { + category: 'fortinet', + description: 'Banned word ', + name: 'fortinet.firewall.banword', + type: 'keyword', + }, + 'fortinet.firewall.botnetdomain': { + category: 'fortinet', + description: 'Botnet Domain Name ', + name: 'fortinet.firewall.botnetdomain', + type: 'keyword', + }, + 'fortinet.firewall.botnetip': { + category: 'fortinet', + description: 'Botnet IP Address ', + name: 'fortinet.firewall.botnetip', + type: 'ip', + }, + 'fortinet.firewall.bssid': { + category: 'fortinet', + description: 'Service Set ID ', + name: 'fortinet.firewall.bssid', + type: 'keyword', + }, + 'fortinet.firewall.call_id': { + category: 'fortinet', + description: 'Caller ID ', + name: 'fortinet.firewall.call_id', + type: 'keyword', + }, + 'fortinet.firewall.carrier_ep': { + category: 'fortinet', + description: 'The FortiOS Carrier end-point identification ', + name: 'fortinet.firewall.carrier_ep', + type: 'keyword', + }, + 'fortinet.firewall.cat': { + category: 'fortinet', + description: 'DNS category ID ', + name: 'fortinet.firewall.cat', + type: 'integer', + }, + 'fortinet.firewall.category': { + category: 'fortinet', + description: 'Authentication category ', + name: 'fortinet.firewall.category', + type: 'keyword', + }, + 'fortinet.firewall.cc': { + category: 'fortinet', + description: 'CC Email Address ', + name: 'fortinet.firewall.cc', + type: 'keyword', + }, + 'fortinet.firewall.cdrcontent': { + category: 'fortinet', + description: 'Cdrcontent ', + name: 'fortinet.firewall.cdrcontent', + type: 'keyword', + }, + 'fortinet.firewall.centralnatid': { + category: 'fortinet', + description: 'Central NAT ID ', + name: 'fortinet.firewall.centralnatid', + type: 'integer', + }, + 'fortinet.firewall.cert': { + category: 'fortinet', + description: 'Certificate ', + name: 'fortinet.firewall.cert', + type: 'keyword', + }, + 'fortinet.firewall.cert-type': { + category: 'fortinet', + description: 'Certificate type ', + name: 'fortinet.firewall.cert-type', + type: 'keyword', + }, + 'fortinet.firewall.certhash': { + category: 'fortinet', + description: 'Certificate hash ', + name: 'fortinet.firewall.certhash', + type: 'keyword', + }, + 'fortinet.firewall.cfgattr': { + category: 'fortinet', + description: 'Configuration attribute ', + name: 'fortinet.firewall.cfgattr', + type: 'keyword', + }, + 'fortinet.firewall.cfgobj': { + category: 'fortinet', + description: 'Configuration object ', + name: 'fortinet.firewall.cfgobj', + type: 'keyword', + }, + 'fortinet.firewall.cfgpath': { + category: 'fortinet', + description: 'Configuration path ', + name: 'fortinet.firewall.cfgpath', + type: 'keyword', + }, + 'fortinet.firewall.cfgtid': { + category: 'fortinet', + description: 'Configuration transaction ID ', + name: 'fortinet.firewall.cfgtid', + type: 'keyword', + }, + 'fortinet.firewall.cfgtxpower': { + category: 'fortinet', + description: 'Configuration TX power ', + name: 'fortinet.firewall.cfgtxpower', + type: 'integer', + }, + 'fortinet.firewall.channel': { + category: 'fortinet', + description: 'Wireless Channel ', + name: 'fortinet.firewall.channel', + type: 'integer', + }, + 'fortinet.firewall.channeltype': { + category: 'fortinet', + description: 'SSH channel type ', + name: 'fortinet.firewall.channeltype', + type: 'keyword', + }, + 'fortinet.firewall.chassisid': { + category: 'fortinet', + description: 'Chassis ID ', + name: 'fortinet.firewall.chassisid', + type: 'integer', + }, + 'fortinet.firewall.checksum': { + category: 'fortinet', + description: 'The checksum of the scanned file ', + name: 'fortinet.firewall.checksum', + type: 'keyword', + }, + 'fortinet.firewall.chgheaders': { + category: 'fortinet', + description: 'HTTP Headers ', + name: 'fortinet.firewall.chgheaders', + type: 'keyword', + }, + 'fortinet.firewall.cldobjid': { + category: 'fortinet', + description: 'Connector object ID ', + name: 'fortinet.firewall.cldobjid', + type: 'keyword', + }, + 'fortinet.firewall.client_addr': { + category: 'fortinet', + description: 'Wifi client address ', + name: 'fortinet.firewall.client_addr', + type: 'keyword', + }, + 'fortinet.firewall.cloudaction': { + category: 'fortinet', + description: 'Cloud Action ', + name: 'fortinet.firewall.cloudaction', + type: 'keyword', + }, + 'fortinet.firewall.clouduser': { + category: 'fortinet', + description: 'Cloud User ', + name: 'fortinet.firewall.clouduser', + type: 'keyword', + }, + 'fortinet.firewall.column': { + category: 'fortinet', + description: 'VOIP Column ', + name: 'fortinet.firewall.column', + type: 'integer', + }, + 'fortinet.firewall.command': { + category: 'fortinet', + description: 'CLI Command ', + name: 'fortinet.firewall.command', + type: 'keyword', + }, + 'fortinet.firewall.community': { + category: 'fortinet', + description: 'SNMP Community ', + name: 'fortinet.firewall.community', + type: 'keyword', + }, + 'fortinet.firewall.configcountry': { + category: 'fortinet', + description: 'Configuration country ', + name: 'fortinet.firewall.configcountry', + type: 'keyword', + }, + 'fortinet.firewall.connection_type': { + category: 'fortinet', + description: 'FortiClient Connection Type ', + name: 'fortinet.firewall.connection_type', + type: 'keyword', + }, + 'fortinet.firewall.conserve': { + category: 'fortinet', + description: 'Flag for conserve mode ', + name: 'fortinet.firewall.conserve', + type: 'keyword', + }, + 'fortinet.firewall.constraint': { + category: 'fortinet', + description: 'WAF http protocol restrictions ', + name: 'fortinet.firewall.constraint', + type: 'keyword', + }, + 'fortinet.firewall.contentdisarmed': { + category: 'fortinet', + description: 'Email scanned content ', + name: 'fortinet.firewall.contentdisarmed', + type: 'keyword', + }, + 'fortinet.firewall.contenttype': { + category: 'fortinet', + description: 'Content Type from HTTP header ', + name: 'fortinet.firewall.contenttype', + type: 'keyword', + }, + 'fortinet.firewall.cookies': { + category: 'fortinet', + description: 'VPN Cookie ', + name: 'fortinet.firewall.cookies', + type: 'keyword', + }, + 'fortinet.firewall.count': { + category: 'fortinet', + description: 'Counts of action type ', + name: 'fortinet.firewall.count', + type: 'integer', + }, + 'fortinet.firewall.countapp': { + category: 'fortinet', + description: 'Number of App Ctrl logs associated with the session ', + name: 'fortinet.firewall.countapp', + type: 'integer', + }, + 'fortinet.firewall.countav': { + category: 'fortinet', + description: 'Number of AV logs associated with the session ', + name: 'fortinet.firewall.countav', + type: 'integer', + }, + 'fortinet.firewall.countcifs': { + category: 'fortinet', + description: 'Number of CIFS logs associated with the session ', + name: 'fortinet.firewall.countcifs', + type: 'integer', + }, + 'fortinet.firewall.countdlp': { + category: 'fortinet', + description: 'Number of DLP logs associated with the session ', + name: 'fortinet.firewall.countdlp', + type: 'integer', + }, + 'fortinet.firewall.countdns': { + category: 'fortinet', + description: 'Number of DNS logs associated with the session ', + name: 'fortinet.firewall.countdns', + type: 'integer', + }, + 'fortinet.firewall.countemail': { + category: 'fortinet', + description: 'Number of email logs associated with the session ', + name: 'fortinet.firewall.countemail', + type: 'integer', + }, + 'fortinet.firewall.countff': { + category: 'fortinet', + description: 'Number of ff logs associated with the session ', + name: 'fortinet.firewall.countff', + type: 'integer', + }, + 'fortinet.firewall.countips': { + category: 'fortinet', + description: 'Number of IPS logs associated with the session ', + name: 'fortinet.firewall.countips', + type: 'integer', + }, + 'fortinet.firewall.countssh': { + category: 'fortinet', + description: 'Number of SSH logs associated with the session ', + name: 'fortinet.firewall.countssh', + type: 'integer', + }, + 'fortinet.firewall.countssl': { + category: 'fortinet', + description: 'Number of SSL logs associated with the session ', + name: 'fortinet.firewall.countssl', + type: 'integer', + }, + 'fortinet.firewall.countwaf': { + category: 'fortinet', + description: 'Number of WAF logs associated with the session ', + name: 'fortinet.firewall.countwaf', + type: 'integer', + }, + 'fortinet.firewall.countweb': { + category: 'fortinet', + description: 'Number of Web filter logs associated with the session ', + name: 'fortinet.firewall.countweb', + type: 'integer', + }, + 'fortinet.firewall.cpu': { + category: 'fortinet', + description: 'CPU Usage ', + name: 'fortinet.firewall.cpu', + type: 'integer', + }, + 'fortinet.firewall.craction': { + category: 'fortinet', + description: 'Client Reputation Action ', + name: 'fortinet.firewall.craction', + type: 'integer', + }, + 'fortinet.firewall.criticalcount': { + category: 'fortinet', + description: 'Number of critical ratings ', + name: 'fortinet.firewall.criticalcount', + type: 'integer', + }, + 'fortinet.firewall.crl': { + category: 'fortinet', + description: 'Client Reputation Level ', + name: 'fortinet.firewall.crl', + type: 'keyword', + }, + 'fortinet.firewall.crlevel': { + category: 'fortinet', + description: 'Client Reputation Level ', + name: 'fortinet.firewall.crlevel', + type: 'keyword', + }, + 'fortinet.firewall.crscore': { + category: 'fortinet', + description: 'Some description ', + name: 'fortinet.firewall.crscore', + type: 'integer', + }, + 'fortinet.firewall.cveid': { + category: 'fortinet', + description: 'CVE ID ', + name: 'fortinet.firewall.cveid', + type: 'keyword', + }, + 'fortinet.firewall.daemon': { + category: 'fortinet', + description: 'Daemon name ', + name: 'fortinet.firewall.daemon', + type: 'keyword', + }, + 'fortinet.firewall.datarange': { + category: 'fortinet', + description: 'Data range for reports ', + name: 'fortinet.firewall.datarange', + type: 'keyword', + }, + 'fortinet.firewall.date': { + category: 'fortinet', + description: 'Date ', + name: 'fortinet.firewall.date', + type: 'keyword', + }, + 'fortinet.firewall.ddnsserver': { + category: 'fortinet', + description: 'DDNS server ', + name: 'fortinet.firewall.ddnsserver', + type: 'ip', + }, + 'fortinet.firewall.desc': { + category: 'fortinet', + description: 'Description ', + name: 'fortinet.firewall.desc', + type: 'keyword', + }, + 'fortinet.firewall.detectionmethod': { + category: 'fortinet', + description: 'Detection method ', + name: 'fortinet.firewall.detectionmethod', + type: 'keyword', + }, + 'fortinet.firewall.devcategory': { + category: 'fortinet', + description: 'Device category ', + name: 'fortinet.firewall.devcategory', + type: 'keyword', + }, + 'fortinet.firewall.devintfname': { + category: 'fortinet', + description: 'HA device Interface Name ', + name: 'fortinet.firewall.devintfname', + type: 'keyword', + }, + 'fortinet.firewall.devtype': { + category: 'fortinet', + description: 'Device type ', + name: 'fortinet.firewall.devtype', + type: 'keyword', + }, + 'fortinet.firewall.dhcp_msg': { + category: 'fortinet', + description: 'DHCP Message ', + name: 'fortinet.firewall.dhcp_msg', + type: 'keyword', + }, + 'fortinet.firewall.dintf': { + category: 'fortinet', + description: 'Destination interface ', + name: 'fortinet.firewall.dintf', + type: 'keyword', + }, + 'fortinet.firewall.disk': { + category: 'fortinet', + description: 'Assosciated disk ', + name: 'fortinet.firewall.disk', + type: 'keyword', + }, + 'fortinet.firewall.disklograte': { + category: 'fortinet', + description: 'Disk logging rate ', + name: 'fortinet.firewall.disklograte', + type: 'long', + }, + 'fortinet.firewall.dlpextra': { + category: 'fortinet', + description: 'DLP extra information ', + name: 'fortinet.firewall.dlpextra', + type: 'keyword', + }, + 'fortinet.firewall.docsource': { + category: 'fortinet', + description: 'DLP fingerprint document source ', + name: 'fortinet.firewall.docsource', + type: 'keyword', + }, + 'fortinet.firewall.domainctrlauthstate': { + category: 'fortinet', + description: 'CIFS domain auth state ', + name: 'fortinet.firewall.domainctrlauthstate', + type: 'integer', + }, + 'fortinet.firewall.domainctrlauthtype': { + category: 'fortinet', + description: 'CIFS domain auth type ', + name: 'fortinet.firewall.domainctrlauthtype', + type: 'integer', + }, + 'fortinet.firewall.domainctrldomain': { + category: 'fortinet', + description: 'CIFS domain auth domain ', + name: 'fortinet.firewall.domainctrldomain', + type: 'keyword', + }, + 'fortinet.firewall.domainctrlip': { + category: 'fortinet', + description: 'CIFS Domain IP ', + name: 'fortinet.firewall.domainctrlip', + type: 'ip', + }, + 'fortinet.firewall.domainctrlname': { + category: 'fortinet', + description: 'CIFS Domain name ', + name: 'fortinet.firewall.domainctrlname', + type: 'keyword', + }, + 'fortinet.firewall.domainctrlprotocoltype': { + category: 'fortinet', + description: 'CIFS Domain connection protocol ', + name: 'fortinet.firewall.domainctrlprotocoltype', + type: 'integer', + }, + 'fortinet.firewall.domainctrlusername': { + category: 'fortinet', + description: 'CIFS Domain username ', + name: 'fortinet.firewall.domainctrlusername', + type: 'keyword', + }, + 'fortinet.firewall.domainfilteridx': { + category: 'fortinet', + description: 'Domain filter ID ', + name: 'fortinet.firewall.domainfilteridx', + type: 'integer', + }, + 'fortinet.firewall.domainfilterlist': { + category: 'fortinet', + description: 'Domain filter name ', + name: 'fortinet.firewall.domainfilterlist', + type: 'keyword', + }, + 'fortinet.firewall.ds': { + category: 'fortinet', + description: 'Direction with distribution system ', + name: 'fortinet.firewall.ds', + type: 'keyword', + }, + 'fortinet.firewall.dst_int': { + category: 'fortinet', + description: 'Destination interface ', + name: 'fortinet.firewall.dst_int', + type: 'keyword', + }, + 'fortinet.firewall.dstintfrole': { + category: 'fortinet', + description: 'Destination interface role ', + name: 'fortinet.firewall.dstintfrole', + type: 'keyword', + }, + 'fortinet.firewall.dstcountry': { + category: 'fortinet', + description: 'Destination country ', + name: 'fortinet.firewall.dstcountry', + type: 'keyword', + }, + 'fortinet.firewall.dstdevcategory': { + category: 'fortinet', + description: 'Destination device category ', + name: 'fortinet.firewall.dstdevcategory', + type: 'keyword', + }, + 'fortinet.firewall.dstdevtype': { + category: 'fortinet', + description: 'Destination device type ', + name: 'fortinet.firewall.dstdevtype', + type: 'keyword', + }, + 'fortinet.firewall.dstfamily': { + category: 'fortinet', + description: 'Destination OS family ', + name: 'fortinet.firewall.dstfamily', + type: 'keyword', + }, + 'fortinet.firewall.dsthwvendor': { + category: 'fortinet', + description: 'Destination HW vendor ', + name: 'fortinet.firewall.dsthwvendor', + type: 'keyword', + }, + 'fortinet.firewall.dsthwversion': { + category: 'fortinet', + description: 'Destination HW version ', + name: 'fortinet.firewall.dsthwversion', + type: 'keyword', + }, + 'fortinet.firewall.dstinetsvc': { + category: 'fortinet', + description: 'Destination interface service ', + name: 'fortinet.firewall.dstinetsvc', + type: 'keyword', + }, + 'fortinet.firewall.dstosname': { + category: 'fortinet', + description: 'Destination OS name ', + name: 'fortinet.firewall.dstosname', + type: 'keyword', + }, + 'fortinet.firewall.dstosversion': { + category: 'fortinet', + description: 'Destination OS version ', + name: 'fortinet.firewall.dstosversion', + type: 'keyword', + }, + 'fortinet.firewall.dstserver': { + category: 'fortinet', + description: 'Destination server ', + name: 'fortinet.firewall.dstserver', + type: 'integer', + }, + 'fortinet.firewall.dstssid': { + category: 'fortinet', + description: 'Destination SSID ', + name: 'fortinet.firewall.dstssid', + type: 'keyword', + }, + 'fortinet.firewall.dstswversion': { + category: 'fortinet', + description: 'Destination software version ', + name: 'fortinet.firewall.dstswversion', + type: 'keyword', + }, + 'fortinet.firewall.dstunauthusersource': { + category: 'fortinet', + description: 'Destination unauthenticated source ', + name: 'fortinet.firewall.dstunauthusersource', + type: 'keyword', + }, + 'fortinet.firewall.dstuuid': { + category: 'fortinet', + description: 'UUID of the Destination IP address ', + name: 'fortinet.firewall.dstuuid', + type: 'keyword', + }, + 'fortinet.firewall.duid': { + category: 'fortinet', + description: 'DHCP UID ', + name: 'fortinet.firewall.duid', + type: 'keyword', + }, + 'fortinet.firewall.eapolcnt': { + category: 'fortinet', + description: 'EAPOL packet count ', + name: 'fortinet.firewall.eapolcnt', + type: 'integer', + }, + 'fortinet.firewall.eapoltype': { + category: 'fortinet', + description: 'EAPOL packet type ', + name: 'fortinet.firewall.eapoltype', + type: 'keyword', + }, + 'fortinet.firewall.encrypt': { + category: 'fortinet', + description: 'Whether the packet is encrypted or not ', + name: 'fortinet.firewall.encrypt', + type: 'integer', + }, + 'fortinet.firewall.encryption': { + category: 'fortinet', + description: 'Encryption method ', + name: 'fortinet.firewall.encryption', + type: 'keyword', + }, + 'fortinet.firewall.epoch': { + category: 'fortinet', + description: 'Epoch used for locating file ', + name: 'fortinet.firewall.epoch', + type: 'integer', + }, + 'fortinet.firewall.espauth': { + category: 'fortinet', + description: 'ESP Authentication ', + name: 'fortinet.firewall.espauth', + type: 'keyword', + }, + 'fortinet.firewall.esptransform': { + category: 'fortinet', + description: 'ESP Transform ', + name: 'fortinet.firewall.esptransform', + type: 'keyword', + }, + 'fortinet.firewall.exch': { + category: 'fortinet', + description: 'Mail Exchanges from DNS response answer section ', + name: 'fortinet.firewall.exch', + type: 'keyword', + }, + 'fortinet.firewall.exchange': { + category: 'fortinet', + description: 'Mail Exchanges from DNS response answer section ', + name: 'fortinet.firewall.exchange', + type: 'keyword', + }, + 'fortinet.firewall.expectedsignature': { + category: 'fortinet', + description: 'Expected SSL signature ', + name: 'fortinet.firewall.expectedsignature', + type: 'keyword', + }, + 'fortinet.firewall.expiry': { + category: 'fortinet', + description: 'FortiGuard override expiry timestamp ', + name: 'fortinet.firewall.expiry', + type: 'keyword', + }, + 'fortinet.firewall.fams_pause': { + category: 'fortinet', + description: 'Fortinet Analysis and Management Service Pause ', + name: 'fortinet.firewall.fams_pause', + type: 'integer', + }, + 'fortinet.firewall.fazlograte': { + category: 'fortinet', + description: 'FortiAnalyzer Logging Rate ', + name: 'fortinet.firewall.fazlograte', + type: 'long', + }, + 'fortinet.firewall.fctemssn': { + category: 'fortinet', + description: 'FortiClient Endpoint SSN ', + name: 'fortinet.firewall.fctemssn', + type: 'keyword', + }, + 'fortinet.firewall.fctuid': { + category: 'fortinet', + description: 'FortiClient UID ', + name: 'fortinet.firewall.fctuid', + type: 'keyword', + }, + 'fortinet.firewall.field': { + category: 'fortinet', + description: 'NTP status field ', + name: 'fortinet.firewall.field', + type: 'keyword', + }, + 'fortinet.firewall.filefilter': { + category: 'fortinet', + description: 'The filter used to identify the affected file ', + name: 'fortinet.firewall.filefilter', + type: 'keyword', + }, + 'fortinet.firewall.filehashsrc': { + category: 'fortinet', + description: 'Filehash source ', + name: 'fortinet.firewall.filehashsrc', + type: 'keyword', + }, + 'fortinet.firewall.filtercat': { + category: 'fortinet', + description: 'DLP filter category ', + name: 'fortinet.firewall.filtercat', + type: 'keyword', + }, + 'fortinet.firewall.filteridx': { + category: 'fortinet', + description: 'DLP filter ID ', + name: 'fortinet.firewall.filteridx', + type: 'integer', + }, + 'fortinet.firewall.filtername': { + category: 'fortinet', + description: 'DLP rule name ', + name: 'fortinet.firewall.filtername', + type: 'keyword', + }, + 'fortinet.firewall.filtertype': { + category: 'fortinet', + description: 'DLP filter type ', + name: 'fortinet.firewall.filtertype', + type: 'keyword', + }, + 'fortinet.firewall.fortiguardresp': { + category: 'fortinet', + description: 'Antispam ESP value ', + name: 'fortinet.firewall.fortiguardresp', + type: 'keyword', + }, + 'fortinet.firewall.forwardedfor': { + category: 'fortinet', + description: 'Email address forwarded ', + name: 'fortinet.firewall.forwardedfor', + type: 'keyword', + }, + 'fortinet.firewall.fqdn': { + category: 'fortinet', + description: 'FQDN ', + name: 'fortinet.firewall.fqdn', + type: 'keyword', + }, + 'fortinet.firewall.frametype': { + category: 'fortinet', + description: 'Wireless frametype ', + name: 'fortinet.firewall.frametype', + type: 'keyword', + }, + 'fortinet.firewall.freediskstorage': { + category: 'fortinet', + description: 'Free disk integer ', + name: 'fortinet.firewall.freediskstorage', + type: 'integer', + }, + 'fortinet.firewall.from': { + category: 'fortinet', + description: 'From email address ', + name: 'fortinet.firewall.from', + type: 'keyword', + }, + 'fortinet.firewall.from_vcluster': { + category: 'fortinet', + description: 'Source virtual cluster number ', + name: 'fortinet.firewall.from_vcluster', + type: 'integer', + }, + 'fortinet.firewall.fsaverdict': { + category: 'fortinet', + description: 'FSA verdict ', + name: 'fortinet.firewall.fsaverdict', + type: 'keyword', + }, + 'fortinet.firewall.fwserver_name': { + category: 'fortinet', + description: 'Web proxy server name ', + name: 'fortinet.firewall.fwserver_name', + type: 'keyword', + }, + 'fortinet.firewall.gateway': { + category: 'fortinet', + description: 'Gateway ip address for PPPoE status report ', + name: 'fortinet.firewall.gateway', + type: 'ip', + }, + 'fortinet.firewall.green': { + category: 'fortinet', + description: 'Memory status ', + name: 'fortinet.firewall.green', + type: 'keyword', + }, + 'fortinet.firewall.groupid': { + category: 'fortinet', + description: 'User Group ID ', + name: 'fortinet.firewall.groupid', + type: 'integer', + }, + 'fortinet.firewall.ha-prio': { + category: 'fortinet', + description: 'HA Priority ', + name: 'fortinet.firewall.ha-prio', + type: 'integer', + }, + 'fortinet.firewall.ha_group': { + category: 'fortinet', + description: 'HA Group ', + name: 'fortinet.firewall.ha_group', + type: 'keyword', + }, + 'fortinet.firewall.ha_role': { + category: 'fortinet', + description: 'HA Role ', + name: 'fortinet.firewall.ha_role', + type: 'keyword', + }, + 'fortinet.firewall.handshake': { + category: 'fortinet', + description: 'SSL Handshake ', + name: 'fortinet.firewall.handshake', + type: 'keyword', + }, + 'fortinet.firewall.hash': { + category: 'fortinet', + description: 'Hash value of downloaded file ', + name: 'fortinet.firewall.hash', + type: 'keyword', + }, + 'fortinet.firewall.hbdn_reason': { + category: 'fortinet', + description: 'Heartbeat down reason ', + name: 'fortinet.firewall.hbdn_reason', + type: 'keyword', + }, + 'fortinet.firewall.highcount': { + category: 'fortinet', + description: 'Highcount fabric summary ', + name: 'fortinet.firewall.highcount', + type: 'integer', + }, + 'fortinet.firewall.host': { + category: 'fortinet', + description: 'Hostname ', + name: 'fortinet.firewall.host', + type: 'keyword', + }, + 'fortinet.firewall.iaid': { + category: 'fortinet', + description: 'DHCPv6 id ', + name: 'fortinet.firewall.iaid', + type: 'keyword', + }, + 'fortinet.firewall.icmpcode': { + category: 'fortinet', + description: 'Destination Port of the ICMP message ', + name: 'fortinet.firewall.icmpcode', + type: 'keyword', + }, + 'fortinet.firewall.icmpid': { + category: 'fortinet', + description: 'Source port of the ICMP message ', + name: 'fortinet.firewall.icmpid', + type: 'keyword', + }, + 'fortinet.firewall.icmptype': { + category: 'fortinet', + description: 'The type of ICMP message ', + name: 'fortinet.firewall.icmptype', + type: 'keyword', + }, + 'fortinet.firewall.identifier': { + category: 'fortinet', + description: 'Network traffic identifier ', + name: 'fortinet.firewall.identifier', + type: 'integer', + }, + 'fortinet.firewall.in_spi': { + category: 'fortinet', + description: 'IPSEC inbound SPI ', + name: 'fortinet.firewall.in_spi', + type: 'keyword', + }, + 'fortinet.firewall.incidentserialno': { + category: 'fortinet', + description: 'Incident serial number ', + name: 'fortinet.firewall.incidentserialno', + type: 'integer', + }, + 'fortinet.firewall.infected': { + category: 'fortinet', + description: 'Infected MMS ', + name: 'fortinet.firewall.infected', + type: 'integer', + }, + 'fortinet.firewall.infectedfilelevel': { + category: 'fortinet', + description: 'DLP infected file level ', + name: 'fortinet.firewall.infectedfilelevel', + type: 'integer', + }, + 'fortinet.firewall.informationsource': { + category: 'fortinet', + description: 'Information source ', + name: 'fortinet.firewall.informationsource', + type: 'keyword', + }, + 'fortinet.firewall.init': { + category: 'fortinet', + description: 'IPSEC init stage ', + name: 'fortinet.firewall.init', + type: 'keyword', + }, + 'fortinet.firewall.initiator': { + category: 'fortinet', + description: 'Original login user name for Fortiguard override ', + name: 'fortinet.firewall.initiator', + type: 'keyword', + }, + 'fortinet.firewall.interface': { + category: 'fortinet', + description: 'Related interface ', + name: 'fortinet.firewall.interface', + type: 'keyword', + }, + 'fortinet.firewall.intf': { + category: 'fortinet', + description: 'Related interface ', + name: 'fortinet.firewall.intf', + type: 'keyword', + }, + 'fortinet.firewall.invalidmac': { + category: 'fortinet', + description: 'The MAC address with invalid OUI ', + name: 'fortinet.firewall.invalidmac', + type: 'keyword', + }, + 'fortinet.firewall.ip': { + category: 'fortinet', + description: 'Related IP ', + name: 'fortinet.firewall.ip', + type: 'ip', + }, + 'fortinet.firewall.iptype': { + category: 'fortinet', + description: 'Related IP type ', + name: 'fortinet.firewall.iptype', + type: 'keyword', + }, + 'fortinet.firewall.keyword': { + category: 'fortinet', + description: 'Keyword used for search ', + name: 'fortinet.firewall.keyword', + type: 'keyword', + }, + 'fortinet.firewall.kind': { + category: 'fortinet', + description: 'VOIP kind ', + name: 'fortinet.firewall.kind', + type: 'keyword', + }, + 'fortinet.firewall.lanin': { + category: 'fortinet', + description: 'LAN incoming traffic in bytes ', + name: 'fortinet.firewall.lanin', + type: 'long', + }, + 'fortinet.firewall.lanout': { + category: 'fortinet', + description: 'LAN outbound traffic in bytes ', + name: 'fortinet.firewall.lanout', + type: 'long', + }, + 'fortinet.firewall.lease': { + category: 'fortinet', + description: 'DHCP lease ', + name: 'fortinet.firewall.lease', + type: 'integer', + }, + 'fortinet.firewall.license_limit': { + category: 'fortinet', + description: 'Maximum Number of FortiClients for the License ', + name: 'fortinet.firewall.license_limit', + type: 'keyword', + }, + 'fortinet.firewall.limit': { + category: 'fortinet', + description: 'Virtual Domain Resource Limit ', + name: 'fortinet.firewall.limit', + type: 'integer', + }, + 'fortinet.firewall.line': { + category: 'fortinet', + description: 'VOIP line ', + name: 'fortinet.firewall.line', + type: 'keyword', + }, + 'fortinet.firewall.live': { + category: 'fortinet', + description: 'Time in seconds ', + name: 'fortinet.firewall.live', + type: 'integer', + }, + 'fortinet.firewall.local': { + category: 'fortinet', + description: 'Local IP for a PPPD Connection ', + name: 'fortinet.firewall.local', + type: 'ip', + }, + 'fortinet.firewall.log': { + category: 'fortinet', + description: 'Log message ', + name: 'fortinet.firewall.log', + type: 'keyword', + }, + 'fortinet.firewall.login': { + category: 'fortinet', + description: 'SSH login ', + name: 'fortinet.firewall.login', + type: 'keyword', + }, + 'fortinet.firewall.lowcount': { + category: 'fortinet', + description: 'Fabric lowcount ', + name: 'fortinet.firewall.lowcount', + type: 'integer', + }, + 'fortinet.firewall.mac': { + category: 'fortinet', + description: 'DHCP mac address ', + name: 'fortinet.firewall.mac', + type: 'keyword', + }, + 'fortinet.firewall.malform_data': { + category: 'fortinet', + description: 'VOIP malformed data ', + name: 'fortinet.firewall.malform_data', + type: 'integer', + }, + 'fortinet.firewall.malform_desc': { + category: 'fortinet', + description: 'VOIP malformed data description ', + name: 'fortinet.firewall.malform_desc', + type: 'keyword', + }, + 'fortinet.firewall.manuf': { + category: 'fortinet', + description: 'Manufacturer name ', + name: 'fortinet.firewall.manuf', + type: 'keyword', + }, + 'fortinet.firewall.masterdstmac': { + category: 'fortinet', + description: 'Master mac address for a host with multiple network interfaces ', + name: 'fortinet.firewall.masterdstmac', + type: 'keyword', + }, + 'fortinet.firewall.mastersrcmac': { + category: 'fortinet', + description: 'The master MAC address for a host that has multiple network interfaces ', + name: 'fortinet.firewall.mastersrcmac', + type: 'keyword', + }, + 'fortinet.firewall.mediumcount': { + category: 'fortinet', + description: 'Fabric medium count ', + name: 'fortinet.firewall.mediumcount', + type: 'integer', + }, + 'fortinet.firewall.mem': { + category: 'fortinet', + description: 'Memory usage system statistics ', + name: 'fortinet.firewall.mem', + type: 'keyword', + }, + 'fortinet.firewall.meshmode': { + category: 'fortinet', + description: 'Wireless mesh mode ', + name: 'fortinet.firewall.meshmode', + type: 'keyword', + }, + 'fortinet.firewall.message_type': { + category: 'fortinet', + description: 'VOIP message type ', + name: 'fortinet.firewall.message_type', + type: 'keyword', + }, + 'fortinet.firewall.method': { + category: 'fortinet', + description: 'HTTP method ', + name: 'fortinet.firewall.method', + type: 'keyword', + }, + 'fortinet.firewall.mgmtcnt': { + category: 'fortinet', + description: 'The number of unauthorized client flooding managemet frames ', + name: 'fortinet.firewall.mgmtcnt', + type: 'integer', + }, + 'fortinet.firewall.mode': { + category: 'fortinet', + description: 'IPSEC mode ', + name: 'fortinet.firewall.mode', + type: 'keyword', + }, + 'fortinet.firewall.module': { + category: 'fortinet', + description: 'PCI-DSS module ', + name: 'fortinet.firewall.module', + type: 'keyword', + }, + 'fortinet.firewall.monitor-name': { + category: 'fortinet', + description: 'Health Monitor Name ', + name: 'fortinet.firewall.monitor-name', + type: 'keyword', + }, + 'fortinet.firewall.monitor-type': { + category: 'fortinet', + description: 'Health Monitor Type ', + name: 'fortinet.firewall.monitor-type', + type: 'keyword', + }, + 'fortinet.firewall.mpsk': { + category: 'fortinet', + description: 'Wireless MPSK ', + name: 'fortinet.firewall.mpsk', + type: 'keyword', + }, + 'fortinet.firewall.msgproto': { + category: 'fortinet', + description: 'Message Protocol Number ', + name: 'fortinet.firewall.msgproto', + type: 'keyword', + }, + 'fortinet.firewall.mtu': { + category: 'fortinet', + description: 'Max Transmission Unit Value ', + name: 'fortinet.firewall.mtu', + type: 'integer', + }, + 'fortinet.firewall.name': { + category: 'fortinet', + description: 'Name ', + name: 'fortinet.firewall.name', + type: 'keyword', + }, + 'fortinet.firewall.nat': { + category: 'fortinet', + description: 'NAT IP Address ', + name: 'fortinet.firewall.nat', + type: 'keyword', + }, + 'fortinet.firewall.netid': { + category: 'fortinet', + description: 'Connector NetID ', + name: 'fortinet.firewall.netid', + type: 'keyword', + }, + 'fortinet.firewall.new_status': { + category: 'fortinet', + description: 'New status on user change ', + name: 'fortinet.firewall.new_status', + type: 'keyword', + }, + 'fortinet.firewall.new_value': { + category: 'fortinet', + description: 'New Virtual Domain Name ', + name: 'fortinet.firewall.new_value', + type: 'keyword', + }, + 'fortinet.firewall.newchannel': { + category: 'fortinet', + description: 'New Channel Number ', + name: 'fortinet.firewall.newchannel', + type: 'integer', + }, + 'fortinet.firewall.newchassisid': { + category: 'fortinet', + description: 'New Chassis ID ', + name: 'fortinet.firewall.newchassisid', + type: 'integer', + }, + 'fortinet.firewall.newslot': { + category: 'fortinet', + description: 'New Slot Number ', + name: 'fortinet.firewall.newslot', + type: 'integer', + }, + 'fortinet.firewall.nextstat': { + category: 'fortinet', + description: 'Time interval in seconds for the next statistics. ', + name: 'fortinet.firewall.nextstat', + type: 'integer', + }, + 'fortinet.firewall.nf_type': { + category: 'fortinet', + description: 'Notification Type ', + name: 'fortinet.firewall.nf_type', + type: 'keyword', + }, + 'fortinet.firewall.noise': { + category: 'fortinet', + description: 'Wifi Noise ', + name: 'fortinet.firewall.noise', + type: 'integer', + }, + 'fortinet.firewall.old_status': { + category: 'fortinet', + description: 'Original Status ', + name: 'fortinet.firewall.old_status', + type: 'keyword', + }, + 'fortinet.firewall.old_value': { + category: 'fortinet', + description: 'Original Virtual Domain name ', + name: 'fortinet.firewall.old_value', + type: 'keyword', + }, + 'fortinet.firewall.oldchannel': { + category: 'fortinet', + description: 'Original channel ', + name: 'fortinet.firewall.oldchannel', + type: 'integer', + }, + 'fortinet.firewall.oldchassisid': { + category: 'fortinet', + description: 'Original Chassis Number ', + name: 'fortinet.firewall.oldchassisid', + type: 'integer', + }, + 'fortinet.firewall.oldslot': { + category: 'fortinet', + description: 'Original Slot Number ', + name: 'fortinet.firewall.oldslot', + type: 'integer', + }, + 'fortinet.firewall.oldsn': { + category: 'fortinet', + description: 'Old Serial number ', + name: 'fortinet.firewall.oldsn', + type: 'keyword', + }, + 'fortinet.firewall.oldwprof': { + category: 'fortinet', + description: 'Old Web Filter Profile ', + name: 'fortinet.firewall.oldwprof', + type: 'keyword', + }, + 'fortinet.firewall.onwire': { + category: 'fortinet', + description: 'A flag to indicate if the AP is onwire or not ', + name: 'fortinet.firewall.onwire', + type: 'keyword', + }, + 'fortinet.firewall.opercountry': { + category: 'fortinet', + description: 'Operating Country ', + name: 'fortinet.firewall.opercountry', + type: 'keyword', + }, + 'fortinet.firewall.opertxpower': { + category: 'fortinet', + description: 'Operating TX power ', + name: 'fortinet.firewall.opertxpower', + type: 'integer', + }, + 'fortinet.firewall.osname': { + category: 'fortinet', + description: 'Operating System name ', + name: 'fortinet.firewall.osname', + type: 'keyword', + }, + 'fortinet.firewall.osversion': { + category: 'fortinet', + description: 'Operating System version ', + name: 'fortinet.firewall.osversion', + type: 'keyword', + }, + 'fortinet.firewall.out_spi': { + category: 'fortinet', + description: 'Out SPI ', + name: 'fortinet.firewall.out_spi', + type: 'keyword', + }, + 'fortinet.firewall.outintf': { + category: 'fortinet', + description: 'Out interface ', + name: 'fortinet.firewall.outintf', + type: 'keyword', + }, + 'fortinet.firewall.passedcount': { + category: 'fortinet', + description: 'Fabric passed count ', + name: 'fortinet.firewall.passedcount', + type: 'integer', + }, + 'fortinet.firewall.passwd': { + category: 'fortinet', + description: 'Changed user password information ', + name: 'fortinet.firewall.passwd', + type: 'keyword', + }, + 'fortinet.firewall.path': { + category: 'fortinet', + description: 'Path of looped configuration for security fabric ', + name: 'fortinet.firewall.path', + type: 'keyword', + }, + 'fortinet.firewall.peer': { + category: 'fortinet', + description: 'WAN optimization peer ', + name: 'fortinet.firewall.peer', + type: 'keyword', + }, + 'fortinet.firewall.peer_notif': { + category: 'fortinet', + description: 'VPN peer notification ', + name: 'fortinet.firewall.peer_notif', + type: 'keyword', + }, + 'fortinet.firewall.phase2_name': { + category: 'fortinet', + description: 'VPN phase2 name ', + name: 'fortinet.firewall.phase2_name', + type: 'keyword', + }, + 'fortinet.firewall.phone': { + category: 'fortinet', + description: 'VOIP Phone ', + name: 'fortinet.firewall.phone', + type: 'keyword', + }, + 'fortinet.firewall.pid': { + category: 'fortinet', + description: 'Process ID ', + name: 'fortinet.firewall.pid', + type: 'integer', + }, + 'fortinet.firewall.policytype': { + category: 'fortinet', + description: 'Policy Type ', + name: 'fortinet.firewall.policytype', + type: 'keyword', + }, + 'fortinet.firewall.poolname': { + category: 'fortinet', + description: 'IP Pool name ', + name: 'fortinet.firewall.poolname', + type: 'keyword', + }, + 'fortinet.firewall.port': { + category: 'fortinet', + description: 'Log upload error port ', + name: 'fortinet.firewall.port', + type: 'integer', + }, + 'fortinet.firewall.portbegin': { + category: 'fortinet', + description: 'IP Pool port number to begin ', + name: 'fortinet.firewall.portbegin', + type: 'integer', + }, + 'fortinet.firewall.portend': { + category: 'fortinet', + description: 'IP Pool port number to end ', + name: 'fortinet.firewall.portend', + type: 'integer', + }, + 'fortinet.firewall.probeproto': { + category: 'fortinet', + description: 'Link Monitor Probe Protocol ', + name: 'fortinet.firewall.probeproto', + type: 'keyword', + }, + 'fortinet.firewall.process': { + category: 'fortinet', + description: 'URL Filter process ', + name: 'fortinet.firewall.process', + type: 'keyword', + }, + 'fortinet.firewall.processtime': { + category: 'fortinet', + description: 'Process time for reports ', + name: 'fortinet.firewall.processtime', + type: 'integer', + }, + 'fortinet.firewall.profile': { + category: 'fortinet', + description: 'Profile Name ', + name: 'fortinet.firewall.profile', + type: 'keyword', + }, + 'fortinet.firewall.profile_vd': { + category: 'fortinet', + description: 'Virtual Domain Name ', + name: 'fortinet.firewall.profile_vd', + type: 'keyword', + }, + 'fortinet.firewall.profilegroup': { + category: 'fortinet', + description: 'Profile Group Name ', + name: 'fortinet.firewall.profilegroup', + type: 'keyword', + }, + 'fortinet.firewall.profiletype': { + category: 'fortinet', + description: 'Profile Type ', + name: 'fortinet.firewall.profiletype', + type: 'keyword', + }, + 'fortinet.firewall.qtypeval': { + category: 'fortinet', + description: 'DNS question type value ', + name: 'fortinet.firewall.qtypeval', + type: 'integer', + }, + 'fortinet.firewall.quarskip': { + category: 'fortinet', + description: 'Quarantine skip explanation ', + name: 'fortinet.firewall.quarskip', + type: 'keyword', + }, + 'fortinet.firewall.quotaexceeded': { + category: 'fortinet', + description: 'If quota has been exceeded ', + name: 'fortinet.firewall.quotaexceeded', + type: 'keyword', + }, + 'fortinet.firewall.quotamax': { + category: 'fortinet', + description: 'Maximum quota allowed - in seconds if time-based - in bytes if traffic-based ', + name: 'fortinet.firewall.quotamax', + type: 'long', + }, + 'fortinet.firewall.quotatype': { + category: 'fortinet', + description: 'Quota type ', + name: 'fortinet.firewall.quotatype', + type: 'keyword', + }, + 'fortinet.firewall.quotaused': { + category: 'fortinet', + description: 'Quota used - in seconds if time-based - in bytes if trafficbased) ', + name: 'fortinet.firewall.quotaused', + type: 'long', + }, + 'fortinet.firewall.radioband': { + category: 'fortinet', + description: 'Radio band ', + name: 'fortinet.firewall.radioband', + type: 'keyword', + }, + 'fortinet.firewall.radioid': { + category: 'fortinet', + description: 'Radio ID ', + name: 'fortinet.firewall.radioid', + type: 'integer', + }, + 'fortinet.firewall.radioidclosest': { + category: 'fortinet', + description: 'Radio ID on the AP closest the rogue AP ', + name: 'fortinet.firewall.radioidclosest', + type: 'integer', + }, + 'fortinet.firewall.radioiddetected': { + category: 'fortinet', + description: 'Radio ID on the AP which detected the rogue AP ', + name: 'fortinet.firewall.radioiddetected', + type: 'integer', + }, + 'fortinet.firewall.rate': { + category: 'fortinet', + description: 'Wireless rogue rate value ', + name: 'fortinet.firewall.rate', + type: 'keyword', + }, + 'fortinet.firewall.rawdata': { + category: 'fortinet', + description: 'Raw data value ', + name: 'fortinet.firewall.rawdata', + type: 'keyword', + }, + 'fortinet.firewall.rawdataid': { + category: 'fortinet', + description: 'Raw data ID ', + name: 'fortinet.firewall.rawdataid', + type: 'keyword', + }, + 'fortinet.firewall.rcvddelta': { + category: 'fortinet', + description: 'Received bytes delta ', + name: 'fortinet.firewall.rcvddelta', + type: 'keyword', + }, + 'fortinet.firewall.reason': { + category: 'fortinet', + description: 'Alert reason ', + name: 'fortinet.firewall.reason', + type: 'keyword', + }, + 'fortinet.firewall.received': { + category: 'fortinet', + description: 'Server key exchange received ', + name: 'fortinet.firewall.received', + type: 'integer', + }, + 'fortinet.firewall.receivedsignature': { + category: 'fortinet', + description: 'Server key exchange received signature ', + name: 'fortinet.firewall.receivedsignature', + type: 'keyword', + }, + 'fortinet.firewall.red': { + category: 'fortinet', + description: 'Memory information in red ', + name: 'fortinet.firewall.red', + type: 'keyword', + }, + 'fortinet.firewall.referralurl': { + category: 'fortinet', + description: 'Web filter referralurl ', + name: 'fortinet.firewall.referralurl', + type: 'keyword', + }, + 'fortinet.firewall.remote': { + category: 'fortinet', + description: 'Remote PPP IP address ', + name: 'fortinet.firewall.remote', + type: 'ip', + }, + 'fortinet.firewall.remotewtptime': { + category: 'fortinet', + description: 'Remote Wifi Radius authentication time ', + name: 'fortinet.firewall.remotewtptime', + type: 'keyword', + }, + 'fortinet.firewall.reporttype': { + category: 'fortinet', + description: 'Report type ', + name: 'fortinet.firewall.reporttype', + type: 'keyword', + }, + 'fortinet.firewall.reqtype': { + category: 'fortinet', + description: 'Request type ', + name: 'fortinet.firewall.reqtype', + type: 'keyword', + }, + 'fortinet.firewall.request_name': { + category: 'fortinet', + description: 'VOIP request name ', + name: 'fortinet.firewall.request_name', + type: 'keyword', + }, + 'fortinet.firewall.result': { + category: 'fortinet', + description: 'VPN phase result ', + name: 'fortinet.firewall.result', + type: 'keyword', + }, + 'fortinet.firewall.role': { + category: 'fortinet', + description: 'VPN Phase 2 role ', + name: 'fortinet.firewall.role', + type: 'keyword', + }, + 'fortinet.firewall.rssi': { + category: 'fortinet', + description: 'Received signal strength indicator ', + name: 'fortinet.firewall.rssi', + type: 'integer', + }, + 'fortinet.firewall.rsso_key': { + category: 'fortinet', + description: 'RADIUS SSO attribute value ', + name: 'fortinet.firewall.rsso_key', + type: 'keyword', + }, + 'fortinet.firewall.ruledata': { + category: 'fortinet', + description: 'Rule data ', + name: 'fortinet.firewall.ruledata', + type: 'keyword', + }, + 'fortinet.firewall.ruletype': { + category: 'fortinet', + description: 'Rule type ', + name: 'fortinet.firewall.ruletype', + type: 'keyword', + }, + 'fortinet.firewall.scanned': { + category: 'fortinet', + description: 'Number of Scanned MMSs ', + name: 'fortinet.firewall.scanned', + type: 'integer', + }, + 'fortinet.firewall.scantime': { + category: 'fortinet', + description: 'Scanned time ', + name: 'fortinet.firewall.scantime', + type: 'long', + }, + 'fortinet.firewall.scope': { + category: 'fortinet', + description: 'FortiGuard Override Scope ', + name: 'fortinet.firewall.scope', + type: 'keyword', + }, + 'fortinet.firewall.security': { + category: 'fortinet', + description: 'Wireless rogue security ', + name: 'fortinet.firewall.security', + type: 'keyword', + }, + 'fortinet.firewall.sensitivity': { + category: 'fortinet', + description: 'Sensitivity for document fingerprint ', + name: 'fortinet.firewall.sensitivity', + type: 'keyword', + }, + 'fortinet.firewall.sensor': { + category: 'fortinet', + description: 'NAC Sensor Name ', + name: 'fortinet.firewall.sensor', + type: 'keyword', + }, + 'fortinet.firewall.sentdelta': { + category: 'fortinet', + description: 'Sent bytes delta ', + name: 'fortinet.firewall.sentdelta', + type: 'keyword', + }, + 'fortinet.firewall.seq': { + category: 'fortinet', + description: 'Sequence number ', + name: 'fortinet.firewall.seq', + type: 'keyword', + }, + 'fortinet.firewall.serial': { + category: 'fortinet', + description: 'WAN optimisation serial ', + name: 'fortinet.firewall.serial', + type: 'keyword', + }, + 'fortinet.firewall.serialno': { + category: 'fortinet', + description: 'Serial number ', + name: 'fortinet.firewall.serialno', + type: 'keyword', + }, + 'fortinet.firewall.server': { + category: 'fortinet', + description: 'AD server FQDN or IP ', + name: 'fortinet.firewall.server', + type: 'keyword', + }, + 'fortinet.firewall.session_id': { + category: 'fortinet', + description: 'Session ID ', + name: 'fortinet.firewall.session_id', + type: 'keyword', + }, + 'fortinet.firewall.sessionid': { + category: 'fortinet', + description: 'WAD Session ID ', + name: 'fortinet.firewall.sessionid', + type: 'integer', + }, + 'fortinet.firewall.setuprate': { + category: 'fortinet', + description: 'Session Setup Rate ', + name: 'fortinet.firewall.setuprate', + type: 'long', + }, + 'fortinet.firewall.severity': { + category: 'fortinet', + description: 'Severity ', + name: 'fortinet.firewall.severity', + type: 'keyword', + }, + 'fortinet.firewall.shaperdroprcvdbyte': { + category: 'fortinet', + description: 'Received bytes dropped by shaper ', + name: 'fortinet.firewall.shaperdroprcvdbyte', + type: 'integer', + }, + 'fortinet.firewall.shaperdropsentbyte': { + category: 'fortinet', + description: 'Sent bytes dropped by shaper ', + name: 'fortinet.firewall.shaperdropsentbyte', + type: 'integer', + }, + 'fortinet.firewall.shaperperipdropbyte': { + category: 'fortinet', + description: 'Dropped bytes per IP by shaper ', + name: 'fortinet.firewall.shaperperipdropbyte', + type: 'integer', + }, + 'fortinet.firewall.shaperperipname': { + category: 'fortinet', + description: 'Traffic shaper name (per IP) ', + name: 'fortinet.firewall.shaperperipname', + type: 'keyword', + }, + 'fortinet.firewall.shaperrcvdname': { + category: 'fortinet', + description: 'Traffic shaper name for received traffic ', + name: 'fortinet.firewall.shaperrcvdname', + type: 'keyword', + }, + 'fortinet.firewall.shapersentname': { + category: 'fortinet', + description: 'Traffic shaper name for sent traffic ', + name: 'fortinet.firewall.shapersentname', + type: 'keyword', + }, + 'fortinet.firewall.shapingpolicyid': { + category: 'fortinet', + description: 'Traffic shaper policy ID ', + name: 'fortinet.firewall.shapingpolicyid', + type: 'integer', + }, + 'fortinet.firewall.signal': { + category: 'fortinet', + description: 'Wireless rogue API signal ', + name: 'fortinet.firewall.signal', + type: 'integer', + }, + 'fortinet.firewall.size': { + category: 'fortinet', + description: 'Email size in bytes ', + name: 'fortinet.firewall.size', + type: 'long', + }, + 'fortinet.firewall.slot': { + category: 'fortinet', + description: 'Slot number ', + name: 'fortinet.firewall.slot', + type: 'integer', + }, + 'fortinet.firewall.sn': { + category: 'fortinet', + description: 'Security fabric serial number ', + name: 'fortinet.firewall.sn', + type: 'keyword', + }, + 'fortinet.firewall.snclosest': { + category: 'fortinet', + description: 'SN of the AP closest to the rogue AP ', + name: 'fortinet.firewall.snclosest', + type: 'keyword', + }, + 'fortinet.firewall.sndetected': { + category: 'fortinet', + description: 'SN of the AP which detected the rogue AP ', + name: 'fortinet.firewall.sndetected', + type: 'keyword', + }, + 'fortinet.firewall.snmeshparent': { + category: 'fortinet', + description: 'SN of the mesh parent ', + name: 'fortinet.firewall.snmeshparent', + type: 'keyword', + }, + 'fortinet.firewall.spi': { + category: 'fortinet', + description: 'IPSEC SPI ', + name: 'fortinet.firewall.spi', + type: 'keyword', + }, + 'fortinet.firewall.src_int': { + category: 'fortinet', + description: 'Source interface ', + name: 'fortinet.firewall.src_int', + type: 'keyword', + }, + 'fortinet.firewall.srcintfrole': { + category: 'fortinet', + description: 'Source interface role ', + name: 'fortinet.firewall.srcintfrole', + type: 'keyword', + }, + 'fortinet.firewall.srccountry': { + category: 'fortinet', + description: 'Source country ', + name: 'fortinet.firewall.srccountry', + type: 'keyword', + }, + 'fortinet.firewall.srcfamily': { + category: 'fortinet', + description: 'Source family ', + name: 'fortinet.firewall.srcfamily', + type: 'keyword', + }, + 'fortinet.firewall.srchwvendor': { + category: 'fortinet', + description: 'Source hardware vendor ', + name: 'fortinet.firewall.srchwvendor', + type: 'keyword', + }, + 'fortinet.firewall.srchwversion': { + category: 'fortinet', + description: 'Source hardware version ', + name: 'fortinet.firewall.srchwversion', + type: 'keyword', + }, + 'fortinet.firewall.srcinetsvc': { + category: 'fortinet', + description: 'Source interface service ', + name: 'fortinet.firewall.srcinetsvc', + type: 'keyword', + }, + 'fortinet.firewall.srcname': { + category: 'fortinet', + description: 'Source name ', + name: 'fortinet.firewall.srcname', + type: 'keyword', + }, + 'fortinet.firewall.srcserver': { + category: 'fortinet', + description: 'Source server ', + name: 'fortinet.firewall.srcserver', + type: 'integer', + }, + 'fortinet.firewall.srcssid': { + category: 'fortinet', + description: 'Source SSID ', + name: 'fortinet.firewall.srcssid', + type: 'keyword', + }, + 'fortinet.firewall.srcswversion': { + category: 'fortinet', + description: 'Source software version ', + name: 'fortinet.firewall.srcswversion', + type: 'keyword', + }, + 'fortinet.firewall.srcuuid': { + category: 'fortinet', + description: 'Source UUID ', + name: 'fortinet.firewall.srcuuid', + type: 'keyword', + }, + 'fortinet.firewall.sscname': { + category: 'fortinet', + description: 'SSC name ', + name: 'fortinet.firewall.sscname', + type: 'keyword', + }, + 'fortinet.firewall.ssid': { + category: 'fortinet', + description: 'Base Service Set ID ', + name: 'fortinet.firewall.ssid', + type: 'keyword', + }, + 'fortinet.firewall.sslaction': { + category: 'fortinet', + description: 'SSL Action ', + name: 'fortinet.firewall.sslaction', + type: 'keyword', + }, + 'fortinet.firewall.ssllocal': { + category: 'fortinet', + description: 'WAD SSL local ', + name: 'fortinet.firewall.ssllocal', + type: 'keyword', + }, + 'fortinet.firewall.sslremote': { + category: 'fortinet', + description: 'WAD SSL remote ', + name: 'fortinet.firewall.sslremote', + type: 'keyword', + }, + 'fortinet.firewall.stacount': { + category: 'fortinet', + description: 'Number of stations/clients ', + name: 'fortinet.firewall.stacount', + type: 'integer', + }, + 'fortinet.firewall.stage': { + category: 'fortinet', + description: 'IPSEC stage ', + name: 'fortinet.firewall.stage', + type: 'keyword', + }, + 'fortinet.firewall.stamac': { + category: 'fortinet', + description: '802.1x station mac ', + name: 'fortinet.firewall.stamac', + type: 'keyword', + }, + 'fortinet.firewall.state': { + category: 'fortinet', + description: 'Admin login state ', + name: 'fortinet.firewall.state', + type: 'keyword', + }, + 'fortinet.firewall.status': { + category: 'fortinet', + description: 'Status ', + name: 'fortinet.firewall.status', + type: 'keyword', + }, + 'fortinet.firewall.stitch': { + category: 'fortinet', + description: 'Automation stitch triggered ', + name: 'fortinet.firewall.stitch', + type: 'keyword', + }, + 'fortinet.firewall.subject': { + category: 'fortinet', + description: 'Email subject ', + name: 'fortinet.firewall.subject', + type: 'keyword', + }, + 'fortinet.firewall.submodule': { + category: 'fortinet', + description: 'Configuration Sub-Module Name ', + name: 'fortinet.firewall.submodule', + type: 'keyword', + }, + 'fortinet.firewall.subservice': { + category: 'fortinet', + description: 'AV subservice ', + name: 'fortinet.firewall.subservice', + type: 'keyword', + }, + 'fortinet.firewall.subtype': { + category: 'fortinet', + description: 'Log subtype ', + name: 'fortinet.firewall.subtype', + type: 'keyword', + }, + 'fortinet.firewall.suspicious': { + category: 'fortinet', + description: 'Number of Suspicious MMSs ', + name: 'fortinet.firewall.suspicious', + type: 'integer', + }, + 'fortinet.firewall.switchproto': { + category: 'fortinet', + description: 'Protocol change information ', + name: 'fortinet.firewall.switchproto', + type: 'keyword', + }, + 'fortinet.firewall.sync_status': { + category: 'fortinet', + description: 'The sync status with the master ', + name: 'fortinet.firewall.sync_status', + type: 'keyword', + }, + 'fortinet.firewall.sync_type': { + category: 'fortinet', + description: 'The sync type with the master ', + name: 'fortinet.firewall.sync_type', + type: 'keyword', + }, + 'fortinet.firewall.sysuptime': { + category: 'fortinet', + description: 'System uptime ', + name: 'fortinet.firewall.sysuptime', + type: 'keyword', + }, + 'fortinet.firewall.tamac': { + category: 'fortinet', + description: 'the MAC address of Transmitter, if none, then Receiver ', + name: 'fortinet.firewall.tamac', + type: 'keyword', + }, + 'fortinet.firewall.threattype': { + category: 'fortinet', + description: 'WIDS threat type ', + name: 'fortinet.firewall.threattype', + type: 'keyword', + }, + 'fortinet.firewall.time': { + category: 'fortinet', + description: 'Time of the event ', + name: 'fortinet.firewall.time', + type: 'keyword', + }, + 'fortinet.firewall.to': { + category: 'fortinet', + description: 'Email to field ', + name: 'fortinet.firewall.to', + type: 'keyword', + }, + 'fortinet.firewall.to_vcluster': { + category: 'fortinet', + description: 'destination virtual cluster number ', + name: 'fortinet.firewall.to_vcluster', + type: 'integer', + }, + 'fortinet.firewall.total': { + category: 'fortinet', + description: 'Total memory ', + name: 'fortinet.firewall.total', + type: 'integer', + }, + 'fortinet.firewall.totalsession': { + category: 'fortinet', + description: 'Total Number of Sessions ', + name: 'fortinet.firewall.totalsession', + type: 'integer', + }, + 'fortinet.firewall.trace_id': { + category: 'fortinet', + description: 'Session clash trace ID ', + name: 'fortinet.firewall.trace_id', + type: 'keyword', + }, + 'fortinet.firewall.trandisp': { + category: 'fortinet', + description: 'NAT translation type ', + name: 'fortinet.firewall.trandisp', + type: 'keyword', + }, + 'fortinet.firewall.transid': { + category: 'fortinet', + description: 'HTTP transaction ID ', + name: 'fortinet.firewall.transid', + type: 'integer', + }, + 'fortinet.firewall.translationid': { + category: 'fortinet', + description: 'DNS filter transaltion ID ', + name: 'fortinet.firewall.translationid', + type: 'keyword', + }, + 'fortinet.firewall.trigger': { + category: 'fortinet', + description: 'Automation stitch trigger ', + name: 'fortinet.firewall.trigger', + type: 'keyword', + }, + 'fortinet.firewall.trueclntip': { + category: 'fortinet', + description: 'File filter true client IP ', + name: 'fortinet.firewall.trueclntip', + type: 'ip', + }, + 'fortinet.firewall.tunnelid': { + category: 'fortinet', + description: 'IPSEC tunnel ID ', + name: 'fortinet.firewall.tunnelid', + type: 'integer', + }, + 'fortinet.firewall.tunnelip': { + category: 'fortinet', + description: 'IPSEC tunnel IP ', + name: 'fortinet.firewall.tunnelip', + type: 'ip', + }, + 'fortinet.firewall.tunneltype': { + category: 'fortinet', + description: 'IPSEC tunnel type ', + name: 'fortinet.firewall.tunneltype', + type: 'keyword', + }, + 'fortinet.firewall.type': { + category: 'fortinet', + description: 'Module type ', + name: 'fortinet.firewall.type', + type: 'keyword', + }, + 'fortinet.firewall.ui': { + category: 'fortinet', + description: 'Admin authentication UI type ', + name: 'fortinet.firewall.ui', + type: 'keyword', + }, + 'fortinet.firewall.unauthusersource': { + category: 'fortinet', + description: 'Unauthenticated user source ', + name: 'fortinet.firewall.unauthusersource', + type: 'keyword', + }, + 'fortinet.firewall.unit': { + category: 'fortinet', + description: 'Power supply unit ', + name: 'fortinet.firewall.unit', + type: 'integer', + }, + 'fortinet.firewall.urlfilteridx': { + category: 'fortinet', + description: 'URL filter ID ', + name: 'fortinet.firewall.urlfilteridx', + type: 'integer', + }, + 'fortinet.firewall.urlfilterlist': { + category: 'fortinet', + description: 'URL filter list ', + name: 'fortinet.firewall.urlfilterlist', + type: 'keyword', + }, + 'fortinet.firewall.urlsource': { + category: 'fortinet', + description: 'URL filter source ', + name: 'fortinet.firewall.urlsource', + type: 'keyword', + }, + 'fortinet.firewall.urltype': { + category: 'fortinet', + description: 'URL filter type ', + name: 'fortinet.firewall.urltype', + type: 'keyword', + }, + 'fortinet.firewall.used': { + category: 'fortinet', + description: 'Number of Used IPs ', + name: 'fortinet.firewall.used', + type: 'integer', + }, + 'fortinet.firewall.used_for_type': { + category: 'fortinet', + description: 'Connection for the type ', + name: 'fortinet.firewall.used_for_type', + type: 'integer', + }, + 'fortinet.firewall.utmaction': { + category: 'fortinet', + description: 'Security action performed by UTM ', + name: 'fortinet.firewall.utmaction', + type: 'keyword', + }, + 'fortinet.firewall.vap': { + category: 'fortinet', + description: 'Virtual AP ', + name: 'fortinet.firewall.vap', + type: 'keyword', + }, + 'fortinet.firewall.vapmode': { + category: 'fortinet', + description: 'Virtual AP mode ', + name: 'fortinet.firewall.vapmode', + type: 'keyword', + }, + 'fortinet.firewall.vcluster': { + category: 'fortinet', + description: 'virtual cluster id ', + name: 'fortinet.firewall.vcluster', + type: 'integer', + }, + 'fortinet.firewall.vcluster_member': { + category: 'fortinet', + description: 'Virtual cluster member ', + name: 'fortinet.firewall.vcluster_member', + type: 'integer', + }, + 'fortinet.firewall.vcluster_state': { + category: 'fortinet', + description: 'Virtual cluster state ', + name: 'fortinet.firewall.vcluster_state', + type: 'keyword', + }, + 'fortinet.firewall.vd': { + category: 'fortinet', + description: 'Virtual Domain Name ', + name: 'fortinet.firewall.vd', + type: 'keyword', + }, + 'fortinet.firewall.vdname': { + category: 'fortinet', + description: 'Virtual Domain Name ', + name: 'fortinet.firewall.vdname', + type: 'keyword', + }, + 'fortinet.firewall.vendorurl': { + category: 'fortinet', + description: 'Vulnerability scan vendor name ', + name: 'fortinet.firewall.vendorurl', + type: 'keyword', + }, + 'fortinet.firewall.version': { + category: 'fortinet', + description: 'Version ', + name: 'fortinet.firewall.version', + type: 'keyword', + }, + 'fortinet.firewall.vip': { + category: 'fortinet', + description: 'Virtual IP ', + name: 'fortinet.firewall.vip', + type: 'keyword', + }, + 'fortinet.firewall.virus': { + category: 'fortinet', + description: 'Virus name ', + name: 'fortinet.firewall.virus', + type: 'keyword', + }, + 'fortinet.firewall.virusid': { + category: 'fortinet', + description: 'Virus ID (unique virus identifier) ', + name: 'fortinet.firewall.virusid', + type: 'integer', + }, + 'fortinet.firewall.voip_proto': { + category: 'fortinet', + description: 'VOIP protocol ', + name: 'fortinet.firewall.voip_proto', + type: 'keyword', + }, + 'fortinet.firewall.vpn': { + category: 'fortinet', + description: 'VPN description ', + name: 'fortinet.firewall.vpn', + type: 'keyword', + }, + 'fortinet.firewall.vpntunnel': { + category: 'fortinet', + description: 'IPsec Vpn Tunnel Name ', + name: 'fortinet.firewall.vpntunnel', + type: 'keyword', + }, + 'fortinet.firewall.vpntype': { + category: 'fortinet', + description: 'The type of the VPN tunnel ', + name: 'fortinet.firewall.vpntype', + type: 'keyword', + }, + 'fortinet.firewall.vrf': { + category: 'fortinet', + description: 'VRF number ', + name: 'fortinet.firewall.vrf', + type: 'integer', + }, + 'fortinet.firewall.vulncat': { + category: 'fortinet', + description: 'Vulnerability Category ', + name: 'fortinet.firewall.vulncat', + type: 'keyword', + }, + 'fortinet.firewall.vulnid': { + category: 'fortinet', + description: 'Vulnerability ID ', + name: 'fortinet.firewall.vulnid', + type: 'integer', + }, + 'fortinet.firewall.vulnname': { + category: 'fortinet', + description: 'Vulnerability name ', + name: 'fortinet.firewall.vulnname', + type: 'keyword', + }, + 'fortinet.firewall.vwlid': { + category: 'fortinet', + description: 'VWL ID ', + name: 'fortinet.firewall.vwlid', + type: 'integer', + }, + 'fortinet.firewall.vwlquality': { + category: 'fortinet', + description: 'VWL quality ', + name: 'fortinet.firewall.vwlquality', + type: 'keyword', + }, + 'fortinet.firewall.vwlservice': { + category: 'fortinet', + description: 'VWL service ', + name: 'fortinet.firewall.vwlservice', + type: 'keyword', + }, + 'fortinet.firewall.vwpvlanid': { + category: 'fortinet', + description: 'VWP VLAN ID ', + name: 'fortinet.firewall.vwpvlanid', + type: 'integer', + }, + 'fortinet.firewall.wanin': { + category: 'fortinet', + description: 'WAN incoming traffic in bytes ', + name: 'fortinet.firewall.wanin', + type: 'long', + }, + 'fortinet.firewall.wanoptapptype': { + category: 'fortinet', + description: 'WAN Optimization Application type ', + name: 'fortinet.firewall.wanoptapptype', + type: 'keyword', + }, + 'fortinet.firewall.wanout': { + category: 'fortinet', + description: 'WAN outgoing traffic in bytes ', + name: 'fortinet.firewall.wanout', + type: 'long', + }, + 'fortinet.firewall.weakwepiv': { + category: 'fortinet', + description: 'Weak Wep Initiation Vector ', + name: 'fortinet.firewall.weakwepiv', + type: 'keyword', + }, + 'fortinet.firewall.xauthgroup': { + category: 'fortinet', + description: 'XAuth Group Name ', + name: 'fortinet.firewall.xauthgroup', + type: 'keyword', + }, + 'fortinet.firewall.xauthuser': { + category: 'fortinet', + description: 'XAuth User Name ', + name: 'fortinet.firewall.xauthuser', + type: 'keyword', + }, + 'fortinet.firewall.xid': { + category: 'fortinet', + description: 'Wireless X ID ', + name: 'fortinet.firewall.xid', + type: 'integer', + }, + 'googlecloud.destination.instance.project_id': { + category: 'googlecloud', + description: 'ID of the project containing the VM. ', + name: 'googlecloud.destination.instance.project_id', + type: 'keyword', + }, + 'googlecloud.destination.instance.region': { + category: 'googlecloud', + description: 'Region of the VM. ', + name: 'googlecloud.destination.instance.region', + type: 'keyword', + }, + 'googlecloud.destination.instance.zone': { + category: 'googlecloud', + description: 'Zone of the VM. ', + name: 'googlecloud.destination.instance.zone', + type: 'keyword', + }, + 'googlecloud.destination.vpc.project_id': { + category: 'googlecloud', + description: 'ID of the project containing the VM. ', + name: 'googlecloud.destination.vpc.project_id', + type: 'keyword', + }, + 'googlecloud.destination.vpc.vpc_name': { + category: 'googlecloud', + description: 'VPC on which the VM is operating. ', + name: 'googlecloud.destination.vpc.vpc_name', + type: 'keyword', + }, + 'googlecloud.destination.vpc.subnetwork_name': { + category: 'googlecloud', + description: 'Subnetwork on which the VM is operating. ', + name: 'googlecloud.destination.vpc.subnetwork_name', + type: 'keyword', + }, + 'googlecloud.source.instance.project_id': { + category: 'googlecloud', + description: 'ID of the project containing the VM. ', + name: 'googlecloud.source.instance.project_id', + type: 'keyword', + }, + 'googlecloud.source.instance.region': { + category: 'googlecloud', + description: 'Region of the VM. ', + name: 'googlecloud.source.instance.region', + type: 'keyword', + }, + 'googlecloud.source.instance.zone': { + category: 'googlecloud', + description: 'Zone of the VM. ', + name: 'googlecloud.source.instance.zone', + type: 'keyword', + }, + 'googlecloud.source.vpc.project_id': { + category: 'googlecloud', + description: 'ID of the project containing the VM. ', + name: 'googlecloud.source.vpc.project_id', + type: 'keyword', + }, + 'googlecloud.source.vpc.vpc_name': { + category: 'googlecloud', + description: 'VPC on which the VM is operating. ', + name: 'googlecloud.source.vpc.vpc_name', + type: 'keyword', + }, + 'googlecloud.source.vpc.subnetwork_name': { + category: 'googlecloud', + description: 'Subnetwork on which the VM is operating. ', + name: 'googlecloud.source.vpc.subnetwork_name', + type: 'keyword', + }, + 'googlecloud.audit.type': { + category: 'googlecloud', + description: 'Type property. ', + name: 'googlecloud.audit.type', + type: 'keyword', + }, + 'googlecloud.audit.authentication_info.principal_email': { + category: 'googlecloud', + description: 'The email address of the authenticated user making the request. ', + name: 'googlecloud.audit.authentication_info.principal_email', + type: 'keyword', + }, + 'googlecloud.audit.authentication_info.authority_selector': { + category: 'googlecloud', + description: + 'The authority selector specified by the requestor, if any. It is not guaranteed that the principal was allowed to use this authority. ', + name: 'googlecloud.audit.authentication_info.authority_selector', + type: 'keyword', + }, + 'googlecloud.audit.authorization_info.permission': { + category: 'googlecloud', + description: 'The required IAM permission. ', + name: 'googlecloud.audit.authorization_info.permission', + type: 'keyword', + }, + 'googlecloud.audit.authorization_info.granted': { + category: 'googlecloud', + description: 'Whether or not authorization for resource and permission was granted. ', + name: 'googlecloud.audit.authorization_info.granted', + type: 'boolean', + }, + 'googlecloud.audit.authorization_info.resource_attributes.service': { + category: 'googlecloud', + description: 'The name of the service. ', + name: 'googlecloud.audit.authorization_info.resource_attributes.service', + type: 'keyword', + }, + 'googlecloud.audit.authorization_info.resource_attributes.name': { + category: 'googlecloud', + description: 'The name of the resource. ', + name: 'googlecloud.audit.authorization_info.resource_attributes.name', + type: 'keyword', + }, + 'googlecloud.audit.authorization_info.resource_attributes.type': { + category: 'googlecloud', + description: 'The type of the resource. ', + name: 'googlecloud.audit.authorization_info.resource_attributes.type', + type: 'keyword', + }, + 'googlecloud.audit.method_name': { + category: 'googlecloud', + description: + "The name of the service method or operation. For API calls, this should be the name of the API method. For example, 'google.datastore.v1.Datastore.RunQuery'. ", + name: 'googlecloud.audit.method_name', + type: 'keyword', + }, + 'googlecloud.audit.num_response_items': { + category: 'googlecloud', + description: 'The number of items returned from a List or Query API method, if applicable. ', + name: 'googlecloud.audit.num_response_items', + type: 'long', + }, + 'googlecloud.audit.request.proto_name': { + category: 'googlecloud', + description: 'Type property of the request. ', + name: 'googlecloud.audit.request.proto_name', + type: 'keyword', + }, + 'googlecloud.audit.request.filter': { + category: 'googlecloud', + description: 'Filter of the request. ', + name: 'googlecloud.audit.request.filter', + type: 'keyword', + }, + 'googlecloud.audit.request.name': { + category: 'googlecloud', + description: 'Name of the request. ', + name: 'googlecloud.audit.request.name', + type: 'keyword', + }, + 'googlecloud.audit.request.resource_name': { + category: 'googlecloud', + description: 'Name of the request resource. ', + name: 'googlecloud.audit.request.resource_name', + type: 'keyword', + }, + 'googlecloud.audit.request_metadata.caller_ip': { + category: 'googlecloud', + description: 'The IP address of the caller. ', + name: 'googlecloud.audit.request_metadata.caller_ip', + type: 'ip', + }, + 'googlecloud.audit.request_metadata.caller_supplied_user_agent': { + category: 'googlecloud', + description: + 'The user agent of the caller. This information is not authenticated and should be treated accordingly. ', + name: 'googlecloud.audit.request_metadata.caller_supplied_user_agent', + type: 'keyword', + }, + 'googlecloud.audit.response.proto_name': { + category: 'googlecloud', + description: 'Type property of the response. ', + name: 'googlecloud.audit.response.proto_name', + type: 'keyword', + }, + 'googlecloud.audit.response.details.group': { + category: 'googlecloud', + description: 'The name of the group. ', + name: 'googlecloud.audit.response.details.group', + type: 'keyword', + }, + 'googlecloud.audit.response.details.kind': { + category: 'googlecloud', + description: 'The kind of the response details. ', + name: 'googlecloud.audit.response.details.kind', + type: 'keyword', + }, + 'googlecloud.audit.response.details.name': { + category: 'googlecloud', + description: 'The name of the response details. ', + name: 'googlecloud.audit.response.details.name', + type: 'keyword', + }, + 'googlecloud.audit.response.details.uid': { + category: 'googlecloud', + description: 'The uid of the response details. ', + name: 'googlecloud.audit.response.details.uid', + type: 'keyword', + }, + 'googlecloud.audit.response.status': { + category: 'googlecloud', + description: 'Status of the response. ', + name: 'googlecloud.audit.response.status', + type: 'keyword', + }, + 'googlecloud.audit.resource_name': { + category: 'googlecloud', + description: + "The resource or collection that is the target of the operation. The name is a scheme-less URI, not including the API service name. For example, 'shelves/SHELF_ID/books'. ", + name: 'googlecloud.audit.resource_name', + type: 'keyword', + }, + 'googlecloud.audit.resource_location.current_locations': { + category: 'googlecloud', + description: 'Current locations of the resource. ', + name: 'googlecloud.audit.resource_location.current_locations', + type: 'keyword', + }, + 'googlecloud.audit.service_name': { + category: 'googlecloud', + description: + 'The name of the API service performing the operation. For example, datastore.googleapis.com. ', + name: 'googlecloud.audit.service_name', + type: 'keyword', + }, + 'googlecloud.audit.status.code': { + category: 'googlecloud', + description: 'The status code, which should be an enum value of google.rpc.Code. ', + name: 'googlecloud.audit.status.code', + type: 'integer', + }, + 'googlecloud.audit.status.message': { + category: 'googlecloud', + description: + 'A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the google.rpc.Status.details field, or localized by the client. ', + name: 'googlecloud.audit.status.message', + type: 'keyword', + }, + 'googlecloud.firewall.rule_details.priority': { + category: 'googlecloud', + description: 'The priority for the firewall rule.', + name: 'googlecloud.firewall.rule_details.priority', + type: 'long', + }, + 'googlecloud.firewall.rule_details.action': { + category: 'googlecloud', + description: 'Action that the rule performs on match.', + name: 'googlecloud.firewall.rule_details.action', + type: 'keyword', + }, + 'googlecloud.firewall.rule_details.direction': { + category: 'googlecloud', + description: 'Direction of traffic that matches this rule.', + name: 'googlecloud.firewall.rule_details.direction', + type: 'keyword', + }, + 'googlecloud.firewall.rule_details.reference': { + category: 'googlecloud', + description: 'Reference to the firewall rule.', + name: 'googlecloud.firewall.rule_details.reference', + type: 'keyword', + }, + 'googlecloud.firewall.rule_details.source_range': { + category: 'googlecloud', + description: 'List of source ranges that the firewall rule applies to.', + name: 'googlecloud.firewall.rule_details.source_range', + type: 'keyword', + }, + 'googlecloud.firewall.rule_details.destination_range': { + category: 'googlecloud', + description: 'List of destination ranges that the firewall applies to.', + name: 'googlecloud.firewall.rule_details.destination_range', + type: 'keyword', + }, + 'googlecloud.firewall.rule_details.source_tag': { + category: 'googlecloud', + description: 'List of all the source tags that the firewall rule applies to. ', + name: 'googlecloud.firewall.rule_details.source_tag', + type: 'keyword', + }, + 'googlecloud.firewall.rule_details.target_tag': { + category: 'googlecloud', + description: 'List of all the target tags that the firewall rule applies to. ', + name: 'googlecloud.firewall.rule_details.target_tag', + type: 'keyword', + }, + 'googlecloud.firewall.rule_details.ip_port_info': { + category: 'googlecloud', + description: 'List of ip protocols and applicable port ranges for rules. ', + name: 'googlecloud.firewall.rule_details.ip_port_info', + type: 'array', + }, + 'googlecloud.firewall.rule_details.source_service_account': { + category: 'googlecloud', + description: 'List of all the source service accounts that the firewall rule applies to. ', + name: 'googlecloud.firewall.rule_details.source_service_account', + type: 'keyword', + }, + 'googlecloud.firewall.rule_details.target_service_account': { + category: 'googlecloud', + description: 'List of all the target service accounts that the firewall rule applies to. ', + name: 'googlecloud.firewall.rule_details.target_service_account', + type: 'keyword', + }, + 'googlecloud.vpcflow.reporter': { + category: 'googlecloud', + description: "The side which reported the flow. Can be either 'SRC' or 'DEST'. ", + name: 'googlecloud.vpcflow.reporter', + type: 'keyword', + }, + 'googlecloud.vpcflow.rtt.ms': { + category: 'googlecloud', + description: + 'Latency as measured (for TCP flows only) during the time interval. This is the time elapsed between sending a SEQ and receiving a corresponding ACK and it contains the network RTT as well as the application related delay. ', + name: 'googlecloud.vpcflow.rtt.ms', + type: 'long', + }, + 'gsuite.actor.type': { + category: 'gsuite', + description: + 'The type of actor. Values can be: *USER*: Another user in the same domain. *EXTERNAL_USER*: A user outside the domain. *KEY*: A non-human actor. ', + name: 'gsuite.actor.type', + type: 'keyword', + }, + 'gsuite.actor.key': { + category: 'gsuite', + description: + 'Only present when `actor.type` is `KEY`. Can be the `consumer_key` of the requestor for OAuth 2LO API requests or an identifier for robot accounts. ', + name: 'gsuite.actor.key', + type: 'keyword', + }, + 'gsuite.event.type': { + category: 'gsuite', + description: + 'The type of GSuite event, mapped from `items[].events[].type` in the original payload. Each fileset can have a different set of values for it, more details can be found at https://developers.google.com/admin-sdk/reports/v1/reference/activities/list ', + example: 'audit#activity', + name: 'gsuite.event.type', + type: 'keyword', + }, + 'gsuite.kind': { + category: 'gsuite', + description: + 'The type of API resource, mapped from `kind` in the original payload. More details can be found at https://developers.google.com/admin-sdk/reports/v1/reference/activities/list ', + example: 'audit#activity', + name: 'gsuite.kind', + type: 'keyword', + }, + 'gsuite.organization.domain': { + category: 'gsuite', + description: "The domain that is affected by the report's event. ", + name: 'gsuite.organization.domain', + type: 'keyword', + }, + 'gsuite.admin.application.edition': { + category: 'gsuite', + description: 'The GSuite edition.', + name: 'gsuite.admin.application.edition', + type: 'keyword', + }, + 'gsuite.admin.application.name': { + category: 'gsuite', + description: "The application's name.", + name: 'gsuite.admin.application.name', + type: 'keyword', + }, + 'gsuite.admin.application.enabled': { + category: 'gsuite', + description: 'The enabled application.', + name: 'gsuite.admin.application.enabled', + type: 'keyword', + }, + 'gsuite.admin.application.licences_order_number': { + category: 'gsuite', + description: 'Order number used to redeem licenses.', + name: 'gsuite.admin.application.licences_order_number', + type: 'keyword', + }, + 'gsuite.admin.application.licences_purchased': { + category: 'gsuite', + description: 'Number of licences purchased.', + name: 'gsuite.admin.application.licences_purchased', + type: 'keyword', + }, + 'gsuite.admin.application.id': { + category: 'gsuite', + description: 'The application ID.', + name: 'gsuite.admin.application.id', + type: 'keyword', + }, + 'gsuite.admin.application.asp_id': { + category: 'gsuite', + description: 'The application specific password ID.', + name: 'gsuite.admin.application.asp_id', + type: 'keyword', + }, + 'gsuite.admin.application.package_id': { + category: 'gsuite', + description: 'The mobile application package ID.', + name: 'gsuite.admin.application.package_id', + type: 'keyword', + }, + 'gsuite.admin.group.email': { + category: 'gsuite', + description: "The group's primary email address.", + name: 'gsuite.admin.group.email', + type: 'keyword', + }, + 'gsuite.admin.new_value': { + category: 'gsuite', + description: 'The new value for the setting.', + name: 'gsuite.admin.new_value', + type: 'keyword', + }, + 'gsuite.admin.old_value': { + category: 'gsuite', + description: 'The old value for the setting.', + name: 'gsuite.admin.old_value', + type: 'keyword', + }, + 'gsuite.admin.org_unit.name': { + category: 'gsuite', + description: 'The organizational unit name.', + name: 'gsuite.admin.org_unit.name', + type: 'keyword', + }, + 'gsuite.admin.org_unit.full': { + category: 'gsuite', + description: 'The org unit full path including the root org unit name.', + name: 'gsuite.admin.org_unit.full', + type: 'keyword', + }, + 'gsuite.admin.setting.name': { + category: 'gsuite', + description: 'The setting name.', + name: 'gsuite.admin.setting.name', + type: 'keyword', + }, + 'gsuite.admin.user_defined_setting.name': { + category: 'gsuite', + description: 'The name of the user-defined setting.', + name: 'gsuite.admin.user_defined_setting.name', + type: 'keyword', + }, + 'gsuite.admin.setting.description': { + category: 'gsuite', + description: 'The setting name.', + name: 'gsuite.admin.setting.description', + type: 'keyword', + }, + 'gsuite.admin.group.priorities': { + category: 'gsuite', + description: 'Group priorities.', + name: 'gsuite.admin.group.priorities', + type: 'keyword', + }, + 'gsuite.admin.domain.alias': { + category: 'gsuite', + description: 'The domain alias.', + name: 'gsuite.admin.domain.alias', + type: 'keyword', + }, + 'gsuite.admin.domain.name': { + category: 'gsuite', + description: 'The primary domain name.', + name: 'gsuite.admin.domain.name', + type: 'keyword', + }, + 'gsuite.admin.domain.secondary_name': { + category: 'gsuite', + description: 'The secondary domain name.', + name: 'gsuite.admin.domain.secondary_name', + type: 'keyword', + }, + 'gsuite.admin.managed_configuration': { + category: 'gsuite', + description: 'The name of the managed configuration.', + name: 'gsuite.admin.managed_configuration', + type: 'keyword', + }, + 'gsuite.admin.non_featured_services_selection': { + category: 'gsuite', + description: + 'Non-featured services selection. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-application-settings#FLASHLIGHT_EDU_NON_FEATURED_SERVICES_SELECTED ', + name: 'gsuite.admin.non_featured_services_selection', + type: 'keyword', + }, + 'gsuite.admin.field': { + category: 'gsuite', + description: 'The name of the field.', + name: 'gsuite.admin.field', + type: 'keyword', + }, + 'gsuite.admin.resource.id': { + category: 'gsuite', + description: 'The name of the resource identifier.', + name: 'gsuite.admin.resource.id', + type: 'keyword', + }, + 'gsuite.admin.user.email': { + category: 'gsuite', + description: "The user's primary email address.", + name: 'gsuite.admin.user.email', + type: 'keyword', + }, + 'gsuite.admin.user.nickname': { + category: 'gsuite', + description: "The user's nickname.", + name: 'gsuite.admin.user.nickname', + type: 'keyword', + }, + 'gsuite.admin.user.birthdate': { + category: 'gsuite', + description: "The user's birth date.", + name: 'gsuite.admin.user.birthdate', + type: 'date', + }, + 'gsuite.admin.gateway.name': { + category: 'gsuite', + description: 'Gateway name. Present on some chat settings.', + name: 'gsuite.admin.gateway.name', + type: 'keyword', + }, + 'gsuite.admin.chrome_os.session_type': { + category: 'gsuite', + description: 'Chrome OS session type.', + name: 'gsuite.admin.chrome_os.session_type', + type: 'keyword', + }, + 'gsuite.admin.device.serial_number': { + category: 'gsuite', + description: 'Device serial number.', + name: 'gsuite.admin.device.serial_number', + type: 'keyword', + }, + 'gsuite.admin.device.id': { + category: 'gsuite', + name: 'gsuite.admin.device.id', + type: 'keyword', + }, + 'gsuite.admin.device.type': { + category: 'gsuite', + description: 'Device type.', + name: 'gsuite.admin.device.type', + type: 'keyword', + }, + 'gsuite.admin.print_server.name': { + category: 'gsuite', + description: 'The name of the print server.', + name: 'gsuite.admin.print_server.name', + type: 'keyword', + }, + 'gsuite.admin.printer.name': { + category: 'gsuite', + description: 'The name of the printer.', + name: 'gsuite.admin.printer.name', + type: 'keyword', + }, + 'gsuite.admin.device.command_details': { + category: 'gsuite', + description: 'Command details.', + name: 'gsuite.admin.device.command_details', + type: 'keyword', + }, + 'gsuite.admin.role.id': { + category: 'gsuite', + description: 'Unique identifier for this role privilege.', + name: 'gsuite.admin.role.id', + type: 'keyword', + }, + 'gsuite.admin.role.name': { + category: 'gsuite', + description: + 'The role name. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-delegated-admin-settings ', + name: 'gsuite.admin.role.name', + type: 'keyword', + }, + 'gsuite.admin.privilege.name': { + category: 'gsuite', + description: 'Privilege name.', + name: 'gsuite.admin.privilege.name', + type: 'keyword', + }, + 'gsuite.admin.service.name': { + category: 'gsuite', + description: 'The service name.', + name: 'gsuite.admin.service.name', + type: 'keyword', + }, + 'gsuite.admin.url.name': { + category: 'gsuite', + description: 'The website name.', + name: 'gsuite.admin.url.name', + type: 'keyword', + }, + 'gsuite.admin.product.name': { + category: 'gsuite', + description: 'The product name.', + name: 'gsuite.admin.product.name', + type: 'keyword', + }, + 'gsuite.admin.product.sku': { + category: 'gsuite', + description: 'The product SKU.', + name: 'gsuite.admin.product.sku', + type: 'keyword', + }, + 'gsuite.admin.bulk_upload.failed': { + category: 'gsuite', + description: 'Number of failed records in bulk upload operation.', + name: 'gsuite.admin.bulk_upload.failed', + type: 'long', + }, + 'gsuite.admin.bulk_upload.total': { + category: 'gsuite', + description: 'Number of total records in bulk upload operation.', + name: 'gsuite.admin.bulk_upload.total', + type: 'long', + }, + 'gsuite.admin.group.allowed_list': { + category: 'gsuite', + description: 'Names of allow-listed groups.', + name: 'gsuite.admin.group.allowed_list', + type: 'keyword', + }, + 'gsuite.admin.email.quarantine_name': { + category: 'gsuite', + description: 'The name of the quarantine.', + name: 'gsuite.admin.email.quarantine_name', + type: 'keyword', + }, + 'gsuite.admin.email.log_search_filter.message_id': { + category: 'gsuite', + description: "The log search filter's email message ID.", + name: 'gsuite.admin.email.log_search_filter.message_id', + type: 'keyword', + }, + 'gsuite.admin.email.log_search_filter.start_date': { + category: 'gsuite', + description: "The log search filter's start date.", + name: 'gsuite.admin.email.log_search_filter.start_date', + type: 'date', + }, + 'gsuite.admin.email.log_search_filter.end_date': { + category: 'gsuite', + description: "The log search filter's ending date.", + name: 'gsuite.admin.email.log_search_filter.end_date', + type: 'date', + }, + 'gsuite.admin.email.log_search_filter.recipient.value': { + category: 'gsuite', + description: "The log search filter's email recipient.", + name: 'gsuite.admin.email.log_search_filter.recipient.value', + type: 'keyword', + }, + 'gsuite.admin.email.log_search_filter.sender.value': { + category: 'gsuite', + description: "The log search filter's email sender.", + name: 'gsuite.admin.email.log_search_filter.sender.value', + type: 'keyword', + }, + 'gsuite.admin.email.log_search_filter.recipient.ip': { + category: 'gsuite', + description: "The log search filter's email recipient's IP address.", + name: 'gsuite.admin.email.log_search_filter.recipient.ip', + type: 'ip', + }, + 'gsuite.admin.email.log_search_filter.sender.ip': { + category: 'gsuite', + description: "The log search filter's email sender's IP address.", + name: 'gsuite.admin.email.log_search_filter.sender.ip', + type: 'ip', + }, + 'gsuite.admin.chrome_licenses.enabled': { + category: 'gsuite', + description: + 'Licences enabled. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-org-settings ', + name: 'gsuite.admin.chrome_licenses.enabled', + type: 'keyword', + }, + 'gsuite.admin.chrome_licenses.allowed': { + category: 'gsuite', + description: + 'Licences enabled. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-org-settings ', + name: 'gsuite.admin.chrome_licenses.allowed', + type: 'keyword', + }, + 'gsuite.admin.oauth2.service.name': { + category: 'gsuite', + description: + 'OAuth2 service name. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-security-settings ', + name: 'gsuite.admin.oauth2.service.name', + type: 'keyword', + }, + 'gsuite.admin.oauth2.application.id': { + category: 'gsuite', + description: 'OAuth2 application ID.', + name: 'gsuite.admin.oauth2.application.id', + type: 'keyword', + }, + 'gsuite.admin.oauth2.application.name': { + category: 'gsuite', + description: 'OAuth2 application name.', + name: 'gsuite.admin.oauth2.application.name', + type: 'keyword', + }, + 'gsuite.admin.oauth2.application.type': { + category: 'gsuite', + description: + 'OAuth2 application type. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-security-settings ', + name: 'gsuite.admin.oauth2.application.type', + type: 'keyword', + }, + 'gsuite.admin.verification_method': { + category: 'gsuite', + description: + 'Related verification method. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-security-settings and https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-domain-settings ', + name: 'gsuite.admin.verification_method', + type: 'keyword', + }, + 'gsuite.admin.alert.name': { + category: 'gsuite', + description: 'The alert name.', + name: 'gsuite.admin.alert.name', + type: 'keyword', + }, + 'gsuite.admin.rule.name': { + category: 'gsuite', + description: 'The rule name.', + name: 'gsuite.admin.rule.name', + type: 'keyword', + }, + 'gsuite.admin.api.client.name': { + category: 'gsuite', + description: 'The API client name.', + name: 'gsuite.admin.api.client.name', + type: 'keyword', + }, + 'gsuite.admin.api.scopes': { + category: 'gsuite', + description: 'The API scopes.', + name: 'gsuite.admin.api.scopes', + type: 'keyword', + }, + 'gsuite.admin.mdm.token': { + category: 'gsuite', + description: 'The MDM vendor enrollment token.', + name: 'gsuite.admin.mdm.token', + type: 'keyword', + }, + 'gsuite.admin.mdm.vendor': { + category: 'gsuite', + description: "The MDM vendor's name.", + name: 'gsuite.admin.mdm.vendor', + type: 'keyword', + }, + 'gsuite.admin.info_type': { + category: 'gsuite', + description: + 'This will be used to state what kind of information was changed. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-domain-settings ', + name: 'gsuite.admin.info_type', + type: 'keyword', + }, + 'gsuite.admin.email_monitor.dest_email': { + category: 'gsuite', + description: 'The destination address of the email monitor.', + name: 'gsuite.admin.email_monitor.dest_email', + type: 'keyword', + }, + 'gsuite.admin.email_monitor.level.chat': { + category: 'gsuite', + description: 'The chat email monitor level.', + name: 'gsuite.admin.email_monitor.level.chat', + type: 'keyword', + }, + 'gsuite.admin.email_monitor.level.draft': { + category: 'gsuite', + description: 'The draft email monitor level.', + name: 'gsuite.admin.email_monitor.level.draft', + type: 'keyword', + }, + 'gsuite.admin.email_monitor.level.incoming': { + category: 'gsuite', + description: 'The incoming email monitor level.', + name: 'gsuite.admin.email_monitor.level.incoming', + type: 'keyword', + }, + 'gsuite.admin.email_monitor.level.outgoing': { + category: 'gsuite', + description: 'The outgoing email monitor level.', + name: 'gsuite.admin.email_monitor.level.outgoing', + type: 'keyword', + }, + 'gsuite.admin.email_dump.include_deleted': { + category: 'gsuite', + description: 'Indicates if deleted emails are included in the export.', + name: 'gsuite.admin.email_dump.include_deleted', + type: 'boolean', + }, + 'gsuite.admin.email_dump.package_content': { + category: 'gsuite', + description: 'The contents of the mailbox package.', + name: 'gsuite.admin.email_dump.package_content', + type: 'keyword', + }, + 'gsuite.admin.email_dump.query': { + category: 'gsuite', + description: 'The search query used for the dump.', + name: 'gsuite.admin.email_dump.query', + type: 'keyword', + }, + 'gsuite.admin.request.id': { + category: 'gsuite', + description: 'The request ID.', + name: 'gsuite.admin.request.id', + type: 'keyword', + }, + 'gsuite.admin.mobile.action.id': { + category: 'gsuite', + description: "The mobile device action's ID.", + name: 'gsuite.admin.mobile.action.id', + type: 'keyword', + }, + 'gsuite.admin.mobile.action.type': { + category: 'gsuite', + description: + "The mobile device action's type. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-mobile-settings ", + name: 'gsuite.admin.mobile.action.type', + type: 'keyword', + }, + 'gsuite.admin.mobile.certificate.name': { + category: 'gsuite', + description: 'The mobile certificate common name.', + name: 'gsuite.admin.mobile.certificate.name', + type: 'keyword', + }, + 'gsuite.admin.mobile.company_owned_devices': { + category: 'gsuite', + description: 'The number of devices a company owns.', + name: 'gsuite.admin.mobile.company_owned_devices', + type: 'long', + }, + 'gsuite.admin.distribution.entity.name': { + category: 'gsuite', + description: + 'The distribution entity value, which can be a group name or an org-unit name. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-mobile-settings ', + name: 'gsuite.admin.distribution.entity.name', + type: 'keyword', + }, + 'gsuite.admin.distribution.entity.type': { + category: 'gsuite', + description: + 'The distribution entity type, which can be a group or an org-unit. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/admin-mobile-settings ', + name: 'gsuite.admin.distribution.entity.type', + type: 'keyword', + }, + 'gsuite.drive.billable': { + category: 'gsuite', + description: 'Whether this activity is billable.', + name: 'gsuite.drive.billable', + type: 'boolean', + }, + 'gsuite.drive.source_folder_id': { + category: 'gsuite', + name: 'gsuite.drive.source_folder_id', + type: 'keyword', + }, + 'gsuite.drive.source_folder_title': { + category: 'gsuite', + name: 'gsuite.drive.source_folder_title', + type: 'keyword', + }, + 'gsuite.drive.destination_folder_id': { + category: 'gsuite', + name: 'gsuite.drive.destination_folder_id', + type: 'keyword', + }, + 'gsuite.drive.destination_folder_title': { + category: 'gsuite', + name: 'gsuite.drive.destination_folder_title', + type: 'keyword', + }, + 'gsuite.drive.file.id': { + category: 'gsuite', + name: 'gsuite.drive.file.id', + type: 'keyword', + }, + 'gsuite.drive.file.type': { + category: 'gsuite', + description: + 'Document Drive type. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/drive ', + name: 'gsuite.drive.file.type', + type: 'keyword', + }, + 'gsuite.drive.originating_app_id': { + category: 'gsuite', + description: 'The Google Cloud Project ID of the application that performed the action. ', + name: 'gsuite.drive.originating_app_id', + type: 'keyword', + }, + 'gsuite.drive.file.owner.email': { + category: 'gsuite', + name: 'gsuite.drive.file.owner.email', + type: 'keyword', + }, + 'gsuite.drive.file.owner.is_shared_drive': { + category: 'gsuite', + description: 'Boolean flag denoting whether owner is a shared drive. ', + name: 'gsuite.drive.file.owner.is_shared_drive', + type: 'boolean', + }, + 'gsuite.drive.primary_event': { + category: 'gsuite', + description: + 'Whether this is a primary event. A single user action in Drive may generate several events. ', + name: 'gsuite.drive.primary_event', + type: 'boolean', + }, + 'gsuite.drive.shared_drive_id': { + category: 'gsuite', + description: + 'The unique identifier of the Team Drive. Only populated for for events relating to a Team Drive or item contained inside a Team Drive. ', + name: 'gsuite.drive.shared_drive_id', + type: 'keyword', + }, + 'gsuite.drive.visibility': { + category: 'gsuite', + description: + 'Visibility of target file. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/drive ', + name: 'gsuite.drive.visibility', + type: 'keyword', + }, + 'gsuite.drive.new_value': { + category: 'gsuite', + description: + 'When a setting or property of the file changes, the new value for it will appear here. ', + name: 'gsuite.drive.new_value', + type: 'keyword', + }, + 'gsuite.drive.old_value': { + category: 'gsuite', + description: + 'When a setting or property of the file changes, the old value for it will appear here. ', + name: 'gsuite.drive.old_value', + type: 'keyword', + }, + 'gsuite.drive.sheets_import_range_recipient_doc': { + category: 'gsuite', + description: 'Doc ID of the recipient of a sheets import range.', + name: 'gsuite.drive.sheets_import_range_recipient_doc', + type: 'keyword', + }, + 'gsuite.drive.old_visibility': { + category: 'gsuite', + description: 'When visibility changes, this holds the old value. ', + name: 'gsuite.drive.old_visibility', + type: 'keyword', + }, + 'gsuite.drive.visibility_change': { + category: 'gsuite', + description: 'When visibility changes, this holds the new overall visibility of the file. ', + name: 'gsuite.drive.visibility_change', + type: 'keyword', + }, + 'gsuite.drive.target_domain': { + category: 'gsuite', + description: + 'The domain for which the acccess scope was changed. This can also be the alias all to indicate the access scope was changed for all domains that have visibility for this document. ', + name: 'gsuite.drive.target_domain', + type: 'keyword', + }, + 'gsuite.drive.added_role': { + category: 'gsuite', + description: + 'Added membership role of a user/group in a Team Drive. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/drive ', + name: 'gsuite.drive.added_role', + type: 'keyword', + }, + 'gsuite.drive.membership_change_type': { + category: 'gsuite', + description: + 'Type of change in Team Drive membership of a user/group. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/drive ', + name: 'gsuite.drive.membership_change_type', + type: 'keyword', + }, + 'gsuite.drive.shared_drive_settings_change_type': { + category: 'gsuite', + description: + 'Type of change in Team Drive settings. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/drive ', + name: 'gsuite.drive.shared_drive_settings_change_type', + type: 'keyword', + }, + 'gsuite.drive.removed_role': { + category: 'gsuite', + description: + 'Removed membership role of a user/group in a Team Drive. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/drive ', + name: 'gsuite.drive.removed_role', + type: 'keyword', + }, + 'gsuite.drive.target': { + category: 'gsuite', + description: 'Target user or group.', + name: 'gsuite.drive.target', + type: 'keyword', + }, + 'gsuite.groups.acl_permission': { + category: 'gsuite', + description: + 'Group permission setting updated. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/groups ', + name: 'gsuite.groups.acl_permission', + type: 'keyword', + }, + 'gsuite.groups.email': { + category: 'gsuite', + description: 'Group email. ', + name: 'gsuite.groups.email', + type: 'keyword', + }, + 'gsuite.groups.member.email': { + category: 'gsuite', + description: 'Member email. ', + name: 'gsuite.groups.member.email', + type: 'keyword', + }, + 'gsuite.groups.member.role': { + category: 'gsuite', + description: + 'Member role. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/groups ', + name: 'gsuite.groups.member.role', + type: 'keyword', + }, + 'gsuite.groups.setting': { + category: 'gsuite', + description: + 'Group setting updated. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/groups ', + name: 'gsuite.groups.setting', + type: 'keyword', + }, + 'gsuite.groups.new_value': { + category: 'gsuite', + description: + 'New value(s) of the group setting. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/groups ', + name: 'gsuite.groups.new_value', + type: 'keyword', + }, + 'gsuite.groups.old_value': { + category: 'gsuite', + description: + 'Old value(s) of the group setting. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/groups', + name: 'gsuite.groups.old_value', + type: 'keyword', + }, + 'gsuite.groups.value': { + category: 'gsuite', + description: + 'Value of the group setting. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/groups ', + name: 'gsuite.groups.value', + type: 'keyword', + }, + 'gsuite.groups.message.id': { + category: 'gsuite', + description: 'SMTP message Id of an email message. Present for moderation events. ', + name: 'gsuite.groups.message.id', + type: 'keyword', + }, + 'gsuite.groups.message.moderation_action': { + category: 'gsuite', + description: 'Message moderation action. Possible values are `approved` and `rejected`. ', + name: 'gsuite.groups.message.moderation_action', + type: 'keyword', + }, + 'gsuite.groups.status': { + category: 'gsuite', + description: + 'A status describing the output of an operation. Possible values are `failed` and `succeeded`. ', + name: 'gsuite.groups.status', + type: 'keyword', + }, + 'gsuite.login.affected_email_address': { + category: 'gsuite', + name: 'gsuite.login.affected_email_address', + type: 'keyword', + }, + 'gsuite.login.challenge_method': { + category: 'gsuite', + description: + 'Login challenge method. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/login. ', + name: 'gsuite.login.challenge_method', + type: 'keyword', + }, + 'gsuite.login.failure_type': { + category: 'gsuite', + description: + 'Login failure type. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/login. ', + name: 'gsuite.login.failure_type', + type: 'keyword', + }, + 'gsuite.login.type': { + category: 'gsuite', + description: + 'Login credentials type. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/login. ', + name: 'gsuite.login.type', + type: 'keyword', + }, + 'gsuite.login.is_second_factor': { + category: 'gsuite', + name: 'gsuite.login.is_second_factor', + type: 'boolean', + }, + 'gsuite.login.is_suspicious': { + category: 'gsuite', + name: 'gsuite.login.is_suspicious', + type: 'boolean', + }, + 'gsuite.saml.application_name': { + category: 'gsuite', + description: 'Saml SP application name. ', + name: 'gsuite.saml.application_name', + type: 'keyword', + }, + 'gsuite.saml.failure_type': { + category: 'gsuite', + description: + 'Login failure type. For a list of possible values refer to https://developers.google.com/admin-sdk/reports/v1/appendix/activity/saml. ', + name: 'gsuite.saml.failure_type', + type: 'keyword', + }, + 'gsuite.saml.initiated_by': { + category: 'gsuite', + description: 'Requester of SAML authentication. ', + name: 'gsuite.saml.initiated_by', + type: 'keyword', + }, + 'gsuite.saml.orgunit_path': { + category: 'gsuite', + description: 'User orgunit. ', + name: 'gsuite.saml.orgunit_path', + type: 'keyword', + }, + 'gsuite.saml.status_code': { + category: 'gsuite', + description: 'SAML status code. ', + name: 'gsuite.saml.status_code', + type: 'long', + }, + 'gsuite.saml.second_level_status_code': { + category: 'gsuite', + description: 'SAML second level status code. ', + name: 'gsuite.saml.second_level_status_code', + type: 'long', + }, + 'ibmmq.errorlog.installation': { + category: 'ibmmq', + description: + 'This is the installation name which can be given at installation time. Each installation of IBM MQ on UNIX, Linux, and Windows, has a unique identifier known as an installation name. The installation name is used to associate things such as queue managers and configuration files with an installation. ', + name: 'ibmmq.errorlog.installation', + type: 'keyword', + }, + 'ibmmq.errorlog.qmgr': { + category: 'ibmmq', + description: + 'Name of the queue manager. Queue managers provide queuing services to applications, and manages the queues that belong to them. ', + name: 'ibmmq.errorlog.qmgr', + type: 'keyword', + }, + 'ibmmq.errorlog.arithinsert': { + category: 'ibmmq', + description: 'Changing content based on error.id', + name: 'ibmmq.errorlog.arithinsert', + type: 'keyword', + }, + 'ibmmq.errorlog.commentinsert': { + category: 'ibmmq', + description: 'Changing content based on error.id', + name: 'ibmmq.errorlog.commentinsert', + type: 'keyword', + }, + 'ibmmq.errorlog.errordescription': { + category: 'ibmmq', + description: 'Please add description', + example: 'Please add example', + name: 'ibmmq.errorlog.errordescription', + type: 'text', + }, + 'ibmmq.errorlog.explanation': { + category: 'ibmmq', + description: 'Explaines the error in more detail', + name: 'ibmmq.errorlog.explanation', + type: 'keyword', + }, + 'ibmmq.errorlog.action': { + category: 'ibmmq', + description: 'Defines what to do when the error occurs', + name: 'ibmmq.errorlog.action', + type: 'keyword', + }, + 'ibmmq.errorlog.code': { + category: 'ibmmq', + description: 'Error code.', + name: 'ibmmq.errorlog.code', + type: 'keyword', + }, + 'iptables.ether_type': { + category: 'iptables', + description: 'Value of the ethernet type field identifying the network layer protocol. ', + name: 'iptables.ether_type', + type: 'long', + }, + 'iptables.flow_label': { + category: 'iptables', + description: 'IPv6 flow label. ', + name: 'iptables.flow_label', + type: 'integer', + }, + 'iptables.fragment_flags': { + category: 'iptables', + description: 'IP fragment flags. A combination of CE, DF and MF. ', + name: 'iptables.fragment_flags', + type: 'keyword', + }, + 'iptables.fragment_offset': { + category: 'iptables', + description: 'Offset of the current IP fragment. ', + name: 'iptables.fragment_offset', + type: 'long', + }, + 'iptables.icmp.code': { + category: 'iptables', + description: 'ICMP code. ', + name: 'iptables.icmp.code', + type: 'long', + }, + 'iptables.icmp.id': { + category: 'iptables', + description: 'ICMP ID. ', + name: 'iptables.icmp.id', + type: 'long', + }, + 'iptables.icmp.parameter': { + category: 'iptables', + description: 'ICMP parameter. ', + name: 'iptables.icmp.parameter', + type: 'long', + }, + 'iptables.icmp.redirect': { + category: 'iptables', + description: 'ICMP redirect address. ', + name: 'iptables.icmp.redirect', + type: 'ip', + }, + 'iptables.icmp.seq': { + category: 'iptables', + description: 'ICMP sequence number. ', + name: 'iptables.icmp.seq', + type: 'long', + }, + 'iptables.icmp.type': { + category: 'iptables', + description: 'ICMP type. ', + name: 'iptables.icmp.type', + type: 'long', + }, + 'iptables.id': { + category: 'iptables', + description: 'Packet identifier. ', + name: 'iptables.id', + type: 'long', + }, + 'iptables.incomplete_bytes': { + category: 'iptables', + description: 'Number of incomplete bytes. ', + name: 'iptables.incomplete_bytes', + type: 'long', + }, + 'iptables.input_device': { + category: 'iptables', + description: 'Device that received the packet. ', + name: 'iptables.input_device', + type: 'keyword', + }, + 'iptables.precedence_bits': { + category: 'iptables', + description: 'IP precedence bits. ', + name: 'iptables.precedence_bits', + type: 'short', + }, + 'iptables.tos': { + category: 'iptables', + description: 'IP Type of Service field. ', + name: 'iptables.tos', + type: 'long', + }, + 'iptables.length': { + category: 'iptables', + description: 'Packet length. ', + name: 'iptables.length', + type: 'long', + }, + 'iptables.output_device': { + category: 'iptables', + description: 'Device that output the packet. ', + name: 'iptables.output_device', + type: 'keyword', + }, + 'iptables.tcp.flags': { + category: 'iptables', + description: 'TCP flags. ', + name: 'iptables.tcp.flags', + type: 'keyword', + }, + 'iptables.tcp.reserved_bits': { + category: 'iptables', + description: 'TCP reserved bits. ', + name: 'iptables.tcp.reserved_bits', + type: 'short', + }, + 'iptables.tcp.seq': { + category: 'iptables', + description: 'TCP sequence number. ', + name: 'iptables.tcp.seq', + type: 'long', + }, + 'iptables.tcp.ack': { + category: 'iptables', + description: 'TCP Acknowledgment number. ', + name: 'iptables.tcp.ack', + type: 'long', + }, + 'iptables.tcp.window': { + category: 'iptables', + description: 'Advertised TCP window size. ', + name: 'iptables.tcp.window', + type: 'long', + }, + 'iptables.ttl': { + category: 'iptables', + description: 'Time To Live field. ', + name: 'iptables.ttl', + type: 'integer', + }, + 'iptables.udp.length': { + category: 'iptables', + description: 'Length of the UDP header and payload. ', + name: 'iptables.udp.length', + type: 'long', + }, + 'iptables.ubiquiti.input_zone': { + category: 'iptables', + description: 'Input zone. ', + name: 'iptables.ubiquiti.input_zone', + type: 'keyword', + }, + 'iptables.ubiquiti.output_zone': { + category: 'iptables', + description: 'Output zone. ', + name: 'iptables.ubiquiti.output_zone', + type: 'keyword', + }, + 'iptables.ubiquiti.rule_number': { + category: 'iptables', + description: 'The rule number within the rule set.', + name: 'iptables.ubiquiti.rule_number', + type: 'keyword', + }, + 'iptables.ubiquiti.rule_set': { + category: 'iptables', + description: 'The rule set name.', + name: 'iptables.ubiquiti.rule_set', + type: 'keyword', + }, + 'microsoft.defender_atp.lastUpdateTime': { + category: 'microsoft', + description: 'The date and time (in UTC) the alert was last updated. ', + name: 'microsoft.defender_atp.lastUpdateTime', + type: 'date', + }, + 'microsoft.defender_atp.resolvedTime': { + category: 'microsoft', + description: "The date and time in which the status of the alert was changed to 'Resolved'. ", + name: 'microsoft.defender_atp.resolvedTime', + type: 'date', + }, + 'microsoft.defender_atp.incidentId': { + category: 'microsoft', + description: 'The Incident ID of the Alert. ', + name: 'microsoft.defender_atp.incidentId', + type: 'keyword', + }, + 'microsoft.defender_atp.investigationId': { + category: 'microsoft', + description: 'The Investigation ID related to the Alert. ', + name: 'microsoft.defender_atp.investigationId', + type: 'keyword', + }, + 'microsoft.defender_atp.investigationState': { + category: 'microsoft', + description: 'The current state of the Investigation. ', + name: 'microsoft.defender_atp.investigationState', + type: 'keyword', + }, + 'microsoft.defender_atp.assignedTo': { + category: 'microsoft', + description: 'Owner of the alert. ', + name: 'microsoft.defender_atp.assignedTo', + type: 'keyword', + }, + 'microsoft.defender_atp.status': { + category: 'microsoft', + description: + "Specifies the current status of the alert. Possible values are: 'Unknown', 'New', 'InProgress' and 'Resolved'. ", + name: 'microsoft.defender_atp.status', + type: 'keyword', + }, + 'microsoft.defender_atp.classification': { + category: 'microsoft', + description: + "Specification of the alert. Possible values are: 'Unknown', 'FalsePositive', 'TruePositive'. ", + name: 'microsoft.defender_atp.classification', + type: 'keyword', + }, + 'microsoft.defender_atp.determination': { + category: 'microsoft', + description: + "Specifies the determination of the alert. Possible values are: 'NotAvailable', 'Apt', 'Malware', 'SecurityPersonnel', 'SecurityTesting', 'UnwantedSoftware', 'Other'. ", + name: 'microsoft.defender_atp.determination', + type: 'keyword', + }, + 'microsoft.defender_atp.threatFamilyName': { + category: 'microsoft', + description: 'Threat family. ', + name: 'microsoft.defender_atp.threatFamilyName', + type: 'keyword', + }, + 'microsoft.defender_atp.rbacGroupName': { + category: 'microsoft', + description: 'User group related to the alert ', + name: 'microsoft.defender_atp.rbacGroupName', + type: 'keyword', + }, + 'microsoft.defender_atp.evidence.domainName': { + category: 'microsoft', + description: 'Domain name related to the alert ', + name: 'microsoft.defender_atp.evidence.domainName', + type: 'keyword', + }, + 'microsoft.defender_atp.evidence.ipAddress': { + category: 'microsoft', + description: 'IP address involved in the alert ', + name: 'microsoft.defender_atp.evidence.ipAddress', + type: 'ip', + }, + 'microsoft.defender_atp.evidence.aadUserId': { + category: 'microsoft', + description: 'ID of the user involved in the alert ', + name: 'microsoft.defender_atp.evidence.aadUserId', + type: 'keyword', + }, + 'microsoft.defender_atp.evidence.accountName': { + category: 'microsoft', + description: 'Username of the user involved in the alert ', + name: 'microsoft.defender_atp.evidence.accountName', + type: 'keyword', + }, + 'microsoft.defender_atp.evidence.entityType': { + category: 'microsoft', + description: 'The type of evidence ', + name: 'microsoft.defender_atp.evidence.entityType', + type: 'keyword', + }, + 'microsoft.defender_atp.evidence.userPrincipalName': { + category: 'microsoft', + description: 'Principal name of the user involved in the alert ', + name: 'microsoft.defender_atp.evidence.userPrincipalName', + type: 'keyword', + }, + 'misp.attack_pattern.id': { + category: 'misp', + description: 'Identifier of the threat indicator. ', + name: 'misp.attack_pattern.id', + type: 'keyword', + }, + 'misp.attack_pattern.name': { + category: 'misp', + description: 'Name of the attack pattern. ', + name: 'misp.attack_pattern.name', + type: 'keyword', + }, + 'misp.attack_pattern.description': { + category: 'misp', + description: 'Description of the attack pattern. ', + name: 'misp.attack_pattern.description', + type: 'text', + }, + 'misp.attack_pattern.kill_chain_phases': { + category: 'misp', + description: 'The kill chain phase(s) to which this attack pattern corresponds. ', + name: 'misp.attack_pattern.kill_chain_phases', + type: 'keyword', + }, + 'misp.campaign.id': { + category: 'misp', + description: 'Identifier of the campaign. ', + name: 'misp.campaign.id', + type: 'keyword', + }, + 'misp.campaign.name': { + category: 'misp', + description: 'Name of the campaign. ', + name: 'misp.campaign.name', + type: 'keyword', + }, + 'misp.campaign.description': { + category: 'misp', + description: 'Description of the campaign. ', + name: 'misp.campaign.description', + type: 'text', + }, + 'misp.campaign.aliases': { + category: 'misp', + description: 'Alternative names used to identify this campaign. ', + name: 'misp.campaign.aliases', + type: 'text', + }, + 'misp.campaign.first_seen': { + category: 'misp', + description: 'The time that this Campaign was first seen, in RFC3339 format. ', + name: 'misp.campaign.first_seen', + type: 'date', + }, + 'misp.campaign.last_seen': { + category: 'misp', + description: 'The time that this Campaign was last seen, in RFC3339 format. ', + name: 'misp.campaign.last_seen', + type: 'date', + }, + 'misp.campaign.objective': { + category: 'misp', + description: + "This field defines the Campaign's primary goal, objective, desired outcome, or intended effect. ", + name: 'misp.campaign.objective', + type: 'keyword', + }, + 'misp.course_of_action.id': { + category: 'misp', + description: 'Identifier of the Course of Action. ', + name: 'misp.course_of_action.id', + type: 'keyword', + }, + 'misp.course_of_action.name': { + category: 'misp', + description: 'The name used to identify the Course of Action. ', + name: 'misp.course_of_action.name', + type: 'keyword', + }, + 'misp.course_of_action.description': { + category: 'misp', + description: 'Description of the Course of Action. ', + name: 'misp.course_of_action.description', + type: 'text', + }, + 'misp.identity.id': { + category: 'misp', + description: 'Identifier of the Identity. ', + name: 'misp.identity.id', + type: 'keyword', + }, + 'misp.identity.name': { + category: 'misp', + description: 'The name used to identify the Identity. ', + name: 'misp.identity.name', + type: 'keyword', + }, + 'misp.identity.description': { + category: 'misp', + description: 'Description of the Identity. ', + name: 'misp.identity.description', + type: 'text', + }, + 'misp.identity.identity_class': { + category: 'misp', + description: + 'The type of entity that this Identity describes, e.g., an individual or organization. Open Vocab - identity-class-ov ', + name: 'misp.identity.identity_class', + type: 'keyword', + }, + 'misp.identity.labels': { + category: 'misp', + description: 'The list of roles that this Identity performs. ', + example: 'CEO\n', + name: 'misp.identity.labels', + type: 'keyword', + }, + 'misp.identity.sectors': { + category: 'misp', + description: + 'The list of sectors that this Identity belongs to. Open Vocab - industry-sector-ov ', + name: 'misp.identity.sectors', + type: 'keyword', + }, + 'misp.identity.contact_information': { + category: 'misp', + description: 'The contact information (e-mail, phone number, etc.) for this Identity. ', + name: 'misp.identity.contact_information', + type: 'text', + }, + 'misp.intrusion_set.id': { + category: 'misp', + description: 'Identifier of the Intrusion Set. ', + name: 'misp.intrusion_set.id', + type: 'keyword', + }, + 'misp.intrusion_set.name': { + category: 'misp', + description: 'The name used to identify the Intrusion Set. ', + name: 'misp.intrusion_set.name', + type: 'keyword', + }, + 'misp.intrusion_set.description': { + category: 'misp', + description: 'Description of the Intrusion Set. ', + name: 'misp.intrusion_set.description', + type: 'text', + }, + 'misp.intrusion_set.aliases': { + category: 'misp', + description: 'Alternative names used to identify the Intrusion Set. ', + name: 'misp.intrusion_set.aliases', + type: 'text', + }, + 'misp.intrusion_set.first_seen': { + category: 'misp', + description: 'The time that this Intrusion Set was first seen, in RFC3339 format. ', + name: 'misp.intrusion_set.first_seen', + type: 'date', + }, + 'misp.intrusion_set.last_seen': { + category: 'misp', + description: 'The time that this Intrusion Set was last seen, in RFC3339 format. ', + name: 'misp.intrusion_set.last_seen', + type: 'date', + }, + 'misp.intrusion_set.goals': { + category: 'misp', + description: 'The high level goals of this Intrusion Set, namely, what are they trying to do. ', + name: 'misp.intrusion_set.goals', + type: 'text', + }, + 'misp.intrusion_set.resource_level': { + category: 'misp', + description: + 'This defines the organizational level at which this Intrusion Set typically works. Open Vocab - attack-resource-level-ov ', + name: 'misp.intrusion_set.resource_level', + type: 'text', + }, + 'misp.intrusion_set.primary_motivation': { + category: 'misp', + description: + 'The primary reason, motivation, or purpose behind this Intrusion Set. Open Vocab - attack-motivation-ov ', + name: 'misp.intrusion_set.primary_motivation', + type: 'text', + }, + 'misp.intrusion_set.secondary_motivations': { + category: 'misp', + description: + 'The secondary reasons, motivations, or purposes behind this Intrusion Set. Open Vocab - attack-motivation-ov ', + name: 'misp.intrusion_set.secondary_motivations', + type: 'text', + }, + 'misp.malware.id': { + category: 'misp', + description: 'Identifier of the Malware. ', + name: 'misp.malware.id', + type: 'keyword', + }, + 'misp.malware.name': { + category: 'misp', + description: 'The name used to identify the Malware. ', + name: 'misp.malware.name', + type: 'keyword', + }, + 'misp.malware.description': { + category: 'misp', + description: 'Description of the Malware. ', + name: 'misp.malware.description', + type: 'text', + }, + 'misp.malware.labels': { + category: 'misp', + description: + 'The type of malware being described. Open Vocab - malware-label-ov. adware,backdoor,bot,ddos,dropper,exploit-kit,keylogger,ransomware, remote-access-trojan,resource-exploitation,rogue-security-software,rootkit, screen-capture,spyware,trojan,virus,worm ', + name: 'misp.malware.labels', + type: 'keyword', + }, + 'misp.malware.kill_chain_phases': { + category: 'misp', + description: 'The list of kill chain phases for which this Malware instance can be used. ', + name: 'misp.malware.kill_chain_phases', + type: 'keyword', + format: 'string', + }, + 'misp.note.id': { + category: 'misp', + description: 'Identifier of the Note. ', + name: 'misp.note.id', + type: 'keyword', + }, + 'misp.note.summary': { + category: 'misp', + description: 'A brief description used as a summary of the Note. ', + name: 'misp.note.summary', + type: 'keyword', + }, + 'misp.note.description': { + category: 'misp', + description: 'The content of the Note. ', + name: 'misp.note.description', + type: 'text', + }, + 'misp.note.authors': { + category: 'misp', + description: 'The name of the author(s) of this Note. ', + name: 'misp.note.authors', + type: 'keyword', + }, + 'misp.note.object_refs': { + category: 'misp', + description: 'The STIX Objects (SDOs and SROs) that the note is being applied to. ', + name: 'misp.note.object_refs', + type: 'keyword', + }, + 'misp.threat_indicator.labels': { + category: 'misp', + description: 'list of type open-vocab that specifies the type of indicator. ', + example: 'Domain Watchlist\n', + name: 'misp.threat_indicator.labels', + type: 'keyword', + }, + 'misp.threat_indicator.id': { + category: 'misp', + description: 'Identifier of the threat indicator. ', + name: 'misp.threat_indicator.id', + type: 'keyword', + }, + 'misp.threat_indicator.version': { + category: 'misp', + description: 'Version of the threat indicator. ', + name: 'misp.threat_indicator.version', + type: 'keyword', + }, + 'misp.threat_indicator.type': { + category: 'misp', + description: 'Type of the threat indicator. ', + name: 'misp.threat_indicator.type', + type: 'keyword', + }, + 'misp.threat_indicator.description': { + category: 'misp', + description: 'Description of the threat indicator. ', + name: 'misp.threat_indicator.description', + type: 'text', + }, + 'misp.threat_indicator.feed': { + category: 'misp', + description: 'Name of the threat feed. ', + name: 'misp.threat_indicator.feed', + type: 'text', + }, + 'misp.threat_indicator.valid_from': { + category: 'misp', + description: + 'The time from which this Indicator should be considered valuable intelligence, in RFC3339 format. ', + name: 'misp.threat_indicator.valid_from', + type: 'date', + }, + 'misp.threat_indicator.valid_until': { + category: 'misp', + description: + 'The time at which this Indicator should no longer be considered valuable intelligence. If the valid_until property is omitted, then there is no constraint on the latest time for which the indicator should be used, in RFC3339 format. ', + name: 'misp.threat_indicator.valid_until', + type: 'date', + }, + 'misp.threat_indicator.severity': { + category: 'misp', + description: 'Threat severity to which this indicator corresponds. ', + example: 'high', + name: 'misp.threat_indicator.severity', + type: 'keyword', + format: 'string', + }, + 'misp.threat_indicator.confidence': { + category: 'misp', + description: 'Confidence level to which this indicator corresponds. ', + example: 'high', + name: 'misp.threat_indicator.confidence', + type: 'keyword', + }, + 'misp.threat_indicator.kill_chain_phases': { + category: 'misp', + description: 'The kill chain phase(s) to which this indicator corresponds. ', + name: 'misp.threat_indicator.kill_chain_phases', + type: 'keyword', + format: 'string', + }, + 'misp.threat_indicator.mitre_tactic': { + category: 'misp', + description: 'MITRE tactics to which this indicator corresponds. ', + example: 'Initial Access', + name: 'misp.threat_indicator.mitre_tactic', + type: 'keyword', + format: 'string', + }, + 'misp.threat_indicator.mitre_technique': { + category: 'misp', + description: 'MITRE techniques to which this indicator corresponds. ', + example: 'Drive-by Compromise', + name: 'misp.threat_indicator.mitre_technique', + type: 'keyword', + format: 'string', + }, + 'misp.threat_indicator.attack_pattern': { + category: 'misp', + description: + 'The attack_pattern for this indicator is a STIX Pattern as specified in STIX Version 2.0 Part 5 - STIX Patterning. ', + example: "[destination:ip = '91.219.29.188/32']\n", + name: 'misp.threat_indicator.attack_pattern', + type: 'keyword', + }, + 'misp.threat_indicator.attack_pattern_kql': { + category: 'misp', + description: + 'The attack_pattern for this indicator is KQL query that matches the attack_pattern specified in the STIX Pattern format. ', + example: 'destination.ip: "91.219.29.188/32"\n', + name: 'misp.threat_indicator.attack_pattern_kql', + type: 'keyword', + }, + 'misp.threat_indicator.negate': { + category: 'misp', + description: 'When set to true, it specifies the absence of the attack_pattern. ', + name: 'misp.threat_indicator.negate', + type: 'boolean', + }, + 'misp.threat_indicator.intrusion_set': { + category: 'misp', + description: 'Name of the intrusion set if known. ', + name: 'misp.threat_indicator.intrusion_set', + type: 'keyword', + }, + 'misp.threat_indicator.campaign': { + category: 'misp', + description: 'Name of the attack campaign if known. ', + name: 'misp.threat_indicator.campaign', + type: 'keyword', + }, + 'misp.threat_indicator.threat_actor': { + category: 'misp', + description: 'Name of the threat actor if known. ', + name: 'misp.threat_indicator.threat_actor', + type: 'keyword', + }, + 'misp.observed_data.id': { + category: 'misp', + description: 'Identifier of the Observed Data. ', + name: 'misp.observed_data.id', + type: 'keyword', + }, + 'misp.observed_data.first_observed': { + category: 'misp', + description: 'The beginning of the time window that the data was observed, in RFC3339 format. ', + name: 'misp.observed_data.first_observed', + type: 'date', + }, + 'misp.observed_data.last_observed': { + category: 'misp', + description: 'The end of the time window that the data was observed, in RFC3339 format. ', + name: 'misp.observed_data.last_observed', + type: 'date', + }, + 'misp.observed_data.number_observed': { + category: 'misp', + description: + 'The number of times the data represented in the objects property was observed. This MUST be an integer between 1 and 999,999,999 inclusive. ', + name: 'misp.observed_data.number_observed', + type: 'integer', + }, + 'misp.observed_data.objects': { + category: 'misp', + description: + 'A dictionary of Cyber Observable Objects that describes the single fact that was observed. ', + name: 'misp.observed_data.objects', + type: 'keyword', + }, + 'misp.report.id': { + category: 'misp', + description: 'Identifier of the Report. ', + name: 'misp.report.id', + type: 'keyword', + }, + 'misp.report.labels': { + category: 'misp', + description: + 'This field is an Open Vocabulary that specifies the primary subject of this report. Open Vocab - report-label-ov. threat-report,attack-pattern,campaign,identity,indicator,malware,observed-data,threat-actor,tool,vulnerability ', + name: 'misp.report.labels', + type: 'keyword', + }, + 'misp.report.name': { + category: 'misp', + description: 'The name used to identify the Report. ', + name: 'misp.report.name', + type: 'keyword', + }, + 'misp.report.description': { + category: 'misp', + description: 'A description that provides more details and context about Report. ', + name: 'misp.report.description', + type: 'text', + }, + 'misp.report.published': { + category: 'misp', + description: + 'The date that this report object was officially published by the creator of this report, in RFC3339 format. ', + name: 'misp.report.published', + type: 'date', + }, + 'misp.report.object_refs': { + category: 'misp', + description: 'Specifies the STIX Objects that are referred to by this Report. ', + name: 'misp.report.object_refs', + type: 'text', + }, + 'misp.threat_actor.id': { + category: 'misp', + description: 'Identifier of the Threat Actor. ', + name: 'misp.threat_actor.id', + type: 'keyword', + }, + 'misp.threat_actor.labels': { + category: 'misp', + description: + 'This field specifies the type of threat actor. Open Vocab - threat-actor-label-ov. activist,competitor,crime-syndicate,criminal,hacker,insider-accidental,insider-disgruntled,nation-state,sensationalist,spy,terrorist ', + name: 'misp.threat_actor.labels', + type: 'keyword', + }, + 'misp.threat_actor.name': { + category: 'misp', + description: 'The name used to identify this Threat Actor or Threat Actor group. ', + name: 'misp.threat_actor.name', + type: 'keyword', + }, + 'misp.threat_actor.description': { + category: 'misp', + description: 'A description that provides more details and context about the Threat Actor. ', + name: 'misp.threat_actor.description', + type: 'text', + }, + 'misp.threat_actor.aliases': { + category: 'misp', + description: 'A list of other names that this Threat Actor is believed to use. ', + name: 'misp.threat_actor.aliases', + type: 'text', + }, + 'misp.threat_actor.roles': { + category: 'misp', + description: + 'This is a list of roles the Threat Actor plays. Open Vocab - threat-actor-role-ov. agent,director,independent,sponsor,infrastructure-operator,infrastructure-architect,malware-author ', + name: 'misp.threat_actor.roles', + type: 'text', + }, + 'misp.threat_actor.goals': { + category: 'misp', + description: 'The high level goals of this Threat Actor, namely, what are they trying to do. ', + name: 'misp.threat_actor.goals', + type: 'text', + }, + 'misp.threat_actor.sophistication': { + category: 'misp', + description: + 'The skill, specific knowledge, special training, or expertise a Threat Actor must have to perform the attack. Open Vocab - threat-actor-sophistication-ov. none,minimal,intermediate,advanced,strategic,expert,innovator ', + name: 'misp.threat_actor.sophistication', + type: 'text', + }, + 'misp.threat_actor.resource_level': { + category: 'misp', + description: + 'This defines the organizational level at which this Threat Actor typically works. Open Vocab - attack-resource-level-ov. individual,club,contest,team,organization,government ', + name: 'misp.threat_actor.resource_level', + type: 'text', + }, + 'misp.threat_actor.primary_motivation': { + category: 'misp', + description: + 'The primary reason, motivation, or purpose behind this Threat Actor. Open Vocab - attack-motivation-ov. accidental,coercion,dominance,ideology,notoriety,organizational-gain,personal-gain,personal-satisfaction,revenge,unpredictable ', + name: 'misp.threat_actor.primary_motivation', + type: 'text', + }, + 'misp.threat_actor.secondary_motivations': { + category: 'misp', + description: + 'The secondary reasons, motivations, or purposes behind this Threat Actor. Open Vocab - attack-motivation-ov. accidental,coercion,dominance,ideology,notoriety,organizational-gain,personal-gain,personal-satisfaction,revenge,unpredictable ', + name: 'misp.threat_actor.secondary_motivations', + type: 'text', + }, + 'misp.threat_actor.personal_motivations': { + category: 'misp', + description: + 'The personal reasons, motivations, or purposes of the Threat Actor regardless of organizational goals. Open Vocab - attack-motivation-ov. accidental,coercion,dominance,ideology,notoriety,organizational-gain,personal-gain,personal-satisfaction,revenge,unpredictable ', + name: 'misp.threat_actor.personal_motivations', + type: 'text', + }, + 'misp.tool.id': { + category: 'misp', + description: 'Identifier of the Tool. ', + name: 'misp.tool.id', + type: 'keyword', + }, + 'misp.tool.labels': { + category: 'misp', + description: + 'The kind(s) of tool(s) being described. Open Vocab - tool-label-ov. denial-of-service,exploitation,information-gathering,network-capture,credential-exploitation,remote-access,vulnerability-scanning ', + name: 'misp.tool.labels', + type: 'keyword', + }, + 'misp.tool.name': { + category: 'misp', + description: 'The name used to identify the Tool. ', + name: 'misp.tool.name', + type: 'keyword', + }, + 'misp.tool.description': { + category: 'misp', + description: 'A description that provides more details and context about the Tool. ', + name: 'misp.tool.description', + type: 'text', + }, + 'misp.tool.tool_version': { + category: 'misp', + description: 'The version identifier associated with the Tool. ', + name: 'misp.tool.tool_version', + type: 'keyword', + }, + 'misp.tool.kill_chain_phases': { + category: 'misp', + description: 'The list of kill chain phases for which this Tool instance can be used. ', + name: 'misp.tool.kill_chain_phases', + type: 'text', + }, + 'misp.vulnerability.id': { + category: 'misp', + description: 'Identifier of the Vulnerability. ', + name: 'misp.vulnerability.id', + type: 'keyword', + }, + 'misp.vulnerability.name': { + category: 'misp', + description: 'The name used to identify the Vulnerability. ', + name: 'misp.vulnerability.name', + type: 'keyword', + }, + 'misp.vulnerability.description': { + category: 'misp', + description: 'A description that provides more details and context about the Vulnerability. ', + name: 'misp.vulnerability.description', + type: 'text', + }, + 'mssql.log.origin': { + category: 'mssql', + description: 'Origin of the message, usually the server but it can also be a recovery process', + name: 'mssql.log.origin', + type: 'keyword', + }, + 'o365.audit.Actor.ID': { + category: 'o365', + name: 'o365.audit.Actor.ID', + type: 'keyword', + }, + 'o365.audit.Actor.Type': { + category: 'o365', + name: 'o365.audit.Actor.Type', + type: 'keyword', + }, + 'o365.audit.ActorContextId': { + category: 'o365', + name: 'o365.audit.ActorContextId', + type: 'keyword', + }, + 'o365.audit.ActorIpAddress': { + category: 'o365', + name: 'o365.audit.ActorIpAddress', + type: 'keyword', + }, + 'o365.audit.ActorUserId': { + category: 'o365', + name: 'o365.audit.ActorUserId', + type: 'keyword', + }, + 'o365.audit.ActorYammerUserId': { + category: 'o365', + name: 'o365.audit.ActorYammerUserId', + type: 'keyword', + }, + 'o365.audit.AlertEntityId': { + category: 'o365', + name: 'o365.audit.AlertEntityId', + type: 'keyword', + }, + 'o365.audit.AlertId': { + category: 'o365', + name: 'o365.audit.AlertId', + type: 'keyword', + }, + 'o365.audit.AlertLinks': { + category: 'o365', + name: 'o365.audit.AlertLinks', + type: 'array', + }, + 'o365.audit.AlertType': { + category: 'o365', + name: 'o365.audit.AlertType', + type: 'keyword', + }, + 'o365.audit.AppId': { + category: 'o365', + name: 'o365.audit.AppId', + type: 'keyword', + }, + 'o365.audit.ApplicationDisplayName': { + category: 'o365', + name: 'o365.audit.ApplicationDisplayName', + type: 'keyword', + }, + 'o365.audit.ApplicationId': { + category: 'o365', + name: 'o365.audit.ApplicationId', + type: 'keyword', + }, + 'o365.audit.AzureActiveDirectoryEventType': { + category: 'o365', + name: 'o365.audit.AzureActiveDirectoryEventType', + type: 'keyword', + }, + 'o365.audit.ExchangeMetaData.*': { + category: 'o365', + name: 'o365.audit.ExchangeMetaData.*', + type: 'object', + }, + 'o365.audit.Category': { + category: 'o365', + name: 'o365.audit.Category', + type: 'keyword', + }, + 'o365.audit.ClientAppId': { + category: 'o365', + name: 'o365.audit.ClientAppId', + type: 'keyword', + }, + 'o365.audit.ClientInfoString': { + category: 'o365', + name: 'o365.audit.ClientInfoString', + type: 'keyword', + }, + 'o365.audit.ClientIP': { + category: 'o365', + name: 'o365.audit.ClientIP', + type: 'keyword', + }, + 'o365.audit.ClientIPAddress': { + category: 'o365', + name: 'o365.audit.ClientIPAddress', + type: 'keyword', + }, + 'o365.audit.Comments': { + category: 'o365', + name: 'o365.audit.Comments', + type: 'text', + }, + 'o365.audit.CorrelationId': { + category: 'o365', + name: 'o365.audit.CorrelationId', + type: 'keyword', + }, + 'o365.audit.CreationTime': { + category: 'o365', + name: 'o365.audit.CreationTime', + type: 'keyword', + }, + 'o365.audit.CustomUniqueId': { + category: 'o365', + name: 'o365.audit.CustomUniqueId', + type: 'keyword', + }, + 'o365.audit.Data': { + category: 'o365', + name: 'o365.audit.Data', + type: 'keyword', + }, + 'o365.audit.DataType': { + category: 'o365', + name: 'o365.audit.DataType', + type: 'keyword', + }, + 'o365.audit.EntityType': { + category: 'o365', + name: 'o365.audit.EntityType', + type: 'keyword', + }, + 'o365.audit.EventData': { + category: 'o365', + name: 'o365.audit.EventData', + type: 'keyword', + }, + 'o365.audit.EventSource': { + category: 'o365', + name: 'o365.audit.EventSource', + type: 'keyword', + }, + 'o365.audit.ExceptionInfo.*': { + category: 'o365', + name: 'o365.audit.ExceptionInfo.*', + type: 'object', + }, + 'o365.audit.ExtendedProperties.*': { + category: 'o365', + name: 'o365.audit.ExtendedProperties.*', + type: 'object', + }, + 'o365.audit.ExternalAccess': { + category: 'o365', + name: 'o365.audit.ExternalAccess', + type: 'keyword', + }, + 'o365.audit.GroupName': { + category: 'o365', + name: 'o365.audit.GroupName', + type: 'keyword', + }, + 'o365.audit.Id': { + category: 'o365', + name: 'o365.audit.Id', + type: 'keyword', + }, + 'o365.audit.ImplicitShare': { + category: 'o365', + name: 'o365.audit.ImplicitShare', + type: 'keyword', + }, + 'o365.audit.IncidentId': { + category: 'o365', + name: 'o365.audit.IncidentId', + type: 'keyword', + }, + 'o365.audit.InternalLogonType': { + category: 'o365', + name: 'o365.audit.InternalLogonType', + type: 'keyword', + }, + 'o365.audit.InterSystemsId': { + category: 'o365', + name: 'o365.audit.InterSystemsId', + type: 'keyword', + }, + 'o365.audit.IntraSystemId': { + category: 'o365', + name: 'o365.audit.IntraSystemId', + type: 'keyword', + }, + 'o365.audit.Item.*': { + category: 'o365', + name: 'o365.audit.Item.*', + type: 'object', + }, + 'o365.audit.Item.*.*': { + category: 'o365', + name: 'o365.audit.Item.*.*', + type: 'object', + }, + 'o365.audit.ItemName': { + category: 'o365', + name: 'o365.audit.ItemName', + type: 'keyword', + }, + 'o365.audit.ItemType': { + category: 'o365', + name: 'o365.audit.ItemType', + type: 'keyword', + }, + 'o365.audit.ListId': { + category: 'o365', + name: 'o365.audit.ListId', + type: 'keyword', + }, + 'o365.audit.ListItemUniqueId': { + category: 'o365', + name: 'o365.audit.ListItemUniqueId', + type: 'keyword', + }, + 'o365.audit.LogonError': { + category: 'o365', + name: 'o365.audit.LogonError', + type: 'keyword', + }, + 'o365.audit.LogonType': { + category: 'o365', + name: 'o365.audit.LogonType', + type: 'keyword', + }, + 'o365.audit.LogonUserSid': { + category: 'o365', + name: 'o365.audit.LogonUserSid', + type: 'keyword', + }, + 'o365.audit.MailboxGuid': { + category: 'o365', + name: 'o365.audit.MailboxGuid', + type: 'keyword', + }, + 'o365.audit.MailboxOwnerMasterAccountSid': { + category: 'o365', + name: 'o365.audit.MailboxOwnerMasterAccountSid', + type: 'keyword', + }, + 'o365.audit.MailboxOwnerSid': { + category: 'o365', + name: 'o365.audit.MailboxOwnerSid', + type: 'keyword', + }, + 'o365.audit.MailboxOwnerUPN': { + category: 'o365', + name: 'o365.audit.MailboxOwnerUPN', + type: 'keyword', + }, + 'o365.audit.Members': { + category: 'o365', + name: 'o365.audit.Members', + type: 'array', + }, + 'o365.audit.Members.*': { + category: 'o365', + name: 'o365.audit.Members.*', + type: 'object', + }, + 'o365.audit.ModifiedProperties.*.*': { + category: 'o365', + name: 'o365.audit.ModifiedProperties.*.*', + type: 'object', + }, + 'o365.audit.Name': { + category: 'o365', + name: 'o365.audit.Name', + type: 'keyword', + }, + 'o365.audit.ObjectId': { + category: 'o365', + name: 'o365.audit.ObjectId', + type: 'keyword', + }, + 'o365.audit.Operation': { + category: 'o365', + name: 'o365.audit.Operation', + type: 'keyword', + }, + 'o365.audit.OrganizationId': { + category: 'o365', + name: 'o365.audit.OrganizationId', + type: 'keyword', + }, + 'o365.audit.OrganizationName': { + category: 'o365', + name: 'o365.audit.OrganizationName', + type: 'keyword', + }, + 'o365.audit.OriginatingServer': { + category: 'o365', + name: 'o365.audit.OriginatingServer', + type: 'keyword', + }, + 'o365.audit.Parameters.*': { + category: 'o365', + name: 'o365.audit.Parameters.*', + type: 'object', + }, + 'o365.audit.PolicyDetails': { + category: 'o365', + name: 'o365.audit.PolicyDetails', + type: 'array', + }, + 'o365.audit.PolicyId': { + category: 'o365', + name: 'o365.audit.PolicyId', + type: 'keyword', + }, + 'o365.audit.RecordType': { + category: 'o365', + name: 'o365.audit.RecordType', + type: 'keyword', + }, + 'o365.audit.ResultStatus': { + category: 'o365', + name: 'o365.audit.ResultStatus', + type: 'keyword', + }, + 'o365.audit.SensitiveInfoDetectionIsIncluded': { + category: 'o365', + name: 'o365.audit.SensitiveInfoDetectionIsIncluded', + type: 'keyword', + }, + 'o365.audit.SharePointMetaData.*': { + category: 'o365', + name: 'o365.audit.SharePointMetaData.*', + type: 'object', + }, + 'o365.audit.SessionId': { + category: 'o365', + name: 'o365.audit.SessionId', + type: 'keyword', + }, + 'o365.audit.Severity': { + category: 'o365', + name: 'o365.audit.Severity', + type: 'keyword', + }, + 'o365.audit.Site': { + category: 'o365', + name: 'o365.audit.Site', + type: 'keyword', + }, + 'o365.audit.SiteUrl': { + category: 'o365', + name: 'o365.audit.SiteUrl', + type: 'keyword', + }, + 'o365.audit.Source': { + category: 'o365', + name: 'o365.audit.Source', + type: 'keyword', + }, + 'o365.audit.SourceFileExtension': { + category: 'o365', + name: 'o365.audit.SourceFileExtension', + type: 'keyword', + }, + 'o365.audit.SourceFileName': { + category: 'o365', + name: 'o365.audit.SourceFileName', + type: 'keyword', + }, + 'o365.audit.SourceRelativeUrl': { + category: 'o365', + name: 'o365.audit.SourceRelativeUrl', + type: 'keyword', + }, + 'o365.audit.Status': { + category: 'o365', + name: 'o365.audit.Status', + type: 'keyword', + }, + 'o365.audit.SupportTicketId': { + category: 'o365', + name: 'o365.audit.SupportTicketId', + type: 'keyword', + }, + 'o365.audit.Target.ID': { + category: 'o365', + name: 'o365.audit.Target.ID', + type: 'keyword', + }, + 'o365.audit.Target.Type': { + category: 'o365', + name: 'o365.audit.Target.Type', + type: 'keyword', + }, + 'o365.audit.TargetContextId': { + category: 'o365', + name: 'o365.audit.TargetContextId', + type: 'keyword', + }, + 'o365.audit.TargetUserOrGroupName': { + category: 'o365', + name: 'o365.audit.TargetUserOrGroupName', + type: 'keyword', + }, + 'o365.audit.TargetUserOrGroupType': { + category: 'o365', + name: 'o365.audit.TargetUserOrGroupType', + type: 'keyword', + }, + 'o365.audit.TeamName': { + category: 'o365', + name: 'o365.audit.TeamName', + type: 'keyword', + }, + 'o365.audit.TeamGuid': { + category: 'o365', + name: 'o365.audit.TeamGuid', + type: 'keyword', + }, + 'o365.audit.UniqueSharingId': { + category: 'o365', + name: 'o365.audit.UniqueSharingId', + type: 'keyword', + }, + 'o365.audit.UserAgent': { + category: 'o365', + name: 'o365.audit.UserAgent', + type: 'keyword', + }, + 'o365.audit.UserId': { + category: 'o365', + name: 'o365.audit.UserId', + type: 'keyword', + }, + 'o365.audit.UserKey': { + category: 'o365', + name: 'o365.audit.UserKey', + type: 'keyword', + }, + 'o365.audit.UserType': { + category: 'o365', + name: 'o365.audit.UserType', + type: 'keyword', + }, + 'o365.audit.Version': { + category: 'o365', + name: 'o365.audit.Version', + type: 'keyword', + }, + 'o365.audit.WebId': { + category: 'o365', + name: 'o365.audit.WebId', + type: 'keyword', + }, + 'o365.audit.Workload': { + category: 'o365', + name: 'o365.audit.Workload', + type: 'keyword', + }, + 'o365.audit.YammerNetworkId': { + category: 'o365', + name: 'o365.audit.YammerNetworkId', + type: 'keyword', + }, + 'okta.uuid': { + category: 'okta', + description: 'The unique identifier of the Okta LogEvent. ', + name: 'okta.uuid', + type: 'keyword', + }, + 'okta.event_type': { + category: 'okta', + description: 'The type of the LogEvent. ', + name: 'okta.event_type', + type: 'keyword', + }, + 'okta.version': { + category: 'okta', + description: 'The version of the LogEvent. ', + name: 'okta.version', + type: 'keyword', + }, + 'okta.severity': { + category: 'okta', + description: 'The severity of the LogEvent. Must be one of DEBUG, INFO, WARN, or ERROR. ', + name: 'okta.severity', + type: 'keyword', + }, + 'okta.display_message': { + category: 'okta', + description: 'The display message of the LogEvent. ', + name: 'okta.display_message', + type: 'keyword', + }, + 'okta.actor.id': { + category: 'okta', + description: 'Identifier of the actor. ', + name: 'okta.actor.id', + type: 'keyword', + }, + 'okta.actor.type': { + category: 'okta', + description: 'Type of the actor. ', + name: 'okta.actor.type', + type: 'keyword', + }, + 'okta.actor.alternate_id': { + category: 'okta', + description: 'Alternate identifier of the actor. ', + name: 'okta.actor.alternate_id', + type: 'keyword', + }, + 'okta.actor.display_name': { + category: 'okta', + description: 'Display name of the actor. ', + name: 'okta.actor.display_name', + type: 'keyword', + }, + 'okta.client.ip': { + category: 'okta', + description: 'The IP address of the client. ', + name: 'okta.client.ip', + type: 'ip', + }, + 'okta.client.user_agent.raw_user_agent': { + category: 'okta', + description: 'The raw informaton of the user agent. ', + name: 'okta.client.user_agent.raw_user_agent', + type: 'keyword', + }, + 'okta.client.user_agent.os': { + category: 'okta', + description: 'The OS informaton. ', + name: 'okta.client.user_agent.os', + type: 'keyword', + }, + 'okta.client.user_agent.browser': { + category: 'okta', + description: 'The browser informaton of the client. ', + name: 'okta.client.user_agent.browser', + type: 'keyword', + }, + 'okta.client.zone': { + category: 'okta', + description: 'The zone information of the client. ', + name: 'okta.client.zone', + type: 'keyword', + }, + 'okta.client.device': { + category: 'okta', + description: 'The information of the client device. ', + name: 'okta.client.device', + type: 'keyword', + }, + 'okta.client.id': { + category: 'okta', + description: 'The identifier of the client. ', + name: 'okta.client.id', + type: 'keyword', + }, + 'okta.outcome.reason': { + category: 'okta', + description: 'The reason of the outcome. ', + name: 'okta.outcome.reason', + type: 'keyword', + }, + 'okta.outcome.result': { + category: 'okta', + description: + 'The result of the outcome. Must be one of: SUCCESS, FAILURE, SKIPPED, ALLOW, DENY, CHALLENGE, UNKNOWN. ', + name: 'okta.outcome.result', + type: 'keyword', + }, + 'okta.target.id': { + category: 'okta', + description: 'Identifier of the actor. ', + name: 'okta.target.id', + type: 'keyword', + }, + 'okta.target.type': { + category: 'okta', + description: 'Type of the actor. ', + name: 'okta.target.type', + type: 'keyword', + }, + 'okta.target.alternate_id': { + category: 'okta', + description: 'Alternate identifier of the actor. ', + name: 'okta.target.alternate_id', + type: 'keyword', + }, + 'okta.target.display_name': { + category: 'okta', + description: 'Display name of the actor. ', + name: 'okta.target.display_name', + type: 'keyword', + }, + 'okta.transaction.id': { + category: 'okta', + description: 'Identifier of the transaction. ', + name: 'okta.transaction.id', + type: 'keyword', + }, + 'okta.transaction.type': { + category: 'okta', + description: 'The type of transaction. Must be one of "WEB", "JOB". ', + name: 'okta.transaction.type', + type: 'keyword', + }, + 'okta.debug_context.debug_data.device_fingerprint': { + category: 'okta', + description: 'The fingerprint of the device. ', + name: 'okta.debug_context.debug_data.device_fingerprint', + type: 'keyword', + }, + 'okta.debug_context.debug_data.request_id': { + category: 'okta', + description: 'The identifier of the request. ', + name: 'okta.debug_context.debug_data.request_id', + type: 'keyword', + }, + 'okta.debug_context.debug_data.request_uri': { + category: 'okta', + description: 'The request URI. ', + name: 'okta.debug_context.debug_data.request_uri', + type: 'keyword', + }, + 'okta.debug_context.debug_data.threat_suspected': { + category: 'okta', + description: 'Threat suspected. ', + name: 'okta.debug_context.debug_data.threat_suspected', + type: 'keyword', + }, + 'okta.debug_context.debug_data.url': { + category: 'okta', + description: 'The URL. ', + name: 'okta.debug_context.debug_data.url', + type: 'keyword', + }, + 'okta.authentication_context.authentication_provider': { + category: 'okta', + description: + 'The information about the authentication provider. Must be one of OKTA_AUTHENTICATION_PROVIDER, ACTIVE_DIRECTORY, LDAP, FEDERATION, SOCIAL, FACTOR_PROVIDER. ', + name: 'okta.authentication_context.authentication_provider', + type: 'keyword', + }, + 'okta.authentication_context.authentication_step': { + category: 'okta', + description: 'The authentication step. ', + name: 'okta.authentication_context.authentication_step', + type: 'integer', + }, + 'okta.authentication_context.credential_provider': { + category: 'okta', + description: + 'The information about credential provider. Must be one of OKTA_CREDENTIAL_PROVIDER, RSA, SYMANTEC, GOOGLE, DUO, YUBIKEY. ', + name: 'okta.authentication_context.credential_provider', + type: 'keyword', + }, + 'okta.authentication_context.credential_type': { + category: 'okta', + description: + 'The information about credential type. Must be one of OTP, SMS, PASSWORD, ASSERTION, IWA, EMAIL, OAUTH2, JWT, CERTIFICATE, PRE_SHARED_SYMMETRIC_KEY, OKTA_CLIENT_SESSION, DEVICE_UDID. ', + name: 'okta.authentication_context.credential_type', + type: 'keyword', + }, + 'okta.authentication_context.issuer.id': { + category: 'okta', + description: 'The identifier of the issuer. ', + name: 'okta.authentication_context.issuer.id', + type: 'keyword', + }, + 'okta.authentication_context.issuer.type': { + category: 'okta', + description: 'The type of the issuer. ', + name: 'okta.authentication_context.issuer.type', + type: 'keyword', + }, + 'okta.authentication_context.external_session_id': { + category: 'okta', + description: 'The session identifer of the external session if any. ', + name: 'okta.authentication_context.external_session_id', + type: 'keyword', + }, + 'okta.authentication_context.interface': { + category: 'okta', + description: 'The interface used. e.g., Outlook, Office365, wsTrust ', + name: 'okta.authentication_context.interface', + type: 'keyword', + }, + 'okta.security_context.as.number': { + category: 'okta', + description: 'The AS number. ', + name: 'okta.security_context.as.number', + type: 'integer', + }, + 'okta.security_context.as.organization.name': { + category: 'okta', + description: 'The organization name. ', + name: 'okta.security_context.as.organization.name', + type: 'keyword', + }, + 'okta.security_context.isp': { + category: 'okta', + description: 'The Internet Service Provider. ', + name: 'okta.security_context.isp', + type: 'keyword', + }, + 'okta.security_context.domain': { + category: 'okta', + description: 'The domain name. ', + name: 'okta.security_context.domain', + type: 'keyword', + }, + 'okta.security_context.is_proxy': { + category: 'okta', + description: 'Whether it is a proxy or not. ', + name: 'okta.security_context.is_proxy', + type: 'boolean', + }, + 'okta.request.ip_chain.ip': { + category: 'okta', + description: 'IP address. ', + name: 'okta.request.ip_chain.ip', + type: 'ip', + }, + 'okta.request.ip_chain.version': { + category: 'okta', + description: 'IP version. Must be one of V4, V6. ', + name: 'okta.request.ip_chain.version', + type: 'keyword', + }, + 'okta.request.ip_chain.source': { + category: 'okta', + description: 'Source information. ', + name: 'okta.request.ip_chain.source', + type: 'keyword', + }, + 'okta.request.ip_chain.geographical_context.city': { + category: 'okta', + description: 'The city.', + name: 'okta.request.ip_chain.geographical_context.city', + type: 'keyword', + }, + 'okta.request.ip_chain.geographical_context.state': { + category: 'okta', + description: 'The state.', + name: 'okta.request.ip_chain.geographical_context.state', + type: 'keyword', + }, + 'okta.request.ip_chain.geographical_context.postal_code': { + category: 'okta', + description: 'The postal code.', + name: 'okta.request.ip_chain.geographical_context.postal_code', + type: 'keyword', + }, + 'okta.request.ip_chain.geographical_context.country': { + category: 'okta', + description: 'The country.', + name: 'okta.request.ip_chain.geographical_context.country', + type: 'keyword', + }, + 'okta.request.ip_chain.geographical_context.geolocation': { + category: 'okta', + description: 'Geolocation information. ', + name: 'okta.request.ip_chain.geographical_context.geolocation', + type: 'geo_point', + }, + 'panw.panos.ruleset': { + category: 'panw', + description: 'Name of the rule that matched this session. ', + name: 'panw.panos.ruleset', + type: 'keyword', + }, + 'panw.panos.source.zone': { + category: 'panw', + description: 'Source zone for this session. ', + name: 'panw.panos.source.zone', + type: 'keyword', + }, + 'panw.panos.source.interface': { + category: 'panw', + description: 'Source interface for this session. ', + name: 'panw.panos.source.interface', + type: 'keyword', + }, + 'panw.panos.source.nat.ip': { + category: 'panw', + description: 'Post-NAT source IP. ', + name: 'panw.panos.source.nat.ip', + type: 'ip', + }, + 'panw.panos.source.nat.port': { + category: 'panw', + description: 'Post-NAT source port. ', + name: 'panw.panos.source.nat.port', + type: 'long', + }, + 'panw.panos.destination.zone': { + category: 'panw', + description: 'Destination zone for this session. ', + name: 'panw.panos.destination.zone', + type: 'keyword', + }, + 'panw.panos.destination.interface': { + category: 'panw', + description: 'Destination interface for this session. ', + name: 'panw.panos.destination.interface', + type: 'keyword', + }, + 'panw.panos.destination.nat.ip': { + category: 'panw', + description: 'Post-NAT destination IP. ', + name: 'panw.panos.destination.nat.ip', + type: 'ip', + }, + 'panw.panos.destination.nat.port': { + category: 'panw', + description: 'Post-NAT destination port. ', + name: 'panw.panos.destination.nat.port', + type: 'long', + }, + 'panw.panos.network.pcap_id': { + category: 'panw', + description: 'Packet capture ID for a threat. ', + name: 'panw.panos.network.pcap_id', + type: 'keyword', + }, + 'panw.panos.network.nat.community_id': { + category: 'panw', + description: 'Community ID flow-hash for the NAT 5-tuple. ', + name: 'panw.panos.network.nat.community_id', + type: 'keyword', + }, + 'panw.panos.file.hash': { + category: 'panw', + description: 'Binary hash for a threat file sent to be analyzed by the WildFire service. ', + name: 'panw.panos.file.hash', + type: 'keyword', + }, + 'panw.panos.url.category': { + category: 'panw', + description: + "For threat URLs, it's the URL category. For WildFire, the verdict on the file and is either 'malicious', 'grayware', or 'benign'. ", + name: 'panw.panos.url.category', + type: 'keyword', + }, + 'panw.panos.flow_id': { + category: 'panw', + description: 'Internal numeric identifier for each session. ', + name: 'panw.panos.flow_id', + type: 'keyword', + }, + 'panw.panos.sequence_number': { + category: 'panw', + description: + 'Log entry identifier that is incremented sequentially. Unique for each log type. ', + name: 'panw.panos.sequence_number', + type: 'long', + }, + 'panw.panos.threat.resource': { + category: 'panw', + description: 'URL or file name for a threat. ', + name: 'panw.panos.threat.resource', + type: 'keyword', + }, + 'panw.panos.threat.id': { + category: 'panw', + description: 'Palo Alto Networks identifier for the threat. ', + name: 'panw.panos.threat.id', + type: 'keyword', + }, + 'panw.panos.threat.name': { + category: 'panw', + description: 'Palo Alto Networks name for the threat. ', + name: 'panw.panos.threat.name', + type: 'keyword', + }, + 'panw.panos.action': { + category: 'panw', + description: 'Action taken for the session.', + name: 'panw.panos.action', + type: 'keyword', + }, + 'rabbitmq.log.pid': { + category: 'rabbitmq', + description: 'The Erlang process id', + example: '<0.222.0>', + name: 'rabbitmq.log.pid', + type: 'keyword', + }, + 'sophos.xg.device': { + category: 'sophos', + description: 'device ', + name: 'sophos.xg.device', + type: 'keyword', + }, + 'sophos.xg.date': { + category: 'sophos', + description: 'Date (yyyy-mm-dd) when the event occurred ', + name: 'sophos.xg.date', + type: 'date', + }, + 'sophos.xg.timezone': { + category: 'sophos', + description: 'Time (hh:mm:ss) when the event occurred ', + name: 'sophos.xg.timezone', + type: 'keyword', + }, + 'sophos.xg.device_name': { + category: 'sophos', + description: 'Model number of the device ', + name: 'sophos.xg.device_name', + type: 'keyword', + }, + 'sophos.xg.device_id': { + category: 'sophos', + description: 'Serial number of the device ', + name: 'sophos.xg.device_id', + type: 'keyword', + }, + 'sophos.xg.log_id': { + category: 'sophos', + description: 'Unique 12 characters code (0101011) ', + name: 'sophos.xg.log_id', + type: 'keyword', + }, + 'sophos.xg.log_type': { + category: 'sophos', + description: 'Type of event e.g. firewall event ', + name: 'sophos.xg.log_type', + type: 'keyword', + }, + 'sophos.xg.log_component': { + category: 'sophos', + description: 'Component responsible for logging e.g. Firewall rule ', + name: 'sophos.xg.log_component', + type: 'keyword', + }, + 'sophos.xg.log_subtype': { + category: 'sophos', + description: 'Sub type of event ', + name: 'sophos.xg.log_subtype', + type: 'keyword', + }, + 'sophos.xg.hb_health': { + category: 'sophos', + description: 'Heartbeat status ', + name: 'sophos.xg.hb_health', + type: 'keyword', + }, + 'sophos.xg.priority': { + category: 'sophos', + description: 'Severity level of traffic ', + name: 'sophos.xg.priority', + type: 'keyword', + }, + 'sophos.xg.status': { + category: 'sophos', + description: 'Ultimate status of traffic – Allowed or Denied ', + name: 'sophos.xg.status', + type: 'keyword', + }, + 'sophos.xg.duration': { + category: 'sophos', + description: 'Durability of traffic (seconds) ', + name: 'sophos.xg.duration', + type: 'long', + }, + 'sophos.xg.fw_rule_id': { + category: 'sophos', + description: 'Firewall Rule ID which is applied on the traffic ', + name: 'sophos.xg.fw_rule_id', + type: 'integer', + }, + 'sophos.xg.user_name': { + category: 'sophos', + description: 'user_name ', + name: 'sophos.xg.user_name', + type: 'keyword', + }, + 'sophos.xg.user_group': { + category: 'sophos', + description: 'Group name to which the user belongs ', + name: 'sophos.xg.user_group', + type: 'keyword', + }, + 'sophos.xg.iap': { + category: 'sophos', + description: 'Internet Access policy ID applied on the traffic ', + name: 'sophos.xg.iap', + type: 'keyword', + }, + 'sophos.xg.ips_policy_id': { + category: 'sophos', + description: 'IPS policy ID applied on the traffic ', + name: 'sophos.xg.ips_policy_id', + type: 'integer', + }, + 'sophos.xg.policy_type': { + category: 'sophos', + description: 'Policy type applied to the traffic ', + name: 'sophos.xg.policy_type', + type: 'keyword', + }, + 'sophos.xg.appfilter_policy_id': { + category: 'sophos', + description: 'Application Filter policy applied on the traffic ', + name: 'sophos.xg.appfilter_policy_id', + type: 'integer', + }, + 'sophos.xg.application_filter_policy': { + category: 'sophos', + description: 'Application Filter policy applied on the traffic ', + name: 'sophos.xg.application_filter_policy', + type: 'integer', + }, + 'sophos.xg.application': { + category: 'sophos', + description: 'Application name ', + name: 'sophos.xg.application', + type: 'keyword', + }, + 'sophos.xg.application_name': { + category: 'sophos', + description: 'Application name ', + name: 'sophos.xg.application_name', + type: 'keyword', + }, + 'sophos.xg.application_risk': { + category: 'sophos', + description: 'Risk level assigned to the application ', + name: 'sophos.xg.application_risk', + type: 'keyword', + }, + 'sophos.xg.application_technology': { + category: 'sophos', + description: 'Technology of the application ', + name: 'sophos.xg.application_technology', + type: 'keyword', + }, + 'sophos.xg.application_category': { + category: 'sophos', + description: 'Application is resolved by signature or synchronized application ', + name: 'sophos.xg.application_category', + type: 'keyword', + }, + 'sophos.xg.appresolvedby': { + category: 'sophos', + description: 'Technology of the application ', + name: 'sophos.xg.appresolvedby', + type: 'keyword', + }, + 'sophos.xg.app_is_cloud': { + category: 'sophos', + description: 'Application is Cloud ', + name: 'sophos.xg.app_is_cloud', + type: 'keyword', + }, + 'sophos.xg.in_interface': { + category: 'sophos', + description: 'Interface for incoming traffic, e.g., Port A ', + name: 'sophos.xg.in_interface', + type: 'keyword', + }, + 'sophos.xg.out_interface': { + category: 'sophos', + description: 'Interface for outgoing traffic, e.g., Port B ', + name: 'sophos.xg.out_interface', + type: 'keyword', + }, + 'sophos.xg.src_ip': { + category: 'sophos', + description: 'Original source IP address of traffic ', + name: 'sophos.xg.src_ip', + type: 'ip', + }, + 'sophos.xg.src_mac': { + category: 'sophos', + description: 'Original source MAC address of traffic ', + name: 'sophos.xg.src_mac', + type: 'keyword', + }, + 'sophos.xg.src_country_code': { + category: 'sophos', + description: 'Code of the country to which the source IP belongs ', + name: 'sophos.xg.src_country_code', + type: 'keyword', + }, + 'sophos.xg.dst_ip': { + category: 'sophos', + description: 'Original destination IP address of traffic ', + name: 'sophos.xg.dst_ip', + type: 'ip', + }, + 'sophos.xg.dst_country_code': { + category: 'sophos', + description: 'Code of the country to which the destination IP belongs ', + name: 'sophos.xg.dst_country_code', + type: 'keyword', + }, + 'sophos.xg.protocol': { + category: 'sophos', + description: 'Protocol number of traffic ', + name: 'sophos.xg.protocol', + type: 'keyword', + }, + 'sophos.xg.src_port': { + category: 'sophos', + description: 'Original source port of TCP and UDP traffic ', + name: 'sophos.xg.src_port', + type: 'integer', + }, + 'sophos.xg.dst_port': { + category: 'sophos', + description: 'Original destination port of TCP and UDP traffic ', + name: 'sophos.xg.dst_port', + type: 'integer', + }, + 'sophos.xg.icmp_type': { + category: 'sophos', + description: 'ICMP type of ICMP traffic ', + name: 'sophos.xg.icmp_type', + type: 'keyword', + }, + 'sophos.xg.icmp_code': { + category: 'sophos', + description: 'ICMP code of ICMP traffic ', + name: 'sophos.xg.icmp_code', + type: 'keyword', + }, + 'sophos.xg.sent_pkts': { + category: 'sophos', + description: 'Total number of packets sent ', + name: 'sophos.xg.sent_pkts', + type: 'long', + }, + 'sophos.xg.received_pkts': { + category: 'sophos', + description: 'Total number of packets received ', + name: 'sophos.xg.received_pkts', + type: 'long', + }, + 'sophos.xg.sent_bytes': { + category: 'sophos', + description: 'Total number of bytes sent ', + name: 'sophos.xg.sent_bytes', + type: 'long', + }, + 'sophos.xg.recv_bytes': { + category: 'sophos', + description: 'Total number of bytes received ', + name: 'sophos.xg.recv_bytes', + type: 'long', + }, + 'sophos.xg.trans_src_ ip': { + category: 'sophos', + description: 'Translated source IP address for outgoing traffic ', + name: 'sophos.xg.trans_src_ ip', + type: 'ip', + }, + 'sophos.xg.trans_src_port': { + category: 'sophos', + description: 'Translated source port for outgoing traffic ', + name: 'sophos.xg.trans_src_port', + type: 'integer', + }, + 'sophos.xg.trans_dst_ip': { + category: 'sophos', + description: 'Translated destination IP address for outgoing traffic ', + name: 'sophos.xg.trans_dst_ip', + type: 'ip', + }, + 'sophos.xg.trans_dst_port': { + category: 'sophos', + description: 'Translated destination port for outgoing traffic ', + name: 'sophos.xg.trans_dst_port', + type: 'integer', + }, + 'sophos.xg.srczonetype': { + category: 'sophos', + description: 'Type of source zone, e.g., LAN ', + name: 'sophos.xg.srczonetype', + type: 'keyword', + }, + 'sophos.xg.srczone': { + category: 'sophos', + description: 'Name of source zone ', + name: 'sophos.xg.srczone', + type: 'keyword', + }, + 'sophos.xg.dstzonetype': { + category: 'sophos', + description: 'Type of destination zone, e.g., WAN ', + name: 'sophos.xg.dstzonetype', + type: 'keyword', + }, + 'sophos.xg.dstzone': { + category: 'sophos', + description: 'Name of destination zone ', + name: 'sophos.xg.dstzone', + type: 'keyword', + }, + 'sophos.xg.dir_disp': { + category: 'sophos', + description: 'TPacket direction. Possible values:“org”, “reply”, “” ', + name: 'sophos.xg.dir_disp', + type: 'keyword', + }, + 'sophos.xg.connevent': { + category: 'sophos', + description: 'Event on which this log is generated ', + name: 'sophos.xg.connevent', + type: 'keyword', + }, + 'sophos.xg.conn_id': { + category: 'sophos', + description: 'Unique identifier of connection ', + name: 'sophos.xg.conn_id', + type: 'integer', + }, + 'sophos.xg.vconn_id': { + category: 'sophos', + description: 'Connection ID of the master connection ', + name: 'sophos.xg.vconn_id', + type: 'integer', + }, + 'sophos.xg.idp_policy_id': { + category: 'sophos', + description: 'IPS policy ID which is applied on the traffic ', + name: 'sophos.xg.idp_policy_id', + type: 'integer', + }, + 'sophos.xg.idp_policy_name': { + category: 'sophos', + description: 'IPS policy name i.e. IPS policy name which is applied on the traffic ', + name: 'sophos.xg.idp_policy_name', + type: 'keyword', + }, + 'sophos.xg.signature_id': { + category: 'sophos', + description: 'Signature ID ', + name: 'sophos.xg.signature_id', + type: 'keyword', + }, + 'sophos.xg.signature_msg': { + category: 'sophos', + description: 'Signature messsage ', + name: 'sophos.xg.signature_msg', + type: 'keyword', + }, + 'sophos.xg.classification': { + category: 'sophos', + description: 'Signature classification ', + name: 'sophos.xg.classification', + type: 'keyword', + }, + 'sophos.xg.rule_priority': { + category: 'sophos', + description: 'Priority of IPS policy ', + name: 'sophos.xg.rule_priority', + type: 'keyword', + }, + 'sophos.xg.platform': { + category: 'sophos', + description: 'Platform of the traffic. ', + name: 'sophos.xg.platform', + type: 'keyword', + }, + 'sophos.xg.category': { + category: 'sophos', + description: 'IPS signature category. ', + name: 'sophos.xg.category', + type: 'keyword', + }, + 'sophos.xg.target': { + category: 'sophos', + description: 'Platform of the traffic. ', + name: 'sophos.xg.target', + type: 'keyword', + }, + 'sophos.xg.eventid': { + category: 'sophos', + description: 'ATP Evenet ID ', + name: 'sophos.xg.eventid', + type: 'keyword', + }, + 'sophos.xg.ep_uuid': { + category: 'sophos', + description: 'Endpoint UUID ', + name: 'sophos.xg.ep_uuid', + type: 'keyword', + }, + 'sophos.xg.threatname': { + category: 'sophos', + description: 'ATP threatname ', + name: 'sophos.xg.threatname', + type: 'keyword', + }, + 'sophos.xg.sourceip': { + category: 'sophos', + description: 'Original source IP address of traffic ', + name: 'sophos.xg.sourceip', + type: 'ip', + }, + 'sophos.xg.destinationip': { + category: 'sophos', + description: 'Original destination IP address of traffic ', + name: 'sophos.xg.destinationip', + type: 'ip', + }, + 'sophos.xg.login_user': { + category: 'sophos', + description: 'ATP login user ', + name: 'sophos.xg.login_user', + type: 'keyword', + }, + 'sophos.xg.eventtype': { + category: 'sophos', + description: 'ATP event type ', + name: 'sophos.xg.eventtype', + type: 'keyword', + }, + 'sophos.xg.execution_path': { + category: 'sophos', + description: 'ATP execution path ', + name: 'sophos.xg.execution_path', + type: 'keyword', + }, + 'sophos.xg.av_policy_name': { + category: 'sophos', + description: 'Malware scanning policy name which is applied on the traffic ', + name: 'sophos.xg.av_policy_name', + type: 'keyword', + }, + 'sophos.xg.from_email_address': { + category: 'sophos', + description: 'Sender email address ', + name: 'sophos.xg.from_email_address', + type: 'keyword', + }, + 'sophos.xg.to_email_address': { + category: 'sophos', + description: 'Receipeint email address ', + name: 'sophos.xg.to_email_address', + type: 'keyword', + }, + 'sophos.xg.subject': { + category: 'sophos', + description: 'Email subject ', + name: 'sophos.xg.subject', + type: 'keyword', + }, + 'sophos.xg.mailsize': { + category: 'sophos', + description: 'mailsize ', + name: 'sophos.xg.mailsize', + type: 'integer', + }, + 'sophos.xg.virus': { + category: 'sophos', + description: 'virus name ', + name: 'sophos.xg.virus', + type: 'keyword', + }, + 'sophos.xg.FTP_url': { + category: 'sophos', + description: 'FTP URL from which virus was downloaded ', + name: 'sophos.xg.FTP_url', + type: 'keyword', + }, + 'sophos.xg.FTP_direction': { + category: 'sophos', + description: 'Direction of FTP transfer: Upload or Download ', + name: 'sophos.xg.FTP_direction', + type: 'keyword', + }, + 'sophos.xg.filesize': { + category: 'sophos', + description: 'Size of the file that contained virus ', + name: 'sophos.xg.filesize', + type: 'integer', + }, + 'sophos.xg.filepath': { + category: 'sophos', + description: 'Path of the file containing virus ', + name: 'sophos.xg.filepath', + type: 'keyword', + }, + 'sophos.xg.filename': { + category: 'sophos', + description: 'File name associated with the event ', + name: 'sophos.xg.filename', + type: 'keyword', + }, + 'sophos.xg.ftpcommand': { + category: 'sophos', + description: 'FTP command used when virus was found ', + name: 'sophos.xg.ftpcommand', + type: 'keyword', + }, + 'sophos.xg.url': { + category: 'sophos', + description: 'URL from which virus was downloaded ', + name: 'sophos.xg.url', + type: 'keyword', + }, + 'sophos.xg.domainname': { + category: 'sophos', + description: 'Domain from which virus was downloaded ', + name: 'sophos.xg.domainname', + type: 'keyword', + }, + 'sophos.xg.quarantine': { + category: 'sophos', + description: 'Path and filename of the file quarantined ', + name: 'sophos.xg.quarantine', + type: 'keyword', + }, + 'sophos.xg.src_domainname': { + category: 'sophos', + description: 'Sender domain name ', + name: 'sophos.xg.src_domainname', + type: 'keyword', + }, + 'sophos.xg.dst_domainname': { + category: 'sophos', + description: 'Receiver domain name ', + name: 'sophos.xg.dst_domainname', + type: 'keyword', + }, + 'sophos.xg.reason': { + category: 'sophos', + description: 'Reason why the record was detected as spam/malicious ', + name: 'sophos.xg.reason', + type: 'keyword', + }, + 'sophos.xg.referer': { + category: 'sophos', + description: 'Referer ', + name: 'sophos.xg.referer', + type: 'keyword', + }, + 'sophos.xg.spamaction': { + category: 'sophos', + description: 'Spam Action ', + name: 'sophos.xg.spamaction', + type: 'keyword', + }, + 'sophos.xg.mailid': { + category: 'sophos', + description: 'mailid ', + name: 'sophos.xg.mailid', + type: 'keyword', + }, + 'sophos.xg.quarantine_reason': { + category: 'sophos', + description: 'Quarantine reason ', + name: 'sophos.xg.quarantine_reason', + type: 'keyword', + }, + 'sophos.xg.status_code': { + category: 'sophos', + description: 'Status code ', + name: 'sophos.xg.status_code', + type: 'keyword', + }, + 'sophos.xg.override_token': { + category: 'sophos', + description: 'Override token ', + name: 'sophos.xg.override_token', + type: 'keyword', + }, + 'sophos.xg.con_id': { + category: 'sophos', + description: 'Unique identifier of connection ', + name: 'sophos.xg.con_id', + type: 'integer', + }, + 'sophos.xg.override_authorizer': { + category: 'sophos', + description: 'Override authorizer ', + name: 'sophos.xg.override_authorizer', + type: 'keyword', + }, + 'sophos.xg.transactionid': { + category: 'sophos', + description: 'Transaction ID of the AV scan. ', + name: 'sophos.xg.transactionid', + type: 'keyword', + }, + 'sophos.xg.upload_file_type': { + category: 'sophos', + description: 'Upload file type ', + name: 'sophos.xg.upload_file_type', + type: 'keyword', + }, + 'sophos.xg.upload_file_name': { + category: 'sophos', + description: 'Upload file name ', + name: 'sophos.xg.upload_file_name', + type: 'keyword', + }, + 'sophos.xg.httpresponsecode': { + category: 'sophos', + description: 'code of HTTP response ', + name: 'sophos.xg.httpresponsecode', + type: 'long', + }, + 'sophos.xg.user_gp': { + category: 'sophos', + description: 'Group name to which the user belongs. ', + name: 'sophos.xg.user_gp', + type: 'keyword', + }, + 'sophos.xg.category_type': { + category: 'sophos', + description: 'Type of category under which website falls ', + name: 'sophos.xg.category_type', + type: 'keyword', + }, + 'sophos.xg.download_file_type': { + category: 'sophos', + description: 'Download file type ', + name: 'sophos.xg.download_file_type', + type: 'keyword', + }, + 'sophos.xg.exceptions': { + category: 'sophos', + description: 'List of the checks excluded by web exceptions. ', + name: 'sophos.xg.exceptions', + type: 'keyword', + }, + 'sophos.xg.contenttype': { + category: 'sophos', + description: 'Type of the content ', + name: 'sophos.xg.contenttype', + type: 'keyword', + }, + 'sophos.xg.override_name': { + category: 'sophos', + description: 'Override name ', + name: 'sophos.xg.override_name', + type: 'keyword', + }, + 'sophos.xg.activityname': { + category: 'sophos', + description: 'Web policy activity that matched and caused the policy result. ', + name: 'sophos.xg.activityname', + type: 'keyword', + }, + 'sophos.xg.download_file_name': { + category: 'sophos', + description: 'Download file name ', + name: 'sophos.xg.download_file_name', + type: 'keyword', + }, + 'sophos.xg.sha1sum': { + category: 'sophos', + description: 'SHA1 checksum of the item being analyzed ', + name: 'sophos.xg.sha1sum', + type: 'keyword', + }, + 'sophos.xg.message_id': { + category: 'sophos', + description: 'Message ID ', + name: 'sophos.xg.message_id', + type: 'keyword', + }, + 'sophos.xg.connid': { + category: 'sophos', + description: 'Connection ID ', + name: 'sophos.xg.connid', + type: 'keyword', + }, + 'sophos.xg.message': { + category: 'sophos', + description: 'Message ', + name: 'sophos.xg.message', + type: 'keyword', + }, + 'sophos.xg.email_subject': { + category: 'sophos', + description: 'Email Subject ', + name: 'sophos.xg.email_subject', + type: 'keyword', + }, + 'sophos.xg.file_path': { + category: 'sophos', + description: 'File path ', + name: 'sophos.xg.file_path', + type: 'keyword', + }, + 'sophos.xg.dstdomain': { + category: 'sophos', + description: 'Destination Domain ', + name: 'sophos.xg.dstdomain', + type: 'keyword', + }, + 'sophos.xg.file_size': { + category: 'sophos', + description: 'File Size ', + name: 'sophos.xg.file_size', + type: 'integer', + }, + 'sophos.xg.transaction_id': { + category: 'sophos', + description: 'Transaction ID ', + name: 'sophos.xg.transaction_id', + type: 'keyword', + }, + 'sophos.xg.website': { + category: 'sophos', + description: 'Website ', + name: 'sophos.xg.website', + type: 'keyword', + }, + 'sophos.xg.file_name': { + category: 'sophos', + description: 'Filename ', + name: 'sophos.xg.file_name', + type: 'keyword', + }, + 'sophos.xg.context_prefix': { + category: 'sophos', + description: 'Content Prefix ', + name: 'sophos.xg.context_prefix', + type: 'keyword', + }, + 'sophos.xg.site_category': { + category: 'sophos', + description: 'Site Category ', + name: 'sophos.xg.site_category', + type: 'keyword', + }, + 'sophos.xg.context_suffix': { + category: 'sophos', + description: 'Context Suffix ', + name: 'sophos.xg.context_suffix', + type: 'keyword', + }, + 'sophos.xg.dictionary_name': { + category: 'sophos', + description: 'Dictionary Name ', + name: 'sophos.xg.dictionary_name', + type: 'keyword', + }, + 'sophos.xg.action': { + category: 'sophos', + description: 'Event Action ', + name: 'sophos.xg.action', + type: 'keyword', + }, + 'sophos.xg.user': { + category: 'sophos', + description: 'User ', + name: 'sophos.xg.user', + type: 'keyword', + }, + 'sophos.xg.context_match': { + category: 'sophos', + description: 'Context Match ', + name: 'sophos.xg.context_match', + type: 'keyword', + }, + 'sophos.xg.direction': { + category: 'sophos', + description: 'Direction ', + name: 'sophos.xg.direction', + type: 'keyword', + }, + 'sophos.xg.auth_client': { + category: 'sophos', + description: 'Auth Client ', + name: 'sophos.xg.auth_client', + type: 'keyword', + }, + 'sophos.xg.auth_mechanism': { + category: 'sophos', + description: 'Auth mechanism ', + name: 'sophos.xg.auth_mechanism', + type: 'keyword', + }, + 'sophos.xg.connectionname': { + category: 'sophos', + description: 'Connectionname ', + name: 'sophos.xg.connectionname', + type: 'keyword', + }, + 'sophos.xg.remotenetwork': { + category: 'sophos', + description: 'remotenetwork ', + name: 'sophos.xg.remotenetwork', + type: 'keyword', + }, + 'sophos.xg.localgateway': { + category: 'sophos', + description: 'Localgateway ', + name: 'sophos.xg.localgateway', + type: 'keyword', + }, + 'sophos.xg.localnetwork': { + category: 'sophos', + description: 'Localnetwork ', + name: 'sophos.xg.localnetwork', + type: 'keyword', + }, + 'sophos.xg.connectiontype': { + category: 'sophos', + description: 'Connectiontype ', + name: 'sophos.xg.connectiontype', + type: 'keyword', + }, + 'sophos.xg.oldversion': { + category: 'sophos', + description: 'Oldversion ', + name: 'sophos.xg.oldversion', + type: 'keyword', + }, + 'sophos.xg.newversion': { + category: 'sophos', + description: 'Newversion ', + name: 'sophos.xg.newversion', + type: 'keyword', + }, + 'sophos.xg.ipaddress': { + category: 'sophos', + description: 'Ipaddress ', + name: 'sophos.xg.ipaddress', + type: 'keyword', + }, + 'sophos.xg.client_physical_address': { + category: 'sophos', + description: 'Client physical address ', + name: 'sophos.xg.client_physical_address', + type: 'keyword', + }, + 'sophos.xg.client_host_name': { + category: 'sophos', + description: 'Client host name ', + name: 'sophos.xg.client_host_name', + type: 'keyword', + }, + 'sophos.xg.raw_data': { + category: 'sophos', + description: 'Raw data ', + name: 'sophos.xg.raw_data', + type: 'keyword', + }, + 'sophos.xg.Mode': { + category: 'sophos', + description: 'Mode ', + name: 'sophos.xg.Mode', + type: 'keyword', + }, + 'sophos.xg.sessionid': { + category: 'sophos', + description: 'Sessionid ', + name: 'sophos.xg.sessionid', + type: 'keyword', + }, + 'sophos.xg.starttime': { + category: 'sophos', + description: 'Starttime ', + name: 'sophos.xg.starttime', + type: 'date', + }, + 'sophos.xg.remote_ip': { + category: 'sophos', + description: 'Remote IP ', + name: 'sophos.xg.remote_ip', + type: 'ip', + }, + 'sophos.xg.timestamp': { + category: 'sophos', + description: 'timestamp ', + name: 'sophos.xg.timestamp', + type: 'date', + }, + 'sophos.xg.SysLog_SERVER_NAME': { + category: 'sophos', + description: 'SysLog SERVER NAME ', + name: 'sophos.xg.SysLog_SERVER_NAME', + type: 'keyword', + }, + 'sophos.xg.backup_mode': { + category: 'sophos', + description: 'Backup mode ', + name: 'sophos.xg.backup_mode', + type: 'keyword', + }, + 'sophos.xg.source': { + category: 'sophos', + description: 'Source ', + name: 'sophos.xg.source', + type: 'keyword', + }, + 'sophos.xg.server': { + category: 'sophos', + description: 'Server ', + name: 'sophos.xg.server', + type: 'keyword', + }, + 'sophos.xg.host': { + category: 'sophos', + description: 'Host ', + name: 'sophos.xg.host', + type: 'keyword', + }, + 'sophos.xg.responsetime': { + category: 'sophos', + description: 'Responsetime ', + name: 'sophos.xg.responsetime', + type: 'long', + }, + 'sophos.xg.cookie': { + category: 'sophos', + description: 'cookie ', + name: 'sophos.xg.cookie', + type: 'keyword', + }, + 'sophos.xg.querystring': { + category: 'sophos', + description: 'querystring ', + name: 'sophos.xg.querystring', + type: 'keyword', + }, + 'sophos.xg.extra': { + category: 'sophos', + description: 'extra ', + name: 'sophos.xg.extra', + type: 'keyword', + }, + 'sophos.xg.PHPSESSID': { + category: 'sophos', + description: 'PHPSESSID ', + name: 'sophos.xg.PHPSESSID', + type: 'keyword', + }, + 'sophos.xg.start_time': { + category: 'sophos', + description: 'Start time ', + name: 'sophos.xg.start_time', + type: 'date', + }, + 'sophos.xg.eventtime': { + category: 'sophos', + description: 'Event time ', + name: 'sophos.xg.eventtime', + type: 'date', + }, + 'sophos.xg.red_id': { + category: 'sophos', + description: 'RED ID ', + name: 'sophos.xg.red_id', + type: 'keyword', + }, + 'sophos.xg.branch_name': { + category: 'sophos', + description: 'Branch Name ', + name: 'sophos.xg.branch_name', + type: 'keyword', + }, + 'sophos.xg.updatedip': { + category: 'sophos', + description: 'updatedip ', + name: 'sophos.xg.updatedip', + type: 'ip', + }, + 'sophos.xg.idle_cpu': { + category: 'sophos', + description: 'idle ## ', + name: 'sophos.xg.idle_cpu', + type: 'float', + }, + 'sophos.xg.system_cpu': { + category: 'sophos', + description: 'system ', + name: 'sophos.xg.system_cpu', + type: 'float', + }, + 'sophos.xg.user_cpu': { + category: 'sophos', + description: 'system ', + name: 'sophos.xg.user_cpu', + type: 'float', + }, + 'sophos.xg.used': { + category: 'sophos', + description: 'used ', + name: 'sophos.xg.used', + type: 'integer', + }, + 'sophos.xg.unit': { + category: 'sophos', + description: 'unit ', + name: 'sophos.xg.unit', + type: 'keyword', + }, + 'sophos.xg.total_memory': { + category: 'sophos', + description: 'Total Memory ', + name: 'sophos.xg.total_memory', + type: 'integer', + }, + 'sophos.xg.free': { + category: 'sophos', + description: 'free ', + name: 'sophos.xg.free', + type: 'integer', + }, + 'sophos.xg.transmittederrors': { + category: 'sophos', + description: 'transmitted errors ', + name: 'sophos.xg.transmittederrors', + type: 'keyword', + }, + 'sophos.xg.receivederrors': { + category: 'sophos', + description: 'received errors ', + name: 'sophos.xg.receivederrors', + type: 'keyword', + }, + 'sophos.xg.receivedkbits': { + category: 'sophos', + description: 'received kbits ', + name: 'sophos.xg.receivedkbits', + type: 'long', + }, + 'sophos.xg.transmittedkbits': { + category: 'sophos', + description: 'transmitted kbits ', + name: 'sophos.xg.transmittedkbits', + type: 'long', + }, + 'sophos.xg.transmitteddrops': { + category: 'sophos', + description: 'transmitted drops ', + name: 'sophos.xg.transmitteddrops', + type: 'long', + }, + 'sophos.xg.receiveddrops': { + category: 'sophos', + description: 'received drops ', + name: 'sophos.xg.receiveddrops', + type: 'long', + }, + 'sophos.xg.collisions': { + category: 'sophos', + description: 'collisions ', + name: 'sophos.xg.collisions', + type: 'long', + }, + 'sophos.xg.interface': { + category: 'sophos', + description: 'interface ', + name: 'sophos.xg.interface', + type: 'keyword', + }, + 'sophos.xg.Configuration': { + category: 'sophos', + description: 'Configuration ', + name: 'sophos.xg.Configuration', + type: 'float', + }, + 'sophos.xg.Reports': { + category: 'sophos', + description: 'Reports ', + name: 'sophos.xg.Reports', + type: 'float', + }, + 'sophos.xg.Signature': { + category: 'sophos', + description: 'Signature ', + name: 'sophos.xg.Signature', + type: 'float', + }, + 'sophos.xg.Temp': { + category: 'sophos', + description: 'Temp ', + name: 'sophos.xg.Temp', + type: 'float', + }, + 'sophos.xg.users': { + category: 'sophos', + description: 'users ', + name: 'sophos.xg.users', + type: 'keyword', + }, + 'sophos.xg.ssid': { + category: 'sophos', + description: 'ssid ', + name: 'sophos.xg.ssid', + type: 'keyword', + }, + 'sophos.xg.ap': { + category: 'sophos', + description: 'ap ', + name: 'sophos.xg.ap', + type: 'keyword', + }, + 'sophos.xg.clients_conn_ssid': { + category: 'sophos', + description: 'clients connection ssid ', + name: 'sophos.xg.clients_conn_ssid', + type: 'keyword', + }, + 'suricata.eve.event_type': { + category: 'suricata', + name: 'suricata.eve.event_type', + type: 'keyword', + }, + 'suricata.eve.app_proto_orig': { + category: 'suricata', + name: 'suricata.eve.app_proto_orig', + type: 'keyword', + }, + 'suricata.eve.tcp.tcp_flags': { + category: 'suricata', + name: 'suricata.eve.tcp.tcp_flags', + type: 'keyword', + }, + 'suricata.eve.tcp.psh': { + category: 'suricata', + name: 'suricata.eve.tcp.psh', + type: 'boolean', + }, + 'suricata.eve.tcp.tcp_flags_tc': { + category: 'suricata', + name: 'suricata.eve.tcp.tcp_flags_tc', + type: 'keyword', + }, + 'suricata.eve.tcp.ack': { + category: 'suricata', + name: 'suricata.eve.tcp.ack', + type: 'boolean', + }, + 'suricata.eve.tcp.syn': { + category: 'suricata', + name: 'suricata.eve.tcp.syn', + type: 'boolean', + }, + 'suricata.eve.tcp.state': { + category: 'suricata', + name: 'suricata.eve.tcp.state', + type: 'keyword', + }, + 'suricata.eve.tcp.tcp_flags_ts': { + category: 'suricata', + name: 'suricata.eve.tcp.tcp_flags_ts', + type: 'keyword', + }, + 'suricata.eve.tcp.rst': { + category: 'suricata', + name: 'suricata.eve.tcp.rst', + type: 'boolean', + }, + 'suricata.eve.tcp.fin': { + category: 'suricata', + name: 'suricata.eve.tcp.fin', + type: 'boolean', + }, + 'suricata.eve.fileinfo.sha1': { + category: 'suricata', + name: 'suricata.eve.fileinfo.sha1', + type: 'keyword', + }, + 'suricata.eve.fileinfo.filename': { + category: 'suricata', + name: 'suricata.eve.fileinfo.filename', + type: 'alias', + }, + 'suricata.eve.fileinfo.tx_id': { + category: 'suricata', + name: 'suricata.eve.fileinfo.tx_id', + type: 'long', + }, + 'suricata.eve.fileinfo.state': { + category: 'suricata', + name: 'suricata.eve.fileinfo.state', + type: 'keyword', + }, + 'suricata.eve.fileinfo.stored': { + category: 'suricata', + name: 'suricata.eve.fileinfo.stored', + type: 'boolean', + }, + 'suricata.eve.fileinfo.gaps': { + category: 'suricata', + name: 'suricata.eve.fileinfo.gaps', + type: 'boolean', + }, + 'suricata.eve.fileinfo.sha256': { + category: 'suricata', + name: 'suricata.eve.fileinfo.sha256', + type: 'keyword', + }, + 'suricata.eve.fileinfo.md5': { + category: 'suricata', + name: 'suricata.eve.fileinfo.md5', + type: 'keyword', + }, + 'suricata.eve.fileinfo.size': { + category: 'suricata', + name: 'suricata.eve.fileinfo.size', + type: 'alias', + }, + 'suricata.eve.icmp_type': { + category: 'suricata', + name: 'suricata.eve.icmp_type', + type: 'long', + }, + 'suricata.eve.dest_port': { + category: 'suricata', + name: 'suricata.eve.dest_port', + type: 'alias', + }, + 'suricata.eve.src_port': { + category: 'suricata', + name: 'suricata.eve.src_port', + type: 'alias', + }, + 'suricata.eve.proto': { + category: 'suricata', + name: 'suricata.eve.proto', + type: 'alias', + }, + 'suricata.eve.pcap_cnt': { + category: 'suricata', + name: 'suricata.eve.pcap_cnt', + type: 'long', + }, + 'suricata.eve.src_ip': { + category: 'suricata', + name: 'suricata.eve.src_ip', + type: 'alias', + }, + 'suricata.eve.dns.type': { + category: 'suricata', + name: 'suricata.eve.dns.type', + type: 'keyword', + }, + 'suricata.eve.dns.rrtype': { + category: 'suricata', + name: 'suricata.eve.dns.rrtype', + type: 'keyword', + }, + 'suricata.eve.dns.rrname': { + category: 'suricata', + name: 'suricata.eve.dns.rrname', + type: 'keyword', + }, + 'suricata.eve.dns.rdata': { + category: 'suricata', + name: 'suricata.eve.dns.rdata', + type: 'keyword', + }, + 'suricata.eve.dns.tx_id': { + category: 'suricata', + name: 'suricata.eve.dns.tx_id', + type: 'long', + }, + 'suricata.eve.dns.ttl': { + category: 'suricata', + name: 'suricata.eve.dns.ttl', + type: 'long', + }, + 'suricata.eve.dns.rcode': { + category: 'suricata', + name: 'suricata.eve.dns.rcode', + type: 'keyword', + }, + 'suricata.eve.dns.id': { + category: 'suricata', + name: 'suricata.eve.dns.id', + type: 'long', + }, + 'suricata.eve.flow_id': { + category: 'suricata', + name: 'suricata.eve.flow_id', + type: 'keyword', + }, + 'suricata.eve.email.status': { + category: 'suricata', + name: 'suricata.eve.email.status', + type: 'keyword', + }, + 'suricata.eve.dest_ip': { + category: 'suricata', + name: 'suricata.eve.dest_ip', + type: 'alias', + }, + 'suricata.eve.icmp_code': { + category: 'suricata', + name: 'suricata.eve.icmp_code', + type: 'long', + }, + 'suricata.eve.http.status': { + category: 'suricata', + name: 'suricata.eve.http.status', + type: 'alias', + }, + 'suricata.eve.http.redirect': { + category: 'suricata', + name: 'suricata.eve.http.redirect', + type: 'keyword', + }, + 'suricata.eve.http.http_user_agent': { + category: 'suricata', + name: 'suricata.eve.http.http_user_agent', + type: 'alias', + }, + 'suricata.eve.http.protocol': { + category: 'suricata', + name: 'suricata.eve.http.protocol', + type: 'keyword', + }, + 'suricata.eve.http.http_refer': { + category: 'suricata', + name: 'suricata.eve.http.http_refer', + type: 'alias', + }, + 'suricata.eve.http.url': { + category: 'suricata', + name: 'suricata.eve.http.url', + type: 'alias', + }, + 'suricata.eve.http.hostname': { + category: 'suricata', + name: 'suricata.eve.http.hostname', + type: 'alias', + }, + 'suricata.eve.http.length': { + category: 'suricata', + name: 'suricata.eve.http.length', + type: 'alias', + }, + 'suricata.eve.http.http_method': { + category: 'suricata', + name: 'suricata.eve.http.http_method', + type: 'alias', + }, + 'suricata.eve.http.http_content_type': { + category: 'suricata', + name: 'suricata.eve.http.http_content_type', + type: 'keyword', + }, + 'suricata.eve.timestamp': { + category: 'suricata', + name: 'suricata.eve.timestamp', + type: 'alias', + }, + 'suricata.eve.in_iface': { + category: 'suricata', + name: 'suricata.eve.in_iface', + type: 'keyword', + }, + 'suricata.eve.alert.category': { + category: 'suricata', + name: 'suricata.eve.alert.category', + type: 'keyword', + }, + 'suricata.eve.alert.severity': { + category: 'suricata', + name: 'suricata.eve.alert.severity', + type: 'alias', + }, + 'suricata.eve.alert.rev': { + category: 'suricata', + name: 'suricata.eve.alert.rev', + type: 'long', + }, + 'suricata.eve.alert.gid': { + category: 'suricata', + name: 'suricata.eve.alert.gid', + type: 'long', + }, + 'suricata.eve.alert.signature': { + category: 'suricata', + name: 'suricata.eve.alert.signature', + type: 'keyword', + }, + 'suricata.eve.alert.action': { + category: 'suricata', + name: 'suricata.eve.alert.action', + type: 'alias', + }, + 'suricata.eve.alert.signature_id': { + category: 'suricata', + name: 'suricata.eve.alert.signature_id', + type: 'long', + }, + 'suricata.eve.ssh.client.proto_version': { + category: 'suricata', + name: 'suricata.eve.ssh.client.proto_version', + type: 'keyword', + }, + 'suricata.eve.ssh.client.software_version': { + category: 'suricata', + name: 'suricata.eve.ssh.client.software_version', + type: 'keyword', + }, + 'suricata.eve.ssh.server.proto_version': { + category: 'suricata', + name: 'suricata.eve.ssh.server.proto_version', + type: 'keyword', + }, + 'suricata.eve.ssh.server.software_version': { + category: 'suricata', + name: 'suricata.eve.ssh.server.software_version', + type: 'keyword', + }, + 'suricata.eve.stats.capture.kernel_packets': { + category: 'suricata', + name: 'suricata.eve.stats.capture.kernel_packets', + type: 'long', + }, + 'suricata.eve.stats.capture.kernel_drops': { + category: 'suricata', + name: 'suricata.eve.stats.capture.kernel_drops', + type: 'long', + }, + 'suricata.eve.stats.capture.kernel_ifdrops': { + category: 'suricata', + name: 'suricata.eve.stats.capture.kernel_ifdrops', + type: 'long', + }, + 'suricata.eve.stats.uptime': { + category: 'suricata', + name: 'suricata.eve.stats.uptime', + type: 'long', + }, + 'suricata.eve.stats.detect.alert': { + category: 'suricata', + name: 'suricata.eve.stats.detect.alert', + type: 'long', + }, + 'suricata.eve.stats.http.memcap': { + category: 'suricata', + name: 'suricata.eve.stats.http.memcap', + type: 'long', + }, + 'suricata.eve.stats.http.memuse': { + category: 'suricata', + name: 'suricata.eve.stats.http.memuse', + type: 'long', + }, + 'suricata.eve.stats.file_store.open_files': { + category: 'suricata', + name: 'suricata.eve.stats.file_store.open_files', + type: 'long', + }, + 'suricata.eve.stats.defrag.max_frag_hits': { + category: 'suricata', + name: 'suricata.eve.stats.defrag.max_frag_hits', + type: 'long', + }, + 'suricata.eve.stats.defrag.ipv4.timeouts': { + category: 'suricata', + name: 'suricata.eve.stats.defrag.ipv4.timeouts', + type: 'long', + }, + 'suricata.eve.stats.defrag.ipv4.fragments': { + category: 'suricata', + name: 'suricata.eve.stats.defrag.ipv4.fragments', + type: 'long', + }, + 'suricata.eve.stats.defrag.ipv4.reassembled': { + category: 'suricata', + name: 'suricata.eve.stats.defrag.ipv4.reassembled', + type: 'long', + }, + 'suricata.eve.stats.defrag.ipv6.timeouts': { + category: 'suricata', + name: 'suricata.eve.stats.defrag.ipv6.timeouts', + type: 'long', + }, + 'suricata.eve.stats.defrag.ipv6.fragments': { + category: 'suricata', + name: 'suricata.eve.stats.defrag.ipv6.fragments', + type: 'long', + }, + 'suricata.eve.stats.defrag.ipv6.reassembled': { + category: 'suricata', + name: 'suricata.eve.stats.defrag.ipv6.reassembled', + type: 'long', + }, + 'suricata.eve.stats.flow.tcp_reuse': { + category: 'suricata', + name: 'suricata.eve.stats.flow.tcp_reuse', + type: 'long', + }, + 'suricata.eve.stats.flow.udp': { + category: 'suricata', + name: 'suricata.eve.stats.flow.udp', + type: 'long', + }, + 'suricata.eve.stats.flow.memcap': { + category: 'suricata', + name: 'suricata.eve.stats.flow.memcap', + type: 'long', + }, + 'suricata.eve.stats.flow.emerg_mode_entered': { + category: 'suricata', + name: 'suricata.eve.stats.flow.emerg_mode_entered', + type: 'long', + }, + 'suricata.eve.stats.flow.emerg_mode_over': { + category: 'suricata', + name: 'suricata.eve.stats.flow.emerg_mode_over', + type: 'long', + }, + 'suricata.eve.stats.flow.tcp': { + category: 'suricata', + name: 'suricata.eve.stats.flow.tcp', + type: 'long', + }, + 'suricata.eve.stats.flow.icmpv6': { + category: 'suricata', + name: 'suricata.eve.stats.flow.icmpv6', + type: 'long', + }, + 'suricata.eve.stats.flow.icmpv4': { + category: 'suricata', + name: 'suricata.eve.stats.flow.icmpv4', + type: 'long', + }, + 'suricata.eve.stats.flow.spare': { + category: 'suricata', + name: 'suricata.eve.stats.flow.spare', + type: 'long', + }, + 'suricata.eve.stats.flow.memuse': { + category: 'suricata', + name: 'suricata.eve.stats.flow.memuse', + type: 'long', + }, + 'suricata.eve.stats.tcp.pseudo_failed': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.pseudo_failed', + type: 'long', + }, + 'suricata.eve.stats.tcp.ssn_memcap_drop': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.ssn_memcap_drop', + type: 'long', + }, + 'suricata.eve.stats.tcp.insert_data_overlap_fail': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.insert_data_overlap_fail', + type: 'long', + }, + 'suricata.eve.stats.tcp.sessions': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.sessions', + type: 'long', + }, + 'suricata.eve.stats.tcp.pseudo': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.pseudo', + type: 'long', + }, + 'suricata.eve.stats.tcp.synack': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.synack', + type: 'long', + }, + 'suricata.eve.stats.tcp.insert_data_normal_fail': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.insert_data_normal_fail', + type: 'long', + }, + 'suricata.eve.stats.tcp.syn': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.syn', + type: 'long', + }, + 'suricata.eve.stats.tcp.memuse': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.memuse', + type: 'long', + }, + 'suricata.eve.stats.tcp.invalid_checksum': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.invalid_checksum', + type: 'long', + }, + 'suricata.eve.stats.tcp.segment_memcap_drop': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.segment_memcap_drop', + type: 'long', + }, + 'suricata.eve.stats.tcp.overlap': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.overlap', + type: 'long', + }, + 'suricata.eve.stats.tcp.insert_list_fail': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.insert_list_fail', + type: 'long', + }, + 'suricata.eve.stats.tcp.rst': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.rst', + type: 'long', + }, + 'suricata.eve.stats.tcp.stream_depth_reached': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.stream_depth_reached', + type: 'long', + }, + 'suricata.eve.stats.tcp.reassembly_memuse': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.reassembly_memuse', + type: 'long', + }, + 'suricata.eve.stats.tcp.reassembly_gap': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.reassembly_gap', + type: 'long', + }, + 'suricata.eve.stats.tcp.overlap_diff_data': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.overlap_diff_data', + type: 'long', + }, + 'suricata.eve.stats.tcp.no_flow': { + category: 'suricata', + name: 'suricata.eve.stats.tcp.no_flow', + type: 'long', + }, + 'suricata.eve.stats.decoder.avg_pkt_size': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.avg_pkt_size', + type: 'long', + }, + 'suricata.eve.stats.decoder.bytes': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.bytes', + type: 'long', + }, + 'suricata.eve.stats.decoder.tcp': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.tcp', + type: 'long', + }, + 'suricata.eve.stats.decoder.raw': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.raw', + type: 'long', + }, + 'suricata.eve.stats.decoder.ppp': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.ppp', + type: 'long', + }, + 'suricata.eve.stats.decoder.vlan_qinq': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.vlan_qinq', + type: 'long', + }, + 'suricata.eve.stats.decoder.null': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.null', + type: 'long', + }, + 'suricata.eve.stats.decoder.ltnull.unsupported_type': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.ltnull.unsupported_type', + type: 'long', + }, + 'suricata.eve.stats.decoder.ltnull.pkt_too_small': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.ltnull.pkt_too_small', + type: 'long', + }, + 'suricata.eve.stats.decoder.invalid': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.invalid', + type: 'long', + }, + 'suricata.eve.stats.decoder.gre': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.gre', + type: 'long', + }, + 'suricata.eve.stats.decoder.ipv4': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.ipv4', + type: 'long', + }, + 'suricata.eve.stats.decoder.ipv6': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.ipv6', + type: 'long', + }, + 'suricata.eve.stats.decoder.pkts': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.pkts', + type: 'long', + }, + 'suricata.eve.stats.decoder.ipv6_in_ipv6': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.ipv6_in_ipv6', + type: 'long', + }, + 'suricata.eve.stats.decoder.ipraw.invalid_ip_version': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.ipraw.invalid_ip_version', + type: 'long', + }, + 'suricata.eve.stats.decoder.pppoe': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.pppoe', + type: 'long', + }, + 'suricata.eve.stats.decoder.udp': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.udp', + type: 'long', + }, + 'suricata.eve.stats.decoder.dce.pkt_too_small': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.dce.pkt_too_small', + type: 'long', + }, + 'suricata.eve.stats.decoder.vlan': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.vlan', + type: 'long', + }, + 'suricata.eve.stats.decoder.sctp': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.sctp', + type: 'long', + }, + 'suricata.eve.stats.decoder.max_pkt_size': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.max_pkt_size', + type: 'long', + }, + 'suricata.eve.stats.decoder.teredo': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.teredo', + type: 'long', + }, + 'suricata.eve.stats.decoder.mpls': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.mpls', + type: 'long', + }, + 'suricata.eve.stats.decoder.sll': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.sll', + type: 'long', + }, + 'suricata.eve.stats.decoder.icmpv6': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.icmpv6', + type: 'long', + }, + 'suricata.eve.stats.decoder.icmpv4': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.icmpv4', + type: 'long', + }, + 'suricata.eve.stats.decoder.erspan': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.erspan', + type: 'long', + }, + 'suricata.eve.stats.decoder.ethernet': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.ethernet', + type: 'long', + }, + 'suricata.eve.stats.decoder.ipv4_in_ipv6': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.ipv4_in_ipv6', + type: 'long', + }, + 'suricata.eve.stats.decoder.ieee8021ah': { + category: 'suricata', + name: 'suricata.eve.stats.decoder.ieee8021ah', + type: 'long', + }, + 'suricata.eve.stats.dns.memcap_global': { + category: 'suricata', + name: 'suricata.eve.stats.dns.memcap_global', + type: 'long', + }, + 'suricata.eve.stats.dns.memcap_state': { + category: 'suricata', + name: 'suricata.eve.stats.dns.memcap_state', + type: 'long', + }, + 'suricata.eve.stats.dns.memuse': { + category: 'suricata', + name: 'suricata.eve.stats.dns.memuse', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.rows_busy': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.rows_busy', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.flows_timeout': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.flows_timeout', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.flows_notimeout': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.flows_notimeout', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.rows_skipped': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.rows_skipped', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.closed_pruned': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.closed_pruned', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.new_pruned': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.new_pruned', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.flows_removed': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.flows_removed', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.bypassed_pruned': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.bypassed_pruned', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.est_pruned': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.est_pruned', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.flows_timeout_inuse': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.flows_timeout_inuse', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.flows_checked': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.flows_checked', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.rows_maxlen': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.rows_maxlen', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.rows_checked': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.rows_checked', + type: 'long', + }, + 'suricata.eve.stats.flow_mgr.rows_empty': { + category: 'suricata', + name: 'suricata.eve.stats.flow_mgr.rows_empty', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.tls': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.tls', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.ftp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.ftp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.http': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.http', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.failed_udp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.failed_udp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.dns_udp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.dns_udp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.dns_tcp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.dns_tcp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.smtp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.smtp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.failed_tcp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.failed_tcp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.msn': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.msn', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.ssh': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.ssh', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.imap': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.imap', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.dcerpc_udp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.dcerpc_udp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.dcerpc_tcp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.dcerpc_tcp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.flow.smb': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.flow.smb', + type: 'long', + }, + 'suricata.eve.stats.app_layer.tx.tls': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.tx.tls', + type: 'long', + }, + 'suricata.eve.stats.app_layer.tx.ftp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.tx.ftp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.tx.http': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.tx.http', + type: 'long', + }, + 'suricata.eve.stats.app_layer.tx.dns_udp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.tx.dns_udp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.tx.dns_tcp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.tx.dns_tcp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.tx.smtp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.tx.smtp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.tx.ssh': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.tx.ssh', + type: 'long', + }, + 'suricata.eve.stats.app_layer.tx.dcerpc_udp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.tx.dcerpc_udp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.tx.dcerpc_tcp': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.tx.dcerpc_tcp', + type: 'long', + }, + 'suricata.eve.stats.app_layer.tx.smb': { + category: 'suricata', + name: 'suricata.eve.stats.app_layer.tx.smb', + type: 'long', + }, + 'suricata.eve.tls.notbefore': { + category: 'suricata', + name: 'suricata.eve.tls.notbefore', + type: 'date', + }, + 'suricata.eve.tls.issuerdn': { + category: 'suricata', + name: 'suricata.eve.tls.issuerdn', + type: 'keyword', + }, + 'suricata.eve.tls.sni': { + category: 'suricata', + name: 'suricata.eve.tls.sni', + type: 'keyword', + }, + 'suricata.eve.tls.version': { + category: 'suricata', + name: 'suricata.eve.tls.version', + type: 'keyword', + }, + 'suricata.eve.tls.session_resumed': { + category: 'suricata', + name: 'suricata.eve.tls.session_resumed', + type: 'boolean', + }, + 'suricata.eve.tls.fingerprint': { + category: 'suricata', + name: 'suricata.eve.tls.fingerprint', + type: 'keyword', + }, + 'suricata.eve.tls.serial': { + category: 'suricata', + name: 'suricata.eve.tls.serial', + type: 'keyword', + }, + 'suricata.eve.tls.notafter': { + category: 'suricata', + name: 'suricata.eve.tls.notafter', + type: 'date', + }, + 'suricata.eve.tls.subject': { + category: 'suricata', + name: 'suricata.eve.tls.subject', + type: 'keyword', + }, + 'suricata.eve.tls.ja3s.string': { + category: 'suricata', + name: 'suricata.eve.tls.ja3s.string', + type: 'keyword', + }, + 'suricata.eve.tls.ja3s.hash': { + category: 'suricata', + name: 'suricata.eve.tls.ja3s.hash', + type: 'keyword', + }, + 'suricata.eve.tls.ja3.string': { + category: 'suricata', + name: 'suricata.eve.tls.ja3.string', + type: 'keyword', + }, + 'suricata.eve.tls.ja3.hash': { + category: 'suricata', + name: 'suricata.eve.tls.ja3.hash', + type: 'keyword', + }, + 'suricata.eve.app_proto_ts': { + category: 'suricata', + name: 'suricata.eve.app_proto_ts', + type: 'keyword', + }, + 'suricata.eve.flow.bytes_toclient': { + category: 'suricata', + name: 'suricata.eve.flow.bytes_toclient', + type: 'alias', + }, + 'suricata.eve.flow.start': { + category: 'suricata', + name: 'suricata.eve.flow.start', + type: 'alias', + }, + 'suricata.eve.flow.pkts_toclient': { + category: 'suricata', + name: 'suricata.eve.flow.pkts_toclient', + type: 'alias', + }, + 'suricata.eve.flow.age': { + category: 'suricata', + name: 'suricata.eve.flow.age', + type: 'long', + }, + 'suricata.eve.flow.state': { + category: 'suricata', + name: 'suricata.eve.flow.state', + type: 'keyword', + }, + 'suricata.eve.flow.bytes_toserver': { + category: 'suricata', + name: 'suricata.eve.flow.bytes_toserver', + type: 'alias', + }, + 'suricata.eve.flow.reason': { + category: 'suricata', + name: 'suricata.eve.flow.reason', + type: 'keyword', + }, + 'suricata.eve.flow.pkts_toserver': { + category: 'suricata', + name: 'suricata.eve.flow.pkts_toserver', + type: 'alias', + }, + 'suricata.eve.flow.end': { + category: 'suricata', + name: 'suricata.eve.flow.end', + type: 'date', + }, + 'suricata.eve.flow.alerted': { + category: 'suricata', + name: 'suricata.eve.flow.alerted', + type: 'boolean', + }, + 'suricata.eve.app_proto': { + category: 'suricata', + name: 'suricata.eve.app_proto', + type: 'alias', + }, + 'suricata.eve.tx_id': { + category: 'suricata', + name: 'suricata.eve.tx_id', + type: 'long', + }, + 'suricata.eve.app_proto_tc': { + category: 'suricata', + name: 'suricata.eve.app_proto_tc', + type: 'keyword', + }, + 'suricata.eve.smtp.rcpt_to': { + category: 'suricata', + name: 'suricata.eve.smtp.rcpt_to', + type: 'keyword', + }, + 'suricata.eve.smtp.mail_from': { + category: 'suricata', + name: 'suricata.eve.smtp.mail_from', + type: 'keyword', + }, + 'suricata.eve.smtp.helo': { + category: 'suricata', + name: 'suricata.eve.smtp.helo', + type: 'keyword', + }, + 'suricata.eve.app_proto_expected': { + category: 'suricata', + name: 'suricata.eve.app_proto_expected', + type: 'keyword', + }, + 'suricata.eve.flags': { + category: 'suricata', + name: 'suricata.eve.flags', + type: 'group', + }, + 'zeek.session_id': { + category: 'zeek', + description: 'A unique identifier of the session ', + name: 'zeek.session_id', + type: 'keyword', + }, + 'zeek.capture_loss.ts_delta': { + category: 'zeek', + description: 'The time delay between this measurement and the last. ', + name: 'zeek.capture_loss.ts_delta', + type: 'integer', + }, + 'zeek.capture_loss.peer': { + category: 'zeek', + description: + 'In the event that there are multiple Bro instances logging to the same host, this distinguishes each peer with its individual name. ', + name: 'zeek.capture_loss.peer', + type: 'keyword', + }, + 'zeek.capture_loss.gaps': { + category: 'zeek', + description: 'Number of missed ACKs from the previous measurement interval. ', + name: 'zeek.capture_loss.gaps', + type: 'integer', + }, + 'zeek.capture_loss.acks': { + category: 'zeek', + description: 'Total number of ACKs seen in the previous measurement interval. ', + name: 'zeek.capture_loss.acks', + type: 'integer', + }, + 'zeek.capture_loss.percent_lost': { + category: 'zeek', + description: "Percentage of ACKs seen where the data being ACKed wasn't seen. ", + name: 'zeek.capture_loss.percent_lost', + type: 'double', + }, + 'zeek.connection.local_orig': { + category: 'zeek', + description: 'Indicates whether the session is originated locally. ', + name: 'zeek.connection.local_orig', + type: 'boolean', + }, + 'zeek.connection.local_resp': { + category: 'zeek', + description: 'Indicates whether the session is responded locally. ', + name: 'zeek.connection.local_resp', + type: 'boolean', + }, + 'zeek.connection.missed_bytes': { + category: 'zeek', + description: 'Missed bytes for the session. ', + name: 'zeek.connection.missed_bytes', + type: 'long', + }, + 'zeek.connection.state': { + category: 'zeek', + description: 'Code indicating the state of the session. ', + name: 'zeek.connection.state', + type: 'keyword', + }, + 'zeek.connection.state_message': { + category: 'zeek', + description: 'The state of the session. ', + name: 'zeek.connection.state_message', + type: 'keyword', + }, + 'zeek.connection.icmp.type': { + category: 'zeek', + description: 'ICMP message type. ', + name: 'zeek.connection.icmp.type', + type: 'integer', + }, + 'zeek.connection.icmp.code': { + category: 'zeek', + description: 'ICMP message code. ', + name: 'zeek.connection.icmp.code', + type: 'integer', + }, + 'zeek.connection.history': { + category: 'zeek', + description: 'Flags indicating the history of the session. ', + name: 'zeek.connection.history', + type: 'keyword', + }, + 'zeek.connection.vlan': { + category: 'zeek', + description: 'VLAN identifier. ', + name: 'zeek.connection.vlan', + type: 'integer', + }, + 'zeek.connection.inner_vlan': { + category: 'zeek', + description: 'VLAN identifier. ', + name: 'zeek.connection.inner_vlan', + type: 'integer', + }, + 'zeek.dce_rpc.rtt': { + category: 'zeek', + description: + "Round trip time from the request to the response. If either the request or response wasn't seen, this will be null. ", + name: 'zeek.dce_rpc.rtt', + type: 'integer', + }, + 'zeek.dce_rpc.named_pipe': { + category: 'zeek', + description: 'Remote pipe name. ', + name: 'zeek.dce_rpc.named_pipe', + type: 'keyword', + }, + 'zeek.dce_rpc.endpoint': { + category: 'zeek', + description: 'Endpoint name looked up from the uuid. ', + name: 'zeek.dce_rpc.endpoint', + type: 'keyword', + }, + 'zeek.dce_rpc.operation': { + category: 'zeek', + description: 'Operation seen in the call. ', + name: 'zeek.dce_rpc.operation', + type: 'keyword', + }, + 'zeek.dhcp.domain': { + category: 'zeek', + description: 'Domain given by the server in option 15. ', + name: 'zeek.dhcp.domain', + type: 'keyword', + }, + 'zeek.dhcp.duration': { + category: 'zeek', + description: + 'Duration of the DHCP session representing the time from the first message to the last, in seconds. ', + name: 'zeek.dhcp.duration', + type: 'double', + }, + 'zeek.dhcp.hostname': { + category: 'zeek', + description: 'Name given by client in Hostname option 12. ', + name: 'zeek.dhcp.hostname', + type: 'keyword', + }, + 'zeek.dhcp.client_fqdn': { + category: 'zeek', + description: 'FQDN given by client in Client FQDN option 81. ', + name: 'zeek.dhcp.client_fqdn', + type: 'keyword', + }, + 'zeek.dhcp.lease_time': { + category: 'zeek', + description: 'IP address lease interval in seconds. ', + name: 'zeek.dhcp.lease_time', + type: 'integer', + }, + 'zeek.dhcp.address.assigned': { + category: 'zeek', + description: 'IP address assigned by the server. ', + name: 'zeek.dhcp.address.assigned', + type: 'ip', + }, + 'zeek.dhcp.address.client': { + category: 'zeek', + description: + 'IP address of the client. If a transaction is only a client sending INFORM messages then there is no lease information exchanged so this is helpful to know who sent the messages. Getting an address in this field does require that the client sources at least one DHCP message using a non-broadcast address. ', + name: 'zeek.dhcp.address.client', + type: 'ip', + }, + 'zeek.dhcp.address.mac': { + category: 'zeek', + description: "Client's hardware address. ", + name: 'zeek.dhcp.address.mac', + type: 'keyword', + }, + 'zeek.dhcp.address.requested': { + category: 'zeek', + description: 'IP address requested by the client. ', + name: 'zeek.dhcp.address.requested', + type: 'ip', + }, + 'zeek.dhcp.address.server': { + category: 'zeek', + description: 'IP address of the DHCP server. ', + name: 'zeek.dhcp.address.server', + type: 'ip', + }, + 'zeek.dhcp.msg.types': { + category: 'zeek', + description: 'List of DHCP message types seen in this exchange. ', + name: 'zeek.dhcp.msg.types', + type: 'keyword', + }, + 'zeek.dhcp.msg.origin': { + category: 'zeek', + description: + '(present if policy/protocols/dhcp/msg-orig.bro is loaded) The address that originated each message from the msg.types field. ', + name: 'zeek.dhcp.msg.origin', + type: 'ip', + }, + 'zeek.dhcp.msg.client': { + category: 'zeek', + description: + 'Message typically accompanied with a DHCP_DECLINE so the client can tell the server why it rejected an address. ', + name: 'zeek.dhcp.msg.client', + type: 'keyword', + }, + 'zeek.dhcp.msg.server': { + category: 'zeek', + description: + 'Message typically accompanied with a DHCP_NAK to let the client know why it rejected the request. ', + name: 'zeek.dhcp.msg.server', + type: 'keyword', + }, + 'zeek.dhcp.software.client': { + category: 'zeek', + description: + '(present if policy/protocols/dhcp/software.bro is loaded) Software reported by the client in the vendor_class option. ', + name: 'zeek.dhcp.software.client', + type: 'keyword', + }, + 'zeek.dhcp.software.server': { + category: 'zeek', + description: + '(present if policy/protocols/dhcp/software.bro is loaded) Software reported by the client in the vendor_class option. ', + name: 'zeek.dhcp.software.server', + type: 'keyword', + }, + 'zeek.dhcp.id.circuit': { + category: 'zeek', + description: + '(present if policy/protocols/dhcp/sub-opts.bro is loaded) Added by DHCP relay agents which terminate switched or permanent circuits. It encodes an agent-local identifier of the circuit from which a DHCP client-to-server packet was received. Typically it should represent a router or switch interface number. ', + name: 'zeek.dhcp.id.circuit', + type: 'keyword', + }, + 'zeek.dhcp.id.remote_agent': { + category: 'zeek', + description: + '(present if policy/protocols/dhcp/sub-opts.bro is loaded) A globally unique identifier added by relay agents to identify the remote host end of the circuit. ', + name: 'zeek.dhcp.id.remote_agent', + type: 'keyword', + }, + 'zeek.dhcp.id.subscriber': { + category: 'zeek', + description: + "(present if policy/protocols/dhcp/sub-opts.bro is loaded) The subscriber ID is a value independent of the physical network configuration so that a customer's DHCP configuration can be given to them correctly no matter where they are physically connected. ", + name: 'zeek.dhcp.id.subscriber', + type: 'keyword', + }, + 'zeek.dnp3.function.request': { + category: 'zeek', + description: 'The name of the function message in the request. ', + name: 'zeek.dnp3.function.request', + type: 'keyword', + }, + 'zeek.dnp3.function.reply': { + category: 'zeek', + description: 'The name of the function message in the reply. ', + name: 'zeek.dnp3.function.reply', + type: 'keyword', + }, + 'zeek.dnp3.id': { + category: 'zeek', + description: "The response's internal indication number. ", + name: 'zeek.dnp3.id', + type: 'integer', + }, + 'zeek.dns.trans_id': { + category: 'zeek', + description: 'DNS transaction identifier. ', + name: 'zeek.dns.trans_id', + type: 'keyword', + }, + 'zeek.dns.rtt': { + category: 'zeek', + description: 'Round trip time for the query and response. ', + name: 'zeek.dns.rtt', + type: 'double', + }, + 'zeek.dns.query': { + category: 'zeek', + description: 'The domain name that is the subject of the DNS query. ', + name: 'zeek.dns.query', + type: 'keyword', + }, + 'zeek.dns.qclass': { + category: 'zeek', + description: 'The QCLASS value specifying the class of the query. ', + name: 'zeek.dns.qclass', + type: 'long', + }, + 'zeek.dns.qclass_name': { + category: 'zeek', + description: 'A descriptive name for the class of the query. ', + name: 'zeek.dns.qclass_name', + type: 'keyword', + }, + 'zeek.dns.qtype': { + category: 'zeek', + description: 'A QTYPE value specifying the type of the query. ', + name: 'zeek.dns.qtype', + type: 'long', + }, + 'zeek.dns.qtype_name': { + category: 'zeek', + description: 'A descriptive name for the type of the query. ', + name: 'zeek.dns.qtype_name', + type: 'keyword', + }, + 'zeek.dns.rcode': { + category: 'zeek', + description: 'The response code value in DNS response messages. ', + name: 'zeek.dns.rcode', + type: 'long', + }, + 'zeek.dns.rcode_name': { + category: 'zeek', + description: 'A descriptive name for the response code value. ', + name: 'zeek.dns.rcode_name', + type: 'keyword', + }, + 'zeek.dns.AA': { + category: 'zeek', + description: + 'The Authoritative Answer bit for response messages specifies that the responding name server is an authority for the domain name in the question section. ', + name: 'zeek.dns.AA', + type: 'boolean', + }, + 'zeek.dns.TC': { + category: 'zeek', + description: 'The Truncation bit specifies that the message was truncated. ', + name: 'zeek.dns.TC', + type: 'boolean', + }, + 'zeek.dns.RD': { + category: 'zeek', + description: + 'The Recursion Desired bit in a request message indicates that the client wants recursive service for this query. ', + name: 'zeek.dns.RD', + type: 'boolean', + }, + 'zeek.dns.RA': { + category: 'zeek', + description: + 'The Recursion Available bit in a response message indicates that the name server supports recursive queries. ', + name: 'zeek.dns.RA', + type: 'boolean', + }, + 'zeek.dns.answers': { + category: 'zeek', + description: 'The set of resource descriptions in the query answer. ', + name: 'zeek.dns.answers', + type: 'keyword', + }, + 'zeek.dns.TTLs': { + category: 'zeek', + description: 'The caching intervals of the associated RRs described by the answers field. ', + name: 'zeek.dns.TTLs', + type: 'double', + }, + 'zeek.dns.rejected': { + category: 'zeek', + description: 'Indicates whether the DNS query was rejected by the server. ', + name: 'zeek.dns.rejected', + type: 'boolean', + }, + 'zeek.dns.total_answers': { + category: 'zeek', + description: 'The total number of resource records in the reply. ', + name: 'zeek.dns.total_answers', + type: 'integer', + }, + 'zeek.dns.total_replies': { + category: 'zeek', + description: 'The total number of resource records in the reply message. ', + name: 'zeek.dns.total_replies', + type: 'integer', + }, + 'zeek.dns.saw_query': { + category: 'zeek', + description: 'Whether the full DNS query has been seen. ', + name: 'zeek.dns.saw_query', + type: 'boolean', + }, + 'zeek.dns.saw_reply': { + category: 'zeek', + description: 'Whether the full DNS reply has been seen. ', + name: 'zeek.dns.saw_reply', + type: 'boolean', + }, + 'zeek.dpd.analyzer': { + category: 'zeek', + description: 'The analyzer that generated the violation. ', + name: 'zeek.dpd.analyzer', + type: 'keyword', + }, + 'zeek.dpd.failure_reason': { + category: 'zeek', + description: 'The textual reason for the analysis failure. ', + name: 'zeek.dpd.failure_reason', + type: 'keyword', + }, + 'zeek.dpd.packet_segment': { + category: 'zeek', + description: + '(present if policy/frameworks/dpd/packet-segment-logging.bro is loaded) A chunk of the payload that most likely resulted in the protocol violation. ', + name: 'zeek.dpd.packet_segment', + type: 'keyword', + }, + 'zeek.files.fuid': { + category: 'zeek', + description: 'A file unique identifier. ', + name: 'zeek.files.fuid', + type: 'keyword', + }, + 'zeek.files.tx_host': { + category: 'zeek', + description: 'The host that transferred the file. ', + name: 'zeek.files.tx_host', + type: 'ip', + }, + 'zeek.files.rx_host': { + category: 'zeek', + description: 'The host that received the file. ', + name: 'zeek.files.rx_host', + type: 'ip', + }, + 'zeek.files.session_ids': { + category: 'zeek', + description: 'The sessions that have this file. ', + name: 'zeek.files.session_ids', + type: 'keyword', + }, + 'zeek.files.source': { + category: 'zeek', + description: + 'An identification of the source of the file data. E.g. it may be a network protocol over which it was transferred, or a local file path which was read, or some other input source. ', + name: 'zeek.files.source', + type: 'keyword', + }, + 'zeek.files.depth': { + category: 'zeek', + description: + 'A value to represent the depth of this file in relation to its source. In SMTP, it is the depth of the MIME attachment on the message. In HTTP, it is the depth of the request within the TCP connection. ', + name: 'zeek.files.depth', + type: 'long', + }, + 'zeek.files.analyzers': { + category: 'zeek', + description: 'A set of analysis types done during the file analysis. ', + name: 'zeek.files.analyzers', + type: 'keyword', + }, + 'zeek.files.mime_type': { + category: 'zeek', + description: 'Mime type of the file. ', + name: 'zeek.files.mime_type', + type: 'keyword', + }, + 'zeek.files.filename': { + category: 'zeek', + description: 'Name of the file if available. ', + name: 'zeek.files.filename', + type: 'keyword', + }, + 'zeek.files.local_orig': { + category: 'zeek', + description: + 'If the source of this file is a network connection, this field indicates if the data originated from the local network or not. ', + name: 'zeek.files.local_orig', + type: 'boolean', + }, + 'zeek.files.is_orig': { + category: 'zeek', + description: + 'If the source of this file is a network connection, this field indicates if the file is being sent by the originator of the connection or the responder. ', + name: 'zeek.files.is_orig', + type: 'boolean', + }, + 'zeek.files.duration': { + category: 'zeek', + description: 'The duration the file was analyzed for. Not the duration of the session. ', + name: 'zeek.files.duration', + type: 'double', + }, + 'zeek.files.seen_bytes': { + category: 'zeek', + description: 'Number of bytes provided to the file analysis engine for the file. ', + name: 'zeek.files.seen_bytes', + type: 'long', + }, + 'zeek.files.total_bytes': { + category: 'zeek', + description: 'Total number of bytes that are supposed to comprise the full file. ', + name: 'zeek.files.total_bytes', + type: 'long', + }, + 'zeek.files.missing_bytes': { + category: 'zeek', + description: + 'The number of bytes in the file stream that were completely missed during the process of analysis. ', + name: 'zeek.files.missing_bytes', + type: 'long', + }, + 'zeek.files.overflow_bytes': { + category: 'zeek', + description: + "The number of bytes in the file stream that were not delivered to stream file analyzers. This could be overlapping bytes or bytes that couldn't be reassembled. ", + name: 'zeek.files.overflow_bytes', + type: 'long', + }, + 'zeek.files.timedout': { + category: 'zeek', + description: 'Whether the file analysis timed out at least once for the file. ', + name: 'zeek.files.timedout', + type: 'boolean', + }, + 'zeek.files.parent_fuid': { + category: 'zeek', + description: + 'Identifier associated with a container file from which this one was extracted as part of the file analysis. ', + name: 'zeek.files.parent_fuid', + type: 'keyword', + }, + 'zeek.files.md5': { + category: 'zeek', + description: 'An MD5 digest of the file contents. ', + name: 'zeek.files.md5', + type: 'keyword', + }, + 'zeek.files.sha1': { + category: 'zeek', + description: 'A SHA1 digest of the file contents. ', + name: 'zeek.files.sha1', + type: 'keyword', + }, + 'zeek.files.sha256': { + category: 'zeek', + description: 'A SHA256 digest of the file contents. ', + name: 'zeek.files.sha256', + type: 'keyword', + }, + 'zeek.files.extracted': { + category: 'zeek', + description: 'Local filename of extracted file. ', + name: 'zeek.files.extracted', + type: 'keyword', + }, + 'zeek.files.extracted_cutoff': { + category: 'zeek', + description: + 'Indicate whether the file being extracted was cut off hence not extracted completely. ', + name: 'zeek.files.extracted_cutoff', + type: 'boolean', + }, + 'zeek.files.extracted_size': { + category: 'zeek', + description: 'The number of bytes extracted to disk. ', + name: 'zeek.files.extracted_size', + type: 'long', + }, + 'zeek.files.entropy': { + category: 'zeek', + description: 'The information density of the contents of the file. ', + name: 'zeek.files.entropy', + type: 'double', + }, + 'zeek.ftp.user': { + category: 'zeek', + description: 'User name for the current FTP session. ', + name: 'zeek.ftp.user', + type: 'keyword', + }, + 'zeek.ftp.password': { + category: 'zeek', + description: 'Password for the current FTP session if captured. ', + name: 'zeek.ftp.password', + type: 'keyword', + }, + 'zeek.ftp.command': { + category: 'zeek', + description: 'Command given by the client. ', + name: 'zeek.ftp.command', + type: 'keyword', + }, + 'zeek.ftp.arg': { + category: 'zeek', + description: 'Argument for the command if one is given. ', + name: 'zeek.ftp.arg', + type: 'keyword', + }, + 'zeek.ftp.file.size': { + category: 'zeek', + description: 'Size of the file if the command indicates a file transfer. ', + name: 'zeek.ftp.file.size', + type: 'long', + }, + 'zeek.ftp.file.mime_type': { + category: 'zeek', + description: 'Sniffed mime type of file. ', + name: 'zeek.ftp.file.mime_type', + type: 'keyword', + }, + 'zeek.ftp.file.fuid': { + category: 'zeek', + description: '(present if base/protocols/ftp/files.bro is loaded) File unique ID. ', + name: 'zeek.ftp.file.fuid', + type: 'keyword', + }, + 'zeek.ftp.reply.code': { + category: 'zeek', + description: 'Reply code from the server in response to the command. ', + name: 'zeek.ftp.reply.code', + type: 'integer', + }, + 'zeek.ftp.reply.msg': { + category: 'zeek', + description: 'Reply message from the server in response to the command. ', + name: 'zeek.ftp.reply.msg', + type: 'keyword', + }, + 'zeek.ftp.data_channel.passive': { + category: 'zeek', + description: 'Whether PASV mode is toggled for control channel. ', + name: 'zeek.ftp.data_channel.passive', + type: 'boolean', + }, + 'zeek.ftp.data_channel.originating_host': { + category: 'zeek', + description: 'The host that will be initiating the data connection. ', + name: 'zeek.ftp.data_channel.originating_host', + type: 'ip', + }, + 'zeek.ftp.data_channel.response_host': { + category: 'zeek', + description: 'The host that will be accepting the data connection. ', + name: 'zeek.ftp.data_channel.response_host', + type: 'ip', + }, + 'zeek.ftp.data_channel.response_port': { + category: 'zeek', + description: 'The port at which the acceptor is listening for the data connection. ', + name: 'zeek.ftp.data_channel.response_port', + type: 'integer', + }, + 'zeek.ftp.cwd': { + category: 'zeek', + description: + "Current working directory that this session is in. By making the default value '.', we can indicate that unless something more concrete is discovered that the existing but unknown directory is ok to use. ", + name: 'zeek.ftp.cwd', + type: 'keyword', + }, + 'zeek.ftp.cmdarg.cmd': { + category: 'zeek', + description: 'Command. ', + name: 'zeek.ftp.cmdarg.cmd', + type: 'keyword', + }, + 'zeek.ftp.cmdarg.arg': { + category: 'zeek', + description: 'Argument for the command if one was given. ', + name: 'zeek.ftp.cmdarg.arg', + type: 'keyword', + }, + 'zeek.ftp.cmdarg.seq': { + category: 'zeek', + description: 'Counter to track how many commands have been executed. ', + name: 'zeek.ftp.cmdarg.seq', + type: 'integer', + }, + 'zeek.ftp.pending_commands': { + category: 'zeek', + description: + 'Queue for commands that have been sent but not yet responded to are tracked here. ', + name: 'zeek.ftp.pending_commands', + type: 'integer', + }, + 'zeek.ftp.passive': { + category: 'zeek', + description: 'Indicates if the session is in active or passive mode. ', + name: 'zeek.ftp.passive', + type: 'boolean', + }, + 'zeek.ftp.capture_password': { + category: 'zeek', + description: 'Determines if the password will be captured for this request. ', + name: 'zeek.ftp.capture_password', + type: 'boolean', + }, + 'zeek.ftp.last_auth_requested': { + category: 'zeek', + description: + 'present if base/protocols/ftp/gridftp.bro is loaded. Last authentication/security mechanism that was used. ', + name: 'zeek.ftp.last_auth_requested', + type: 'keyword', + }, + 'zeek.http.trans_depth': { + category: 'zeek', + description: + 'Represents the pipelined depth into the connection of this request/response transaction. ', + name: 'zeek.http.trans_depth', + type: 'integer', + }, + 'zeek.http.status_msg': { + category: 'zeek', + description: 'Status message returned by the server. ', + name: 'zeek.http.status_msg', + type: 'keyword', + }, + 'zeek.http.info_code': { + category: 'zeek', + description: 'Last seen 1xx informational reply code returned by the server. ', + name: 'zeek.http.info_code', + type: 'integer', + }, + 'zeek.http.info_msg': { + category: 'zeek', + description: 'Last seen 1xx informational reply message returned by the server. ', + name: 'zeek.http.info_msg', + type: 'keyword', + }, + 'zeek.http.tags': { + category: 'zeek', + description: + 'A set of indicators of various attributes discovered and related to a particular request/response pair. ', + name: 'zeek.http.tags', + type: 'keyword', + }, + 'zeek.http.password': { + category: 'zeek', + description: 'Password if basic-auth is performed for the request. ', + name: 'zeek.http.password', + type: 'keyword', + }, + 'zeek.http.captured_password': { + category: 'zeek', + description: 'Determines if the password will be captured for this request. ', + name: 'zeek.http.captured_password', + type: 'boolean', + }, + 'zeek.http.proxied': { + category: 'zeek', + description: 'All of the headers that may indicate if the HTTP request was proxied. ', + name: 'zeek.http.proxied', + type: 'keyword', + }, + 'zeek.http.range_request': { + category: 'zeek', + description: 'Indicates if this request can assume 206 partial content in response. ', + name: 'zeek.http.range_request', + type: 'boolean', + }, + 'zeek.http.client_header_names': { + category: 'zeek', + description: + 'The vector of HTTP header names sent by the client. No header values are included here, just the header names. ', + name: 'zeek.http.client_header_names', + type: 'keyword', + }, + 'zeek.http.server_header_names': { + category: 'zeek', + description: + 'The vector of HTTP header names sent by the server. No header values are included here, just the header names. ', + name: 'zeek.http.server_header_names', + type: 'keyword', + }, + 'zeek.http.orig_fuids': { + category: 'zeek', + description: 'An ordered vector of file unique IDs from the originator. ', + name: 'zeek.http.orig_fuids', + type: 'keyword', + }, + 'zeek.http.orig_mime_types': { + category: 'zeek', + description: 'An ordered vector of mime types from the originator. ', + name: 'zeek.http.orig_mime_types', + type: 'keyword', + }, + 'zeek.http.orig_filenames': { + category: 'zeek', + description: 'An ordered vector of filenames from the originator. ', + name: 'zeek.http.orig_filenames', + type: 'keyword', + }, + 'zeek.http.resp_fuids': { + category: 'zeek', + description: 'An ordered vector of file unique IDs from the responder. ', + name: 'zeek.http.resp_fuids', + type: 'keyword', + }, + 'zeek.http.resp_mime_types': { + category: 'zeek', + description: 'An ordered vector of mime types from the responder. ', + name: 'zeek.http.resp_mime_types', + type: 'keyword', + }, + 'zeek.http.resp_filenames': { + category: 'zeek', + description: 'An ordered vector of filenames from the responder. ', + name: 'zeek.http.resp_filenames', + type: 'keyword', + }, + 'zeek.http.orig_mime_depth': { + category: 'zeek', + description: 'Current number of MIME entities in the HTTP request message body. ', + name: 'zeek.http.orig_mime_depth', + type: 'integer', + }, + 'zeek.http.resp_mime_depth': { + category: 'zeek', + description: 'Current number of MIME entities in the HTTP response message body. ', + name: 'zeek.http.resp_mime_depth', + type: 'integer', + }, + 'zeek.intel.seen.indicator': { + category: 'zeek', + description: 'The intelligence indicator. ', + name: 'zeek.intel.seen.indicator', + type: 'keyword', + }, + 'zeek.intel.seen.indicator_type': { + category: 'zeek', + description: 'The type of data the indicator represents. ', + name: 'zeek.intel.seen.indicator_type', + type: 'keyword', + }, + 'zeek.intel.seen.host': { + category: 'zeek', + description: 'If the indicator type was Intel::ADDR, then this field will be present. ', + name: 'zeek.intel.seen.host', + type: 'keyword', + }, + 'zeek.intel.seen.conn': { + category: 'zeek', + description: + 'If the data was discovered within a connection, the connection record should go here to give context to the data. ', + name: 'zeek.intel.seen.conn', + type: 'keyword', + }, + 'zeek.intel.seen.where': { + category: 'zeek', + description: 'Where the data was discovered. ', + name: 'zeek.intel.seen.where', + type: 'keyword', + }, + 'zeek.intel.seen.node': { + category: 'zeek', + description: 'The name of the node where the match was discovered. ', + name: 'zeek.intel.seen.node', + type: 'keyword', + }, + 'zeek.intel.seen.uid': { + category: 'zeek', + description: + 'If the data was discovered within a connection, the connection uid should go here to give context to the data. If the conn field is provided, this will be automatically filled out. ', + name: 'zeek.intel.seen.uid', + type: 'keyword', + }, + 'zeek.intel.seen.f': { + category: 'zeek', + description: + 'If the data was discovered within a file, the file record should go here to provide context to the data. ', + name: 'zeek.intel.seen.f', + type: 'object', + }, + 'zeek.intel.seen.fuid': { + category: 'zeek', + description: + 'If the data was discovered within a file, the file uid should go here to provide context to the data. If the file record f is provided, this will be automatically filled out. ', + name: 'zeek.intel.seen.fuid', + type: 'keyword', + }, + 'zeek.intel.matched': { + category: 'zeek', + description: 'Event to represent a match in the intelligence data from data that was seen. ', + name: 'zeek.intel.matched', + type: 'keyword', + }, + 'zeek.intel.sources': { + category: 'zeek', + description: 'Sources which supplied data for this match. ', + name: 'zeek.intel.sources', + type: 'keyword', + }, + 'zeek.intel.fuid': { + category: 'zeek', + description: + 'If a file was associated with this intelligence hit, this is the uid for the file. ', + name: 'zeek.intel.fuid', + type: 'keyword', + }, + 'zeek.intel.file_mime_type': { + category: 'zeek', + description: + 'A mime type if the intelligence hit is related to a file. If the $f field is provided this will be automatically filled out. ', + name: 'zeek.intel.file_mime_type', + type: 'keyword', + }, + 'zeek.intel.file_desc': { + category: 'zeek', + description: + 'Frequently files can be described to give a bit more context. If the $f field is provided this field will be automatically filled out. ', + name: 'zeek.intel.file_desc', + type: 'keyword', + }, + 'zeek.irc.nick': { + category: 'zeek', + description: 'Nickname given for the connection. ', + name: 'zeek.irc.nick', + type: 'keyword', + }, + 'zeek.irc.user': { + category: 'zeek', + description: 'Username given for the connection. ', + name: 'zeek.irc.user', + type: 'keyword', + }, + 'zeek.irc.command': { + category: 'zeek', + description: 'Command given by the client. ', + name: 'zeek.irc.command', + type: 'keyword', + }, + 'zeek.irc.value': { + category: 'zeek', + description: 'Value for the command given by the client. ', + name: 'zeek.irc.value', + type: 'keyword', + }, + 'zeek.irc.addl': { + category: 'zeek', + description: 'Any additional data for the command. ', + name: 'zeek.irc.addl', + type: 'keyword', + }, + 'zeek.irc.dcc.file.name': { + category: 'zeek', + description: 'Present if base/protocols/irc/dcc-send.bro is loaded. DCC filename requested. ', + name: 'zeek.irc.dcc.file.name', + type: 'keyword', + }, + 'zeek.irc.dcc.file.size': { + category: 'zeek', + description: + 'Present if base/protocols/irc/dcc-send.bro is loaded. Size of the DCC transfer as indicated by the sender. ', + name: 'zeek.irc.dcc.file.size', + type: 'long', + }, + 'zeek.irc.dcc.mime_type': { + category: 'zeek', + description: + 'present if base/protocols/irc/dcc-send.bro is loaded. Sniffed mime type of the file. ', + name: 'zeek.irc.dcc.mime_type', + type: 'keyword', + }, + 'zeek.irc.fuid': { + category: 'zeek', + description: 'present if base/protocols/irc/files.bro is loaded. File unique ID. ', + name: 'zeek.irc.fuid', + type: 'keyword', + }, + 'zeek.kerberos.request_type': { + category: 'zeek', + description: 'Request type - Authentication Service (AS) or Ticket Granting Service (TGS). ', + name: 'zeek.kerberos.request_type', + type: 'keyword', + }, + 'zeek.kerberos.client': { + category: 'zeek', + description: 'Client name. ', + name: 'zeek.kerberos.client', + type: 'keyword', + }, + 'zeek.kerberos.service': { + category: 'zeek', + description: 'Service name. ', + name: 'zeek.kerberos.service', + type: 'keyword', + }, + 'zeek.kerberos.success': { + category: 'zeek', + description: 'Request result. ', + name: 'zeek.kerberos.success', + type: 'boolean', + }, + 'zeek.kerberos.error.code': { + category: 'zeek', + description: 'Error code. ', + name: 'zeek.kerberos.error.code', + type: 'integer', + }, + 'zeek.kerberos.error.msg': { + category: 'zeek', + description: 'Error message. ', + name: 'zeek.kerberos.error.msg', + type: 'keyword', + }, + 'zeek.kerberos.valid.from': { + category: 'zeek', + description: 'Ticket valid from. ', + name: 'zeek.kerberos.valid.from', + type: 'date', + }, + 'zeek.kerberos.valid.until': { + category: 'zeek', + description: 'Ticket valid until. ', + name: 'zeek.kerberos.valid.until', + type: 'date', + }, + 'zeek.kerberos.valid.days': { + category: 'zeek', + description: 'Number of days the ticket is valid for. ', + name: 'zeek.kerberos.valid.days', + type: 'integer', + }, + 'zeek.kerberos.cipher': { + category: 'zeek', + description: 'Ticket encryption type. ', + name: 'zeek.kerberos.cipher', + type: 'keyword', + }, + 'zeek.kerberos.forwardable': { + category: 'zeek', + description: 'Forwardable ticket requested. ', + name: 'zeek.kerberos.forwardable', + type: 'boolean', + }, + 'zeek.kerberos.renewable': { + category: 'zeek', + description: 'Renewable ticket requested. ', + name: 'zeek.kerberos.renewable', + type: 'boolean', + }, + 'zeek.kerberos.ticket.auth': { + category: 'zeek', + description: 'Hash of ticket used to authorize request/transaction. ', + name: 'zeek.kerberos.ticket.auth', + type: 'keyword', + }, + 'zeek.kerberos.ticket.new': { + category: 'zeek', + description: 'Hash of ticket returned by the KDC. ', + name: 'zeek.kerberos.ticket.new', + type: 'keyword', + }, + 'zeek.kerberos.cert.client.value': { + category: 'zeek', + description: 'Client certificate. ', + name: 'zeek.kerberos.cert.client.value', + type: 'keyword', + }, + 'zeek.kerberos.cert.client.fuid': { + category: 'zeek', + description: 'File unique ID of client cert. ', + name: 'zeek.kerberos.cert.client.fuid', + type: 'keyword', + }, + 'zeek.kerberos.cert.client.subject': { + category: 'zeek', + description: 'Subject of client certificate. ', + name: 'zeek.kerberos.cert.client.subject', + type: 'keyword', + }, + 'zeek.kerberos.cert.server.value': { + category: 'zeek', + description: 'Server certificate. ', + name: 'zeek.kerberos.cert.server.value', + type: 'keyword', + }, + 'zeek.kerberos.cert.server.fuid': { + category: 'zeek', + description: 'File unique ID of server certificate. ', + name: 'zeek.kerberos.cert.server.fuid', + type: 'keyword', + }, + 'zeek.kerberos.cert.server.subject': { + category: 'zeek', + description: 'Subject of server certificate. ', + name: 'zeek.kerberos.cert.server.subject', + type: 'keyword', + }, + 'zeek.modbus.function': { + category: 'zeek', + description: 'The name of the function message that was sent. ', + name: 'zeek.modbus.function', + type: 'keyword', + }, + 'zeek.modbus.exception': { + category: 'zeek', + description: 'The exception if the response was a failure. ', + name: 'zeek.modbus.exception', + type: 'keyword', + }, + 'zeek.modbus.track_address': { + category: 'zeek', + description: + 'Present if policy/protocols/modbus/track-memmap.bro is loaded. Modbus track address. ', + name: 'zeek.modbus.track_address', + type: 'integer', + }, + 'zeek.mysql.cmd': { + category: 'zeek', + description: 'The command that was issued. ', + name: 'zeek.mysql.cmd', + type: 'keyword', + }, + 'zeek.mysql.arg': { + category: 'zeek', + description: 'The argument issued to the command. ', + name: 'zeek.mysql.arg', + type: 'keyword', + }, + 'zeek.mysql.success': { + category: 'zeek', + description: 'Whether the command succeeded. ', + name: 'zeek.mysql.success', + type: 'boolean', + }, + 'zeek.mysql.rows': { + category: 'zeek', + description: 'The number of affected rows, if any. ', + name: 'zeek.mysql.rows', + type: 'integer', + }, + 'zeek.mysql.response': { + category: 'zeek', + description: 'Server message, if any. ', + name: 'zeek.mysql.response', + type: 'keyword', + }, + 'zeek.notice.connection_id': { + category: 'zeek', + description: 'Identifier of the related connection session. ', + name: 'zeek.notice.connection_id', + type: 'keyword', + }, + 'zeek.notice.icmp_id': { + category: 'zeek', + description: 'Identifier of the related ICMP session. ', + name: 'zeek.notice.icmp_id', + type: 'keyword', + }, + 'zeek.notice.file.id': { + category: 'zeek', + description: 'An identifier associated with a single file that is related to this notice. ', + name: 'zeek.notice.file.id', + type: 'keyword', + }, + 'zeek.notice.file.parent_id': { + category: 'zeek', + description: 'Identifier associated with a container file from which this one was extracted. ', + name: 'zeek.notice.file.parent_id', + type: 'keyword', + }, + 'zeek.notice.file.source': { + category: 'zeek', + description: + 'An identification of the source of the file data. E.g. it may be a network protocol over which it was transferred, or a local file path which was read, or some other input source. ', + name: 'zeek.notice.file.source', + type: 'keyword', + }, + 'zeek.notice.file.mime_type': { + category: 'zeek', + description: 'A mime type if the notice is related to a file. ', + name: 'zeek.notice.file.mime_type', + type: 'keyword', + }, + 'zeek.notice.file.is_orig': { + category: 'zeek', + description: + 'If the source of this file is a network connection, this field indicates if the file is being sent by the originator of the connection or the responder. ', + name: 'zeek.notice.file.is_orig', + type: 'boolean', + }, + 'zeek.notice.file.seen_bytes': { + category: 'zeek', + description: 'Number of bytes provided to the file analysis engine for the file. ', + name: 'zeek.notice.file.seen_bytes', + type: 'long', + }, + 'zeek.notice.ffile.total_bytes': { + category: 'zeek', + description: 'Total number of bytes that are supposed to comprise the full file. ', + name: 'zeek.notice.ffile.total_bytes', + type: 'long', + }, + 'zeek.notice.file.missing_bytes': { + category: 'zeek', + description: + 'The number of bytes in the file stream that were completely missed during the process of analysis. ', + name: 'zeek.notice.file.missing_bytes', + type: 'long', + }, + 'zeek.notice.file.overflow_bytes': { + category: 'zeek', + description: + "The number of bytes in the file stream that were not delivered to stream file analyzers. This could be overlapping bytes or bytes that couldn't be reassembled. ", + name: 'zeek.notice.file.overflow_bytes', + type: 'long', + }, + 'zeek.notice.fuid': { + category: 'zeek', + description: 'A file unique ID if this notice is related to a file. ', + name: 'zeek.notice.fuid', + type: 'keyword', + }, + 'zeek.notice.note': { + category: 'zeek', + description: 'The type of the notice. ', + name: 'zeek.notice.note', + type: 'keyword', + }, + 'zeek.notice.msg': { + category: 'zeek', + description: 'The human readable message for the notice. ', + name: 'zeek.notice.msg', + type: 'keyword', + }, + 'zeek.notice.sub': { + category: 'zeek', + description: 'The human readable sub-message. ', + name: 'zeek.notice.sub', + type: 'keyword', + }, + 'zeek.notice.n': { + category: 'zeek', + description: 'Associated count, or a status code. ', + name: 'zeek.notice.n', + type: 'long', + }, + 'zeek.notice.peer_name': { + category: 'zeek', + description: 'Name of remote peer that raised this notice. ', + name: 'zeek.notice.peer_name', + type: 'keyword', + }, + 'zeek.notice.peer_descr': { + category: 'zeek', + description: 'Textual description for the peer that raised this notice. ', + name: 'zeek.notice.peer_descr', + type: 'text', + }, + 'zeek.notice.actions': { + category: 'zeek', + description: 'The actions which have been applied to this notice. ', + name: 'zeek.notice.actions', + type: 'keyword', + }, + 'zeek.notice.email_body_sections': { + category: 'zeek', + description: + 'By adding chunks of text into this element, other scripts can expand on notices that are being emailed. ', + name: 'zeek.notice.email_body_sections', + type: 'text', + }, + 'zeek.notice.email_delay_tokens': { + category: 'zeek', + description: + 'Adding a string token to this set will cause the built-in emailing functionality to delay sending the email either the token has been removed or the email has been delayed for the specified time duration. ', + name: 'zeek.notice.email_delay_tokens', + type: 'keyword', + }, + 'zeek.notice.identifier': { + category: 'zeek', + description: + 'This field is provided when a notice is generated for the purpose of deduplicating notices. ', + name: 'zeek.notice.identifier', + type: 'keyword', + }, + 'zeek.notice.suppress_for': { + category: 'zeek', + description: + 'This field indicates the length of time that this unique notice should be suppressed. ', + name: 'zeek.notice.suppress_for', + type: 'double', + }, + 'zeek.notice.dropped': { + category: 'zeek', + description: 'Indicate if the source IP address was dropped and denied network access. ', + name: 'zeek.notice.dropped', + type: 'boolean', + }, + 'zeek.ntlm.domain': { + category: 'zeek', + description: 'Domain name given by the client. ', + name: 'zeek.ntlm.domain', + type: 'keyword', + }, + 'zeek.ntlm.hostname': { + category: 'zeek', + description: 'Hostname given by the client. ', + name: 'zeek.ntlm.hostname', + type: 'keyword', + }, + 'zeek.ntlm.success': { + category: 'zeek', + description: 'Indicate whether or not the authentication was successful. ', + name: 'zeek.ntlm.success', + type: 'boolean', + }, + 'zeek.ntlm.username': { + category: 'zeek', + description: 'Username given by the client. ', + name: 'zeek.ntlm.username', + type: 'keyword', + }, + 'zeek.ntlm.server.name.dns': { + category: 'zeek', + description: 'DNS name given by the server in a CHALLENGE. ', + name: 'zeek.ntlm.server.name.dns', + type: 'keyword', + }, + 'zeek.ntlm.server.name.netbios': { + category: 'zeek', + description: 'NetBIOS name given by the server in a CHALLENGE. ', + name: 'zeek.ntlm.server.name.netbios', + type: 'keyword', + }, + 'zeek.ntlm.server.name.tree': { + category: 'zeek', + description: 'Tree name given by the server in a CHALLENGE. ', + name: 'zeek.ntlm.server.name.tree', + type: 'keyword', + }, + 'zeek.ocsp.file_id': { + category: 'zeek', + description: 'File id of the OCSP reply. ', + name: 'zeek.ocsp.file_id', + type: 'keyword', + }, + 'zeek.ocsp.hash.algorithm': { + category: 'zeek', + description: 'Hash algorithm used to generate issuerNameHash and issuerKeyHash. ', + name: 'zeek.ocsp.hash.algorithm', + type: 'keyword', + }, + 'zeek.ocsp.hash.issuer.name': { + category: 'zeek', + description: "Hash of the issuer's distingueshed name. ", + name: 'zeek.ocsp.hash.issuer.name', + type: 'keyword', + }, + 'zeek.ocsp.hash.issuer.key': { + category: 'zeek', + description: "Hash of the issuer's public key. ", + name: 'zeek.ocsp.hash.issuer.key', + type: 'keyword', + }, + 'zeek.ocsp.serial_number': { + category: 'zeek', + description: 'Serial number of the affected certificate. ', + name: 'zeek.ocsp.serial_number', + type: 'keyword', + }, + 'zeek.ocsp.status': { + category: 'zeek', + description: 'Status of the affected certificate. ', + name: 'zeek.ocsp.status', + type: 'keyword', + }, + 'zeek.ocsp.revoke.time': { + category: 'zeek', + description: 'Time at which the certificate was revoked. ', + name: 'zeek.ocsp.revoke.time', + type: 'date', + }, + 'zeek.ocsp.revoke.reason': { + category: 'zeek', + description: 'Reason for which the certificate was revoked. ', + name: 'zeek.ocsp.revoke.reason', + type: 'keyword', + }, + 'zeek.ocsp.update.this': { + category: 'zeek', + description: 'The time at which the status being shows is known to have been correct. ', + name: 'zeek.ocsp.update.this', + type: 'date', + }, + 'zeek.ocsp.update.next': { + category: 'zeek', + description: + 'The latest time at which new information about the status of the certificate will be available. ', + name: 'zeek.ocsp.update.next', + type: 'date', + }, + 'zeek.pe.client': { + category: 'zeek', + description: "The client's version string. ", + name: 'zeek.pe.client', + type: 'keyword', + }, + 'zeek.pe.id': { + category: 'zeek', + description: 'File id of this portable executable file. ', + name: 'zeek.pe.id', + type: 'keyword', + }, + 'zeek.pe.machine': { + category: 'zeek', + description: 'The target machine that the file was compiled for. ', + name: 'zeek.pe.machine', + type: 'keyword', + }, + 'zeek.pe.compile_time': { + category: 'zeek', + description: 'The time that the file was created at. ', + name: 'zeek.pe.compile_time', + type: 'date', + }, + 'zeek.pe.os': { + category: 'zeek', + description: 'The required operating system. ', + name: 'zeek.pe.os', + type: 'keyword', + }, + 'zeek.pe.subsystem': { + category: 'zeek', + description: 'The subsystem that is required to run this file. ', + name: 'zeek.pe.subsystem', + type: 'keyword', + }, + 'zeek.pe.is_exe': { + category: 'zeek', + description: 'Is the file an executable, or just an object file? ', + name: 'zeek.pe.is_exe', + type: 'boolean', + }, + 'zeek.pe.is_64bit': { + category: 'zeek', + description: 'Is the file a 64-bit executable? ', + name: 'zeek.pe.is_64bit', + type: 'boolean', + }, + 'zeek.pe.uses_aslr': { + category: 'zeek', + description: 'Does the file support Address Space Layout Randomization? ', + name: 'zeek.pe.uses_aslr', + type: 'boolean', + }, + 'zeek.pe.uses_dep': { + category: 'zeek', + description: 'Does the file support Data Execution Prevention? ', + name: 'zeek.pe.uses_dep', + type: 'boolean', + }, + 'zeek.pe.uses_code_integrity': { + category: 'zeek', + description: 'Does the file enforce code integrity checks? ', + name: 'zeek.pe.uses_code_integrity', + type: 'boolean', + }, + 'zeek.pe.uses_seh': { + category: 'zeek', + description: 'Does the file use structured exception handing? ', + name: 'zeek.pe.uses_seh', + type: 'boolean', + }, + 'zeek.pe.has_import_table': { + category: 'zeek', + description: 'Does the file have an import table? ', + name: 'zeek.pe.has_import_table', + type: 'boolean', + }, + 'zeek.pe.has_export_table': { + category: 'zeek', + description: 'Does the file have an export table? ', + name: 'zeek.pe.has_export_table', + type: 'boolean', + }, + 'zeek.pe.has_cert_table': { + category: 'zeek', + description: 'Does the file have an attribute certificate table? ', + name: 'zeek.pe.has_cert_table', + type: 'boolean', + }, + 'zeek.pe.has_debug_data': { + category: 'zeek', + description: 'Does the file have a debug table? ', + name: 'zeek.pe.has_debug_data', + type: 'boolean', + }, + 'zeek.pe.section_names': { + category: 'zeek', + description: 'The names of the sections, in order. ', + name: 'zeek.pe.section_names', + type: 'keyword', + }, + 'zeek.radius.username': { + category: 'zeek', + description: 'The username, if present. ', + name: 'zeek.radius.username', + type: 'keyword', + }, + 'zeek.radius.mac': { + category: 'zeek', + description: 'MAC address, if present. ', + name: 'zeek.radius.mac', + type: 'keyword', + }, + 'zeek.radius.framed_addr': { + category: 'zeek', + description: + 'The address given to the network access server, if present. This is only a hint from the RADIUS server and the network access server is not required to honor the address. ', + name: 'zeek.radius.framed_addr', + type: 'ip', + }, + 'zeek.radius.remote_ip': { + category: 'zeek', + description: + 'Remote IP address, if present. This is collected from the Tunnel-Client-Endpoint attribute. ', + name: 'zeek.radius.remote_ip', + type: 'ip', + }, + 'zeek.radius.connect_info': { + category: 'zeek', + description: 'Connect info, if present. ', + name: 'zeek.radius.connect_info', + type: 'keyword', + }, + 'zeek.radius.reply_msg': { + category: 'zeek', + description: + 'Reply message from the server challenge. This is frequently shown to the user authenticating. ', + name: 'zeek.radius.reply_msg', + type: 'keyword', + }, + 'zeek.radius.result': { + category: 'zeek', + description: 'Successful or failed authentication. ', + name: 'zeek.radius.result', + type: 'keyword', + }, + 'zeek.radius.ttl': { + category: 'zeek', + description: + 'The duration between the first request and either the "Access-Accept" message or an error. If the field is empty, it means that either the request or response was not seen. ', + name: 'zeek.radius.ttl', + type: 'integer', + }, + 'zeek.radius.logged': { + category: 'zeek', + description: 'Whether this has already been logged and can be ignored. ', + name: 'zeek.radius.logged', + type: 'boolean', + }, + 'zeek.rdp.cookie': { + category: 'zeek', + description: 'Cookie value used by the client machine. This is typically a username. ', + name: 'zeek.rdp.cookie', + type: 'keyword', + }, + 'zeek.rdp.result': { + category: 'zeek', + description: + "Status result for the connection. It's a mix between RDP negotation failure messages and GCC server create response messages. ", + name: 'zeek.rdp.result', + type: 'keyword', + }, + 'zeek.rdp.security_protocol': { + category: 'zeek', + description: 'Security protocol chosen by the server. ', + name: 'zeek.rdp.security_protocol', + type: 'keyword', + }, + 'zeek.rdp.keyboard_layout': { + category: 'zeek', + description: 'Keyboard layout (language) of the client machine. ', + name: 'zeek.rdp.keyboard_layout', + type: 'keyword', + }, + 'zeek.rdp.client.build': { + category: 'zeek', + description: 'RDP client version used by the client machine. ', + name: 'zeek.rdp.client.build', + type: 'keyword', + }, + 'zeek.rdp.client.client_name': { + category: 'zeek', + description: 'Name of the client machine. ', + name: 'zeek.rdp.client.client_name', + type: 'keyword', + }, + 'zeek.rdp.client.product_id': { + category: 'zeek', + description: 'Product ID of the client machine. ', + name: 'zeek.rdp.client.product_id', + type: 'keyword', + }, + 'zeek.rdp.desktop.width': { + category: 'zeek', + description: 'Desktop width of the client machine. ', + name: 'zeek.rdp.desktop.width', + type: 'integer', + }, + 'zeek.rdp.desktop.height': { + category: 'zeek', + description: 'Desktop height of the client machine. ', + name: 'zeek.rdp.desktop.height', + type: 'integer', + }, + 'zeek.rdp.desktop.color_depth': { + category: 'zeek', + description: 'The color depth requested by the client in the high_color_depth field. ', + name: 'zeek.rdp.desktop.color_depth', + type: 'keyword', + }, + 'zeek.rdp.cert.type': { + category: 'zeek', + description: + 'If the connection is being encrypted with native RDP encryption, this is the type of cert being used. ', + name: 'zeek.rdp.cert.type', + type: 'keyword', + }, + 'zeek.rdp.cert.count': { + category: 'zeek', + description: 'The number of certs seen. X.509 can transfer an entire certificate chain. ', + name: 'zeek.rdp.cert.count', + type: 'integer', + }, + 'zeek.rdp.cert.permanent': { + category: 'zeek', + description: + 'Indicates if the provided certificate or certificate chain is permanent or temporary. ', + name: 'zeek.rdp.cert.permanent', + type: 'boolean', + }, + 'zeek.rdp.encryption.level': { + category: 'zeek', + description: 'Encryption level of the connection. ', + name: 'zeek.rdp.encryption.level', + type: 'keyword', + }, + 'zeek.rdp.encryption.method': { + category: 'zeek', + description: 'Encryption method of the connection. ', + name: 'zeek.rdp.encryption.method', + type: 'keyword', + }, + 'zeek.rdp.done': { + category: 'zeek', + description: 'Track status of logging RDP connections. ', + name: 'zeek.rdp.done', + type: 'boolean', + }, + 'zeek.rdp.ssl': { + category: 'zeek', + description: + '(present if policy/protocols/rdp/indicate_ssl.bro is loaded) Flag the connection if it was seen over SSL. ', + name: 'zeek.rdp.ssl', + type: 'boolean', + }, + 'zeek.rfb.version.client.major': { + category: 'zeek', + description: 'Major version of the client. ', + name: 'zeek.rfb.version.client.major', + type: 'keyword', + }, + 'zeek.rfb.version.client.minor': { + category: 'zeek', + description: 'Minor version of the client. ', + name: 'zeek.rfb.version.client.minor', + type: 'keyword', + }, + 'zeek.rfb.version.server.major': { + category: 'zeek', + description: 'Major version of the server. ', + name: 'zeek.rfb.version.server.major', + type: 'keyword', + }, + 'zeek.rfb.version.server.minor': { + category: 'zeek', + description: 'Minor version of the server. ', + name: 'zeek.rfb.version.server.minor', + type: 'keyword', + }, + 'zeek.rfb.auth.success': { + category: 'zeek', + description: 'Whether or not authentication was successful. ', + name: 'zeek.rfb.auth.success', + type: 'boolean', + }, + 'zeek.rfb.auth.method': { + category: 'zeek', + description: 'Identifier of authentication method used. ', + name: 'zeek.rfb.auth.method', + type: 'keyword', + }, + 'zeek.rfb.share_flag': { + category: 'zeek', + description: 'Whether the client has an exclusive or a shared session. ', + name: 'zeek.rfb.share_flag', + type: 'boolean', + }, + 'zeek.rfb.desktop_name': { + category: 'zeek', + description: 'Name of the screen that is being shared. ', + name: 'zeek.rfb.desktop_name', + type: 'keyword', + }, + 'zeek.rfb.width': { + category: 'zeek', + description: 'Width of the screen that is being shared. ', + name: 'zeek.rfb.width', + type: 'integer', + }, + 'zeek.rfb.height': { + category: 'zeek', + description: 'Height of the screen that is being shared. ', + name: 'zeek.rfb.height', + type: 'integer', + }, + 'zeek.sip.transaction_depth': { + category: 'zeek', + description: + 'Represents the pipelined depth into the connection of this request/response transaction. ', + name: 'zeek.sip.transaction_depth', + type: 'integer', + }, + 'zeek.sip.sequence.method': { + category: 'zeek', + description: 'Verb used in the SIP request (INVITE, REGISTER etc.). ', + name: 'zeek.sip.sequence.method', + type: 'keyword', + }, + 'zeek.sip.sequence.number': { + category: 'zeek', + description: 'Contents of the CSeq: header from the client. ', + name: 'zeek.sip.sequence.number', + type: 'keyword', + }, + 'zeek.sip.uri': { + category: 'zeek', + description: 'URI used in the request. ', + name: 'zeek.sip.uri', + type: 'keyword', + }, + 'zeek.sip.date': { + category: 'zeek', + description: 'Contents of the Date: header from the client. ', + name: 'zeek.sip.date', + type: 'keyword', + }, + 'zeek.sip.request.from': { + category: 'zeek', + description: + "Contents of the request From: header Note: The tag= value that's usually appended to the sender is stripped off and not logged. ", + name: 'zeek.sip.request.from', + type: 'keyword', + }, + 'zeek.sip.request.to': { + category: 'zeek', + description: 'Contents of the To: header. ', + name: 'zeek.sip.request.to', + type: 'keyword', + }, + 'zeek.sip.request.path': { + category: 'zeek', + description: 'The client message transmission path, as extracted from the headers. ', + name: 'zeek.sip.request.path', + type: 'keyword', + }, + 'zeek.sip.request.body_length': { + category: 'zeek', + description: 'Contents of the Content-Length: header from the client. ', + name: 'zeek.sip.request.body_length', + type: 'long', + }, + 'zeek.sip.response.from': { + category: 'zeek', + description: + "Contents of the response From: header Note: The tag= value that's usually appended to the sender is stripped off and not logged. ", + name: 'zeek.sip.response.from', + type: 'keyword', + }, + 'zeek.sip.response.to': { + category: 'zeek', + description: 'Contents of the response To: header. ', + name: 'zeek.sip.response.to', + type: 'keyword', + }, + 'zeek.sip.response.path': { + category: 'zeek', + description: 'The server message transmission path, as extracted from the headers. ', + name: 'zeek.sip.response.path', + type: 'keyword', + }, + 'zeek.sip.response.body_length': { + category: 'zeek', + description: 'Contents of the Content-Length: header from the server. ', + name: 'zeek.sip.response.body_length', + type: 'long', + }, + 'zeek.sip.reply_to': { + category: 'zeek', + description: 'Contents of the Reply-To: header. ', + name: 'zeek.sip.reply_to', + type: 'keyword', + }, + 'zeek.sip.call_id': { + category: 'zeek', + description: 'Contents of the Call-ID: header from the client. ', + name: 'zeek.sip.call_id', + type: 'keyword', + }, + 'zeek.sip.subject': { + category: 'zeek', + description: 'Contents of the Subject: header from the client. ', + name: 'zeek.sip.subject', + type: 'keyword', + }, + 'zeek.sip.user_agent': { + category: 'zeek', + description: 'Contents of the User-Agent: header from the client. ', + name: 'zeek.sip.user_agent', + type: 'keyword', + }, + 'zeek.sip.status.code': { + category: 'zeek', + description: 'Status code returned by the server. ', + name: 'zeek.sip.status.code', + type: 'integer', + }, + 'zeek.sip.status.msg': { + category: 'zeek', + description: 'Status message returned by the server. ', + name: 'zeek.sip.status.msg', + type: 'keyword', + }, + 'zeek.sip.warning': { + category: 'zeek', + description: 'Contents of the Warning: header. ', + name: 'zeek.sip.warning', + type: 'keyword', + }, + 'zeek.sip.content_type': { + category: 'zeek', + description: 'Contents of the Content-Type: header from the server. ', + name: 'zeek.sip.content_type', + type: 'keyword', + }, + 'zeek.smb_cmd.command': { + category: 'zeek', + description: 'The command sent by the client. ', + name: 'zeek.smb_cmd.command', + type: 'keyword', + }, + 'zeek.smb_cmd.sub_command': { + category: 'zeek', + description: 'The subcommand sent by the client, if present. ', + name: 'zeek.smb_cmd.sub_command', + type: 'keyword', + }, + 'zeek.smb_cmd.argument': { + category: 'zeek', + description: 'Command argument sent by the client, if any. ', + name: 'zeek.smb_cmd.argument', + type: 'keyword', + }, + 'zeek.smb_cmd.status': { + category: 'zeek', + description: "Server reply to the client's command. ", + name: 'zeek.smb_cmd.status', + type: 'keyword', + }, + 'zeek.smb_cmd.rtt': { + category: 'zeek', + description: 'Round trip time from the request to the response. ', + name: 'zeek.smb_cmd.rtt', + type: 'double', + }, + 'zeek.smb_cmd.version': { + category: 'zeek', + description: 'Version of SMB for the command. ', + name: 'zeek.smb_cmd.version', + type: 'keyword', + }, + 'zeek.smb_cmd.username': { + category: 'zeek', + description: 'Authenticated username, if available. ', + name: 'zeek.smb_cmd.username', + type: 'keyword', + }, + 'zeek.smb_cmd.tree': { + category: 'zeek', + description: + 'If this is related to a tree, this is the tree that was used for the current command. ', + name: 'zeek.smb_cmd.tree', + type: 'keyword', + }, + 'zeek.smb_cmd.tree_service': { + category: 'zeek', + description: 'The type of tree (disk share, printer share, named pipe, etc.). ', + name: 'zeek.smb_cmd.tree_service', + type: 'keyword', + }, + 'zeek.smb_cmd.file.name': { + category: 'zeek', + description: 'Filename if one was seen. ', + name: 'zeek.smb_cmd.file.name', + type: 'keyword', + }, + 'zeek.smb_cmd.file.action': { + category: 'zeek', + description: 'Action this log record represents. ', + name: 'zeek.smb_cmd.file.action', + type: 'keyword', + }, + 'zeek.smb_cmd.file.uid': { + category: 'zeek', + description: 'UID of the referenced file. ', + name: 'zeek.smb_cmd.file.uid', + type: 'keyword', + }, + 'zeek.smb_cmd.file.host.tx': { + category: 'zeek', + description: 'Address of the transmitting host. ', + name: 'zeek.smb_cmd.file.host.tx', + type: 'ip', + }, + 'zeek.smb_cmd.file.host.rx': { + category: 'zeek', + description: 'Address of the receiving host. ', + name: 'zeek.smb_cmd.file.host.rx', + type: 'ip', + }, + 'zeek.smb_cmd.smb1_offered_dialects': { + category: 'zeek', + description: + 'Present if base/protocols/smb/smb1-main.bro is loaded. Dialects offered by the client. ', + name: 'zeek.smb_cmd.smb1_offered_dialects', + type: 'keyword', + }, + 'zeek.smb_cmd.smb2_offered_dialects': { + category: 'zeek', + description: + 'Present if base/protocols/smb/smb2-main.bro is loaded. Dialects offered by the client. ', + name: 'zeek.smb_cmd.smb2_offered_dialects', + type: 'integer', + }, + 'zeek.smb_files.action': { + category: 'zeek', + description: 'Action this log record represents. ', + name: 'zeek.smb_files.action', + type: 'keyword', + }, + 'zeek.smb_files.fid': { + category: 'zeek', + description: 'ID referencing this file. ', + name: 'zeek.smb_files.fid', + type: 'integer', + }, + 'zeek.smb_files.name': { + category: 'zeek', + description: 'Filename if one was seen. ', + name: 'zeek.smb_files.name', + type: 'keyword', + }, + 'zeek.smb_files.path': { + category: 'zeek', + description: 'Path pulled from the tree this file was transferred to or from. ', + name: 'zeek.smb_files.path', + type: 'keyword', + }, + 'zeek.smb_files.previous_name': { + category: 'zeek', + description: "If the rename action was seen, this will be the file's previous name. ", + name: 'zeek.smb_files.previous_name', + type: 'keyword', + }, + 'zeek.smb_files.size': { + category: 'zeek', + description: 'Byte size of the file. ', + name: 'zeek.smb_files.size', + type: 'long', + }, + 'zeek.smb_files.times.accessed': { + category: 'zeek', + description: "The file's access time. ", + name: 'zeek.smb_files.times.accessed', + type: 'date', + }, + 'zeek.smb_files.times.changed': { + category: 'zeek', + description: "The file's change time. ", + name: 'zeek.smb_files.times.changed', + type: 'date', + }, + 'zeek.smb_files.times.created': { + category: 'zeek', + description: "The file's create time. ", + name: 'zeek.smb_files.times.created', + type: 'date', + }, + 'zeek.smb_files.times.modified': { + category: 'zeek', + description: "The file's modify time. ", + name: 'zeek.smb_files.times.modified', + type: 'date', + }, + 'zeek.smb_files.uuid': { + category: 'zeek', + description: 'UUID referencing this file if DCE/RPC. ', + name: 'zeek.smb_files.uuid', + type: 'keyword', + }, + 'zeek.smb_mapping.path': { + category: 'zeek', + description: 'Name of the tree path. ', + name: 'zeek.smb_mapping.path', + type: 'keyword', + }, + 'zeek.smb_mapping.service': { + category: 'zeek', + description: 'The type of resource of the tree (disk share, printer share, named pipe, etc.). ', + name: 'zeek.smb_mapping.service', + type: 'keyword', + }, + 'zeek.smb_mapping.native_file_system': { + category: 'zeek', + description: 'File system of the tree. ', + name: 'zeek.smb_mapping.native_file_system', + type: 'keyword', + }, + 'zeek.smb_mapping.share_type': { + category: 'zeek', + description: + 'If this is SMB2, a share type will be included. For SMB1, the type of share will be deduced and included as well. ', + name: 'zeek.smb_mapping.share_type', + type: 'keyword', + }, + 'zeek.smtp.transaction_depth': { + category: 'zeek', + description: + 'A count to represent the depth of this message transaction in a single connection where multiple messages were transferred. ', + name: 'zeek.smtp.transaction_depth', + type: 'integer', + }, + 'zeek.smtp.helo': { + category: 'zeek', + description: 'Contents of the Helo header. ', + name: 'zeek.smtp.helo', + type: 'keyword', + }, + 'zeek.smtp.mail_from': { + category: 'zeek', + description: 'Email addresses found in the MAIL FROM header. ', + name: 'zeek.smtp.mail_from', + type: 'keyword', + }, + 'zeek.smtp.rcpt_to': { + category: 'zeek', + description: 'Email addresses found in the RCPT TO header. ', + name: 'zeek.smtp.rcpt_to', + type: 'keyword', + }, + 'zeek.smtp.date': { + category: 'zeek', + description: 'Contents of the Date header. ', + name: 'zeek.smtp.date', + type: 'date', + }, + 'zeek.smtp.from': { + category: 'zeek', + description: 'Contents of the From header. ', + name: 'zeek.smtp.from', + type: 'keyword', + }, + 'zeek.smtp.to': { + category: 'zeek', + description: 'Contents of the To header. ', + name: 'zeek.smtp.to', + type: 'keyword', + }, + 'zeek.smtp.cc': { + category: 'zeek', + description: 'Contents of the CC header. ', + name: 'zeek.smtp.cc', + type: 'keyword', + }, + 'zeek.smtp.reply_to': { + category: 'zeek', + description: 'Contents of the ReplyTo header. ', + name: 'zeek.smtp.reply_to', + type: 'keyword', + }, + 'zeek.smtp.msg_id': { + category: 'zeek', + description: 'Contents of the MsgID header. ', + name: 'zeek.smtp.msg_id', + type: 'keyword', + }, + 'zeek.smtp.in_reply_to': { + category: 'zeek', + description: 'Contents of the In-Reply-To header. ', + name: 'zeek.smtp.in_reply_to', + type: 'keyword', + }, + 'zeek.smtp.subject': { + category: 'zeek', + description: 'Contents of the Subject header. ', + name: 'zeek.smtp.subject', + type: 'keyword', + }, + 'zeek.smtp.x_originating_ip': { + category: 'zeek', + description: 'Contents of the X-Originating-IP header. ', + name: 'zeek.smtp.x_originating_ip', + type: 'keyword', + }, + 'zeek.smtp.first_received': { + category: 'zeek', + description: 'Contents of the first Received header. ', + name: 'zeek.smtp.first_received', + type: 'keyword', + }, + 'zeek.smtp.second_received': { + category: 'zeek', + description: 'Contents of the second Received header. ', + name: 'zeek.smtp.second_received', + type: 'keyword', + }, + 'zeek.smtp.last_reply': { + category: 'zeek', + description: 'The last message that the server sent to the client. ', + name: 'zeek.smtp.last_reply', + type: 'keyword', + }, + 'zeek.smtp.path': { + category: 'zeek', + description: 'The message transmission path, as extracted from the headers. ', + name: 'zeek.smtp.path', + type: 'ip', + }, + 'zeek.smtp.user_agent': { + category: 'zeek', + description: 'Value of the User-Agent header from the client. ', + name: 'zeek.smtp.user_agent', + type: 'keyword', + }, + 'zeek.smtp.tls': { + category: 'zeek', + description: 'Indicates that the connection has switched to using TLS. ', + name: 'zeek.smtp.tls', + type: 'boolean', + }, + 'zeek.smtp.process_received_from': { + category: 'zeek', + description: 'Indicates if the "Received: from" headers should still be processed. ', + name: 'zeek.smtp.process_received_from', + type: 'boolean', + }, + 'zeek.smtp.has_client_activity': { + category: 'zeek', + description: 'Indicates if client activity has been seen, but not yet logged. ', + name: 'zeek.smtp.has_client_activity', + type: 'boolean', + }, + 'zeek.smtp.fuids': { + category: 'zeek', + description: + '(present if base/protocols/smtp/files.bro is loaded) An ordered vector of file unique IDs seen attached to the message. ', + name: 'zeek.smtp.fuids', + type: 'keyword', + }, + 'zeek.smtp.is_webmail': { + category: 'zeek', + description: 'Indicates if the message was sent through a webmail interface. ', + name: 'zeek.smtp.is_webmail', + type: 'boolean', + }, + 'zeek.snmp.duration': { + category: 'zeek', + description: + 'The amount of time between the first packet beloning to the SNMP session and the latest one seen. ', + name: 'zeek.snmp.duration', + type: 'double', + }, + 'zeek.snmp.version': { + category: 'zeek', + description: 'The version of SNMP being used. ', + name: 'zeek.snmp.version', + type: 'keyword', + }, + 'zeek.snmp.community': { + category: 'zeek', + description: + "The community string of the first SNMP packet associated with the session. This is used as part of SNMP's (v1 and v2c) administrative/security framework. See RFC 1157 or RFC 1901. ", + name: 'zeek.snmp.community', + type: 'keyword', + }, + 'zeek.snmp.get.requests': { + category: 'zeek', + description: + 'The number of variable bindings in GetRequest/GetNextRequest PDUs seen for the session. ', + name: 'zeek.snmp.get.requests', + type: 'integer', + }, + 'zeek.snmp.get.bulk_requests': { + category: 'zeek', + description: 'The number of variable bindings in GetBulkRequest PDUs seen for the session. ', + name: 'zeek.snmp.get.bulk_requests', + type: 'integer', + }, + 'zeek.snmp.get.responses': { + category: 'zeek', + description: + 'The number of variable bindings in GetResponse/Response PDUs seen for the session. ', + name: 'zeek.snmp.get.responses', + type: 'integer', + }, + 'zeek.snmp.set.requests': { + category: 'zeek', + description: 'The number of variable bindings in SetRequest PDUs seen for the session. ', + name: 'zeek.snmp.set.requests', + type: 'integer', + }, + 'zeek.snmp.display_string': { + category: 'zeek', + description: 'A system description of the SNMP responder endpoint. ', + name: 'zeek.snmp.display_string', + type: 'keyword', + }, + 'zeek.snmp.up_since': { + category: 'zeek', + description: "The time at which the SNMP responder endpoint claims it's been up since. ", + name: 'zeek.snmp.up_since', + type: 'date', + }, + 'zeek.socks.version': { + category: 'zeek', + description: 'Protocol version of SOCKS. ', + name: 'zeek.socks.version', + type: 'integer', + }, + 'zeek.socks.user': { + category: 'zeek', + description: 'Username used to request a login to the proxy. ', + name: 'zeek.socks.user', + type: 'keyword', + }, + 'zeek.socks.password': { + category: 'zeek', + description: 'Password used to request a login to the proxy. ', + name: 'zeek.socks.password', + type: 'keyword', + }, + 'zeek.socks.status': { + category: 'zeek', + description: 'Server status for the attempt at using the proxy. ', + name: 'zeek.socks.status', + type: 'keyword', + }, + 'zeek.socks.request.host': { + category: 'zeek', + description: 'Client requested SOCKS address. Could be an address, a name or both. ', + name: 'zeek.socks.request.host', + type: 'keyword', + }, + 'zeek.socks.request.port': { + category: 'zeek', + description: 'Client requested port. ', + name: 'zeek.socks.request.port', + type: 'integer', + }, + 'zeek.socks.bound.host': { + category: 'zeek', + description: 'Server bound address. Could be an address, a name or both. ', + name: 'zeek.socks.bound.host', + type: 'keyword', + }, + 'zeek.socks.bound.port': { + category: 'zeek', + description: 'Server bound port. ', + name: 'zeek.socks.bound.port', + type: 'integer', + }, + 'zeek.socks.capture_password': { + category: 'zeek', + description: 'Determines if the password will be captured for this request. ', + name: 'zeek.socks.capture_password', + type: 'boolean', + }, + 'zeek.ssh.client': { + category: 'zeek', + description: "The client's version string. ", + name: 'zeek.ssh.client', + type: 'keyword', + }, + 'zeek.ssh.direction': { + category: 'zeek', + description: + 'Direction of the connection. If the client was a local host logging into an external host, this would be OUTBOUND. INBOUND would be set for the opposite situation. ', + name: 'zeek.ssh.direction', + type: 'keyword', + }, + 'zeek.ssh.host_key': { + category: 'zeek', + description: "The server's key thumbprint. ", + name: 'zeek.ssh.host_key', + type: 'keyword', + }, + 'zeek.ssh.server': { + category: 'zeek', + description: "The server's version string. ", + name: 'zeek.ssh.server', + type: 'keyword', + }, + 'zeek.ssh.version': { + category: 'zeek', + description: 'SSH major version (1 or 2). ', + name: 'zeek.ssh.version', + type: 'integer', + }, + 'zeek.ssh.algorithm.cipher': { + category: 'zeek', + description: 'The encryption algorithm in use. ', + name: 'zeek.ssh.algorithm.cipher', + type: 'keyword', + }, + 'zeek.ssh.algorithm.compression': { + category: 'zeek', + description: 'The compression algorithm in use. ', + name: 'zeek.ssh.algorithm.compression', + type: 'keyword', + }, + 'zeek.ssh.algorithm.host_key': { + category: 'zeek', + description: "The server host key's algorithm. ", + name: 'zeek.ssh.algorithm.host_key', + type: 'keyword', + }, + 'zeek.ssh.algorithm.key_exchange': { + category: 'zeek', + description: 'The key exchange algorithm in use. ', + name: 'zeek.ssh.algorithm.key_exchange', + type: 'keyword', + }, + 'zeek.ssh.algorithm.mac': { + category: 'zeek', + description: 'The signing (MAC) algorithm in use. ', + name: 'zeek.ssh.algorithm.mac', + type: 'keyword', + }, + 'zeek.ssh.auth.attempts': { + category: 'zeek', + description: + "The number of authentication attemps we observed. There's always at least one, since some servers might support no authentication at all. It's important to note that not all of these are failures, since some servers require two-factor auth (e.g. password AND pubkey). ", + name: 'zeek.ssh.auth.attempts', + type: 'integer', + }, + 'zeek.ssh.auth.success': { + category: 'zeek', + description: 'Authentication result. ', + name: 'zeek.ssh.auth.success', + type: 'boolean', + }, + 'zeek.ssl.version': { + category: 'zeek', + description: 'SSL/TLS version that was logged. ', + name: 'zeek.ssl.version', + type: 'keyword', + }, + 'zeek.ssl.cipher': { + category: 'zeek', + description: 'SSL/TLS cipher suite that was logged. ', + name: 'zeek.ssl.cipher', + type: 'keyword', + }, + 'zeek.ssl.curve': { + category: 'zeek', + description: 'Elliptic curve that was logged when using ECDH/ECDHE. ', + name: 'zeek.ssl.curve', + type: 'keyword', + }, + 'zeek.ssl.resumed': { + category: 'zeek', + description: + 'Flag to indicate if the session was resumed reusing the key material exchanged in an earlier connection. ', + name: 'zeek.ssl.resumed', + type: 'boolean', + }, + 'zeek.ssl.next_protocol': { + category: 'zeek', + description: + 'Next protocol the server chose using the application layer next protocol extension. ', + name: 'zeek.ssl.next_protocol', + type: 'keyword', + }, + 'zeek.ssl.established': { + category: 'zeek', + description: 'Flag to indicate if this ssl session has been established successfully. ', + name: 'zeek.ssl.established', + type: 'boolean', + }, + 'zeek.ssl.validation.status': { + category: 'zeek', + description: 'Result of certificate validation for this connection. ', + name: 'zeek.ssl.validation.status', + type: 'keyword', + }, + 'zeek.ssl.validation.code': { + category: 'zeek', + description: + 'Result of certificate validation for this connection, given as OpenSSL validation code. ', + name: 'zeek.ssl.validation.code', + type: 'keyword', + }, + 'zeek.ssl.last_alert': { + category: 'zeek', + description: 'Last alert that was seen during the connection. ', + name: 'zeek.ssl.last_alert', + type: 'keyword', + }, + 'zeek.ssl.server.name': { + category: 'zeek', + description: + 'Value of the Server Name Indicator SSL/TLS extension. It indicates the server name that the client was requesting. ', + name: 'zeek.ssl.server.name', + type: 'keyword', + }, + 'zeek.ssl.server.cert_chain': { + category: 'zeek', + description: + 'Chain of certificates offered by the server to validate its complete signing chain. ', + name: 'zeek.ssl.server.cert_chain', + type: 'keyword', + }, + 'zeek.ssl.server.cert_chain_fuids': { + category: 'zeek', + description: + 'An ordered vector of certificate file identifiers for the certificates offered by the server. ', + name: 'zeek.ssl.server.cert_chain_fuids', + type: 'keyword', + }, + 'zeek.ssl.server.issuer.common_name': { + category: 'zeek', + description: 'Common name of the signer of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.issuer.common_name', + type: 'keyword', + }, + 'zeek.ssl.server.issuer.country': { + category: 'zeek', + description: 'Country code of the signer of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.issuer.country', + type: 'keyword', + }, + 'zeek.ssl.server.issuer.locality': { + category: 'zeek', + description: 'Locality of the signer of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.issuer.locality', + type: 'keyword', + }, + 'zeek.ssl.server.issuer.organization': { + category: 'zeek', + description: 'Organization of the signer of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.issuer.organization', + type: 'keyword', + }, + 'zeek.ssl.server.issuer.organizational_unit': { + category: 'zeek', + description: + 'Organizational unit of the signer of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.issuer.organizational_unit', + type: 'keyword', + }, + 'zeek.ssl.server.issuer.state': { + category: 'zeek', + description: + 'State or province name of the signer of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.issuer.state', + type: 'keyword', + }, + 'zeek.ssl.server.subject.common_name': { + category: 'zeek', + description: 'Common name of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.subject.common_name', + type: 'keyword', + }, + 'zeek.ssl.server.subject.country': { + category: 'zeek', + description: 'Country code of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.subject.country', + type: 'keyword', + }, + 'zeek.ssl.server.subject.locality': { + category: 'zeek', + description: 'Locality of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.subject.locality', + type: 'keyword', + }, + 'zeek.ssl.server.subject.organization': { + category: 'zeek', + description: 'Organization of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.subject.organization', + type: 'keyword', + }, + 'zeek.ssl.server.subject.organizational_unit': { + category: 'zeek', + description: 'Organizational unit of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.subject.organizational_unit', + type: 'keyword', + }, + 'zeek.ssl.server.subject.state': { + category: 'zeek', + description: 'State or province name of the X.509 certificate offered by the server. ', + name: 'zeek.ssl.server.subject.state', + type: 'keyword', + }, + 'zeek.ssl.client.cert_chain': { + category: 'zeek', + description: + 'Chain of certificates offered by the client to validate its complete signing chain. ', + name: 'zeek.ssl.client.cert_chain', + type: 'keyword', + }, + 'zeek.ssl.client.cert_chain_fuids': { + category: 'zeek', + description: + 'An ordered vector of certificate file identifiers for the certificates offered by the client. ', + name: 'zeek.ssl.client.cert_chain_fuids', + type: 'keyword', + }, + 'zeek.ssl.client.issuer.common_name': { + category: 'zeek', + description: 'Common name of the signer of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.issuer.common_name', + type: 'keyword', + }, + 'zeek.ssl.client.issuer.country': { + category: 'zeek', + description: 'Country code of the signer of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.issuer.country', + type: 'keyword', + }, + 'zeek.ssl.client.issuer.locality': { + category: 'zeek', + description: 'Locality of the signer of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.issuer.locality', + type: 'keyword', + }, + 'zeek.ssl.client.issuer.organization': { + category: 'zeek', + description: 'Organization of the signer of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.issuer.organization', + type: 'keyword', + }, + 'zeek.ssl.client.issuer.organizational_unit': { + category: 'zeek', + description: + 'Organizational unit of the signer of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.issuer.organizational_unit', + type: 'keyword', + }, + 'zeek.ssl.client.issuer.state': { + category: 'zeek', + description: + 'State or province name of the signer of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.issuer.state', + type: 'keyword', + }, + 'zeek.ssl.client.subject.common_name': { + category: 'zeek', + description: 'Common name of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.subject.common_name', + type: 'keyword', + }, + 'zeek.ssl.client.subject.country': { + category: 'zeek', + description: 'Country code of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.subject.country', + type: 'keyword', + }, + 'zeek.ssl.client.subject.locality': { + category: 'zeek', + description: 'Locality of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.subject.locality', + type: 'keyword', + }, + 'zeek.ssl.client.subject.organization': { + category: 'zeek', + description: 'Organization of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.subject.organization', + type: 'keyword', + }, + 'zeek.ssl.client.subject.organizational_unit': { + category: 'zeek', + description: 'Organizational unit of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.subject.organizational_unit', + type: 'keyword', + }, + 'zeek.ssl.client.subject.state': { + category: 'zeek', + description: 'State or province name of the X.509 certificate offered by the client. ', + name: 'zeek.ssl.client.subject.state', + type: 'keyword', + }, + 'zeek.stats.peer': { + category: 'zeek', + description: 'Peer that generated this log. Mostly for clusters. ', + name: 'zeek.stats.peer', + type: 'keyword', + }, + 'zeek.stats.memory': { + category: 'zeek', + description: 'Amount of memory currently in use in MB. ', + name: 'zeek.stats.memory', + type: 'integer', + }, + 'zeek.stats.packets.processed': { + category: 'zeek', + description: 'Number of packets processed since the last stats interval. ', + name: 'zeek.stats.packets.processed', + type: 'long', + }, + 'zeek.stats.packets.dropped': { + category: 'zeek', + description: + 'Number of packets dropped since the last stats interval if reading live traffic. ', + name: 'zeek.stats.packets.dropped', + type: 'long', + }, + 'zeek.stats.packets.received': { + category: 'zeek', + description: + 'Number of packets seen on the link since the last stats interval if reading live traffic. ', + name: 'zeek.stats.packets.received', + type: 'long', + }, + 'zeek.stats.bytes.received': { + category: 'zeek', + description: 'Number of bytes received since the last stats interval if reading live traffic. ', + name: 'zeek.stats.bytes.received', + type: 'long', + }, + 'zeek.stats.connections.tcp.active': { + category: 'zeek', + description: 'TCP connections currently in memory. ', + name: 'zeek.stats.connections.tcp.active', + type: 'integer', + }, + 'zeek.stats.connections.tcp.count': { + category: 'zeek', + description: 'TCP connections seen since last stats interval. ', + name: 'zeek.stats.connections.tcp.count', + type: 'integer', + }, + 'zeek.stats.connections.udp.active': { + category: 'zeek', + description: 'UDP connections currently in memory. ', + name: 'zeek.stats.connections.udp.active', + type: 'integer', + }, + 'zeek.stats.connections.udp.count': { + category: 'zeek', + description: 'UDP connections seen since last stats interval. ', + name: 'zeek.stats.connections.udp.count', + type: 'integer', + }, + 'zeek.stats.connections.icmp.active': { + category: 'zeek', + description: 'ICMP connections currently in memory. ', + name: 'zeek.stats.connections.icmp.active', + type: 'integer', + }, + 'zeek.stats.connections.icmp.count': { + category: 'zeek', + description: 'ICMP connections seen since last stats interval. ', + name: 'zeek.stats.connections.icmp.count', + type: 'integer', + }, + 'zeek.stats.events.processed': { + category: 'zeek', + description: 'Number of events processed since the last stats interval. ', + name: 'zeek.stats.events.processed', + type: 'integer', + }, + 'zeek.stats.events.queued': { + category: 'zeek', + description: 'Number of events that have been queued since the last stats interval. ', + name: 'zeek.stats.events.queued', + type: 'integer', + }, + 'zeek.stats.timers.count': { + category: 'zeek', + description: 'Number of timers scheduled since last stats interval. ', + name: 'zeek.stats.timers.count', + type: 'integer', + }, + 'zeek.stats.timers.active': { + category: 'zeek', + description: 'Current number of scheduled timers. ', + name: 'zeek.stats.timers.active', + type: 'integer', + }, + 'zeek.stats.files.count': { + category: 'zeek', + description: 'Number of files seen since last stats interval. ', + name: 'zeek.stats.files.count', + type: 'integer', + }, + 'zeek.stats.files.active': { + category: 'zeek', + description: 'Current number of files actively being seen. ', + name: 'zeek.stats.files.active', + type: 'integer', + }, + 'zeek.stats.dns_requests.count': { + category: 'zeek', + description: 'Number of DNS requests seen since last stats interval. ', + name: 'zeek.stats.dns_requests.count', + type: 'integer', + }, + 'zeek.stats.dns_requests.active': { + category: 'zeek', + description: 'Current number of DNS requests awaiting a reply. ', + name: 'zeek.stats.dns_requests.active', + type: 'integer', + }, + 'zeek.stats.reassembly_size.tcp': { + category: 'zeek', + description: 'Current size of TCP data in reassembly. ', + name: 'zeek.stats.reassembly_size.tcp', + type: 'integer', + }, + 'zeek.stats.reassembly_size.file': { + category: 'zeek', + description: 'Current size of File data in reassembly. ', + name: 'zeek.stats.reassembly_size.file', + type: 'integer', + }, + 'zeek.stats.reassembly_size.frag': { + category: 'zeek', + description: 'Current size of packet fragment data in reassembly. ', + name: 'zeek.stats.reassembly_size.frag', + type: 'integer', + }, + 'zeek.stats.reassembly_size.unknown': { + category: 'zeek', + description: 'Current size of unknown data in reassembly (this is only PIA buffer right now). ', + name: 'zeek.stats.reassembly_size.unknown', + type: 'integer', + }, + 'zeek.stats.timestamp_lag': { + category: 'zeek', + description: 'Lag between the wall clock and packet timestamps if reading live traffic. ', + name: 'zeek.stats.timestamp_lag', + type: 'integer', + }, + 'zeek.syslog.facility': { + category: 'zeek', + description: 'Syslog facility for the message. ', + name: 'zeek.syslog.facility', + type: 'keyword', + }, + 'zeek.syslog.severity': { + category: 'zeek', + description: 'Syslog severity for the message. ', + name: 'zeek.syslog.severity', + type: 'keyword', + }, + 'zeek.syslog.message': { + category: 'zeek', + description: 'The plain text message. ', + name: 'zeek.syslog.message', + type: 'keyword', + }, + 'zeek.tunnel.type': { + category: 'zeek', + description: 'The type of tunnel. ', + name: 'zeek.tunnel.type', + type: 'keyword', + }, + 'zeek.tunnel.action': { + category: 'zeek', + description: 'The type of activity that occurred. ', + name: 'zeek.tunnel.action', + type: 'keyword', + }, + 'zeek.weird.name': { + category: 'zeek', + description: 'The name of the weird that occurred. ', + name: 'zeek.weird.name', + type: 'keyword', + }, + 'zeek.weird.additional_info': { + category: 'zeek', + description: 'Additional information accompanying the weird if any. ', + name: 'zeek.weird.additional_info', + type: 'keyword', + }, + 'zeek.weird.notice': { + category: 'zeek', + description: 'Indicate if this weird was also turned into a notice. ', + name: 'zeek.weird.notice', + type: 'boolean', + }, + 'zeek.weird.peer': { + category: 'zeek', + description: + 'The peer that originated this weird. This is helpful in cluster deployments if a particular cluster node is having trouble to help identify which node is having trouble. ', + name: 'zeek.weird.peer', + type: 'keyword', + }, + 'zeek.weird.identifier': { + category: 'zeek', + description: + 'This field is to be provided when a weird is generated for the purpose of deduplicating weirds. The identifier string should be unique for a single instance of the weird. This field is used to define when a weird is conceptually a duplicate of a previous weird. ', + name: 'zeek.weird.identifier', + type: 'keyword', + }, + 'zeek.x509.id': { + category: 'zeek', + description: 'File id of this certificate. ', + name: 'zeek.x509.id', + type: 'keyword', + }, + 'zeek.x509.certificate.version': { + category: 'zeek', + description: 'Version number. ', + name: 'zeek.x509.certificate.version', + type: 'integer', + }, + 'zeek.x509.certificate.serial': { + category: 'zeek', + description: 'Serial number. ', + name: 'zeek.x509.certificate.serial', + type: 'keyword', + }, + 'zeek.x509.certificate.subject.country': { + category: 'zeek', + description: 'Country provided in the certificate subject. ', + name: 'zeek.x509.certificate.subject.country', + type: 'keyword', + }, + 'zeek.x509.certificate.subject.common_name': { + category: 'zeek', + description: 'Common name provided in the certificate subject. ', + name: 'zeek.x509.certificate.subject.common_name', + type: 'keyword', + }, + 'zeek.x509.certificate.subject.locality': { + category: 'zeek', + description: 'Locality provided in the certificate subject. ', + name: 'zeek.x509.certificate.subject.locality', + type: 'keyword', + }, + 'zeek.x509.certificate.subject.organization': { + category: 'zeek', + description: 'Organization provided in the certificate subject. ', + name: 'zeek.x509.certificate.subject.organization', + type: 'keyword', + }, + 'zeek.x509.certificate.subject.organizational_unit': { + category: 'zeek', + description: 'Organizational unit provided in the certificate subject. ', + name: 'zeek.x509.certificate.subject.organizational_unit', + type: 'keyword', + }, + 'zeek.x509.certificate.subject.state': { + category: 'zeek', + description: 'State or province provided in the certificate subject. ', + name: 'zeek.x509.certificate.subject.state', + type: 'keyword', + }, + 'zeek.x509.certificate.issuer.country': { + category: 'zeek', + description: 'Country provided in the certificate issuer field. ', + name: 'zeek.x509.certificate.issuer.country', + type: 'keyword', + }, + 'zeek.x509.certificate.issuer.common_name': { + category: 'zeek', + description: 'Common name provided in the certificate issuer field. ', + name: 'zeek.x509.certificate.issuer.common_name', + type: 'keyword', + }, + 'zeek.x509.certificate.issuer.locality': { + category: 'zeek', + description: 'Locality provided in the certificate issuer field. ', + name: 'zeek.x509.certificate.issuer.locality', + type: 'keyword', + }, + 'zeek.x509.certificate.issuer.organization': { + category: 'zeek', + description: 'Organization provided in the certificate issuer field. ', + name: 'zeek.x509.certificate.issuer.organization', + type: 'keyword', + }, + 'zeek.x509.certificate.issuer.organizational_unit': { + category: 'zeek', + description: 'Organizational unit provided in the certificate issuer field. ', + name: 'zeek.x509.certificate.issuer.organizational_unit', + type: 'keyword', + }, + 'zeek.x509.certificate.issuer.state': { + category: 'zeek', + description: 'State or province provided in the certificate issuer field. ', + name: 'zeek.x509.certificate.issuer.state', + type: 'keyword', + }, + 'zeek.x509.certificate.common_name': { + category: 'zeek', + description: 'Last (most specific) common name. ', + name: 'zeek.x509.certificate.common_name', + type: 'keyword', + }, + 'zeek.x509.certificate.valid.from': { + category: 'zeek', + description: 'Timestamp before when certificate is not valid. ', + name: 'zeek.x509.certificate.valid.from', + type: 'date', + }, + 'zeek.x509.certificate.valid.until': { + category: 'zeek', + description: 'Timestamp after when certificate is not valid. ', + name: 'zeek.x509.certificate.valid.until', + type: 'date', + }, + 'zeek.x509.certificate.key.algorithm': { + category: 'zeek', + description: 'Name of the key algorithm. ', + name: 'zeek.x509.certificate.key.algorithm', + type: 'keyword', + }, + 'zeek.x509.certificate.key.type': { + category: 'zeek', + description: 'Key type, if key parseable by openssl (either rsa, dsa or ec). ', + name: 'zeek.x509.certificate.key.type', + type: 'keyword', + }, + 'zeek.x509.certificate.key.length': { + category: 'zeek', + description: 'Key length in bits. ', + name: 'zeek.x509.certificate.key.length', + type: 'integer', + }, + 'zeek.x509.certificate.signature_algorithm': { + category: 'zeek', + description: 'Name of the signature algorithm. ', + name: 'zeek.x509.certificate.signature_algorithm', + type: 'keyword', + }, + 'zeek.x509.certificate.exponent': { + category: 'zeek', + description: 'Exponent, if RSA-certificate. ', + name: 'zeek.x509.certificate.exponent', + type: 'keyword', + }, + 'zeek.x509.certificate.curve': { + category: 'zeek', + description: 'Curve, if EC-certificate. ', + name: 'zeek.x509.certificate.curve', + type: 'keyword', + }, + 'zeek.x509.san.dns': { + category: 'zeek', + description: 'List of DNS entries in SAN. ', + name: 'zeek.x509.san.dns', + type: 'keyword', + }, + 'zeek.x509.san.uri': { + category: 'zeek', + description: 'List of URI entries in SAN. ', + name: 'zeek.x509.san.uri', + type: 'keyword', + }, + 'zeek.x509.san.email': { + category: 'zeek', + description: 'List of email entries in SAN. ', + name: 'zeek.x509.san.email', + type: 'keyword', + }, + 'zeek.x509.san.ip': { + category: 'zeek', + description: 'List of IP entries in SAN. ', + name: 'zeek.x509.san.ip', + type: 'ip', + }, + 'zeek.x509.san.other_fields': { + category: 'zeek', + description: 'True if the certificate contained other, not recognized or parsed name fields. ', + name: 'zeek.x509.san.other_fields', + type: 'boolean', + }, + 'zeek.x509.basic_constraints.certificate_authority': { + category: 'zeek', + description: 'CA flag set or not. ', + name: 'zeek.x509.basic_constraints.certificate_authority', + type: 'boolean', + }, + 'zeek.x509.basic_constraints.path_length': { + category: 'zeek', + description: 'Maximum path length. ', + name: 'zeek.x509.basic_constraints.path_length', + type: 'integer', + }, + 'zeek.x509.log_cert': { + category: 'zeek', + description: + 'Present if policy/protocols/ssl/log-hostcerts-only.bro is loaded Logging of certificate is suppressed if set to F. ', + name: 'zeek.x509.log_cert', + type: 'boolean', + }, + 'awscloudwatch.log_group': { + category: 'awscloudwatch', + description: 'The name of the log group to which this event belongs.', + name: 'awscloudwatch.log_group', + type: 'keyword', + }, + 'awscloudwatch.log_stream': { + category: 'awscloudwatch', + description: 'The name of the log stream to which this event belongs.', + name: 'awscloudwatch.log_stream', + type: 'keyword', + }, + 'awscloudwatch.ingestion_time': { + category: 'awscloudwatch', + description: 'The time the event was ingested in AWS CloudWatch.', + name: 'awscloudwatch.ingestion_time', + type: 'keyword', + }, + 'netflow.type': { + category: 'netflow', + description: 'The type of NetFlow record described by this event. ', + name: 'netflow.type', + type: 'keyword', + }, + 'netflow.exporter.address': { + category: 'netflow', + description: "Exporter's network address in IP:port format. ", + name: 'netflow.exporter.address', + type: 'keyword', + }, + 'netflow.exporter.source_id': { + category: 'netflow', + description: 'Observation domain ID to which this record belongs. ', + name: 'netflow.exporter.source_id', + type: 'long', + }, + 'netflow.exporter.timestamp': { + category: 'netflow', + description: 'Time and date of export. ', + name: 'netflow.exporter.timestamp', + type: 'date', + }, + 'netflow.exporter.uptime_millis': { + category: 'netflow', + description: 'How long the exporter process has been running, in milliseconds. ', + name: 'netflow.exporter.uptime_millis', + type: 'long', + }, + 'netflow.exporter.version': { + category: 'netflow', + description: 'NetFlow version used. ', + name: 'netflow.exporter.version', + type: 'integer', + }, + 'netflow.octet_delta_count': { + category: 'netflow', + name: 'netflow.octet_delta_count', + type: 'long', + }, + 'netflow.packet_delta_count': { + category: 'netflow', + name: 'netflow.packet_delta_count', + type: 'long', + }, + 'netflow.delta_flow_count': { + category: 'netflow', + name: 'netflow.delta_flow_count', + type: 'long', + }, + 'netflow.protocol_identifier': { + category: 'netflow', + name: 'netflow.protocol_identifier', + type: 'short', + }, + 'netflow.ip_class_of_service': { + category: 'netflow', + name: 'netflow.ip_class_of_service', + type: 'short', + }, + 'netflow.tcp_control_bits': { + category: 'netflow', + name: 'netflow.tcp_control_bits', + type: 'integer', + }, + 'netflow.source_transport_port': { + category: 'netflow', + name: 'netflow.source_transport_port', + type: 'integer', + }, + 'netflow.source_ipv4_address': { + category: 'netflow', + name: 'netflow.source_ipv4_address', + type: 'ip', + }, + 'netflow.source_ipv4_prefix_length': { + category: 'netflow', + name: 'netflow.source_ipv4_prefix_length', + type: 'short', + }, + 'netflow.ingress_interface': { + category: 'netflow', + name: 'netflow.ingress_interface', + type: 'long', + }, + 'netflow.destination_transport_port': { + category: 'netflow', + name: 'netflow.destination_transport_port', + type: 'integer', + }, + 'netflow.destination_ipv4_address': { + category: 'netflow', + name: 'netflow.destination_ipv4_address', + type: 'ip', + }, + 'netflow.destination_ipv4_prefix_length': { + category: 'netflow', + name: 'netflow.destination_ipv4_prefix_length', + type: 'short', + }, + 'netflow.egress_interface': { + category: 'netflow', + name: 'netflow.egress_interface', + type: 'long', + }, + 'netflow.ip_next_hop_ipv4_address': { + category: 'netflow', + name: 'netflow.ip_next_hop_ipv4_address', + type: 'ip', + }, + 'netflow.bgp_source_as_number': { + category: 'netflow', + name: 'netflow.bgp_source_as_number', + type: 'long', + }, + 'netflow.bgp_destination_as_number': { + category: 'netflow', + name: 'netflow.bgp_destination_as_number', + type: 'long', + }, + 'netflow.bgp_next_hop_ipv4_address': { + category: 'netflow', + name: 'netflow.bgp_next_hop_ipv4_address', + type: 'ip', + }, + 'netflow.post_mcast_packet_delta_count': { + category: 'netflow', + name: 'netflow.post_mcast_packet_delta_count', + type: 'long', + }, + 'netflow.post_mcast_octet_delta_count': { + category: 'netflow', + name: 'netflow.post_mcast_octet_delta_count', + type: 'long', + }, + 'netflow.flow_end_sys_up_time': { + category: 'netflow', + name: 'netflow.flow_end_sys_up_time', + type: 'long', + }, + 'netflow.flow_start_sys_up_time': { + category: 'netflow', + name: 'netflow.flow_start_sys_up_time', + type: 'long', + }, + 'netflow.post_octet_delta_count': { + category: 'netflow', + name: 'netflow.post_octet_delta_count', + type: 'long', + }, + 'netflow.post_packet_delta_count': { + category: 'netflow', + name: 'netflow.post_packet_delta_count', + type: 'long', + }, + 'netflow.minimum_ip_total_length': { + category: 'netflow', + name: 'netflow.minimum_ip_total_length', + type: 'long', + }, + 'netflow.maximum_ip_total_length': { + category: 'netflow', + name: 'netflow.maximum_ip_total_length', + type: 'long', + }, + 'netflow.source_ipv6_address': { + category: 'netflow', + name: 'netflow.source_ipv6_address', + type: 'ip', + }, + 'netflow.destination_ipv6_address': { + category: 'netflow', + name: 'netflow.destination_ipv6_address', + type: 'ip', + }, + 'netflow.source_ipv6_prefix_length': { + category: 'netflow', + name: 'netflow.source_ipv6_prefix_length', + type: 'short', + }, + 'netflow.destination_ipv6_prefix_length': { + category: 'netflow', + name: 'netflow.destination_ipv6_prefix_length', + type: 'short', + }, + 'netflow.flow_label_ipv6': { + category: 'netflow', + name: 'netflow.flow_label_ipv6', + type: 'long', + }, + 'netflow.icmp_type_code_ipv4': { + category: 'netflow', + name: 'netflow.icmp_type_code_ipv4', + type: 'integer', + }, + 'netflow.igmp_type': { + category: 'netflow', + name: 'netflow.igmp_type', + type: 'short', + }, + 'netflow.sampling_interval': { + category: 'netflow', + name: 'netflow.sampling_interval', + type: 'long', + }, + 'netflow.sampling_algorithm': { + category: 'netflow', + name: 'netflow.sampling_algorithm', + type: 'short', + }, + 'netflow.flow_active_timeout': { + category: 'netflow', + name: 'netflow.flow_active_timeout', + type: 'integer', + }, + 'netflow.flow_idle_timeout': { + category: 'netflow', + name: 'netflow.flow_idle_timeout', + type: 'integer', + }, + 'netflow.engine_type': { + category: 'netflow', + name: 'netflow.engine_type', + type: 'short', + }, + 'netflow.engine_id': { + category: 'netflow', + name: 'netflow.engine_id', + type: 'short', + }, + 'netflow.exported_octet_total_count': { + category: 'netflow', + name: 'netflow.exported_octet_total_count', + type: 'long', + }, + 'netflow.exported_message_total_count': { + category: 'netflow', + name: 'netflow.exported_message_total_count', + type: 'long', + }, + 'netflow.exported_flow_record_total_count': { + category: 'netflow', + name: 'netflow.exported_flow_record_total_count', + type: 'long', + }, + 'netflow.ipv4_router_sc': { + category: 'netflow', + name: 'netflow.ipv4_router_sc', + type: 'ip', + }, + 'netflow.source_ipv4_prefix': { + category: 'netflow', + name: 'netflow.source_ipv4_prefix', + type: 'ip', + }, + 'netflow.destination_ipv4_prefix': { + category: 'netflow', + name: 'netflow.destination_ipv4_prefix', + type: 'ip', + }, + 'netflow.mpls_top_label_type': { + category: 'netflow', + name: 'netflow.mpls_top_label_type', + type: 'short', + }, + 'netflow.mpls_top_label_ipv4_address': { + category: 'netflow', + name: 'netflow.mpls_top_label_ipv4_address', + type: 'ip', + }, + 'netflow.sampler_id': { + category: 'netflow', + name: 'netflow.sampler_id', + type: 'short', + }, + 'netflow.sampler_mode': { + category: 'netflow', + name: 'netflow.sampler_mode', + type: 'short', + }, + 'netflow.sampler_random_interval': { + category: 'netflow', + name: 'netflow.sampler_random_interval', + type: 'long', + }, + 'netflow.class_id': { + category: 'netflow', + name: 'netflow.class_id', + type: 'long', + }, + 'netflow.minimum_ttl': { + category: 'netflow', + name: 'netflow.minimum_ttl', + type: 'short', + }, + 'netflow.maximum_ttl': { + category: 'netflow', + name: 'netflow.maximum_ttl', + type: 'short', + }, + 'netflow.fragment_identification': { + category: 'netflow', + name: 'netflow.fragment_identification', + type: 'long', + }, + 'netflow.post_ip_class_of_service': { + category: 'netflow', + name: 'netflow.post_ip_class_of_service', + type: 'short', + }, + 'netflow.source_mac_address': { + category: 'netflow', + name: 'netflow.source_mac_address', + type: 'keyword', + }, + 'netflow.post_destination_mac_address': { + category: 'netflow', + name: 'netflow.post_destination_mac_address', + type: 'keyword', + }, + 'netflow.vlan_id': { + category: 'netflow', + name: 'netflow.vlan_id', + type: 'integer', + }, + 'netflow.post_vlan_id': { + category: 'netflow', + name: 'netflow.post_vlan_id', + type: 'integer', + }, + 'netflow.ip_version': { + category: 'netflow', + name: 'netflow.ip_version', + type: 'short', + }, + 'netflow.flow_direction': { + category: 'netflow', + name: 'netflow.flow_direction', + type: 'short', + }, + 'netflow.ip_next_hop_ipv6_address': { + category: 'netflow', + name: 'netflow.ip_next_hop_ipv6_address', + type: 'ip', + }, + 'netflow.bgp_next_hop_ipv6_address': { + category: 'netflow', + name: 'netflow.bgp_next_hop_ipv6_address', + type: 'ip', + }, + 'netflow.ipv6_extension_headers': { + category: 'netflow', + name: 'netflow.ipv6_extension_headers', + type: 'long', + }, + 'netflow.mpls_top_label_stack_section': { + category: 'netflow', + name: 'netflow.mpls_top_label_stack_section', + type: 'short', + }, + 'netflow.mpls_label_stack_section2': { + category: 'netflow', + name: 'netflow.mpls_label_stack_section2', + type: 'short', + }, + 'netflow.mpls_label_stack_section3': { + category: 'netflow', + name: 'netflow.mpls_label_stack_section3', + type: 'short', + }, + 'netflow.mpls_label_stack_section4': { + category: 'netflow', + name: 'netflow.mpls_label_stack_section4', + type: 'short', + }, + 'netflow.mpls_label_stack_section5': { + category: 'netflow', + name: 'netflow.mpls_label_stack_section5', + type: 'short', + }, + 'netflow.mpls_label_stack_section6': { + category: 'netflow', + name: 'netflow.mpls_label_stack_section6', + type: 'short', + }, + 'netflow.mpls_label_stack_section7': { + category: 'netflow', + name: 'netflow.mpls_label_stack_section7', + type: 'short', + }, + 'netflow.mpls_label_stack_section8': { + category: 'netflow', + name: 'netflow.mpls_label_stack_section8', + type: 'short', + }, + 'netflow.mpls_label_stack_section9': { + category: 'netflow', + name: 'netflow.mpls_label_stack_section9', + type: 'short', + }, + 'netflow.mpls_label_stack_section10': { + category: 'netflow', + name: 'netflow.mpls_label_stack_section10', + type: 'short', + }, + 'netflow.destination_mac_address': { + category: 'netflow', + name: 'netflow.destination_mac_address', + type: 'keyword', + }, + 'netflow.post_source_mac_address': { + category: 'netflow', + name: 'netflow.post_source_mac_address', + type: 'keyword', + }, + 'netflow.interface_name': { + category: 'netflow', + name: 'netflow.interface_name', + type: 'keyword', + }, + 'netflow.interface_description': { + category: 'netflow', + name: 'netflow.interface_description', + type: 'keyword', + }, + 'netflow.sampler_name': { + category: 'netflow', + name: 'netflow.sampler_name', + type: 'keyword', + }, + 'netflow.octet_total_count': { + category: 'netflow', + name: 'netflow.octet_total_count', + type: 'long', + }, + 'netflow.packet_total_count': { + category: 'netflow', + name: 'netflow.packet_total_count', + type: 'long', + }, + 'netflow.flags_and_sampler_id': { + category: 'netflow', + name: 'netflow.flags_and_sampler_id', + type: 'long', + }, + 'netflow.fragment_offset': { + category: 'netflow', + name: 'netflow.fragment_offset', + type: 'integer', + }, + 'netflow.forwarding_status': { + category: 'netflow', + name: 'netflow.forwarding_status', + type: 'short', + }, + 'netflow.mpls_vpn_route_distinguisher': { + category: 'netflow', + name: 'netflow.mpls_vpn_route_distinguisher', + type: 'short', + }, + 'netflow.mpls_top_label_prefix_length': { + category: 'netflow', + name: 'netflow.mpls_top_label_prefix_length', + type: 'short', + }, + 'netflow.src_traffic_index': { + category: 'netflow', + name: 'netflow.src_traffic_index', + type: 'long', + }, + 'netflow.dst_traffic_index': { + category: 'netflow', + name: 'netflow.dst_traffic_index', + type: 'long', + }, + 'netflow.application_description': { + category: 'netflow', + name: 'netflow.application_description', + type: 'keyword', + }, + 'netflow.application_id': { + category: 'netflow', + name: 'netflow.application_id', + type: 'short', + }, + 'netflow.application_name': { + category: 'netflow', + name: 'netflow.application_name', + type: 'keyword', + }, + 'netflow.post_ip_diff_serv_code_point': { + category: 'netflow', + name: 'netflow.post_ip_diff_serv_code_point', + type: 'short', + }, + 'netflow.multicast_replication_factor': { + category: 'netflow', + name: 'netflow.multicast_replication_factor', + type: 'long', + }, + 'netflow.class_name': { + category: 'netflow', + name: 'netflow.class_name', + type: 'keyword', + }, + 'netflow.classification_engine_id': { + category: 'netflow', + name: 'netflow.classification_engine_id', + type: 'short', + }, + 'netflow.layer2packet_section_offset': { + category: 'netflow', + name: 'netflow.layer2packet_section_offset', + type: 'integer', + }, + 'netflow.layer2packet_section_size': { + category: 'netflow', + name: 'netflow.layer2packet_section_size', + type: 'integer', + }, + 'netflow.layer2packet_section_data': { + category: 'netflow', + name: 'netflow.layer2packet_section_data', + type: 'short', + }, + 'netflow.bgp_next_adjacent_as_number': { + category: 'netflow', + name: 'netflow.bgp_next_adjacent_as_number', + type: 'long', + }, + 'netflow.bgp_prev_adjacent_as_number': { + category: 'netflow', + name: 'netflow.bgp_prev_adjacent_as_number', + type: 'long', + }, + 'netflow.exporter_ipv4_address': { + category: 'netflow', + name: 'netflow.exporter_ipv4_address', + type: 'ip', + }, + 'netflow.exporter_ipv6_address': { + category: 'netflow', + name: 'netflow.exporter_ipv6_address', + type: 'ip', + }, + 'netflow.dropped_octet_delta_count': { + category: 'netflow', + name: 'netflow.dropped_octet_delta_count', + type: 'long', + }, + 'netflow.dropped_packet_delta_count': { + category: 'netflow', + name: 'netflow.dropped_packet_delta_count', + type: 'long', + }, + 'netflow.dropped_octet_total_count': { + category: 'netflow', + name: 'netflow.dropped_octet_total_count', + type: 'long', + }, + 'netflow.dropped_packet_total_count': { + category: 'netflow', + name: 'netflow.dropped_packet_total_count', + type: 'long', + }, + 'netflow.flow_end_reason': { + category: 'netflow', + name: 'netflow.flow_end_reason', + type: 'short', + }, + 'netflow.common_properties_id': { + category: 'netflow', + name: 'netflow.common_properties_id', + type: 'long', + }, + 'netflow.observation_point_id': { + category: 'netflow', + name: 'netflow.observation_point_id', + type: 'long', + }, + 'netflow.icmp_type_code_ipv6': { + category: 'netflow', + name: 'netflow.icmp_type_code_ipv6', + type: 'integer', + }, + 'netflow.mpls_top_label_ipv6_address': { + category: 'netflow', + name: 'netflow.mpls_top_label_ipv6_address', + type: 'ip', + }, + 'netflow.line_card_id': { + category: 'netflow', + name: 'netflow.line_card_id', + type: 'long', + }, + 'netflow.port_id': { + category: 'netflow', + name: 'netflow.port_id', + type: 'long', + }, + 'netflow.metering_process_id': { + category: 'netflow', + name: 'netflow.metering_process_id', + type: 'long', + }, + 'netflow.exporting_process_id': { + category: 'netflow', + name: 'netflow.exporting_process_id', + type: 'long', + }, + 'netflow.template_id': { + category: 'netflow', + name: 'netflow.template_id', + type: 'integer', + }, + 'netflow.wlan_channel_id': { + category: 'netflow', + name: 'netflow.wlan_channel_id', + type: 'short', + }, + 'netflow.wlan_ssid': { + category: 'netflow', + name: 'netflow.wlan_ssid', + type: 'keyword', + }, + 'netflow.flow_id': { + category: 'netflow', + name: 'netflow.flow_id', + type: 'long', + }, + 'netflow.observation_domain_id': { + category: 'netflow', + name: 'netflow.observation_domain_id', + type: 'long', + }, + 'netflow.flow_start_seconds': { + category: 'netflow', + name: 'netflow.flow_start_seconds', + type: 'date', + }, + 'netflow.flow_end_seconds': { + category: 'netflow', + name: 'netflow.flow_end_seconds', + type: 'date', + }, + 'netflow.flow_start_milliseconds': { + category: 'netflow', + name: 'netflow.flow_start_milliseconds', + type: 'date', + }, + 'netflow.flow_end_milliseconds': { + category: 'netflow', + name: 'netflow.flow_end_milliseconds', + type: 'date', + }, + 'netflow.flow_start_microseconds': { + category: 'netflow', + name: 'netflow.flow_start_microseconds', + type: 'date', + }, + 'netflow.flow_end_microseconds': { + category: 'netflow', + name: 'netflow.flow_end_microseconds', + type: 'date', + }, + 'netflow.flow_start_nanoseconds': { + category: 'netflow', + name: 'netflow.flow_start_nanoseconds', + type: 'date', + }, + 'netflow.flow_end_nanoseconds': { + category: 'netflow', + name: 'netflow.flow_end_nanoseconds', + type: 'date', + }, + 'netflow.flow_start_delta_microseconds': { + category: 'netflow', + name: 'netflow.flow_start_delta_microseconds', + type: 'long', + }, + 'netflow.flow_end_delta_microseconds': { + category: 'netflow', + name: 'netflow.flow_end_delta_microseconds', + type: 'long', + }, + 'netflow.system_init_time_milliseconds': { + category: 'netflow', + name: 'netflow.system_init_time_milliseconds', + type: 'date', + }, + 'netflow.flow_duration_milliseconds': { + category: 'netflow', + name: 'netflow.flow_duration_milliseconds', + type: 'long', + }, + 'netflow.flow_duration_microseconds': { + category: 'netflow', + name: 'netflow.flow_duration_microseconds', + type: 'long', + }, + 'netflow.observed_flow_total_count': { + category: 'netflow', + name: 'netflow.observed_flow_total_count', + type: 'long', + }, + 'netflow.ignored_packet_total_count': { + category: 'netflow', + name: 'netflow.ignored_packet_total_count', + type: 'long', + }, + 'netflow.ignored_octet_total_count': { + category: 'netflow', + name: 'netflow.ignored_octet_total_count', + type: 'long', + }, + 'netflow.not_sent_flow_total_count': { + category: 'netflow', + name: 'netflow.not_sent_flow_total_count', + type: 'long', + }, + 'netflow.not_sent_packet_total_count': { + category: 'netflow', + name: 'netflow.not_sent_packet_total_count', + type: 'long', + }, + 'netflow.not_sent_octet_total_count': { + category: 'netflow', + name: 'netflow.not_sent_octet_total_count', + type: 'long', + }, + 'netflow.destination_ipv6_prefix': { + category: 'netflow', + name: 'netflow.destination_ipv6_prefix', + type: 'ip', + }, + 'netflow.source_ipv6_prefix': { + category: 'netflow', + name: 'netflow.source_ipv6_prefix', + type: 'ip', + }, + 'netflow.post_octet_total_count': { + category: 'netflow', + name: 'netflow.post_octet_total_count', + type: 'long', + }, + 'netflow.post_packet_total_count': { + category: 'netflow', + name: 'netflow.post_packet_total_count', + type: 'long', + }, + 'netflow.flow_key_indicator': { + category: 'netflow', + name: 'netflow.flow_key_indicator', + type: 'long', + }, + 'netflow.post_mcast_packet_total_count': { + category: 'netflow', + name: 'netflow.post_mcast_packet_total_count', + type: 'long', + }, + 'netflow.post_mcast_octet_total_count': { + category: 'netflow', + name: 'netflow.post_mcast_octet_total_count', + type: 'long', + }, + 'netflow.icmp_type_ipv4': { + category: 'netflow', + name: 'netflow.icmp_type_ipv4', + type: 'short', + }, + 'netflow.icmp_code_ipv4': { + category: 'netflow', + name: 'netflow.icmp_code_ipv4', + type: 'short', + }, + 'netflow.icmp_type_ipv6': { + category: 'netflow', + name: 'netflow.icmp_type_ipv6', + type: 'short', + }, + 'netflow.icmp_code_ipv6': { + category: 'netflow', + name: 'netflow.icmp_code_ipv6', + type: 'short', + }, + 'netflow.udp_source_port': { + category: 'netflow', + name: 'netflow.udp_source_port', + type: 'integer', + }, + 'netflow.udp_destination_port': { + category: 'netflow', + name: 'netflow.udp_destination_port', + type: 'integer', + }, + 'netflow.tcp_source_port': { + category: 'netflow', + name: 'netflow.tcp_source_port', + type: 'integer', + }, + 'netflow.tcp_destination_port': { + category: 'netflow', + name: 'netflow.tcp_destination_port', + type: 'integer', + }, + 'netflow.tcp_sequence_number': { + category: 'netflow', + name: 'netflow.tcp_sequence_number', + type: 'long', + }, + 'netflow.tcp_acknowledgement_number': { + category: 'netflow', + name: 'netflow.tcp_acknowledgement_number', + type: 'long', + }, + 'netflow.tcp_window_size': { + category: 'netflow', + name: 'netflow.tcp_window_size', + type: 'integer', + }, + 'netflow.tcp_urgent_pointer': { + category: 'netflow', + name: 'netflow.tcp_urgent_pointer', + type: 'integer', + }, + 'netflow.tcp_header_length': { + category: 'netflow', + name: 'netflow.tcp_header_length', + type: 'short', + }, + 'netflow.ip_header_length': { + category: 'netflow', + name: 'netflow.ip_header_length', + type: 'short', + }, + 'netflow.total_length_ipv4': { + category: 'netflow', + name: 'netflow.total_length_ipv4', + type: 'integer', + }, + 'netflow.payload_length_ipv6': { + category: 'netflow', + name: 'netflow.payload_length_ipv6', + type: 'integer', + }, + 'netflow.ip_ttl': { + category: 'netflow', + name: 'netflow.ip_ttl', + type: 'short', + }, + 'netflow.next_header_ipv6': { + category: 'netflow', + name: 'netflow.next_header_ipv6', + type: 'short', + }, + 'netflow.mpls_payload_length': { + category: 'netflow', + name: 'netflow.mpls_payload_length', + type: 'long', + }, + 'netflow.ip_diff_serv_code_point': { + category: 'netflow', + name: 'netflow.ip_diff_serv_code_point', + type: 'short', + }, + 'netflow.ip_precedence': { + category: 'netflow', + name: 'netflow.ip_precedence', + type: 'short', + }, + 'netflow.fragment_flags': { + category: 'netflow', + name: 'netflow.fragment_flags', + type: 'short', + }, + 'netflow.octet_delta_sum_of_squares': { + category: 'netflow', + name: 'netflow.octet_delta_sum_of_squares', + type: 'long', + }, + 'netflow.octet_total_sum_of_squares': { + category: 'netflow', + name: 'netflow.octet_total_sum_of_squares', + type: 'long', + }, + 'netflow.mpls_top_label_ttl': { + category: 'netflow', + name: 'netflow.mpls_top_label_ttl', + type: 'short', + }, + 'netflow.mpls_label_stack_length': { + category: 'netflow', + name: 'netflow.mpls_label_stack_length', + type: 'long', + }, + 'netflow.mpls_label_stack_depth': { + category: 'netflow', + name: 'netflow.mpls_label_stack_depth', + type: 'long', + }, + 'netflow.mpls_top_label_exp': { + category: 'netflow', + name: 'netflow.mpls_top_label_exp', + type: 'short', + }, + 'netflow.ip_payload_length': { + category: 'netflow', + name: 'netflow.ip_payload_length', + type: 'long', + }, + 'netflow.udp_message_length': { + category: 'netflow', + name: 'netflow.udp_message_length', + type: 'integer', + }, + 'netflow.is_multicast': { + category: 'netflow', + name: 'netflow.is_multicast', + type: 'short', + }, + 'netflow.ipv4_ihl': { + category: 'netflow', + name: 'netflow.ipv4_ihl', + type: 'short', + }, + 'netflow.ipv4_options': { + category: 'netflow', + name: 'netflow.ipv4_options', + type: 'long', + }, + 'netflow.tcp_options': { + category: 'netflow', + name: 'netflow.tcp_options', + type: 'long', + }, + 'netflow.padding_octets': { + category: 'netflow', + name: 'netflow.padding_octets', + type: 'short', + }, + 'netflow.collector_ipv4_address': { + category: 'netflow', + name: 'netflow.collector_ipv4_address', + type: 'ip', + }, + 'netflow.collector_ipv6_address': { + category: 'netflow', + name: 'netflow.collector_ipv6_address', + type: 'ip', + }, + 'netflow.export_interface': { + category: 'netflow', + name: 'netflow.export_interface', + type: 'long', + }, + 'netflow.export_protocol_version': { + category: 'netflow', + name: 'netflow.export_protocol_version', + type: 'short', + }, + 'netflow.export_transport_protocol': { + category: 'netflow', + name: 'netflow.export_transport_protocol', + type: 'short', + }, + 'netflow.collector_transport_port': { + category: 'netflow', + name: 'netflow.collector_transport_port', + type: 'integer', + }, + 'netflow.exporter_transport_port': { + category: 'netflow', + name: 'netflow.exporter_transport_port', + type: 'integer', + }, + 'netflow.tcp_syn_total_count': { + category: 'netflow', + name: 'netflow.tcp_syn_total_count', + type: 'long', + }, + 'netflow.tcp_fin_total_count': { + category: 'netflow', + name: 'netflow.tcp_fin_total_count', + type: 'long', + }, + 'netflow.tcp_rst_total_count': { + category: 'netflow', + name: 'netflow.tcp_rst_total_count', + type: 'long', + }, + 'netflow.tcp_psh_total_count': { + category: 'netflow', + name: 'netflow.tcp_psh_total_count', + type: 'long', + }, + 'netflow.tcp_ack_total_count': { + category: 'netflow', + name: 'netflow.tcp_ack_total_count', + type: 'long', + }, + 'netflow.tcp_urg_total_count': { + category: 'netflow', + name: 'netflow.tcp_urg_total_count', + type: 'long', + }, + 'netflow.ip_total_length': { + category: 'netflow', + name: 'netflow.ip_total_length', + type: 'long', + }, + 'netflow.post_nat_source_ipv4_address': { + category: 'netflow', + name: 'netflow.post_nat_source_ipv4_address', + type: 'ip', + }, + 'netflow.post_nat_destination_ipv4_address': { + category: 'netflow', + name: 'netflow.post_nat_destination_ipv4_address', + type: 'ip', + }, + 'netflow.post_napt_source_transport_port': { + category: 'netflow', + name: 'netflow.post_napt_source_transport_port', + type: 'integer', + }, + 'netflow.post_napt_destination_transport_port': { + category: 'netflow', + name: 'netflow.post_napt_destination_transport_port', + type: 'integer', + }, + 'netflow.nat_originating_address_realm': { + category: 'netflow', + name: 'netflow.nat_originating_address_realm', + type: 'short', + }, + 'netflow.nat_event': { + category: 'netflow', + name: 'netflow.nat_event', + type: 'short', + }, + 'netflow.initiator_octets': { + category: 'netflow', + name: 'netflow.initiator_octets', + type: 'long', + }, + 'netflow.responder_octets': { + category: 'netflow', + name: 'netflow.responder_octets', + type: 'long', + }, + 'netflow.firewall_event': { + category: 'netflow', + name: 'netflow.firewall_event', + type: 'short', + }, + 'netflow.ingress_vrfid': { + category: 'netflow', + name: 'netflow.ingress_vrfid', + type: 'long', + }, + 'netflow.egress_vrfid': { + category: 'netflow', + name: 'netflow.egress_vrfid', + type: 'long', + }, + 'netflow.vr_fname': { + category: 'netflow', + name: 'netflow.vr_fname', + type: 'keyword', + }, + 'netflow.post_mpls_top_label_exp': { + category: 'netflow', + name: 'netflow.post_mpls_top_label_exp', + type: 'short', + }, + 'netflow.tcp_window_scale': { + category: 'netflow', + name: 'netflow.tcp_window_scale', + type: 'integer', + }, + 'netflow.biflow_direction': { + category: 'netflow', + name: 'netflow.biflow_direction', + type: 'short', + }, + 'netflow.ethernet_header_length': { + category: 'netflow', + name: 'netflow.ethernet_header_length', + type: 'short', + }, + 'netflow.ethernet_payload_length': { + category: 'netflow', + name: 'netflow.ethernet_payload_length', + type: 'integer', + }, + 'netflow.ethernet_total_length': { + category: 'netflow', + name: 'netflow.ethernet_total_length', + type: 'integer', + }, + 'netflow.dot1q_vlan_id': { + category: 'netflow', + name: 'netflow.dot1q_vlan_id', + type: 'integer', + }, + 'netflow.dot1q_priority': { + category: 'netflow', + name: 'netflow.dot1q_priority', + type: 'short', + }, + 'netflow.dot1q_customer_vlan_id': { + category: 'netflow', + name: 'netflow.dot1q_customer_vlan_id', + type: 'integer', + }, + 'netflow.dot1q_customer_priority': { + category: 'netflow', + name: 'netflow.dot1q_customer_priority', + type: 'short', + }, + 'netflow.metro_evc_id': { + category: 'netflow', + name: 'netflow.metro_evc_id', + type: 'keyword', + }, + 'netflow.metro_evc_type': { + category: 'netflow', + name: 'netflow.metro_evc_type', + type: 'short', + }, + 'netflow.pseudo_wire_id': { + category: 'netflow', + name: 'netflow.pseudo_wire_id', + type: 'long', + }, + 'netflow.pseudo_wire_type': { + category: 'netflow', + name: 'netflow.pseudo_wire_type', + type: 'integer', + }, + 'netflow.pseudo_wire_control_word': { + category: 'netflow', + name: 'netflow.pseudo_wire_control_word', + type: 'long', + }, + 'netflow.ingress_physical_interface': { + category: 'netflow', + name: 'netflow.ingress_physical_interface', + type: 'long', + }, + 'netflow.egress_physical_interface': { + category: 'netflow', + name: 'netflow.egress_physical_interface', + type: 'long', + }, + 'netflow.post_dot1q_vlan_id': { + category: 'netflow', + name: 'netflow.post_dot1q_vlan_id', + type: 'integer', + }, + 'netflow.post_dot1q_customer_vlan_id': { + category: 'netflow', + name: 'netflow.post_dot1q_customer_vlan_id', + type: 'integer', + }, + 'netflow.ethernet_type': { + category: 'netflow', + name: 'netflow.ethernet_type', + type: 'integer', + }, + 'netflow.post_ip_precedence': { + category: 'netflow', + name: 'netflow.post_ip_precedence', + type: 'short', + }, + 'netflow.collection_time_milliseconds': { + category: 'netflow', + name: 'netflow.collection_time_milliseconds', + type: 'date', + }, + 'netflow.export_sctp_stream_id': { + category: 'netflow', + name: 'netflow.export_sctp_stream_id', + type: 'integer', + }, + 'netflow.max_export_seconds': { + category: 'netflow', + name: 'netflow.max_export_seconds', + type: 'date', + }, + 'netflow.max_flow_end_seconds': { + category: 'netflow', + name: 'netflow.max_flow_end_seconds', + type: 'date', + }, + 'netflow.message_md5_checksum': { + category: 'netflow', + name: 'netflow.message_md5_checksum', + type: 'short', + }, + 'netflow.message_scope': { + category: 'netflow', + name: 'netflow.message_scope', + type: 'short', + }, + 'netflow.min_export_seconds': { + category: 'netflow', + name: 'netflow.min_export_seconds', + type: 'date', + }, + 'netflow.min_flow_start_seconds': { + category: 'netflow', + name: 'netflow.min_flow_start_seconds', + type: 'date', + }, + 'netflow.opaque_octets': { + category: 'netflow', + name: 'netflow.opaque_octets', + type: 'short', + }, + 'netflow.session_scope': { + category: 'netflow', + name: 'netflow.session_scope', + type: 'short', + }, + 'netflow.max_flow_end_microseconds': { + category: 'netflow', + name: 'netflow.max_flow_end_microseconds', + type: 'date', + }, + 'netflow.max_flow_end_milliseconds': { + category: 'netflow', + name: 'netflow.max_flow_end_milliseconds', + type: 'date', + }, + 'netflow.max_flow_end_nanoseconds': { + category: 'netflow', + name: 'netflow.max_flow_end_nanoseconds', + type: 'date', + }, + 'netflow.min_flow_start_microseconds': { + category: 'netflow', + name: 'netflow.min_flow_start_microseconds', + type: 'date', + }, + 'netflow.min_flow_start_milliseconds': { + category: 'netflow', + name: 'netflow.min_flow_start_milliseconds', + type: 'date', + }, + 'netflow.min_flow_start_nanoseconds': { + category: 'netflow', + name: 'netflow.min_flow_start_nanoseconds', + type: 'date', + }, + 'netflow.collector_certificate': { + category: 'netflow', + name: 'netflow.collector_certificate', + type: 'short', + }, + 'netflow.exporter_certificate': { + category: 'netflow', + name: 'netflow.exporter_certificate', + type: 'short', + }, + 'netflow.data_records_reliability': { + category: 'netflow', + name: 'netflow.data_records_reliability', + type: 'boolean', + }, + 'netflow.observation_point_type': { + category: 'netflow', + name: 'netflow.observation_point_type', + type: 'short', + }, + 'netflow.new_connection_delta_count': { + category: 'netflow', + name: 'netflow.new_connection_delta_count', + type: 'long', + }, + 'netflow.connection_sum_duration_seconds': { + category: 'netflow', + name: 'netflow.connection_sum_duration_seconds', + type: 'long', + }, + 'netflow.connection_transaction_id': { + category: 'netflow', + name: 'netflow.connection_transaction_id', + type: 'long', + }, + 'netflow.post_nat_source_ipv6_address': { + category: 'netflow', + name: 'netflow.post_nat_source_ipv6_address', + type: 'ip', + }, + 'netflow.post_nat_destination_ipv6_address': { + category: 'netflow', + name: 'netflow.post_nat_destination_ipv6_address', + type: 'ip', + }, + 'netflow.nat_pool_id': { + category: 'netflow', + name: 'netflow.nat_pool_id', + type: 'long', + }, + 'netflow.nat_pool_name': { + category: 'netflow', + name: 'netflow.nat_pool_name', + type: 'keyword', + }, + 'netflow.anonymization_flags': { + category: 'netflow', + name: 'netflow.anonymization_flags', + type: 'integer', + }, + 'netflow.anonymization_technique': { + category: 'netflow', + name: 'netflow.anonymization_technique', + type: 'integer', + }, + 'netflow.information_element_index': { + category: 'netflow', + name: 'netflow.information_element_index', + type: 'integer', + }, + 'netflow.p2p_technology': { + category: 'netflow', + name: 'netflow.p2p_technology', + type: 'keyword', + }, + 'netflow.tunnel_technology': { + category: 'netflow', + name: 'netflow.tunnel_technology', + type: 'keyword', + }, + 'netflow.encrypted_technology': { + category: 'netflow', + name: 'netflow.encrypted_technology', + type: 'keyword', + }, + 'netflow.bgp_validity_state': { + category: 'netflow', + name: 'netflow.bgp_validity_state', + type: 'short', + }, + 'netflow.ip_sec_spi': { + category: 'netflow', + name: 'netflow.ip_sec_spi', + type: 'long', + }, + 'netflow.gre_key': { + category: 'netflow', + name: 'netflow.gre_key', + type: 'long', + }, + 'netflow.nat_type': { + category: 'netflow', + name: 'netflow.nat_type', + type: 'short', + }, + 'netflow.initiator_packets': { + category: 'netflow', + name: 'netflow.initiator_packets', + type: 'long', + }, + 'netflow.responder_packets': { + category: 'netflow', + name: 'netflow.responder_packets', + type: 'long', + }, + 'netflow.observation_domain_name': { + category: 'netflow', + name: 'netflow.observation_domain_name', + type: 'keyword', + }, + 'netflow.selection_sequence_id': { + category: 'netflow', + name: 'netflow.selection_sequence_id', + type: 'long', + }, + 'netflow.selector_id': { + category: 'netflow', + name: 'netflow.selector_id', + type: 'long', + }, + 'netflow.information_element_id': { + category: 'netflow', + name: 'netflow.information_element_id', + type: 'integer', + }, + 'netflow.selector_algorithm': { + category: 'netflow', + name: 'netflow.selector_algorithm', + type: 'integer', + }, + 'netflow.sampling_packet_interval': { + category: 'netflow', + name: 'netflow.sampling_packet_interval', + type: 'long', + }, + 'netflow.sampling_packet_space': { + category: 'netflow', + name: 'netflow.sampling_packet_space', + type: 'long', + }, + 'netflow.sampling_time_interval': { + category: 'netflow', + name: 'netflow.sampling_time_interval', + type: 'long', + }, + 'netflow.sampling_time_space': { + category: 'netflow', + name: 'netflow.sampling_time_space', + type: 'long', + }, + 'netflow.sampling_size': { + category: 'netflow', + name: 'netflow.sampling_size', + type: 'long', + }, + 'netflow.sampling_population': { + category: 'netflow', + name: 'netflow.sampling_population', + type: 'long', + }, + 'netflow.sampling_probability': { + category: 'netflow', + name: 'netflow.sampling_probability', + type: 'double', + }, + 'netflow.data_link_frame_size': { + category: 'netflow', + name: 'netflow.data_link_frame_size', + type: 'integer', + }, + 'netflow.ip_header_packet_section': { + category: 'netflow', + name: 'netflow.ip_header_packet_section', + type: 'short', + }, + 'netflow.ip_payload_packet_section': { + category: 'netflow', + name: 'netflow.ip_payload_packet_section', + type: 'short', + }, + 'netflow.data_link_frame_section': { + category: 'netflow', + name: 'netflow.data_link_frame_section', + type: 'short', + }, + 'netflow.mpls_label_stack_section': { + category: 'netflow', + name: 'netflow.mpls_label_stack_section', + type: 'short', + }, + 'netflow.mpls_payload_packet_section': { + category: 'netflow', + name: 'netflow.mpls_payload_packet_section', + type: 'short', + }, + 'netflow.selector_id_total_pkts_observed': { + category: 'netflow', + name: 'netflow.selector_id_total_pkts_observed', + type: 'long', + }, + 'netflow.selector_id_total_pkts_selected': { + category: 'netflow', + name: 'netflow.selector_id_total_pkts_selected', + type: 'long', + }, + 'netflow.absolute_error': { + category: 'netflow', + name: 'netflow.absolute_error', + type: 'double', + }, + 'netflow.relative_error': { + category: 'netflow', + name: 'netflow.relative_error', + type: 'double', + }, + 'netflow.observation_time_seconds': { + category: 'netflow', + name: 'netflow.observation_time_seconds', + type: 'date', + }, + 'netflow.observation_time_milliseconds': { + category: 'netflow', + name: 'netflow.observation_time_milliseconds', + type: 'date', + }, + 'netflow.observation_time_microseconds': { + category: 'netflow', + name: 'netflow.observation_time_microseconds', + type: 'date', + }, + 'netflow.observation_time_nanoseconds': { + category: 'netflow', + name: 'netflow.observation_time_nanoseconds', + type: 'date', + }, + 'netflow.digest_hash_value': { + category: 'netflow', + name: 'netflow.digest_hash_value', + type: 'long', + }, + 'netflow.hash_ip_payload_offset': { + category: 'netflow', + name: 'netflow.hash_ip_payload_offset', + type: 'long', + }, + 'netflow.hash_ip_payload_size': { + category: 'netflow', + name: 'netflow.hash_ip_payload_size', + type: 'long', + }, + 'netflow.hash_output_range_min': { + category: 'netflow', + name: 'netflow.hash_output_range_min', + type: 'long', + }, + 'netflow.hash_output_range_max': { + category: 'netflow', + name: 'netflow.hash_output_range_max', + type: 'long', + }, + 'netflow.hash_selected_range_min': { + category: 'netflow', + name: 'netflow.hash_selected_range_min', + type: 'long', + }, + 'netflow.hash_selected_range_max': { + category: 'netflow', + name: 'netflow.hash_selected_range_max', + type: 'long', + }, + 'netflow.hash_digest_output': { + category: 'netflow', + name: 'netflow.hash_digest_output', + type: 'boolean', + }, + 'netflow.hash_initialiser_value': { + category: 'netflow', + name: 'netflow.hash_initialiser_value', + type: 'long', + }, + 'netflow.selector_name': { + category: 'netflow', + name: 'netflow.selector_name', + type: 'keyword', + }, + 'netflow.upper_ci_limit': { + category: 'netflow', + name: 'netflow.upper_ci_limit', + type: 'double', + }, + 'netflow.lower_ci_limit': { + category: 'netflow', + name: 'netflow.lower_ci_limit', + type: 'double', + }, + 'netflow.confidence_level': { + category: 'netflow', + name: 'netflow.confidence_level', + type: 'double', + }, + 'netflow.information_element_data_type': { + category: 'netflow', + name: 'netflow.information_element_data_type', + type: 'short', + }, + 'netflow.information_element_description': { + category: 'netflow', + name: 'netflow.information_element_description', + type: 'keyword', + }, + 'netflow.information_element_name': { + category: 'netflow', + name: 'netflow.information_element_name', + type: 'keyword', + }, + 'netflow.information_element_range_begin': { + category: 'netflow', + name: 'netflow.information_element_range_begin', + type: 'long', + }, + 'netflow.information_element_range_end': { + category: 'netflow', + name: 'netflow.information_element_range_end', + type: 'long', + }, + 'netflow.information_element_semantics': { + category: 'netflow', + name: 'netflow.information_element_semantics', + type: 'short', + }, + 'netflow.information_element_units': { + category: 'netflow', + name: 'netflow.information_element_units', + type: 'integer', + }, + 'netflow.private_enterprise_number': { + category: 'netflow', + name: 'netflow.private_enterprise_number', + type: 'long', + }, + 'netflow.virtual_station_interface_id': { + category: 'netflow', + name: 'netflow.virtual_station_interface_id', + type: 'short', + }, + 'netflow.virtual_station_interface_name': { + category: 'netflow', + name: 'netflow.virtual_station_interface_name', + type: 'keyword', + }, + 'netflow.virtual_station_uuid': { + category: 'netflow', + name: 'netflow.virtual_station_uuid', + type: 'short', + }, + 'netflow.virtual_station_name': { + category: 'netflow', + name: 'netflow.virtual_station_name', + type: 'keyword', + }, + 'netflow.layer2_segment_id': { + category: 'netflow', + name: 'netflow.layer2_segment_id', + type: 'long', + }, + 'netflow.layer2_octet_delta_count': { + category: 'netflow', + name: 'netflow.layer2_octet_delta_count', + type: 'long', + }, + 'netflow.layer2_octet_total_count': { + category: 'netflow', + name: 'netflow.layer2_octet_total_count', + type: 'long', + }, + 'netflow.ingress_unicast_packet_total_count': { + category: 'netflow', + name: 'netflow.ingress_unicast_packet_total_count', + type: 'long', + }, + 'netflow.ingress_multicast_packet_total_count': { + category: 'netflow', + name: 'netflow.ingress_multicast_packet_total_count', + type: 'long', + }, + 'netflow.ingress_broadcast_packet_total_count': { + category: 'netflow', + name: 'netflow.ingress_broadcast_packet_total_count', + type: 'long', + }, + 'netflow.egress_unicast_packet_total_count': { + category: 'netflow', + name: 'netflow.egress_unicast_packet_total_count', + type: 'long', + }, + 'netflow.egress_broadcast_packet_total_count': { + category: 'netflow', + name: 'netflow.egress_broadcast_packet_total_count', + type: 'long', + }, + 'netflow.monitoring_interval_start_milli_seconds': { + category: 'netflow', + name: 'netflow.monitoring_interval_start_milli_seconds', + type: 'date', + }, + 'netflow.monitoring_interval_end_milli_seconds': { + category: 'netflow', + name: 'netflow.monitoring_interval_end_milli_seconds', + type: 'date', + }, + 'netflow.port_range_start': { + category: 'netflow', + name: 'netflow.port_range_start', + type: 'integer', + }, + 'netflow.port_range_end': { + category: 'netflow', + name: 'netflow.port_range_end', + type: 'integer', + }, + 'netflow.port_range_step_size': { + category: 'netflow', + name: 'netflow.port_range_step_size', + type: 'integer', + }, + 'netflow.port_range_num_ports': { + category: 'netflow', + name: 'netflow.port_range_num_ports', + type: 'integer', + }, + 'netflow.sta_mac_address': { + category: 'netflow', + name: 'netflow.sta_mac_address', + type: 'keyword', + }, + 'netflow.sta_ipv4_address': { + category: 'netflow', + name: 'netflow.sta_ipv4_address', + type: 'ip', + }, + 'netflow.wtp_mac_address': { + category: 'netflow', + name: 'netflow.wtp_mac_address', + type: 'keyword', + }, + 'netflow.ingress_interface_type': { + category: 'netflow', + name: 'netflow.ingress_interface_type', + type: 'long', + }, + 'netflow.egress_interface_type': { + category: 'netflow', + name: 'netflow.egress_interface_type', + type: 'long', + }, + 'netflow.rtp_sequence_number': { + category: 'netflow', + name: 'netflow.rtp_sequence_number', + type: 'integer', + }, + 'netflow.user_name': { + category: 'netflow', + name: 'netflow.user_name', + type: 'keyword', + }, + 'netflow.application_category_name': { + category: 'netflow', + name: 'netflow.application_category_name', + type: 'keyword', + }, + 'netflow.application_sub_category_name': { + category: 'netflow', + name: 'netflow.application_sub_category_name', + type: 'keyword', + }, + 'netflow.application_group_name': { + category: 'netflow', + name: 'netflow.application_group_name', + type: 'keyword', + }, + 'netflow.original_flows_present': { + category: 'netflow', + name: 'netflow.original_flows_present', + type: 'long', + }, + 'netflow.original_flows_initiated': { + category: 'netflow', + name: 'netflow.original_flows_initiated', + type: 'long', + }, + 'netflow.original_flows_completed': { + category: 'netflow', + name: 'netflow.original_flows_completed', + type: 'long', + }, + 'netflow.distinct_count_of_source_ip_address': { + category: 'netflow', + name: 'netflow.distinct_count_of_source_ip_address', + type: 'long', + }, + 'netflow.distinct_count_of_destination_ip_address': { + category: 'netflow', + name: 'netflow.distinct_count_of_destination_ip_address', + type: 'long', + }, + 'netflow.distinct_count_of_source_ipv4_address': { + category: 'netflow', + name: 'netflow.distinct_count_of_source_ipv4_address', + type: 'long', + }, + 'netflow.distinct_count_of_destination_ipv4_address': { + category: 'netflow', + name: 'netflow.distinct_count_of_destination_ipv4_address', + type: 'long', + }, + 'netflow.distinct_count_of_source_ipv6_address': { + category: 'netflow', + name: 'netflow.distinct_count_of_source_ipv6_address', + type: 'long', + }, + 'netflow.distinct_count_of_destination_ipv6_address': { + category: 'netflow', + name: 'netflow.distinct_count_of_destination_ipv6_address', + type: 'long', + }, + 'netflow.value_distribution_method': { + category: 'netflow', + name: 'netflow.value_distribution_method', + type: 'short', + }, + 'netflow.rfc3550_jitter_milliseconds': { + category: 'netflow', + name: 'netflow.rfc3550_jitter_milliseconds', + type: 'long', + }, + 'netflow.rfc3550_jitter_microseconds': { + category: 'netflow', + name: 'netflow.rfc3550_jitter_microseconds', + type: 'long', + }, + 'netflow.rfc3550_jitter_nanoseconds': { + category: 'netflow', + name: 'netflow.rfc3550_jitter_nanoseconds', + type: 'long', + }, + 'netflow.dot1q_dei': { + category: 'netflow', + name: 'netflow.dot1q_dei', + type: 'boolean', + }, + 'netflow.dot1q_customer_dei': { + category: 'netflow', + name: 'netflow.dot1q_customer_dei', + type: 'boolean', + }, + 'netflow.flow_selector_algorithm': { + category: 'netflow', + name: 'netflow.flow_selector_algorithm', + type: 'integer', + }, + 'netflow.flow_selected_octet_delta_count': { + category: 'netflow', + name: 'netflow.flow_selected_octet_delta_count', + type: 'long', + }, + 'netflow.flow_selected_packet_delta_count': { + category: 'netflow', + name: 'netflow.flow_selected_packet_delta_count', + type: 'long', + }, + 'netflow.flow_selected_flow_delta_count': { + category: 'netflow', + name: 'netflow.flow_selected_flow_delta_count', + type: 'long', + }, + 'netflow.selector_id_total_flows_observed': { + category: 'netflow', + name: 'netflow.selector_id_total_flows_observed', + type: 'long', + }, + 'netflow.selector_id_total_flows_selected': { + category: 'netflow', + name: 'netflow.selector_id_total_flows_selected', + type: 'long', + }, + 'netflow.sampling_flow_interval': { + category: 'netflow', + name: 'netflow.sampling_flow_interval', + type: 'long', + }, + 'netflow.sampling_flow_spacing': { + category: 'netflow', + name: 'netflow.sampling_flow_spacing', + type: 'long', + }, + 'netflow.flow_sampling_time_interval': { + category: 'netflow', + name: 'netflow.flow_sampling_time_interval', + type: 'long', + }, + 'netflow.flow_sampling_time_spacing': { + category: 'netflow', + name: 'netflow.flow_sampling_time_spacing', + type: 'long', + }, + 'netflow.hash_flow_domain': { + category: 'netflow', + name: 'netflow.hash_flow_domain', + type: 'integer', + }, + 'netflow.transport_octet_delta_count': { + category: 'netflow', + name: 'netflow.transport_octet_delta_count', + type: 'long', + }, + 'netflow.transport_packet_delta_count': { + category: 'netflow', + name: 'netflow.transport_packet_delta_count', + type: 'long', + }, + 'netflow.original_exporter_ipv4_address': { + category: 'netflow', + name: 'netflow.original_exporter_ipv4_address', + type: 'ip', + }, + 'netflow.original_exporter_ipv6_address': { + category: 'netflow', + name: 'netflow.original_exporter_ipv6_address', + type: 'ip', + }, + 'netflow.original_observation_domain_id': { + category: 'netflow', + name: 'netflow.original_observation_domain_id', + type: 'long', + }, + 'netflow.intermediate_process_id': { + category: 'netflow', + name: 'netflow.intermediate_process_id', + type: 'long', + }, + 'netflow.ignored_data_record_total_count': { + category: 'netflow', + name: 'netflow.ignored_data_record_total_count', + type: 'long', + }, + 'netflow.data_link_frame_type': { + category: 'netflow', + name: 'netflow.data_link_frame_type', + type: 'integer', + }, + 'netflow.section_offset': { + category: 'netflow', + name: 'netflow.section_offset', + type: 'integer', + }, + 'netflow.section_exported_octets': { + category: 'netflow', + name: 'netflow.section_exported_octets', + type: 'integer', + }, + 'netflow.dot1q_service_instance_tag': { + category: 'netflow', + name: 'netflow.dot1q_service_instance_tag', + type: 'short', + }, + 'netflow.dot1q_service_instance_id': { + category: 'netflow', + name: 'netflow.dot1q_service_instance_id', + type: 'long', + }, + 'netflow.dot1q_service_instance_priority': { + category: 'netflow', + name: 'netflow.dot1q_service_instance_priority', + type: 'short', + }, + 'netflow.dot1q_customer_source_mac_address': { + category: 'netflow', + name: 'netflow.dot1q_customer_source_mac_address', + type: 'keyword', + }, + 'netflow.dot1q_customer_destination_mac_address': { + category: 'netflow', + name: 'netflow.dot1q_customer_destination_mac_address', + type: 'keyword', + }, + 'netflow.post_layer2_octet_delta_count': { + category: 'netflow', + name: 'netflow.post_layer2_octet_delta_count', + type: 'long', + }, + 'netflow.post_mcast_layer2_octet_delta_count': { + category: 'netflow', + name: 'netflow.post_mcast_layer2_octet_delta_count', + type: 'long', + }, + 'netflow.post_layer2_octet_total_count': { + category: 'netflow', + name: 'netflow.post_layer2_octet_total_count', + type: 'long', + }, + 'netflow.post_mcast_layer2_octet_total_count': { + category: 'netflow', + name: 'netflow.post_mcast_layer2_octet_total_count', + type: 'long', + }, + 'netflow.minimum_layer2_total_length': { + category: 'netflow', + name: 'netflow.minimum_layer2_total_length', + type: 'long', + }, + 'netflow.maximum_layer2_total_length': { + category: 'netflow', + name: 'netflow.maximum_layer2_total_length', + type: 'long', + }, + 'netflow.dropped_layer2_octet_delta_count': { + category: 'netflow', + name: 'netflow.dropped_layer2_octet_delta_count', + type: 'long', + }, + 'netflow.dropped_layer2_octet_total_count': { + category: 'netflow', + name: 'netflow.dropped_layer2_octet_total_count', + type: 'long', + }, + 'netflow.ignored_layer2_octet_total_count': { + category: 'netflow', + name: 'netflow.ignored_layer2_octet_total_count', + type: 'long', + }, + 'netflow.not_sent_layer2_octet_total_count': { + category: 'netflow', + name: 'netflow.not_sent_layer2_octet_total_count', + type: 'long', + }, + 'netflow.layer2_octet_delta_sum_of_squares': { + category: 'netflow', + name: 'netflow.layer2_octet_delta_sum_of_squares', + type: 'long', + }, + 'netflow.layer2_octet_total_sum_of_squares': { + category: 'netflow', + name: 'netflow.layer2_octet_total_sum_of_squares', + type: 'long', + }, + 'netflow.layer2_frame_delta_count': { + category: 'netflow', + name: 'netflow.layer2_frame_delta_count', + type: 'long', + }, + 'netflow.layer2_frame_total_count': { + category: 'netflow', + name: 'netflow.layer2_frame_total_count', + type: 'long', + }, + 'netflow.pseudo_wire_destination_ipv4_address': { + category: 'netflow', + name: 'netflow.pseudo_wire_destination_ipv4_address', + type: 'ip', + }, + 'netflow.ignored_layer2_frame_total_count': { + category: 'netflow', + name: 'netflow.ignored_layer2_frame_total_count', + type: 'long', + }, + 'netflow.mib_object_value_integer': { + category: 'netflow', + name: 'netflow.mib_object_value_integer', + type: 'integer', + }, + 'netflow.mib_object_value_octet_string': { + category: 'netflow', + name: 'netflow.mib_object_value_octet_string', + type: 'short', + }, + 'netflow.mib_object_value_oid': { + category: 'netflow', + name: 'netflow.mib_object_value_oid', + type: 'short', + }, + 'netflow.mib_object_value_bits': { + category: 'netflow', + name: 'netflow.mib_object_value_bits', + type: 'short', + }, + 'netflow.mib_object_value_ip_address': { + category: 'netflow', + name: 'netflow.mib_object_value_ip_address', + type: 'ip', + }, + 'netflow.mib_object_value_counter': { + category: 'netflow', + name: 'netflow.mib_object_value_counter', + type: 'long', + }, + 'netflow.mib_object_value_gauge': { + category: 'netflow', + name: 'netflow.mib_object_value_gauge', + type: 'long', + }, + 'netflow.mib_object_value_time_ticks': { + category: 'netflow', + name: 'netflow.mib_object_value_time_ticks', + type: 'long', + }, + 'netflow.mib_object_value_unsigned': { + category: 'netflow', + name: 'netflow.mib_object_value_unsigned', + type: 'long', + }, + 'netflow.mib_object_identifier': { + category: 'netflow', + name: 'netflow.mib_object_identifier', + type: 'short', + }, + 'netflow.mib_sub_identifier': { + category: 'netflow', + name: 'netflow.mib_sub_identifier', + type: 'long', + }, + 'netflow.mib_index_indicator': { + category: 'netflow', + name: 'netflow.mib_index_indicator', + type: 'long', + }, + 'netflow.mib_capture_time_semantics': { + category: 'netflow', + name: 'netflow.mib_capture_time_semantics', + type: 'short', + }, + 'netflow.mib_context_engine_id': { + category: 'netflow', + name: 'netflow.mib_context_engine_id', + type: 'short', + }, + 'netflow.mib_context_name': { + category: 'netflow', + name: 'netflow.mib_context_name', + type: 'keyword', + }, + 'netflow.mib_object_name': { + category: 'netflow', + name: 'netflow.mib_object_name', + type: 'keyword', + }, + 'netflow.mib_object_description': { + category: 'netflow', + name: 'netflow.mib_object_description', + type: 'keyword', + }, + 'netflow.mib_object_syntax': { + category: 'netflow', + name: 'netflow.mib_object_syntax', + type: 'keyword', + }, + 'netflow.mib_module_name': { + category: 'netflow', + name: 'netflow.mib_module_name', + type: 'keyword', + }, + 'netflow.mobile_imsi': { + category: 'netflow', + name: 'netflow.mobile_imsi', + type: 'keyword', + }, + 'netflow.mobile_msisdn': { + category: 'netflow', + name: 'netflow.mobile_msisdn', + type: 'keyword', + }, + 'netflow.http_status_code': { + category: 'netflow', + name: 'netflow.http_status_code', + type: 'integer', + }, + 'netflow.source_transport_ports_limit': { + category: 'netflow', + name: 'netflow.source_transport_ports_limit', + type: 'integer', + }, + 'netflow.http_request_method': { + category: 'netflow', + name: 'netflow.http_request_method', + type: 'keyword', + }, + 'netflow.http_request_host': { + category: 'netflow', + name: 'netflow.http_request_host', + type: 'keyword', + }, + 'netflow.http_request_target': { + category: 'netflow', + name: 'netflow.http_request_target', + type: 'keyword', + }, + 'netflow.http_message_version': { + category: 'netflow', + name: 'netflow.http_message_version', + type: 'keyword', + }, + 'netflow.nat_instance_id': { + category: 'netflow', + name: 'netflow.nat_instance_id', + type: 'long', + }, + 'netflow.internal_address_realm': { + category: 'netflow', + name: 'netflow.internal_address_realm', + type: 'short', + }, + 'netflow.external_address_realm': { + category: 'netflow', + name: 'netflow.external_address_realm', + type: 'short', + }, + 'netflow.nat_quota_exceeded_event': { + category: 'netflow', + name: 'netflow.nat_quota_exceeded_event', + type: 'long', + }, + 'netflow.nat_threshold_event': { + category: 'netflow', + name: 'netflow.nat_threshold_event', + type: 'long', + }, + 'netflow.http_user_agent': { + category: 'netflow', + name: 'netflow.http_user_agent', + type: 'keyword', + }, + 'netflow.http_content_type': { + category: 'netflow', + name: 'netflow.http_content_type', + type: 'keyword', + }, + 'netflow.http_reason_phrase': { + category: 'netflow', + name: 'netflow.http_reason_phrase', + type: 'keyword', + }, + 'netflow.max_session_entries': { + category: 'netflow', + name: 'netflow.max_session_entries', + type: 'long', + }, + 'netflow.max_bib_entries': { + category: 'netflow', + name: 'netflow.max_bib_entries', + type: 'long', + }, + 'netflow.max_entries_per_user': { + category: 'netflow', + name: 'netflow.max_entries_per_user', + type: 'long', + }, + 'netflow.max_subscribers': { + category: 'netflow', + name: 'netflow.max_subscribers', + type: 'long', + }, + 'netflow.max_fragments_pending_reassembly': { + category: 'netflow', + name: 'netflow.max_fragments_pending_reassembly', + type: 'long', + }, + 'netflow.address_pool_high_threshold': { + category: 'netflow', + name: 'netflow.address_pool_high_threshold', + type: 'long', + }, + 'netflow.address_pool_low_threshold': { + category: 'netflow', + name: 'netflow.address_pool_low_threshold', + type: 'long', + }, + 'netflow.address_port_mapping_high_threshold': { + category: 'netflow', + name: 'netflow.address_port_mapping_high_threshold', + type: 'long', + }, + 'netflow.address_port_mapping_low_threshold': { + category: 'netflow', + name: 'netflow.address_port_mapping_low_threshold', + type: 'long', + }, + 'netflow.address_port_mapping_per_user_high_threshold': { + category: 'netflow', + name: 'netflow.address_port_mapping_per_user_high_threshold', + type: 'long', + }, + 'netflow.global_address_mapping_high_threshold': { + category: 'netflow', + name: 'netflow.global_address_mapping_high_threshold', + type: 'long', + }, + 'netflow.vpn_identifier': { + category: 'netflow', + name: 'netflow.vpn_identifier', + type: 'short', + }, + bucket_name: { + category: 'base', + description: 'Name of the S3 bucket that this log retrieved from. ', + name: 'bucket_name', + type: 'keyword', + }, + object_key: { + category: 'base', + description: 'Name of the S3 object that this log retrieved from. ', + name: 'object_key', + type: 'keyword', + }, + 'cef.version': { + category: 'cef', + description: 'Version of the CEF specification used by the message. ', + name: 'cef.version', + type: 'keyword', + }, + 'cef.device.vendor': { + category: 'cef', + description: 'Vendor of the device that produced the message. ', + name: 'cef.device.vendor', + type: 'keyword', + }, + 'cef.device.product': { + category: 'cef', + description: 'Product of the device that produced the message. ', + name: 'cef.device.product', + type: 'keyword', + }, + 'cef.device.version': { + category: 'cef', + description: 'Version of the product that produced the message. ', + name: 'cef.device.version', + type: 'keyword', + }, + 'cef.device.event_class_id': { + category: 'cef', + description: 'Unique identifier of the event type. ', + name: 'cef.device.event_class_id', + type: 'keyword', + }, + 'cef.severity': { + category: 'cef', + description: + 'Importance of the event. The valid string values are Unknown, Low, Medium, High, and Very-High. The valid integer values are 0-3=Low, 4-6=Medium, 7- 8=High, and 9-10=Very-High. ', + example: 'Very-High', + name: 'cef.severity', + type: 'keyword', + }, + 'cef.name': { + category: 'cef', + description: 'Short description of the event. ', + name: 'cef.name', + type: 'keyword', + }, + 'cef.extensions.agentAddress': { + category: 'cef', + description: 'The IP address of the ArcSight connector that processed the event.', + name: 'cef.extensions.agentAddress', + type: 'ip', + }, + 'cef.extensions.agentDnsDomain': { + category: 'cef', + description: 'The DNS domain name of the ArcSight connector that processed the event.', + name: 'cef.extensions.agentDnsDomain', + type: 'keyword', + }, + 'cef.extensions.agentHostName': { + category: 'cef', + description: 'The hostname of the ArcSight connector that processed the event.', + name: 'cef.extensions.agentHostName', + type: 'keyword', + }, + 'cef.extensions.agentId': { + category: 'cef', + description: 'The agent ID of the ArcSight connector that processed the event.', + name: 'cef.extensions.agentId', + type: 'keyword', + }, + 'cef.extensions.agentMacAddress': { + category: 'cef', + description: 'The MAC address of the ArcSight connector that processed the event.', + name: 'cef.extensions.agentMacAddress', + type: 'keyword', + }, + 'cef.extensions.agentNtDomain': { + category: 'cef', + description: 'null', + name: 'cef.extensions.agentNtDomain', + type: 'keyword', + }, + 'cef.extensions.agentReceiptTime': { + category: 'cef', + description: + 'The time at which information about the event was received by the ArcSight connector.', + name: 'cef.extensions.agentReceiptTime', + type: 'date', + }, + 'cef.extensions.agentTimeZone': { + category: 'cef', + description: 'The agent time zone of the ArcSight connector that processed the event.', + name: 'cef.extensions.agentTimeZone', + type: 'keyword', + }, + 'cef.extensions.agentTranslatedAddress': { + category: 'cef', + description: 'null', + name: 'cef.extensions.agentTranslatedAddress', + type: 'ip', + }, + 'cef.extensions.agentTranslatedZoneExternalID': { + category: 'cef', + description: 'null', + name: 'cef.extensions.agentTranslatedZoneExternalID', + type: 'keyword', + }, + 'cef.extensions.agentTranslatedZoneURI': { + category: 'cef', + description: 'null', + name: 'cef.extensions.agentTranslatedZoneURI', + type: 'keyword', + }, + 'cef.extensions.agentType': { + category: 'cef', + description: 'The agent type of the ArcSight connector that processed the event', + name: 'cef.extensions.agentType', + type: 'keyword', + }, + 'cef.extensions.agentVersion': { + category: 'cef', + description: 'The version of the ArcSight connector that processed the event.', + name: 'cef.extensions.agentVersion', + type: 'keyword', + }, + 'cef.extensions.agentZoneExternalID': { + category: 'cef', + description: 'null', + name: 'cef.extensions.agentZoneExternalID', + type: 'keyword', + }, + 'cef.extensions.agentZoneURI': { + category: 'cef', + description: 'null', + name: 'cef.extensions.agentZoneURI', + type: 'keyword', + }, + 'cef.extensions.applicationProtocol': { + category: 'cef', + description: + 'Application level protocol, example values are HTTP, HTTPS, SSHv2, Telnet, POP, IMPA, IMAPS, and so on.', + name: 'cef.extensions.applicationProtocol', + type: 'keyword', + }, + 'cef.extensions.baseEventCount': { + category: 'cef', + description: + 'A count associated with this event. How many times was this same event observed? Count can be omitted if it is 1.', + name: 'cef.extensions.baseEventCount', + type: 'long', + }, + 'cef.extensions.bytesIn': { + category: 'cef', + description: + 'Number of bytes transferred inbound, relative to the source to destination relationship, meaning that data was flowing from source to destination.', + name: 'cef.extensions.bytesIn', + type: 'long', + }, + 'cef.extensions.bytesOut': { + category: 'cef', + description: + 'Number of bytes transferred outbound relative to the source to destination relationship. For example, the byte number of data flowing from the destination to the source.', + name: 'cef.extensions.bytesOut', + type: 'long', + }, + 'cef.extensions.customerExternalID': { + category: 'cef', + description: 'null', + name: 'cef.extensions.customerExternalID', + type: 'keyword', + }, + 'cef.extensions.customerURI': { + category: 'cef', + description: 'null', + name: 'cef.extensions.customerURI', + type: 'keyword', + }, + 'cef.extensions.destinationAddress': { + category: 'cef', + description: + 'Identifies the destination address that the event refers to in an IP network. The format is an IPv4 address.', + name: 'cef.extensions.destinationAddress', + type: 'ip', + }, + 'cef.extensions.destinationDnsDomain': { + category: 'cef', + description: 'The DNS domain part of the complete fully qualified domain name (FQDN).', + name: 'cef.extensions.destinationDnsDomain', + type: 'keyword', + }, + 'cef.extensions.destinationGeoLatitude': { + category: 'cef', + description: "The latitudinal value from which the destination's IP address belongs.", + name: 'cef.extensions.destinationGeoLatitude', + type: 'double', + }, + 'cef.extensions.destinationGeoLongitude': { + category: 'cef', + description: "The longitudinal value from which the destination's IP address belongs.", + name: 'cef.extensions.destinationGeoLongitude', + type: 'double', + }, + 'cef.extensions.destinationHostName': { + category: 'cef', + description: + 'Identifies the destination that an event refers to in an IP network. The format should be a fully qualified domain name (FQDN) associated with the destination node, when a node is available.', + name: 'cef.extensions.destinationHostName', + type: 'keyword', + }, + 'cef.extensions.destinationMacAddress': { + category: 'cef', + description: 'Six colon-seperated hexadecimal numbers.', + name: 'cef.extensions.destinationMacAddress', + type: 'keyword', + }, + 'cef.extensions.destinationNtDomain': { + category: 'cef', + description: 'The Windows domain name of the destination address.', + name: 'cef.extensions.destinationNtDomain', + type: 'keyword', + }, + 'cef.extensions.destinationPort': { + category: 'cef', + description: 'The valid port numbers are between 0 and 65535.', + name: 'cef.extensions.destinationPort', + type: 'long', + }, + 'cef.extensions.destinationProcessId': { + category: 'cef', + description: + 'Provides the ID of the destination process associated with the event. For example, if an event contains process ID 105, "105" is the process ID.', + name: 'cef.extensions.destinationProcessId', + type: 'long', + }, + 'cef.extensions.destinationProcessName': { + category: 'cef', + description: "The name of the event's destination process.", + name: 'cef.extensions.destinationProcessName', + type: 'keyword', + }, + 'cef.extensions.destinationServiceName': { + category: 'cef', + description: 'The service targeted by this event.', + name: 'cef.extensions.destinationServiceName', + type: 'keyword', + }, + 'cef.extensions.destinationTranslatedAddress': { + category: 'cef', + description: 'Identifies the translated destination that the event refers to in an IP network.', + name: 'cef.extensions.destinationTranslatedAddress', + type: 'ip', + }, + 'cef.extensions.destinationTranslatedPort': { + category: 'cef', + description: + 'Port after it was translated; for example, a firewall. Valid port numbers are 0 to 65535.', + name: 'cef.extensions.destinationTranslatedPort', + type: 'long', + }, + 'cef.extensions.destinationTranslatedZoneExternalID': { + category: 'cef', + description: 'null', + name: 'cef.extensions.destinationTranslatedZoneExternalID', + type: 'keyword', + }, + 'cef.extensions.destinationTranslatedZoneURI': { + category: 'cef', + description: + 'The URI for the Translated Zone that the destination asset has been assigned to in ArcSight.', + name: 'cef.extensions.destinationTranslatedZoneURI', + type: 'keyword', + }, + 'cef.extensions.destinationUserId': { + category: 'cef', + description: + 'Identifies the destination user by ID. For example, in UNIX, the root user is generally associated with user ID 0.', + name: 'cef.extensions.destinationUserId', + type: 'keyword', + }, + 'cef.extensions.destinationUserName': { + category: 'cef', + description: + "Identifies the destination user by name. This is the user associated with the event's destination. Email addresses are often mapped into the UserName fields. The recipient is a candidate to put into this field.", + name: 'cef.extensions.destinationUserName', + type: 'keyword', + }, + 'cef.extensions.destinationUserPrivileges': { + category: 'cef', + description: + 'The typical values are "Administrator", "User", and "Guest". This identifies the destination user\'s privileges. In UNIX, for example, activity executed on the root user would be identified with destinationUser Privileges of "Administrator".', + name: 'cef.extensions.destinationUserPrivileges', + type: 'keyword', + }, + 'cef.extensions.destinationZoneExternalID': { + category: 'cef', + description: 'null', + name: 'cef.extensions.destinationZoneExternalID', + type: 'keyword', + }, + 'cef.extensions.destinationZoneURI': { + category: 'cef', + description: + 'The URI for the Zone that the destination asset has been assigned to in ArcSight.', + name: 'cef.extensions.destinationZoneURI', + type: 'keyword', + }, + 'cef.extensions.deviceAction': { + category: 'cef', + description: 'Action taken by the device.', + name: 'cef.extensions.deviceAction', + type: 'keyword', + }, + 'cef.extensions.deviceAddress': { + category: 'cef', + description: 'Identifies the device address that an event refers to in an IP network.', + name: 'cef.extensions.deviceAddress', + type: 'ip', + }, + 'cef.extensions.deviceCustomFloatingPoint1Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomFloatingPoint1Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomFloatingPoint3Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomFloatingPoint3Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomFloatingPoint4Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomFloatingPoint4Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomDate1': { + category: 'cef', + description: + 'One of two timestamp fields available to map fields that do not apply to any other in this dictionary.', + name: 'cef.extensions.deviceCustomDate1', + type: 'date', + }, + 'cef.extensions.deviceCustomDate1Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomDate1Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomDate2': { + category: 'cef', + description: + 'One of two timestamp fields available to map fields that do not apply to any other in this dictionary.', + name: 'cef.extensions.deviceCustomDate2', + type: 'date', + }, + 'cef.extensions.deviceCustomDate2Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomDate2Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomFloatingPoint1': { + category: 'cef', + description: + 'One of four floating point fields available to map fields that do not apply to any other in this dictionary.', + name: 'cef.extensions.deviceCustomFloatingPoint1', + type: 'double', + }, + 'cef.extensions.deviceCustomFloatingPoint2': { + category: 'cef', + description: + 'One of four floating point fields available to map fields that do not apply to any other in this dictionary.', + name: 'cef.extensions.deviceCustomFloatingPoint2', + type: 'double', + }, + 'cef.extensions.deviceCustomFloatingPoint2Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomFloatingPoint2Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomFloatingPoint3': { + category: 'cef', + description: + 'One of four floating point fields available to map fields that do not apply to any other in this dictionary.', + name: 'cef.extensions.deviceCustomFloatingPoint3', + type: 'double', + }, + 'cef.extensions.deviceCustomFloatingPoint4': { + category: 'cef', + description: + 'One of four floating point fields available to map fields that do not apply to any other in this dictionary.', + name: 'cef.extensions.deviceCustomFloatingPoint4', + type: 'double', + }, + 'cef.extensions.deviceCustomIPv6Address1': { + category: 'cef', + description: + 'One of four IPv6 address fields available to map fields that do not apply to any other in this dictionary.', + name: 'cef.extensions.deviceCustomIPv6Address1', + type: 'ip', + }, + 'cef.extensions.deviceCustomIPv6Address1Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomIPv6Address1Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomIPv6Address2': { + category: 'cef', + description: + 'One of four IPv6 address fields available to map fields that do not apply to any other in this dictionary.', + name: 'cef.extensions.deviceCustomIPv6Address2', + type: 'ip', + }, + 'cef.extensions.deviceCustomIPv6Address2Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomIPv6Address2Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomIPv6Address3': { + category: 'cef', + description: + 'One of four IPv6 address fields available to map fields that do not apply to any other in this dictionary.', + name: 'cef.extensions.deviceCustomIPv6Address3', + type: 'ip', + }, + 'cef.extensions.deviceCustomIPv6Address3Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomIPv6Address3Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomIPv6Address4': { + category: 'cef', + description: + 'One of four IPv6 address fields available to map fields that do not apply to any other in this dictionary.', + name: 'cef.extensions.deviceCustomIPv6Address4', + type: 'ip', + }, + 'cef.extensions.deviceCustomIPv6Address4Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomIPv6Address4Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomNumber1': { + category: 'cef', + description: + 'One of three number fields available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceCustomNumber1', + type: 'long', + }, + 'cef.extensions.deviceCustomNumber1Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomNumber1Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomNumber2': { + category: 'cef', + description: + 'One of three number fields available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceCustomNumber2', + type: 'long', + }, + 'cef.extensions.deviceCustomNumber2Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomNumber2Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomNumber3': { + category: 'cef', + description: + 'One of three number fields available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceCustomNumber3', + type: 'long', + }, + 'cef.extensions.deviceCustomNumber3Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomNumber3Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString1': { + category: 'cef', + description: + 'One of six strings available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceCustomString1', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString1Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomString1Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString2': { + category: 'cef', + description: + 'One of six strings available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceCustomString2', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString2Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomString2Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString3': { + category: 'cef', + description: + 'One of six strings available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceCustomString3', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString3Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomString3Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString4': { + category: 'cef', + description: + 'One of six strings available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceCustomString4', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString4Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomString4Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString5': { + category: 'cef', + description: + 'One of six strings available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceCustomString5', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString5Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomString5Label', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString6': { + category: 'cef', + description: + 'One of six strings available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceCustomString6', + type: 'keyword', + }, + 'cef.extensions.deviceCustomString6Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceCustomString6Label', + type: 'keyword', + }, + 'cef.extensions.deviceDirection': { + category: 'cef', + description: + 'Any information about what direction the observed communication has taken. The following values are supported - "0" for inbound or "1" for outbound.', + name: 'cef.extensions.deviceDirection', + type: 'long', + }, + 'cef.extensions.deviceDnsDomain': { + category: 'cef', + description: 'The DNS domain part of the complete fully qualified domain name (FQDN).', + name: 'cef.extensions.deviceDnsDomain', + type: 'keyword', + }, + 'cef.extensions.deviceEventCategory': { + category: 'cef', + description: + 'Represents the category assigned by the originating device. Devices often use their own categorization schema to classify event. Example "/Monitor/Disk/Read".', + name: 'cef.extensions.deviceEventCategory', + type: 'keyword', + }, + 'cef.extensions.deviceExternalId': { + category: 'cef', + description: 'A name that uniquely identifies the device generating this event.', + name: 'cef.extensions.deviceExternalId', + type: 'keyword', + }, + 'cef.extensions.deviceFacility': { + category: 'cef', + description: + 'The facility generating this event. For example, Syslog has an explicit facility associated with every event.', + name: 'cef.extensions.deviceFacility', + type: 'keyword', + }, + 'cef.extensions.deviceFlexNumber1': { + category: 'cef', + description: + 'One of two alternative number fields available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceFlexNumber1', + type: 'long', + }, + 'cef.extensions.deviceFlexNumber1Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceFlexNumber1Label', + type: 'keyword', + }, + 'cef.extensions.deviceFlexNumber2': { + category: 'cef', + description: + 'One of two alternative number fields available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible.', + name: 'cef.extensions.deviceFlexNumber2', + type: 'long', + }, + 'cef.extensions.deviceFlexNumber2Label': { + category: 'cef', + description: + 'All custom fields have a corresponding label field. Each of these fields is a string and describes the purpose of the custom field.', + name: 'cef.extensions.deviceFlexNumber2Label', + type: 'keyword', + }, + 'cef.extensions.deviceHostName': { + category: 'cef', + description: + 'The format should be a fully qualified domain name (FQDN) associated with the device node, when a node is available.', + name: 'cef.extensions.deviceHostName', + type: 'keyword', + }, + 'cef.extensions.deviceInboundInterface': { + category: 'cef', + description: 'Interface on which the packet or data entered the device.', + name: 'cef.extensions.deviceInboundInterface', + type: 'keyword', + }, + 'cef.extensions.deviceMacAddress': { + category: 'cef', + description: 'Six colon-separated hexadecimal numbers.', + name: 'cef.extensions.deviceMacAddress', + type: 'keyword', + }, + 'cef.extensions.deviceNtDomain': { + category: 'cef', + description: 'The Windows domain name of the device address.', + name: 'cef.extensions.deviceNtDomain', + type: 'keyword', + }, + 'cef.extensions.deviceOutboundInterface': { + category: 'cef', + description: 'Interface on which the packet or data left the device.', + name: 'cef.extensions.deviceOutboundInterface', + type: 'keyword', + }, + 'cef.extensions.devicePayloadId': { + category: 'cef', + description: 'Unique identifier for the payload associated with the event.', + name: 'cef.extensions.devicePayloadId', + type: 'keyword', + }, + 'cef.extensions.deviceProcessId': { + category: 'cef', + description: 'Provides the ID of the process on the device generating the event.', + name: 'cef.extensions.deviceProcessId', + type: 'long', + }, + 'cef.extensions.deviceProcessName': { + category: 'cef', + description: + 'Process name associated with the event. An example might be the process generating the syslog entry in UNIX.', + name: 'cef.extensions.deviceProcessName', + type: 'keyword', + }, + 'cef.extensions.deviceReceiptTime': { + category: 'cef', + description: + 'The time at which the event related to the activity was received. The format is MMM dd yyyy HH:mm:ss or milliseconds since epoch (Jan 1st 1970)', + name: 'cef.extensions.deviceReceiptTime', + type: 'date', + }, + 'cef.extensions.deviceTimeZone': { + category: 'cef', + description: 'The time zone for the device generating the event.', + name: 'cef.extensions.deviceTimeZone', + type: 'keyword', + }, + 'cef.extensions.deviceTranslatedAddress': { + category: 'cef', + description: + 'Identifies the translated device address that the event refers to in an IP network.', + name: 'cef.extensions.deviceTranslatedAddress', + type: 'ip', + }, + 'cef.extensions.deviceTranslatedZoneExternalID': { + category: 'cef', + description: 'null', + name: 'cef.extensions.deviceTranslatedZoneExternalID', + type: 'keyword', + }, + 'cef.extensions.deviceTranslatedZoneURI': { + category: 'cef', + description: + 'The URI for the Translated Zone that the device asset has been assigned to in ArcSight.', + name: 'cef.extensions.deviceTranslatedZoneURI', + type: 'keyword', + }, + 'cef.extensions.deviceZoneExternalID': { + category: 'cef', + description: 'null', + name: 'cef.extensions.deviceZoneExternalID', + type: 'keyword', + }, + 'cef.extensions.deviceZoneURI': { + category: 'cef', + description: 'Thee URI for the Zone that the device asset has been assigned to in ArcSight.', + name: 'cef.extensions.deviceZoneURI', + type: 'keyword', + }, + 'cef.extensions.endTime': { + category: 'cef', + description: + 'The time at which the activity related to the event ended. The format is MMM dd yyyy HH:mm:ss or milliseconds since epoch (Jan 1st1970). An example would be reporting the end of a session.', + name: 'cef.extensions.endTime', + type: 'date', + }, + 'cef.extensions.eventId': { + category: 'cef', + description: 'This is a unique ID that ArcSight assigns to each event.', + name: 'cef.extensions.eventId', + type: 'long', + }, + 'cef.extensions.eventOutcome': { + category: 'cef', + description: "Displays the outcome, usually as 'success' or 'failure'.", + name: 'cef.extensions.eventOutcome', + type: 'keyword', + }, + 'cef.extensions.externalId': { + category: 'cef', + description: + 'The ID used by an originating device. They are usually increasing numbers, associated with events.', + name: 'cef.extensions.externalId', + type: 'keyword', + }, + 'cef.extensions.fileCreateTime': { + category: 'cef', + description: 'Time when the file was created.', + name: 'cef.extensions.fileCreateTime', + type: 'date', + }, + 'cef.extensions.fileHash': { + category: 'cef', + description: 'Hash of a file.', + name: 'cef.extensions.fileHash', + type: 'keyword', + }, + 'cef.extensions.fileId': { + category: 'cef', + description: 'An ID associated with a file could be the inode.', + name: 'cef.extensions.fileId', + type: 'keyword', + }, + 'cef.extensions.fileModificationTime': { + category: 'cef', + description: 'Time when the file was last modified.', + name: 'cef.extensions.fileModificationTime', + type: 'date', + }, + 'cef.extensions.filename': { + category: 'cef', + description: 'Name of the file only (without its path).', + name: 'cef.extensions.filename', + type: 'keyword', + }, + 'cef.extensions.filePath': { + category: 'cef', + description: 'Full path to the file, including file name itself.', + name: 'cef.extensions.filePath', + type: 'keyword', + }, + 'cef.extensions.filePermission': { + category: 'cef', + description: 'Permissions of the file.', + name: 'cef.extensions.filePermission', + type: 'keyword', + }, + 'cef.extensions.fileSize': { + category: 'cef', + description: 'Size of the file.', + name: 'cef.extensions.fileSize', + type: 'long', + }, + 'cef.extensions.fileType': { + category: 'cef', + description: 'Type of file (pipe, socket, etc.)', + name: 'cef.extensions.fileType', + type: 'keyword', + }, + 'cef.extensions.flexDate1': { + category: 'cef', + description: + 'A timestamp field available to map a timestamp that does not apply to any other defined timestamp field in this dictionary. Use all flex fields sparingly and seek a more specific, dictionary supplied field when possible. These fields are typically reserved for customer use and should not be set by vendors unless necessary.', + name: 'cef.extensions.flexDate1', + type: 'date', + }, + 'cef.extensions.flexDate1Label': { + category: 'cef', + description: 'The label field is a string and describes the purpose of the flex field.', + name: 'cef.extensions.flexDate1Label', + type: 'keyword', + }, + 'cef.extensions.flexString1': { + category: 'cef', + description: + 'One of four floating point fields available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible. These fields are typically reserved for customer use and should not be set by vendors unless necessary.', + name: 'cef.extensions.flexString1', + type: 'keyword', + }, + 'cef.extensions.flexString2': { + category: 'cef', + description: + 'One of four floating point fields available to map fields that do not apply to any other in this dictionary. Use sparingly and seek a more specific, dictionary supplied field when possible. These fields are typically reserved for customer use and should not be set by vendors unless necessary.', + name: 'cef.extensions.flexString2', + type: 'keyword', + }, + 'cef.extensions.flexString1Label': { + category: 'cef', + description: 'The label field is a string and describes the purpose of the flex field.', + name: 'cef.extensions.flexString1Label', + type: 'keyword', + }, + 'cef.extensions.flexString2Label': { + category: 'cef', + description: 'The label field is a string and describes the purpose of the flex field.', + name: 'cef.extensions.flexString2Label', + type: 'keyword', + }, + 'cef.extensions.message': { + category: 'cef', + description: + 'An arbitrary message giving more details about the event. Multi-line entries can be produced by using \\n as the new line separator.', + name: 'cef.extensions.message', + type: 'keyword', + }, + 'cef.extensions.oldFileCreateTime': { + category: 'cef', + description: 'Time when old file was created.', + name: 'cef.extensions.oldFileCreateTime', + type: 'date', + }, + 'cef.extensions.oldFileHash': { + category: 'cef', + description: 'Hash of the old file.', + name: 'cef.extensions.oldFileHash', + type: 'keyword', + }, + 'cef.extensions.oldFileId': { + category: 'cef', + description: 'An ID associated with the old file could be the inode.', + name: 'cef.extensions.oldFileId', + type: 'keyword', + }, + 'cef.extensions.oldFileModificationTime': { + category: 'cef', + description: 'Time when old file was last modified.', + name: 'cef.extensions.oldFileModificationTime', + type: 'date', + }, + 'cef.extensions.oldFileName': { + category: 'cef', + description: 'Name of the old file.', + name: 'cef.extensions.oldFileName', + type: 'keyword', + }, + 'cef.extensions.oldFilePath': { + category: 'cef', + description: 'Full path to the old file, including the file name itself.', + name: 'cef.extensions.oldFilePath', + type: 'keyword', + }, + 'cef.extensions.oldFilePermission': { + category: 'cef', + description: 'Permissions of the old file.', + name: 'cef.extensions.oldFilePermission', + type: 'keyword', + }, + 'cef.extensions.oldFileSize': { + category: 'cef', + description: 'Size of the old file.', + name: 'cef.extensions.oldFileSize', + type: 'long', + }, + 'cef.extensions.oldFileType': { + category: 'cef', + description: 'Type of the old file (pipe, socket, etc.)', + name: 'cef.extensions.oldFileType', + type: 'keyword', + }, + 'cef.extensions.rawEvent': { + category: 'cef', + description: 'null', + name: 'cef.extensions.rawEvent', + type: 'keyword', + }, + 'cef.extensions.Reason': { + category: 'cef', + description: + 'The reason an audit event was generated. For example "bad password" or "unknown user". This could also be an error or return code. Example "0x1234".', + name: 'cef.extensions.Reason', + type: 'keyword', + }, + 'cef.extensions.requestClientApplication': { + category: 'cef', + description: 'The User-Agent associated with the request.', + name: 'cef.extensions.requestClientApplication', + type: 'keyword', + }, + 'cef.extensions.requestContext': { + category: 'cef', + description: + 'Description of the content from which the request originated (for example, HTTP Referrer)', + name: 'cef.extensions.requestContext', + type: 'keyword', + }, + 'cef.extensions.requestCookies': { + category: 'cef', + description: 'Cookies associated with the request.', + name: 'cef.extensions.requestCookies', + type: 'keyword', + }, + 'cef.extensions.requestMethod': { + category: 'cef', + description: 'The HTTP method used to access a URL.', + name: 'cef.extensions.requestMethod', + type: 'keyword', + }, + 'cef.extensions.requestUrl': { + category: 'cef', + description: + 'In the case of an HTTP request, this field contains the URL accessed. The URL should contain the protocol as well.', + name: 'cef.extensions.requestUrl', + type: 'keyword', + }, + 'cef.extensions.sourceAddress': { + category: 'cef', + description: 'Identifies the source that an event refers to in an IP network.', + name: 'cef.extensions.sourceAddress', + type: 'ip', + }, + 'cef.extensions.sourceDnsDomain': { + category: 'cef', + description: 'The DNS domain part of the complete fully qualified domain name (FQDN).', + name: 'cef.extensions.sourceDnsDomain', + type: 'keyword', + }, + 'cef.extensions.sourceGeoLatitude': { + category: 'cef', + description: 'null', + name: 'cef.extensions.sourceGeoLatitude', + type: 'double', + }, + 'cef.extensions.sourceGeoLongitude': { + category: 'cef', + description: 'null', + name: 'cef.extensions.sourceGeoLongitude', + type: 'double', + }, + 'cef.extensions.sourceHostName': { + category: 'cef', + description: + "Identifies the source that an event refers to in an IP network. The format should be a fully qualified domain name (FQDN) associated with the source node, when a mode is available. Examples: 'host' or 'host.domain.com'. ", + name: 'cef.extensions.sourceHostName', + type: 'keyword', + }, + 'cef.extensions.sourceMacAddress': { + category: 'cef', + description: 'Six colon-separated hexadecimal numbers.', + example: '00:0d:60:af:1b:61', + name: 'cef.extensions.sourceMacAddress', + type: 'keyword', + }, + 'cef.extensions.sourceNtDomain': { + category: 'cef', + description: 'The Windows domain name for the source address.', + name: 'cef.extensions.sourceNtDomain', + type: 'keyword', + }, + 'cef.extensions.sourcePort': { + category: 'cef', + description: 'The valid port numbers are 0 to 65535.', + name: 'cef.extensions.sourcePort', + type: 'long', + }, + 'cef.extensions.sourceProcessId': { + category: 'cef', + description: 'The ID of the source process associated with the event.', + name: 'cef.extensions.sourceProcessId', + type: 'long', + }, + 'cef.extensions.sourceProcessName': { + category: 'cef', + description: "The name of the event's source process.", + name: 'cef.extensions.sourceProcessName', + type: 'keyword', + }, + 'cef.extensions.sourceServiceName': { + category: 'cef', + description: 'The service that is responsible for generating this event.', + name: 'cef.extensions.sourceServiceName', + type: 'keyword', + }, + 'cef.extensions.sourceTranslatedAddress': { + category: 'cef', + description: 'Identifies the translated source that the event refers to in an IP network.', + name: 'cef.extensions.sourceTranslatedAddress', + type: 'ip', + }, + 'cef.extensions.sourceTranslatedPort': { + category: 'cef', + description: + 'A port number after being translated by, for example, a firewall. Valid port numbers are 0 to 65535.', + name: 'cef.extensions.sourceTranslatedPort', + type: 'long', + }, + 'cef.extensions.sourceTranslatedZoneExternalID': { + category: 'cef', + description: 'null', + name: 'cef.extensions.sourceTranslatedZoneExternalID', + type: 'keyword', + }, + 'cef.extensions.sourceTranslatedZoneURI': { + category: 'cef', + description: + 'The URI for the Translated Zone that the destination asset has been assigned to in ArcSight.', + name: 'cef.extensions.sourceTranslatedZoneURI', + type: 'keyword', + }, + 'cef.extensions.sourceUserId': { + category: 'cef', + description: + 'Identifies the source user by ID. This is the user associated with the source of the event. For example, in UNIX, the root user is generally associated with user ID 0.', + name: 'cef.extensions.sourceUserId', + type: 'keyword', + }, + 'cef.extensions.sourceUserName': { + category: 'cef', + description: + 'Identifies the source user by name. Email addresses are also mapped into the UserName fields. The sender is a candidate to put into this field.', + name: 'cef.extensions.sourceUserName', + type: 'keyword', + }, + 'cef.extensions.sourceUserPrivileges': { + category: 'cef', + description: + 'The typical values are "Administrator", "User", and "Guest". It identifies the source user\'s privileges. In UNIX, for example, activity executed by the root user would be identified with "Administrator".', + name: 'cef.extensions.sourceUserPrivileges', + type: 'keyword', + }, + 'cef.extensions.sourceZoneExternalID': { + category: 'cef', + description: 'null', + name: 'cef.extensions.sourceZoneExternalID', + type: 'keyword', + }, + 'cef.extensions.sourceZoneURI': { + category: 'cef', + description: 'The URI for the Zone that the source asset has been assigned to in ArcSight.', + name: 'cef.extensions.sourceZoneURI', + type: 'keyword', + }, + 'cef.extensions.startTime': { + category: 'cef', + description: + 'The time when the activity the event referred to started. The format is MMM dd yyyy HH:mm:ss or milliseconds since epoch (Jan 1st 1970)', + name: 'cef.extensions.startTime', + type: 'date', + }, + 'cef.extensions.transportProtocol': { + category: 'cef', + description: + 'Identifies the Layer-4 protocol used. The possible values are protocols such as TCP or UDP.', + name: 'cef.extensions.transportProtocol', + type: 'keyword', + }, + 'cef.extensions.type': { + category: 'cef', + description: + '0 means base event, 1 means aggregated, 2 means correlation, and 3 means action. This field can be omitted for base events (type 0).', + name: 'cef.extensions.type', + type: 'long', + }, + 'cef.extensions.categoryDeviceType': { + category: 'cef', + description: 'Device type. Examples - Proxy, IDS, Web Server', + name: 'cef.extensions.categoryDeviceType', + type: 'keyword', + }, + 'cef.extensions.categoryObject': { + category: 'cef', + description: + 'Object that the event is about. For example it can be an operating sytem, database, file, etc.', + name: 'cef.extensions.categoryObject', + type: 'keyword', + }, + 'cef.extensions.categoryBehavior': { + category: 'cef', + description: + "Action or a behavior associated with an event. It's what is being done to the object.", + name: 'cef.extensions.categoryBehavior', + type: 'keyword', + }, + 'cef.extensions.categoryTechnique': { + category: 'cef', + description: 'Technique being used (e.g. /DoS).', + name: 'cef.extensions.categoryTechnique', + type: 'keyword', + }, + 'cef.extensions.categoryDeviceGroup': { + category: 'cef', + description: 'General device group like Firewall.', + name: 'cef.extensions.categoryDeviceGroup', + type: 'keyword', + }, + 'cef.extensions.categorySignificance': { + category: 'cef', + description: 'Characterization of the importance of the event.', + name: 'cef.extensions.categorySignificance', + type: 'keyword', + }, + 'cef.extensions.categoryOutcome': { + category: 'cef', + description: 'Outcome of the event (e.g. sucess, failure, or attempt).', + name: 'cef.extensions.categoryOutcome', + type: 'keyword', + }, + 'cef.extensions.managerReceiptTime': { + category: 'cef', + description: 'When the Arcsight ESM received the event.', + name: 'cef.extensions.managerReceiptTime', + type: 'date', + }, + 'source.service.name': { + category: 'source', + description: 'Service that is the source of the event.', + name: 'source.service.name', + type: 'keyword', + }, + 'destination.service.name': { + category: 'destination', + description: 'Service that is the target of the event.', + name: 'destination.service.name', + type: 'keyword', + }, + type: { + category: 'base', + description: + 'The type of the transaction (for example, HTTP, MySQL, Redis, or RUM) or "flow" in case of flows. ', + name: 'type', + }, + 'server.process.name': { + category: 'server', + description: 'The name of the process that served the transaction. ', + name: 'server.process.name', + }, + 'server.process.args': { + category: 'server', + description: 'The command-line of the process that served the transaction. ', + name: 'server.process.args', + }, + 'server.process.executable': { + category: 'server', + description: 'Absolute path to the server process executable. ', + name: 'server.process.executable', + }, + 'server.process.working_directory': { + category: 'server', + description: 'The working directory of the server process. ', + name: 'server.process.working_directory', + }, + 'server.process.start': { + category: 'server', + description: 'The time the server process started. ', + name: 'server.process.start', + }, + 'client.process.name': { + category: 'client', + description: 'The name of the process that initiated the transaction. ', + name: 'client.process.name', + }, + 'client.process.args': { + category: 'client', + description: 'The command-line of the process that initiated the transaction. ', + name: 'client.process.args', + }, + 'client.process.executable': { + category: 'client', + description: 'Absolute path to the client process executable. ', + name: 'client.process.executable', + }, + 'client.process.working_directory': { + category: 'client', + description: 'The working directory of the client process. ', + name: 'client.process.working_directory', + }, + 'client.process.start': { + category: 'client', + description: 'The time the client process started. ', + name: 'client.process.start', + }, + real_ip: { + category: 'base', + description: + 'If the server initiating the transaction is a proxy, this field contains the original client IP address. For HTTP, for example, the IP address extracted from a configurable HTTP header, by default `X-Forwarded-For`. Unless this field is disabled, it always has a value, and it matches the `client_ip` for non proxy clients. ', + name: 'real_ip', + type: 'alias', + }, + transport: { + category: 'base', + description: + 'The transport protocol used for the transaction. If not specified, then tcp is assumed. ', + name: 'transport', + type: 'alias', + }, + 'flow.final': { + category: 'flow', + description: + 'Indicates if event is last event in flow. If final is false, the event reports an intermediate flow state only. ', + name: 'flow.final', + type: 'boolean', + }, + 'flow.id': { + category: 'flow', + description: 'Internal flow ID based on connection meta data and address. ', + name: 'flow.id', + }, + 'flow.vlan': { + category: 'flow', + description: + "VLAN identifier from the 802.1q frame. In case of a multi-tagged frame this field will be an array with the outer tag's VLAN identifier listed first. ", + name: 'flow.vlan', + type: 'long', + }, + flow_id: { + category: 'base', + name: 'flow_id', + type: 'alias', + }, + final: { + category: 'base', + name: 'final', + type: 'alias', + }, + vlan: { + category: 'base', + name: 'vlan', + type: 'alias', + }, + 'source.stats.net_bytes_total': { + category: 'source', + name: 'source.stats.net_bytes_total', + type: 'alias', + }, + 'source.stats.net_packets_total': { + category: 'source', + name: 'source.stats.net_packets_total', + type: 'alias', + }, + 'dest.stats.net_bytes_total': { + category: 'dest', + name: 'dest.stats.net_bytes_total', + type: 'alias', + }, + 'dest.stats.net_packets_total': { + category: 'dest', + name: 'dest.stats.net_packets_total', + type: 'alias', + }, + status: { + category: 'base', + description: + 'The high level status of the transaction. The way to compute this value depends on the protocol, but the result has a meaning independent of the protocol. ', + name: 'status', + }, + method: { + category: 'base', + description: + 'The command/verb/method of the transaction. For HTTP, this is the method name (GET, POST, PUT, and so on), for SQL this is the verb (SELECT, UPDATE, DELETE, and so on). ', + name: 'method', + }, + resource: { + category: 'base', + description: + 'The logical resource that this transaction refers to. For HTTP, this is the URL path up to the last slash (/). For example, if the URL is `/users/1`, the resource is `/users`. For databases, the resource is typically the table name. The field is not filled for all transaction types. ', + name: 'resource', + }, + path: { + category: 'base', + description: + 'The path the transaction refers to. For HTTP, this is the URL. For SQL databases, this is the table name. For key-value stores, this is the key. ', + name: 'path', + }, + query: { + category: 'base', + description: + 'The query in a human readable format. For HTTP, it will typically be something like `GET /users/_search?name=test`. For MySQL, it is something like `SELECT id from users where name=test`. ', + name: 'query', + type: 'keyword', + }, + params: { + category: 'base', + description: + 'The request parameters. For HTTP, these are the POST or GET parameters. For Thrift-RPC, these are the parameters from the request. ', + name: 'params', + type: 'text', + }, + notes: { + category: 'base', + description: + 'Messages from Packetbeat itself. This field usually contains error messages for interpreting the raw data. This information can be helpful for troubleshooting. ', + name: 'notes', + type: 'alias', + }, + request: { + category: 'base', + description: + 'For text protocols, this is the request as seen on the wire (application layer only). For binary protocols this is our representation of the request. ', + name: 'request', + type: 'text', + }, + response: { + category: 'base', + description: + 'For text protocols, this is the response as seen on the wire (application layer only). For binary protocols this is our representation of the request. ', + name: 'response', + type: 'text', + }, + bytes_in: { + category: 'base', + description: + 'The number of bytes of the request. Note that this size is the application layer message length, without the length of the IP or TCP headers. ', + name: 'bytes_in', + type: 'alias', + }, + bytes_out: { + category: 'base', + description: + 'The number of bytes of the response. Note that this size is the application layer message length, without the length of the IP or TCP headers. ', + name: 'bytes_out', + type: 'alias', + }, + 'amqp.reply-code': { + category: 'amqp', + description: 'AMQP reply code to an error, similar to http reply-code ', + example: 404, + name: 'amqp.reply-code', + type: 'long', + }, + 'amqp.reply-text': { + category: 'amqp', + description: 'Text explaining the error. ', + name: 'amqp.reply-text', + type: 'keyword', + }, + 'amqp.class-id': { + category: 'amqp', + description: 'Failing method class. ', + name: 'amqp.class-id', + type: 'long', + }, + 'amqp.method-id': { + category: 'amqp', + description: 'Failing method ID. ', + name: 'amqp.method-id', + type: 'long', + }, + 'amqp.exchange': { + category: 'amqp', + description: 'Name of the exchange. ', + name: 'amqp.exchange', + type: 'keyword', + }, + 'amqp.exchange-type': { + category: 'amqp', + description: 'Exchange type. ', + example: 'fanout', + name: 'amqp.exchange-type', + type: 'keyword', + }, + 'amqp.passive': { + category: 'amqp', + description: 'If set, do not create exchange/queue. ', + name: 'amqp.passive', + type: 'boolean', + }, + 'amqp.durable': { + category: 'amqp', + description: 'If set, request a durable exchange/queue. ', + name: 'amqp.durable', + type: 'boolean', + }, + 'amqp.exclusive': { + category: 'amqp', + description: 'If set, request an exclusive queue. ', + name: 'amqp.exclusive', + type: 'boolean', + }, + 'amqp.auto-delete': { + category: 'amqp', + description: 'If set, auto-delete queue when unused. ', + name: 'amqp.auto-delete', + type: 'boolean', + }, + 'amqp.no-wait': { + category: 'amqp', + description: 'If set, the server will not respond to the method. ', + name: 'amqp.no-wait', + type: 'boolean', + }, + 'amqp.consumer-tag': { + category: 'amqp', + description: 'Identifier for the consumer, valid within the current channel. ', + name: 'amqp.consumer-tag', + }, + 'amqp.delivery-tag': { + category: 'amqp', + description: 'The server-assigned and channel-specific delivery tag. ', + name: 'amqp.delivery-tag', + type: 'long', + }, + 'amqp.message-count': { + category: 'amqp', + description: + 'The number of messages in the queue, which will be zero for newly-declared queues. ', + name: 'amqp.message-count', + type: 'long', + }, + 'amqp.consumer-count': { + category: 'amqp', + description: 'The number of consumers of a queue. ', + name: 'amqp.consumer-count', + type: 'long', + }, + 'amqp.routing-key': { + category: 'amqp', + description: 'Message routing key. ', + name: 'amqp.routing-key', + type: 'keyword', + }, + 'amqp.no-ack': { + category: 'amqp', + description: 'If set, the server does not expect acknowledgements for messages. ', + name: 'amqp.no-ack', + type: 'boolean', + }, + 'amqp.no-local': { + category: 'amqp', + description: + 'If set, the server will not send messages to the connection that published them. ', + name: 'amqp.no-local', + type: 'boolean', + }, + 'amqp.if-unused': { + category: 'amqp', + description: 'Delete only if unused. ', + name: 'amqp.if-unused', + type: 'boolean', + }, + 'amqp.if-empty': { + category: 'amqp', + description: 'Delete only if empty. ', + name: 'amqp.if-empty', + type: 'boolean', + }, + 'amqp.queue': { + category: 'amqp', + description: 'The queue name identifies the queue within the vhost. ', + name: 'amqp.queue', + type: 'keyword', + }, + 'amqp.redelivered': { + category: 'amqp', + description: + 'Indicates that the message has been previously delivered to this or another client. ', + name: 'amqp.redelivered', + type: 'boolean', + }, + 'amqp.multiple': { + category: 'amqp', + description: 'Acknowledge multiple messages. ', + name: 'amqp.multiple', + type: 'boolean', + }, + 'amqp.arguments': { + category: 'amqp', + description: 'Optional additional arguments passed to some methods. Can be of various types. ', + name: 'amqp.arguments', + type: 'object', + }, + 'amqp.mandatory': { + category: 'amqp', + description: 'Indicates mandatory routing. ', + name: 'amqp.mandatory', + type: 'boolean', + }, + 'amqp.immediate': { + category: 'amqp', + description: 'Request immediate delivery. ', + name: 'amqp.immediate', + type: 'boolean', + }, + 'amqp.content-type': { + category: 'amqp', + description: 'MIME content type. ', + example: 'text/plain', + name: 'amqp.content-type', + type: 'keyword', + }, + 'amqp.content-encoding': { + category: 'amqp', + description: 'MIME content encoding. ', + name: 'amqp.content-encoding', + type: 'keyword', + }, + 'amqp.headers': { + category: 'amqp', + description: 'Message header field table. ', + name: 'amqp.headers', + type: 'object', + }, + 'amqp.delivery-mode': { + category: 'amqp', + description: 'Non-persistent (1) or persistent (2). ', + name: 'amqp.delivery-mode', + type: 'keyword', + }, + 'amqp.priority': { + category: 'amqp', + description: 'Message priority, 0 to 9. ', + name: 'amqp.priority', + type: 'long', + }, + 'amqp.correlation-id': { + category: 'amqp', + description: 'Application correlation identifier. ', + name: 'amqp.correlation-id', + type: 'keyword', + }, + 'amqp.reply-to': { + category: 'amqp', + description: 'Address to reply to. ', + name: 'amqp.reply-to', + type: 'keyword', + }, + 'amqp.expiration': { + category: 'amqp', + description: 'Message expiration specification. ', + name: 'amqp.expiration', + type: 'keyword', + }, + 'amqp.message-id': { + category: 'amqp', + description: 'Application message identifier. ', + name: 'amqp.message-id', + type: 'keyword', + }, + 'amqp.timestamp': { + category: 'amqp', + description: 'Message timestamp. ', + name: 'amqp.timestamp', + type: 'keyword', + }, + 'amqp.type': { + category: 'amqp', + description: 'Message type name. ', + name: 'amqp.type', + type: 'keyword', + }, + 'amqp.user-id': { + category: 'amqp', + description: 'Creating user id. ', + name: 'amqp.user-id', + type: 'keyword', + }, + 'amqp.app-id': { + category: 'amqp', + description: 'Creating application id. ', + name: 'amqp.app-id', + type: 'keyword', + }, + no_request: { + category: 'base', + name: 'no_request', + type: 'alias', + }, + 'cassandra.no_request': { + category: 'cassandra', + description: 'Indicates that there is no request because this is a PUSH message. ', + name: 'cassandra.no_request', + type: 'boolean', + }, + 'cassandra.request.headers.version': { + category: 'cassandra', + description: 'The version of the protocol.', + name: 'cassandra.request.headers.version', + type: 'long', + }, + 'cassandra.request.headers.flags': { + category: 'cassandra', + description: 'Flags applying to this frame.', + name: 'cassandra.request.headers.flags', + type: 'keyword', + }, + 'cassandra.request.headers.stream': { + category: 'cassandra', + description: + 'A frame has a stream id. If a client sends a request message with the stream id X, it is guaranteed that the stream id of the response to that message will be X.', + name: 'cassandra.request.headers.stream', + type: 'keyword', + }, + 'cassandra.request.headers.op': { + category: 'cassandra', + description: 'An operation type that distinguishes the actual message.', + name: 'cassandra.request.headers.op', + type: 'keyword', + }, + 'cassandra.request.headers.length': { + category: 'cassandra', + description: + 'A integer representing the length of the body of the frame (a frame is limited to 256MB in length).', + name: 'cassandra.request.headers.length', + type: 'long', + }, + 'cassandra.request.query': { + category: 'cassandra', + description: 'The CQL query which client send to cassandra.', + name: 'cassandra.request.query', + type: 'keyword', + }, + 'cassandra.response.headers.version': { + category: 'cassandra', + description: 'The version of the protocol.', + name: 'cassandra.response.headers.version', + type: 'long', + }, + 'cassandra.response.headers.flags': { + category: 'cassandra', + description: 'Flags applying to this frame.', + name: 'cassandra.response.headers.flags', + type: 'keyword', + }, + 'cassandra.response.headers.stream': { + category: 'cassandra', + description: + 'A frame has a stream id. If a client sends a request message with the stream id X, it is guaranteed that the stream id of the response to that message will be X.', + name: 'cassandra.response.headers.stream', + type: 'keyword', + }, + 'cassandra.response.headers.op': { + category: 'cassandra', + description: 'An operation type that distinguishes the actual message.', + name: 'cassandra.response.headers.op', + type: 'keyword', + }, + 'cassandra.response.headers.length': { + category: 'cassandra', + description: + 'A integer representing the length of the body of the frame (a frame is limited to 256MB in length).', + name: 'cassandra.response.headers.length', + type: 'long', + }, + 'cassandra.response.result.type': { + category: 'cassandra', + description: 'Cassandra result type.', + name: 'cassandra.response.result.type', + type: 'keyword', + }, + 'cassandra.response.result.rows.num_rows': { + category: 'cassandra', + description: 'Representing the number of rows present in this result.', + name: 'cassandra.response.result.rows.num_rows', + type: 'long', + }, + 'cassandra.response.result.rows.meta.keyspace': { + category: 'cassandra', + description: 'Only present after set Global_tables_spec, the keyspace name.', + name: 'cassandra.response.result.rows.meta.keyspace', + type: 'keyword', + }, + 'cassandra.response.result.rows.meta.table': { + category: 'cassandra', + description: 'Only present after set Global_tables_spec, the table name.', + name: 'cassandra.response.result.rows.meta.table', + type: 'keyword', + }, + 'cassandra.response.result.rows.meta.flags': { + category: 'cassandra', + description: 'Provides information on the formatting of the remaining information.', + name: 'cassandra.response.result.rows.meta.flags', + type: 'keyword', + }, + 'cassandra.response.result.rows.meta.col_count': { + category: 'cassandra', + description: + 'Representing the number of columns selected by the query that produced this result.', + name: 'cassandra.response.result.rows.meta.col_count', + type: 'long', + }, + 'cassandra.response.result.rows.meta.pkey_columns': { + category: 'cassandra', + description: 'Representing the PK columns index and counts.', + name: 'cassandra.response.result.rows.meta.pkey_columns', + type: 'long', + }, + 'cassandra.response.result.rows.meta.paging_state': { + category: 'cassandra', + description: + 'The paging_state is a bytes value that should be used in QUERY/EXECUTE to continue paging and retrieve the remainder of the result for this query.', + name: 'cassandra.response.result.rows.meta.paging_state', + type: 'keyword', + }, + 'cassandra.response.result.keyspace': { + category: 'cassandra', + description: 'Indicating the name of the keyspace that has been set.', + name: 'cassandra.response.result.keyspace', + type: 'keyword', + }, + 'cassandra.response.result.schema_change.change': { + category: 'cassandra', + description: 'Representing the type of changed involved.', + name: 'cassandra.response.result.schema_change.change', + type: 'keyword', + }, + 'cassandra.response.result.schema_change.keyspace': { + category: 'cassandra', + description: 'This describes which keyspace has changed.', + name: 'cassandra.response.result.schema_change.keyspace', + type: 'keyword', + }, + 'cassandra.response.result.schema_change.table': { + category: 'cassandra', + description: 'This describes which table has changed.', + name: 'cassandra.response.result.schema_change.table', + type: 'keyword', + }, + 'cassandra.response.result.schema_change.object': { + category: 'cassandra', + description: + 'This describes the name of said affected object (either the table, user type, function, or aggregate name).', + name: 'cassandra.response.result.schema_change.object', + type: 'keyword', + }, + 'cassandra.response.result.schema_change.target': { + category: 'cassandra', + description: 'Target could be "FUNCTION" or "AGGREGATE", multiple arguments.', + name: 'cassandra.response.result.schema_change.target', + type: 'keyword', + }, + 'cassandra.response.result.schema_change.name': { + category: 'cassandra', + description: 'The function/aggregate name.', + name: 'cassandra.response.result.schema_change.name', + type: 'keyword', + }, + 'cassandra.response.result.schema_change.args': { + category: 'cassandra', + description: 'One string for each argument type (as CQL type).', + name: 'cassandra.response.result.schema_change.args', + type: 'keyword', + }, + 'cassandra.response.result.prepared.prepared_id': { + category: 'cassandra', + description: 'Representing the prepared query ID.', + name: 'cassandra.response.result.prepared.prepared_id', + type: 'keyword', + }, + 'cassandra.response.result.prepared.req_meta.keyspace': { + category: 'cassandra', + description: 'Only present after set Global_tables_spec, the keyspace name.', + name: 'cassandra.response.result.prepared.req_meta.keyspace', + type: 'keyword', + }, + 'cassandra.response.result.prepared.req_meta.table': { + category: 'cassandra', + description: 'Only present after set Global_tables_spec, the table name.', + name: 'cassandra.response.result.prepared.req_meta.table', + type: 'keyword', + }, + 'cassandra.response.result.prepared.req_meta.flags': { + category: 'cassandra', + description: 'Provides information on the formatting of the remaining information.', + name: 'cassandra.response.result.prepared.req_meta.flags', + type: 'keyword', + }, + 'cassandra.response.result.prepared.req_meta.col_count': { + category: 'cassandra', + description: + 'Representing the number of columns selected by the query that produced this result.', + name: 'cassandra.response.result.prepared.req_meta.col_count', + type: 'long', + }, + 'cassandra.response.result.prepared.req_meta.pkey_columns': { + category: 'cassandra', + description: 'Representing the PK columns index and counts.', + name: 'cassandra.response.result.prepared.req_meta.pkey_columns', + type: 'long', + }, + 'cassandra.response.result.prepared.req_meta.paging_state': { + category: 'cassandra', + description: + 'The paging_state is a bytes value that should be used in QUERY/EXECUTE to continue paging and retrieve the remainder of the result for this query.', + name: 'cassandra.response.result.prepared.req_meta.paging_state', + type: 'keyword', + }, + 'cassandra.response.result.prepared.resp_meta.keyspace': { + category: 'cassandra', + description: 'Only present after set Global_tables_spec, the keyspace name.', + name: 'cassandra.response.result.prepared.resp_meta.keyspace', + type: 'keyword', + }, + 'cassandra.response.result.prepared.resp_meta.table': { + category: 'cassandra', + description: 'Only present after set Global_tables_spec, the table name.', + name: 'cassandra.response.result.prepared.resp_meta.table', + type: 'keyword', + }, + 'cassandra.response.result.prepared.resp_meta.flags': { + category: 'cassandra', + description: 'Provides information on the formatting of the remaining information.', + name: 'cassandra.response.result.prepared.resp_meta.flags', + type: 'keyword', + }, + 'cassandra.response.result.prepared.resp_meta.col_count': { + category: 'cassandra', + description: + 'Representing the number of columns selected by the query that produced this result.', + name: 'cassandra.response.result.prepared.resp_meta.col_count', + type: 'long', + }, + 'cassandra.response.result.prepared.resp_meta.pkey_columns': { + category: 'cassandra', + description: 'Representing the PK columns index and counts.', + name: 'cassandra.response.result.prepared.resp_meta.pkey_columns', + type: 'long', + }, + 'cassandra.response.result.prepared.resp_meta.paging_state': { + category: 'cassandra', + description: + 'The paging_state is a bytes value that should be used in QUERY/EXECUTE to continue paging and retrieve the remainder of the result for this query.', + name: 'cassandra.response.result.prepared.resp_meta.paging_state', + type: 'keyword', + }, + 'cassandra.response.supported': { + category: 'cassandra', + description: + 'Indicates which startup options are supported by the server. This message comes as a response to an OPTIONS message.', + name: 'cassandra.response.supported', + type: 'object', + }, + 'cassandra.response.authentication.class': { + category: 'cassandra', + description: 'Indicates the full class name of the IAuthenticator in use', + name: 'cassandra.response.authentication.class', + type: 'keyword', + }, + 'cassandra.response.warnings': { + category: 'cassandra', + description: 'The text of the warnings, only occur when Warning flag was set.', + name: 'cassandra.response.warnings', + type: 'keyword', + }, + 'cassandra.response.event.type': { + category: 'cassandra', + description: 'Representing the event type.', + name: 'cassandra.response.event.type', + type: 'keyword', + }, + 'cassandra.response.event.change': { + category: 'cassandra', + description: + 'The message corresponding respectively to the type of change followed by the address of the new/removed node.', + name: 'cassandra.response.event.change', + type: 'keyword', + }, + 'cassandra.response.event.host': { + category: 'cassandra', + description: 'Representing the node ip.', + name: 'cassandra.response.event.host', + type: 'keyword', + }, + 'cassandra.response.event.port': { + category: 'cassandra', + description: 'Representing the node port.', + name: 'cassandra.response.event.port', + type: 'long', + }, + 'cassandra.response.event.schema_change.change': { + category: 'cassandra', + description: 'Representing the type of changed involved.', + name: 'cassandra.response.event.schema_change.change', + type: 'keyword', + }, + 'cassandra.response.event.schema_change.keyspace': { + category: 'cassandra', + description: 'This describes which keyspace has changed.', + name: 'cassandra.response.event.schema_change.keyspace', + type: 'keyword', + }, + 'cassandra.response.event.schema_change.table': { + category: 'cassandra', + description: 'This describes which table has changed.', + name: 'cassandra.response.event.schema_change.table', + type: 'keyword', + }, + 'cassandra.response.event.schema_change.object': { + category: 'cassandra', + description: + 'This describes the name of said affected object (either the table, user type, function, or aggregate name).', + name: 'cassandra.response.event.schema_change.object', + type: 'keyword', + }, + 'cassandra.response.event.schema_change.target': { + category: 'cassandra', + description: 'Target could be "FUNCTION" or "AGGREGATE", multiple arguments.', + name: 'cassandra.response.event.schema_change.target', + type: 'keyword', + }, + 'cassandra.response.event.schema_change.name': { + category: 'cassandra', + description: 'The function/aggregate name.', + name: 'cassandra.response.event.schema_change.name', + type: 'keyword', + }, + 'cassandra.response.event.schema_change.args': { + category: 'cassandra', + description: 'One string for each argument type (as CQL type).', + name: 'cassandra.response.event.schema_change.args', + type: 'keyword', + }, + 'cassandra.response.error.code': { + category: 'cassandra', + description: 'The error code of the Cassandra response.', + name: 'cassandra.response.error.code', + type: 'long', + }, + 'cassandra.response.error.msg': { + category: 'cassandra', + description: 'The error message of the Cassandra response.', + name: 'cassandra.response.error.msg', + type: 'keyword', + }, + 'cassandra.response.error.type': { + category: 'cassandra', + description: 'The error type of the Cassandra response.', + name: 'cassandra.response.error.type', + type: 'keyword', + }, + 'cassandra.response.error.details.read_consistency': { + category: 'cassandra', + description: 'Representing the consistency level of the query that triggered the exception.', + name: 'cassandra.response.error.details.read_consistency', + type: 'keyword', + }, + 'cassandra.response.error.details.required': { + category: 'cassandra', + description: + 'Representing the number of nodes that should be alive to respect consistency level.', + name: 'cassandra.response.error.details.required', + type: 'long', + }, + 'cassandra.response.error.details.alive': { + category: 'cassandra', + description: + 'Representing the number of replicas that were known to be alive when the request had been processed (since an unavailable exception has been triggered).', + name: 'cassandra.response.error.details.alive', + type: 'long', + }, + 'cassandra.response.error.details.received': { + category: 'cassandra', + description: 'Representing the number of nodes having acknowledged the request.', + name: 'cassandra.response.error.details.received', + type: 'long', + }, + 'cassandra.response.error.details.blockfor': { + category: 'cassandra', + description: + 'Representing the number of replicas whose acknowledgement is required to achieve consistency level.', + name: 'cassandra.response.error.details.blockfor', + type: 'long', + }, + 'cassandra.response.error.details.write_type': { + category: 'cassandra', + description: 'Describe the type of the write that timed out.', + name: 'cassandra.response.error.details.write_type', + type: 'keyword', + }, + 'cassandra.response.error.details.data_present': { + category: 'cassandra', + description: 'It means the replica that was asked for data had responded.', + name: 'cassandra.response.error.details.data_present', + type: 'boolean', + }, + 'cassandra.response.error.details.keyspace': { + category: 'cassandra', + description: 'The keyspace of the failed function.', + name: 'cassandra.response.error.details.keyspace', + type: 'keyword', + }, + 'cassandra.response.error.details.table': { + category: 'cassandra', + description: 'The keyspace of the failed function.', + name: 'cassandra.response.error.details.table', + type: 'keyword', + }, + 'cassandra.response.error.details.stmt_id': { + category: 'cassandra', + description: 'Representing the unknown ID.', + name: 'cassandra.response.error.details.stmt_id', + type: 'keyword', + }, + 'cassandra.response.error.details.num_failures': { + category: 'cassandra', + description: + 'Representing the number of nodes that experience a failure while executing the request.', + name: 'cassandra.response.error.details.num_failures', + type: 'keyword', + }, + 'cassandra.response.error.details.function': { + category: 'cassandra', + description: 'The name of the failed function.', + name: 'cassandra.response.error.details.function', + type: 'keyword', + }, + 'cassandra.response.error.details.arg_types': { + category: 'cassandra', + description: 'One string for each argument type (as CQL type) of the failed function.', + name: 'cassandra.response.error.details.arg_types', + type: 'keyword', + }, + 'dhcpv4.transaction_id': { + category: 'dhcpv4', + description: + 'Transaction ID, a random number chosen by the client, used by the client and server to associate messages and responses between a client and a server. ', + name: 'dhcpv4.transaction_id', + type: 'keyword', + }, + 'dhcpv4.seconds': { + category: 'dhcpv4', + description: + 'Number of seconds elapsed since client began address acquisition or renewal process. ', + name: 'dhcpv4.seconds', + type: 'long', + }, + 'dhcpv4.flags': { + category: 'dhcpv4', + description: + 'Flags are set by the client to indicate how the DHCP server should its reply -- either unicast or broadcast. ', + name: 'dhcpv4.flags', + type: 'keyword', + }, + 'dhcpv4.client_ip': { + category: 'dhcpv4', + description: 'The current IP address of the client.', + name: 'dhcpv4.client_ip', + type: 'ip', + }, + 'dhcpv4.assigned_ip': { + category: 'dhcpv4', + description: + 'The IP address that the DHCP server is assigning to the client. This field is also known as "your" IP address. ', + name: 'dhcpv4.assigned_ip', + type: 'ip', + }, + 'dhcpv4.server_ip': { + category: 'dhcpv4', + description: + 'The IP address of the DHCP server that the client should use for the next step in the bootstrap process. ', + name: 'dhcpv4.server_ip', + type: 'ip', + }, + 'dhcpv4.relay_ip': { + category: 'dhcpv4', + description: + 'The relay IP address used by the client to contact the server (i.e. a DHCP relay server). ', + name: 'dhcpv4.relay_ip', + type: 'ip', + }, + 'dhcpv4.client_mac': { + category: 'dhcpv4', + description: "The client's MAC address (layer two).", + name: 'dhcpv4.client_mac', + type: 'keyword', + }, + 'dhcpv4.server_name': { + category: 'dhcpv4', + description: + 'The name of the server sending the message. Optional. Used in DHCPOFFER or DHCPACK messages. ', + name: 'dhcpv4.server_name', + type: 'keyword', + }, + 'dhcpv4.op_code': { + category: 'dhcpv4', + description: 'The message op code (bootrequest or bootreply). ', + example: 'bootreply', + name: 'dhcpv4.op_code', + type: 'keyword', + }, + 'dhcpv4.hops': { + category: 'dhcpv4', + description: 'The number of hops the DHCP message went through.', + name: 'dhcpv4.hops', + type: 'long', + }, + 'dhcpv4.hardware_type': { + category: 'dhcpv4', + description: 'The type of hardware used for the local network (Ethernet, LocalTalk, etc). ', + name: 'dhcpv4.hardware_type', + type: 'keyword', + }, + 'dhcpv4.option.message_type': { + category: 'dhcpv4', + description: + 'The specific type of DHCP message being sent (e.g. discover, offer, request, decline, ack, nak, release, inform). ', + example: 'ack', + name: 'dhcpv4.option.message_type', + type: 'keyword', + }, + 'dhcpv4.option.parameter_request_list': { + category: 'dhcpv4', + description: + 'This option is used by a DHCP client to request values for specified configuration parameters. ', + name: 'dhcpv4.option.parameter_request_list', + type: 'keyword', + }, + 'dhcpv4.option.requested_ip_address': { + category: 'dhcpv4', + description: + 'This option is used in a client request (DHCPDISCOVER) to allow the client to request that a particular IP address be assigned. ', + name: 'dhcpv4.option.requested_ip_address', + type: 'ip', + }, + 'dhcpv4.option.server_identifier': { + category: 'dhcpv4', + description: 'IP address of the individual DHCP server which handled this message. ', + name: 'dhcpv4.option.server_identifier', + type: 'ip', + }, + 'dhcpv4.option.broadcast_address': { + category: 'dhcpv4', + description: "This option specifies the broadcast address in use on the client's subnet. ", + name: 'dhcpv4.option.broadcast_address', + type: 'ip', + }, + 'dhcpv4.option.max_dhcp_message_size': { + category: 'dhcpv4', + description: + 'This option specifies the maximum length DHCP message that the client is willing to accept. ', + name: 'dhcpv4.option.max_dhcp_message_size', + type: 'long', + }, + 'dhcpv4.option.class_identifier': { + category: 'dhcpv4', + description: + "This option is used by DHCP clients to optionally identify the vendor type and configuration of a DHCP client. Vendors may choose to define specific vendor class identifiers to convey particular configuration or other identification information about a client. For example, the identifier may encode the client's hardware configuration. ", + name: 'dhcpv4.option.class_identifier', + type: 'keyword', + }, + 'dhcpv4.option.domain_name': { + category: 'dhcpv4', + description: + 'This option specifies the domain name that client should use when resolving hostnames via the Domain Name System. ', + name: 'dhcpv4.option.domain_name', + type: 'keyword', + }, + 'dhcpv4.option.dns_servers': { + category: 'dhcpv4', + description: + 'The domain name server option specifies a list of Domain Name System servers available to the client. ', + name: 'dhcpv4.option.dns_servers', + type: 'ip', + }, + 'dhcpv4.option.vendor_identifying_options': { + category: 'dhcpv4', + description: + 'A DHCP client may use this option to unambiguously identify the vendor that manufactured the hardware on which the client is running, the software in use, or an industry consortium to which the vendor belongs. This field is described in RFC 3925. ', + name: 'dhcpv4.option.vendor_identifying_options', + type: 'object', + }, + 'dhcpv4.option.subnet_mask': { + category: 'dhcpv4', + description: 'The subnet mask that the client should use on the currnet network. ', + name: 'dhcpv4.option.subnet_mask', + type: 'ip', + }, + 'dhcpv4.option.utc_time_offset_sec': { + category: 'dhcpv4', + description: + "The time offset field specifies the offset of the client's subnet in seconds from Coordinated Universal Time (UTC). ", + name: 'dhcpv4.option.utc_time_offset_sec', + type: 'long', + }, + 'dhcpv4.option.router': { + category: 'dhcpv4', + description: + "The router option specifies a list of IP addresses for routers on the client's subnet. ", + name: 'dhcpv4.option.router', + type: 'ip', + }, + 'dhcpv4.option.time_servers': { + category: 'dhcpv4', + description: + 'The time server option specifies a list of RFC 868 time servers available to the client. ', + name: 'dhcpv4.option.time_servers', + type: 'ip', + }, + 'dhcpv4.option.ntp_servers': { + category: 'dhcpv4', + description: + 'This option specifies a list of IP addresses indicating NTP servers available to the client. ', + name: 'dhcpv4.option.ntp_servers', + type: 'ip', + }, + 'dhcpv4.option.hostname': { + category: 'dhcpv4', + description: 'This option specifies the name of the client. ', + name: 'dhcpv4.option.hostname', + type: 'keyword', + }, + 'dhcpv4.option.ip_address_lease_time_sec': { + category: 'dhcpv4', + description: + 'This option is used in a client request (DHCPDISCOVER or DHCPREQUEST) to allow the client to request a lease time for the IP address. In a server reply (DHCPOFFER), a DHCP server uses this option to specify the lease time it is willing to offer. ', + name: 'dhcpv4.option.ip_address_lease_time_sec', + type: 'long', + }, + 'dhcpv4.option.message': { + category: 'dhcpv4', + description: + 'This option is used by a DHCP server to provide an error message to a DHCP client in a DHCPNAK message in the event of a failure. A client may use this option in a DHCPDECLINE message to indicate the why the client declined the offered parameters. ', + name: 'dhcpv4.option.message', + type: 'text', + }, + 'dhcpv4.option.renewal_time_sec': { + category: 'dhcpv4', + description: + 'This option specifies the time interval from address assignment until the client transitions to the RENEWING state. ', + name: 'dhcpv4.option.renewal_time_sec', + type: 'long', + }, + 'dhcpv4.option.rebinding_time_sec': { + category: 'dhcpv4', + description: + 'This option specifies the time interval from address assignment until the client transitions to the REBINDING state. ', + name: 'dhcpv4.option.rebinding_time_sec', + type: 'long', + }, + 'dhcpv4.option.boot_file_name': { + category: 'dhcpv4', + description: + "This option is used to identify a bootfile when the 'file' field in the DHCP header has been used for DHCP options. ", + name: 'dhcpv4.option.boot_file_name', + type: 'keyword', + }, + 'dns.flags.authoritative': { + category: 'dns', + description: + 'A DNS flag specifying that the responding server is an authority for the domain name used in the question. ', + name: 'dns.flags.authoritative', + type: 'boolean', + }, + 'dns.flags.recursion_available': { + category: 'dns', + description: + 'A DNS flag specifying whether recursive query support is available in the name server. ', + name: 'dns.flags.recursion_available', + type: 'boolean', + }, + 'dns.flags.recursion_desired': { + category: 'dns', + description: + 'A DNS flag specifying that the client directs the server to pursue a query recursively. Recursive query support is optional. ', + name: 'dns.flags.recursion_desired', + type: 'boolean', + }, + 'dns.flags.authentic_data': { + category: 'dns', + description: + 'A DNS flag specifying that the recursive server considers the response authentic. ', + name: 'dns.flags.authentic_data', + type: 'boolean', + }, + 'dns.flags.checking_disabled': { + category: 'dns', + description: + 'A DNS flag specifying that the client disables the server signature validation of the query. ', + name: 'dns.flags.checking_disabled', + type: 'boolean', + }, + 'dns.flags.truncated_response': { + category: 'dns', + description: 'A DNS flag specifying that only the first 512 bytes of the reply were returned. ', + name: 'dns.flags.truncated_response', + type: 'boolean', + }, + 'dns.question.etld_plus_one': { + category: 'dns', + description: + 'The effective top-level domain (eTLD) plus one more label. For example, the eTLD+1 for "foo.bar.golang.org." is "golang.org.". The data for determining the eTLD comes from an embedded copy of the data from http://publicsuffix.org.', + example: 'amazon.co.uk.', + name: 'dns.question.etld_plus_one', + }, + 'dns.answers_count': { + category: 'dns', + description: 'The number of resource records contained in the `dns.answers` field. ', + name: 'dns.answers_count', + type: 'long', + }, + 'dns.authorities': { + category: 'dns', + description: 'An array containing a dictionary for each authority section from the answer. ', + name: 'dns.authorities', + type: 'object', + }, + 'dns.authorities_count': { + category: 'dns', + description: + 'The number of resource records contained in the `dns.authorities` field. The `dns.authorities` field may or may not be included depending on the configuration of Packetbeat. ', + name: 'dns.authorities_count', + type: 'long', + }, + 'dns.authorities.name': { + category: 'dns', + description: 'The domain name to which this resource record pertains.', + example: 'example.com.', + name: 'dns.authorities.name', + }, + 'dns.authorities.type': { + category: 'dns', + description: 'The type of data contained in this resource record.', + example: 'NS', + name: 'dns.authorities.type', + }, + 'dns.authorities.class': { + category: 'dns', + description: 'The class of DNS data contained in this resource record.', + example: 'IN', + name: 'dns.authorities.class', + }, + 'dns.additionals': { + category: 'dns', + description: 'An array containing a dictionary for each additional section from the answer. ', + name: 'dns.additionals', + type: 'object', + }, + 'dns.additionals_count': { + category: 'dns', + description: + 'The number of resource records contained in the `dns.additionals` field. The `dns.additionals` field may or may not be included depending on the configuration of Packetbeat. ', + name: 'dns.additionals_count', + type: 'long', + }, + 'dns.additionals.name': { + category: 'dns', + description: 'The domain name to which this resource record pertains.', + example: 'example.com.', + name: 'dns.additionals.name', + }, + 'dns.additionals.type': { + category: 'dns', + description: 'The type of data contained in this resource record.', + example: 'NS', + name: 'dns.additionals.type', + }, + 'dns.additionals.class': { + category: 'dns', + description: 'The class of DNS data contained in this resource record.', + example: 'IN', + name: 'dns.additionals.class', + }, + 'dns.additionals.ttl': { + category: 'dns', + description: + 'The time interval in seconds that this resource record may be cached before it should be discarded. Zero values mean that the data should not be cached. ', + name: 'dns.additionals.ttl', + type: 'long', + }, + 'dns.additionals.data': { + category: 'dns', + description: + 'The data describing the resource. The meaning of this data depends on the type and class of the resource record. ', + name: 'dns.additionals.data', + }, + 'dns.opt.version': { + category: 'dns', + description: 'The EDNS version.', + example: '0', + name: 'dns.opt.version', + }, + 'dns.opt.do': { + category: 'dns', + description: 'If set, the transaction uses DNSSEC.', + name: 'dns.opt.do', + type: 'boolean', + }, + 'dns.opt.ext_rcode': { + category: 'dns', + description: 'Extended response code field.', + example: 'BADVERS', + name: 'dns.opt.ext_rcode', + }, + 'dns.opt.udp_size': { + category: 'dns', + description: "Requestor's UDP payload size (in bytes).", + name: 'dns.opt.udp_size', + type: 'long', + }, + 'http.request.headers': { + category: 'http', + description: + 'A map containing the captured header fields from the request. Which headers to capture is configurable. If headers with the same header name are present in the message, they will be separated by commas. ', + name: 'http.request.headers', + type: 'object', + }, + 'http.request.params': { + category: 'http', + name: 'http.request.params', + type: 'alias', + }, + 'http.response.status_phrase': { + category: 'http', + description: 'The HTTP status phrase.', + example: 'Not Found', + name: 'http.response.status_phrase', + }, + 'http.response.headers': { + category: 'http', + description: + 'A map containing the captured header fields from the response. Which headers to capture is configurable. If headers with the same header name are present in the message, they will be separated by commas. ', + name: 'http.response.headers', + type: 'object', + }, + 'http.response.code': { + category: 'http', + name: 'http.response.code', + type: 'alias', + }, + 'http.response.phrase': { + category: 'http', + name: 'http.response.phrase', + type: 'alias', + }, + 'icmp.version': { + category: 'icmp', + description: 'The version of the ICMP protocol.', + name: 'icmp.version', + }, + 'icmp.request.message': { + category: 'icmp', + description: 'A human readable form of the request.', + name: 'icmp.request.message', + type: 'keyword', + }, + 'icmp.request.type': { + category: 'icmp', + description: 'The request type.', + name: 'icmp.request.type', + type: 'long', + }, + 'icmp.request.code': { + category: 'icmp', + description: 'The request code.', + name: 'icmp.request.code', + type: 'long', + }, + 'icmp.response.message': { + category: 'icmp', + description: 'A human readable form of the response.', + name: 'icmp.response.message', + type: 'keyword', + }, + 'icmp.response.type': { + category: 'icmp', + description: 'The response type.', + name: 'icmp.response.type', + type: 'long', + }, + 'icmp.response.code': { + category: 'icmp', + description: 'The response code.', + name: 'icmp.response.code', + type: 'long', + }, + 'memcache.protocol_type': { + category: 'memcache', + description: + 'The memcache protocol implementation. The value can be "binary" for binary-based, "text" for text-based, or "unknown" for an unknown memcache protocol type. ', + name: 'memcache.protocol_type', + type: 'keyword', + }, + 'memcache.request.line': { + category: 'memcache', + description: 'The raw command line for unknown commands ONLY. ', + name: 'memcache.request.line', + type: 'keyword', + }, + 'memcache.request.command': { + category: 'memcache', + description: + 'The memcache command being requested in the memcache text protocol. For example "set" or "get". The binary protocol opcodes are translated into memcache text protocol commands. ', + name: 'memcache.request.command', + type: 'keyword', + }, + 'memcache.response.command': { + category: 'memcache', + description: + 'Either the text based protocol response message type or the name of the originating request if binary protocol is used. ', + name: 'memcache.response.command', + type: 'keyword', + }, + 'memcache.request.type': { + category: 'memcache', + description: + 'The memcache command classification. This value can be "UNKNOWN", "Load", "Store", "Delete", "Counter", "Info", "SlabCtrl", "LRUCrawler", "Stats", "Success", "Fail", or "Auth". ', + name: 'memcache.request.type', + type: 'keyword', + }, + 'memcache.response.type': { + category: 'memcache', + description: + 'The memcache command classification. This value can be "UNKNOWN", "Load", "Store", "Delete", "Counter", "Info", "SlabCtrl", "LRUCrawler", "Stats", "Success", "Fail", or "Auth". The text based protocol will employ any of these, whereas the binary based protocol will mirror the request commands only (see `memcache.response.status` for binary protocol). ', + name: 'memcache.response.type', + type: 'keyword', + }, + 'memcache.response.error_msg': { + category: 'memcache', + description: 'The optional error message in the memcache response (text based protocol only). ', + name: 'memcache.response.error_msg', + type: 'keyword', + }, + 'memcache.request.opcode': { + category: 'memcache', + description: 'The binary protocol message opcode name. ', + name: 'memcache.request.opcode', + type: 'keyword', + }, + 'memcache.response.opcode': { + category: 'memcache', + description: 'The binary protocol message opcode name. ', + name: 'memcache.response.opcode', + type: 'keyword', + }, + 'memcache.request.opcode_value': { + category: 'memcache', + description: 'The binary protocol message opcode value. ', + name: 'memcache.request.opcode_value', + type: 'long', + }, + 'memcache.response.opcode_value': { + category: 'memcache', + description: 'The binary protocol message opcode value. ', + name: 'memcache.response.opcode_value', + type: 'long', + }, + 'memcache.request.opaque': { + category: 'memcache', + description: + 'The binary protocol opaque header value used for correlating request with response messages. ', + name: 'memcache.request.opaque', + type: 'long', + }, + 'memcache.response.opaque': { + category: 'memcache', + description: + 'The binary protocol opaque header value used for correlating request with response messages. ', + name: 'memcache.response.opaque', + type: 'long', + }, + 'memcache.request.vbucket': { + category: 'memcache', + description: 'The vbucket index sent in the binary message. ', + name: 'memcache.request.vbucket', + type: 'long', + }, + 'memcache.response.status': { + category: 'memcache', + description: 'The textual representation of the response error code (binary protocol only). ', + name: 'memcache.response.status', + type: 'keyword', + }, + 'memcache.response.status_code': { + category: 'memcache', + description: 'The status code value returned in the response (binary protocol only). ', + name: 'memcache.response.status_code', + type: 'long', + }, + 'memcache.request.keys': { + category: 'memcache', + description: 'The list of keys sent in the store or load commands. ', + name: 'memcache.request.keys', + type: 'array', + }, + 'memcache.response.keys': { + category: 'memcache', + description: 'The list of keys returned for the load command (if present). ', + name: 'memcache.response.keys', + type: 'array', + }, + 'memcache.request.count_values': { + category: 'memcache', + description: + 'The number of values found in the memcache request message. If the command does not send any data, this field is missing. ', + name: 'memcache.request.count_values', + type: 'long', + }, + 'memcache.response.count_values': { + category: 'memcache', + description: + 'The number of values found in the memcache response message. If the command does not send any data, this field is missing. ', + name: 'memcache.response.count_values', + type: 'long', + }, + 'memcache.request.values': { + category: 'memcache', + description: 'The list of base64 encoded values sent with the request (if present). ', + name: 'memcache.request.values', + type: 'array', + }, + 'memcache.response.values': { + category: 'memcache', + description: 'The list of base64 encoded values sent with the response (if present). ', + name: 'memcache.response.values', + type: 'array', + }, + 'memcache.request.bytes': { + category: 'memcache', + description: 'The byte count of the values being transferred. ', + name: 'memcache.request.bytes', + type: 'long', + format: 'bytes', + }, + 'memcache.response.bytes': { + category: 'memcache', + description: 'The byte count of the values being transferred. ', + name: 'memcache.response.bytes', + type: 'long', + format: 'bytes', + }, + 'memcache.request.delta': { + category: 'memcache', + description: 'The counter increment/decrement delta value. ', + name: 'memcache.request.delta', + type: 'long', + }, + 'memcache.request.initial': { + category: 'memcache', + description: 'The counter increment/decrement initial value parameter (binary protocol only). ', + name: 'memcache.request.initial', + type: 'long', + }, + 'memcache.request.verbosity': { + category: 'memcache', + description: 'The value of the memcache "verbosity" command. ', + name: 'memcache.request.verbosity', + type: 'long', + }, + 'memcache.request.raw_args': { + category: 'memcache', + description: + 'The text protocol raw arguments for the "stats ..." and "lru crawl ..." commands. ', + name: 'memcache.request.raw_args', + type: 'keyword', + }, + 'memcache.request.source_class': { + category: 'memcache', + description: "The source class id in 'slab reassign' command. ", + name: 'memcache.request.source_class', + type: 'long', + }, + 'memcache.request.dest_class': { + category: 'memcache', + description: "The destination class id in 'slab reassign' command. ", + name: 'memcache.request.dest_class', + type: 'long', + }, + 'memcache.request.automove': { + category: 'memcache', + description: + 'The automove mode in the \'slab automove\' command expressed as a string. This value can be "standby"(=0), "slow"(=1), "aggressive"(=2), or the raw value if the value is unknown. ', + name: 'memcache.request.automove', + type: 'keyword', + }, + 'memcache.request.flags': { + category: 'memcache', + description: 'The memcache command flags sent in the request (if present). ', + name: 'memcache.request.flags', + type: 'long', + }, + 'memcache.response.flags': { + category: 'memcache', + description: 'The memcache message flags sent in the response (if present). ', + name: 'memcache.response.flags', + type: 'long', + }, + 'memcache.request.exptime': { + category: 'memcache', + description: + 'The data expiry time in seconds sent with the memcache command (if present). If the value is <30 days, the expiry time is relative to "now", or else it is an absolute Unix time in seconds (32-bit). ', + name: 'memcache.request.exptime', + type: 'long', + }, + 'memcache.request.sleep_us': { + category: 'memcache', + description: "The sleep setting in microseconds for the 'lru_crawler sleep' command. ", + name: 'memcache.request.sleep_us', + type: 'long', + }, + 'memcache.response.value': { + category: 'memcache', + description: 'The counter value returned by a counter operation. ', + name: 'memcache.response.value', + type: 'long', + }, + 'memcache.request.noreply': { + category: 'memcache', + description: + 'Set to true if noreply was set in the request. The `memcache.response` field will be missing. ', + name: 'memcache.request.noreply', + type: 'boolean', + }, + 'memcache.request.quiet': { + category: 'memcache', + description: 'Set to true if the binary protocol message is to be treated as a quiet message. ', + name: 'memcache.request.quiet', + type: 'boolean', + }, + 'memcache.request.cas_unique': { + category: 'memcache', + description: 'The CAS (compare-and-swap) identifier if present. ', + name: 'memcache.request.cas_unique', + type: 'long', + }, + 'memcache.response.cas_unique': { + category: 'memcache', + description: + 'The CAS (compare-and-swap) identifier to be used with CAS-based updates (if present). ', + name: 'memcache.response.cas_unique', + type: 'long', + }, + 'memcache.response.stats': { + category: 'memcache', + description: + 'The list of statistic values returned. Each entry is a dictionary with the fields "name" and "value". ', + name: 'memcache.response.stats', + type: 'array', + }, + 'memcache.response.version': { + category: 'memcache', + description: 'The returned memcache version string. ', + name: 'memcache.response.version', + type: 'keyword', + }, + 'mongodb.error': { + category: 'mongodb', + description: + 'If the MongoDB request has resulted in an error, this field contains the error message returned by the server. ', + name: 'mongodb.error', + }, + 'mongodb.fullCollectionName': { + category: 'mongodb', + description: + 'The full collection name. The full collection name is the concatenation of the database name with the collection name, using a dot (.) for the concatenation. For example, for the database foo and the collection bar, the full collection name is foo.bar. ', + name: 'mongodb.fullCollectionName', + }, + 'mongodb.numberToSkip': { + category: 'mongodb', + description: + 'Sets the number of documents to omit - starting from the first document in the resulting dataset - when returning the result of the query. ', + name: 'mongodb.numberToSkip', + type: 'long', + }, + 'mongodb.numberToReturn': { + category: 'mongodb', + description: 'The requested maximum number of documents to be returned. ', + name: 'mongodb.numberToReturn', + type: 'long', + }, + 'mongodb.numberReturned': { + category: 'mongodb', + description: 'The number of documents in the reply. ', + name: 'mongodb.numberReturned', + type: 'long', + }, + 'mongodb.startingFrom': { + category: 'mongodb', + description: 'Where in the cursor this reply is starting. ', + name: 'mongodb.startingFrom', + }, + 'mongodb.query': { + category: 'mongodb', + description: + 'A JSON document that represents the query. The query will contain one or more elements, all of which must match for a document to be included in the result set. Possible elements include $query, $orderby, $hint, $explain, and $snapshot. ', + name: 'mongodb.query', + }, + 'mongodb.returnFieldsSelector': { + category: 'mongodb', + description: + 'A JSON document that limits the fields in the returned documents. The returnFieldsSelector contains one or more elements, each of which is the name of a field that should be returned, and the integer value 1. ', + name: 'mongodb.returnFieldsSelector', + }, + 'mongodb.selector': { + category: 'mongodb', + description: + 'A BSON document that specifies the query for selecting the document to update or delete. ', + name: 'mongodb.selector', + }, + 'mongodb.update': { + category: 'mongodb', + description: + 'A BSON document that specifies the update to be performed. For information on specifying updates, see the Update Operations documentation from the MongoDB Manual. ', + name: 'mongodb.update', + }, + 'mongodb.cursorId': { + category: 'mongodb', + description: + 'The cursor identifier returned in the OP_REPLY. This must be the value that was returned from the database. ', + name: 'mongodb.cursorId', + }, + 'mysql.affected_rows': { + category: 'mysql', + description: + 'If the MySQL command is successful, this field contains the affected number of rows of the last statement. ', + name: 'mysql.affected_rows', + type: 'long', + }, + 'mysql.insert_id': { + category: 'mysql', + description: + 'If the INSERT query is successful, this field contains the id of the newly inserted row. ', + name: 'mysql.insert_id', + }, + 'mysql.num_fields': { + category: 'mysql', + description: + 'If the SELECT query is successful, this field is set to the number of fields returned. ', + name: 'mysql.num_fields', + }, + 'mysql.num_rows': { + category: 'mysql', + description: + 'If the SELECT query is successful, this field is set to the number of rows returned. ', + name: 'mysql.num_rows', + }, + 'mysql.query': { + category: 'mysql', + description: "The row mysql query as read from the transaction's request. ", + name: 'mysql.query', + }, + 'mysql.error_code': { + category: 'mysql', + description: 'The error code returned by MySQL. ', + name: 'mysql.error_code', + type: 'long', + }, + 'mysql.error_message': { + category: 'mysql', + description: 'The error info message returned by MySQL. ', + name: 'mysql.error_message', + }, + 'nfs.version': { + category: 'nfs', + description: 'NFS protocol version number.', + name: 'nfs.version', + type: 'long', + }, + 'nfs.minor_version': { + category: 'nfs', + description: 'NFS protocol minor version number.', + name: 'nfs.minor_version', + type: 'long', + }, + 'nfs.tag': { + category: 'nfs', + description: 'NFS v4 COMPOUND operation tag.', + name: 'nfs.tag', + }, + 'nfs.opcode': { + category: 'nfs', + description: 'NFS operation name, or main operation name, in case of COMPOUND calls. ', + name: 'nfs.opcode', + }, + 'nfs.status': { + category: 'nfs', + description: 'NFS operation reply status.', + name: 'nfs.status', + }, + 'rpc.xid': { + category: 'rpc', + description: 'RPC message transaction identifier.', + name: 'rpc.xid', + }, + 'rpc.status': { + category: 'rpc', + description: 'RPC message reply status.', + name: 'rpc.status', + }, + 'rpc.auth_flavor': { + category: 'rpc', + description: 'RPC authentication flavor.', + name: 'rpc.auth_flavor', + }, + 'rpc.cred.uid': { + category: 'rpc', + description: "RPC caller's user id, in case of auth-unix.", + name: 'rpc.cred.uid', + type: 'long', + }, + 'rpc.cred.gid': { + category: 'rpc', + description: "RPC caller's group id, in case of auth-unix.", + name: 'rpc.cred.gid', + type: 'long', + }, + 'rpc.cred.gids': { + category: 'rpc', + description: "RPC caller's secondary group ids, in case of auth-unix.", + name: 'rpc.cred.gids', + }, + 'rpc.cred.stamp': { + category: 'rpc', + description: 'Arbitrary ID which the caller machine may generate.', + name: 'rpc.cred.stamp', + type: 'long', + }, + 'rpc.cred.machinename': { + category: 'rpc', + description: "The name of the caller's machine.", + name: 'rpc.cred.machinename', + }, + 'rpc.call_size': { + category: 'rpc', + description: 'RPC call size with argument.', + name: 'rpc.call_size', + type: 'alias', + }, + 'rpc.reply_size': { + category: 'rpc', + description: 'RPC reply size with argument.', + name: 'rpc.reply_size', + type: 'alias', + }, + 'pgsql.error_code': { + category: 'pgsql', + description: 'The PostgreSQL error code.', + name: 'pgsql.error_code', + type: 'long', + }, + 'pgsql.error_message': { + category: 'pgsql', + description: 'The PostgreSQL error message.', + name: 'pgsql.error_message', + }, + 'pgsql.error_severity': { + category: 'pgsql', + description: 'The PostgreSQL error severity.', + name: 'pgsql.error_severity', + }, + 'pgsql.num_fields': { + category: 'pgsql', + description: + 'If the SELECT query if successful, this field is set to the number of fields returned. ', + name: 'pgsql.num_fields', + }, + 'pgsql.num_rows': { + category: 'pgsql', + description: + 'If the SELECT query if successful, this field is set to the number of rows returned. ', + name: 'pgsql.num_rows', + }, + 'redis.return_value': { + category: 'redis', + description: 'The return value of the Redis command in a human readable format. ', + name: 'redis.return_value', + }, + 'redis.error': { + category: 'redis', + description: + 'If the Redis command has resulted in an error, this field contains the error message returned by the Redis server. ', + name: 'redis.error', + }, + 'thrift.params': { + category: 'thrift', + description: + 'The RPC method call parameters in a human readable format. If the IDL files are available, the parameters use names whenever possible. Otherwise, the IDs from the message are used. ', + name: 'thrift.params', + }, + 'thrift.service': { + category: 'thrift', + description: 'The name of the Thrift-RPC service as defined in the IDL files. ', + name: 'thrift.service', + }, + 'thrift.return_value': { + category: 'thrift', + description: + 'The value returned by the Thrift-RPC call. This is encoded in a human readable format. ', + name: 'thrift.return_value', + }, + 'thrift.exceptions': { + category: 'thrift', + description: + 'If the call resulted in exceptions, this field contains the exceptions in a human readable format. ', + name: 'thrift.exceptions', + }, + 'tls.client.x509.version': { + category: 'tls', + description: 'Version of x509 format.', + example: 3, + name: 'tls.client.x509.version', + type: 'keyword', + }, + 'tls.client.x509.version_number': { + category: 'tls', + description: 'Version of x509 format.', + example: 3, + name: 'tls.client.x509.version_number', + type: 'keyword', + }, + 'tls.client.x509.serial_number': { + category: 'tls', + description: + 'Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. ', + example: '55FBB9C7DEBF09809D12CCAA', + name: 'tls.client.x509.serial_number', + type: 'keyword', + }, + 'tls.client.x509.issuer.distinguished_name': { + category: 'tls', + description: 'Distinguished name (DN) of issuing certificate authority.', + example: 'C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 High Assurance Server CA', + name: 'tls.client.x509.issuer.distinguished_name', + type: 'keyword', + }, + 'tls.client.x509.issuer.common_name': { + category: 'tls', + description: 'List of common name (CN) of issuing certificate authority.', + example: 'DigiCert SHA2 High Assurance Server CA', + name: 'tls.client.x509.issuer.common_name', + type: 'keyword', + }, + 'tls.client.x509.issuer.organizational_unit': { + category: 'tls', + description: 'List of organizational units (OU) of issuing certificate authority.', + example: 'www.digicert.com', + name: 'tls.client.x509.issuer.organizational_unit', + type: 'keyword', + }, + 'tls.client.x509.issuer.organization': { + category: 'tls', + description: 'List of organizations (O) of issuing certificate authority.', + example: 'DigiCert Inc', + name: 'tls.client.x509.issuer.organization', + type: 'keyword', + }, + 'tls.client.x509.issuer.locality': { + category: 'tls', + description: 'List of locality names (L)', + example: 'Mountain View', + name: 'tls.client.x509.issuer.locality', + type: 'keyword', + }, + 'tls.client.x509.issuer.province': { + category: 'tls', + description: 'Province or region within country.', + name: 'tls.client.x509.issuer.province', + type: 'keyword', + }, + 'tls.client.x509.issuer.state_or_province': { + category: 'tls', + description: 'List of state or province names (ST, S, or P)', + example: 'California', + name: 'tls.client.x509.issuer.state_or_province', + type: 'keyword', + }, + 'tls.client.x509.issuer.country': { + category: 'tls', + description: 'List of country (C) codes', + example: 'US', + name: 'tls.client.x509.issuer.country', + type: 'keyword', + }, + 'tls.client.x509.signature_algorithm': { + category: 'tls', + description: + 'Identifier for certificate signature algorithm. Recommend using names found in Go Lang Crypto library (See https://github.com/golang/go/blob/go1.14/src/crypto/x509/x509.go#L337-L353).', + example: 'SHA256-RSA', + name: 'tls.client.x509.signature_algorithm', + type: 'keyword', + }, + 'tls.client.x509.not_before': { + category: 'tls', + description: 'Time at which the certificate is first considered valid.', + example: '"2019-08-16T01:40:25.000Z"', + name: 'tls.client.x509.not_before', + type: 'date', + }, + 'tls.client.x509.not_after': { + category: 'tls', + description: 'Time at which the certificate is no longer considered valid.', + example: '"2020-07-16T03:15:39.000Z"', + name: 'tls.client.x509.not_after', + type: 'date', + }, + 'tls.client.x509.subject.distinguished_name': { + category: 'tls', + description: 'Distinguished name (DN) of the certificate subject entity.', + example: 'C=US, ST=California, L=San Francisco, O=Fastly, Inc., CN=r2.shared.global.fastly.net', + name: 'tls.client.x509.subject.distinguished_name', + type: 'keyword', + }, + 'tls.client.x509.subject.common_name': { + category: 'tls', + description: 'List of common names (CN) of subject.', + example: 'r2.shared.global.fastly.net', + name: 'tls.client.x509.subject.common_name', + type: 'keyword', + }, + 'tls.client.x509.subject.organizational_unit': { + category: 'tls', + description: 'List of organizational units (OU) of subject.', + name: 'tls.client.x509.subject.organizational_unit', + type: 'keyword', + }, + 'tls.client.x509.subject.organization': { + category: 'tls', + description: 'List of organizations (O) of subject.', + example: 'Fastly, Inc.', + name: 'tls.client.x509.subject.organization', + type: 'keyword', + }, + 'tls.client.x509.subject.locality': { + category: 'tls', + description: 'List of locality names (L)', + example: 'San Francisco', + name: 'tls.client.x509.subject.locality', + type: 'keyword', + }, + 'tls.client.x509.subject.province': { + category: 'tls', + description: 'Province or region within country.', + name: 'tls.client.x509.subject.province', + type: 'keyword', + }, + 'tls.client.x509.subject.state_or_province': { + category: 'tls', + description: 'List of state or province names (ST, S, or P)', + example: 'California', + name: 'tls.client.x509.subject.state_or_province', + type: 'keyword', + }, + 'tls.client.x509.subject.country': { + category: 'tls', + description: 'List of country (C) code', + example: 'US', + name: 'tls.client.x509.subject.country', + type: 'keyword', + }, + 'tls.client.x509.public_key_algorithm': { + category: 'tls', + description: 'Algorithm used to generate the public key.', + example: 'RSA', + name: 'tls.client.x509.public_key_algorithm', + type: 'keyword', + }, + 'tls.client.x509.public_key_size': { + category: 'tls', + description: 'The size of the public key space in bits.', + example: 2048, + name: 'tls.client.x509.public_key_size', + type: 'long', + }, + 'tls.client.x509.alternative_names': { + category: 'tls', + description: + 'List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses.', + example: '*.elastic.co', + name: 'tls.client.x509.alternative_names', + type: 'keyword', + }, + 'tls.server.x509.version': { + category: 'tls', + description: 'Version of x509 format.', + example: 3, + name: 'tls.server.x509.version', + type: 'keyword', + }, + 'tls.server.x509.version_number': { + category: 'tls', + description: 'Version of x509 format.', + example: 3, + name: 'tls.server.x509.version_number', + type: 'keyword', + }, + 'tls.server.x509.serial_number': { + category: 'tls', + description: + 'Unique serial number issued by the certificate authority. For consistency, if this value is alphanumeric, it should be formatted without colons and uppercase characters. ', + example: '55FBB9C7DEBF09809D12CCAA', + name: 'tls.server.x509.serial_number', + type: 'keyword', + }, + 'tls.server.x509.issuer.distinguished_name': { + category: 'tls', + description: 'Distinguished name (DN) of issuing certificate authority.', + example: 'C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 High Assurance Server CA', + name: 'tls.server.x509.issuer.distinguished_name', + type: 'keyword', + }, + 'tls.server.x509.issuer.common_name': { + category: 'tls', + description: 'List of common name (CN) of issuing certificate authority.', + example: 'DigiCert SHA2 High Assurance Server CA', + name: 'tls.server.x509.issuer.common_name', + type: 'keyword', + }, + 'tls.server.x509.issuer.organizational_unit': { + category: 'tls', + description: 'List of organizational units (OU) of issuing certificate authority.', + example: 'www.digicert.com', + name: 'tls.server.x509.issuer.organizational_unit', + type: 'keyword', + }, + 'tls.server.x509.issuer.organization': { + category: 'tls', + description: 'List of organizations (O) of issuing certificate authority.', + example: 'DigiCert Inc', + name: 'tls.server.x509.issuer.organization', + type: 'keyword', + }, + 'tls.server.x509.issuer.locality': { + category: 'tls', + description: 'List of locality names (L)', + example: 'Mountain View', + name: 'tls.server.x509.issuer.locality', + type: 'keyword', + }, + 'tls.server.x509.issuer.province': { + category: 'tls', + description: 'Province or region within country.', + name: 'tls.server.x509.issuer.province', + type: 'keyword', + }, + 'tls.server.x509.issuer.state_or_province': { + category: 'tls', + description: 'List of state or province names (ST, S, or P)', + example: 'California', + name: 'tls.server.x509.issuer.state_or_province', + type: 'keyword', + }, + 'tls.server.x509.issuer.country': { + category: 'tls', + description: 'List of country (C) codes', + example: 'US', + name: 'tls.server.x509.issuer.country', + type: 'keyword', + }, + 'tls.server.x509.signature_algorithm': { + category: 'tls', + description: + 'Identifier for certificate signature algorithm. Recommend using names found in Go Lang Crypto library (See https://github.com/golang/go/blob/go1.14/src/crypto/x509/x509.go#L337-L353).', + example: 'SHA256-RSA', + name: 'tls.server.x509.signature_algorithm', + type: 'keyword', + }, + 'tls.server.x509.not_before': { + category: 'tls', + description: 'Time at which the certificate is first considered valid.', + example: '"2019-08-16T01:40:25.000Z"', + name: 'tls.server.x509.not_before', + type: 'date', + }, + 'tls.server.x509.not_after': { + category: 'tls', + description: 'Time at which the certificate is no longer considered valid.', + example: '"2020-07-16T03:15:39.000Z"', + name: 'tls.server.x509.not_after', + type: 'date', + }, + 'tls.server.x509.subject.distinguished_name': { + category: 'tls', + description: 'Distinguished name (DN) of the certificate subject entity.', + example: 'C=US, ST=California, L=San Francisco, O=Fastly, Inc., CN=r2.shared.global.fastly.net', + name: 'tls.server.x509.subject.distinguished_name', + type: 'keyword', + }, + 'tls.server.x509.subject.common_name': { + category: 'tls', + description: 'List of common names (CN) of subject.', + example: 'r2.shared.global.fastly.net', + name: 'tls.server.x509.subject.common_name', + type: 'keyword', + }, + 'tls.server.x509.subject.organizational_unit': { + category: 'tls', + description: 'List of organizational units (OU) of subject.', + name: 'tls.server.x509.subject.organizational_unit', + type: 'keyword', + }, + 'tls.server.x509.subject.organization': { + category: 'tls', + description: 'List of organizations (O) of subject.', + example: 'Fastly, Inc.', + name: 'tls.server.x509.subject.organization', + type: 'keyword', + }, + 'tls.server.x509.subject.locality': { + category: 'tls', + description: 'List of locality names (L)', + example: 'San Francisco', + name: 'tls.server.x509.subject.locality', + type: 'keyword', + }, + 'tls.server.x509.subject.province': { + category: 'tls', + description: 'Province or region within country.', + name: 'tls.server.x509.subject.province', + type: 'keyword', + }, + 'tls.server.x509.subject.state_or_province': { + category: 'tls', + description: 'List of state or province names (ST, S, or P)', + example: 'California', + name: 'tls.server.x509.subject.state_or_province', + type: 'keyword', + }, + 'tls.server.x509.subject.country': { + category: 'tls', + description: 'List of country (C) code', + example: 'US', + name: 'tls.server.x509.subject.country', + type: 'keyword', + }, + 'tls.server.x509.public_key_algorithm': { + category: 'tls', + description: 'Algorithm used to generate the public key.', + example: 'RSA', + name: 'tls.server.x509.public_key_algorithm', + type: 'keyword', + }, + 'tls.server.x509.public_key_size': { + category: 'tls', + description: 'The size of the public key space in bits.', + example: 2048, + name: 'tls.server.x509.public_key_size', + type: 'long', + }, + 'tls.server.x509.alternative_names': { + category: 'tls', + description: + 'List of subject alternative names (SAN). Name types vary by certificate authority and certificate type but commonly contain IP addresses, DNS names (and wildcards), and email addresses.', + example: '*.elastic.co', + name: 'tls.server.x509.alternative_names', + type: 'keyword', + }, + 'tls.detailed.version': { + category: 'tls', + description: 'The version of the TLS protocol used. ', + example: 'TLS 1.3', + name: 'tls.detailed.version', + type: 'keyword', + }, + 'tls.detailed.resumption_method': { + category: 'tls', + description: + 'If the session has been resumed, the underlying method used. One of "id" for TLS session ID or "ticket" for TLS ticket extension. ', + name: 'tls.detailed.resumption_method', + type: 'keyword', + }, + 'tls.detailed.client_certificate_requested': { + category: 'tls', + description: + 'Whether the server has requested the client to authenticate itself using a client certificate. ', + name: 'tls.detailed.client_certificate_requested', + type: 'boolean', + }, + 'tls.detailed.client_hello.version': { + category: 'tls', + description: + 'The version of the TLS protocol by which the client wishes to communicate during this session. ', + name: 'tls.detailed.client_hello.version', + type: 'keyword', + }, + 'tls.detailed.client_hello.session_id': { + category: 'tls', + description: + 'Unique number to identify the session for the corresponding connection with the client. ', + name: 'tls.detailed.client_hello.session_id', + type: 'keyword', + }, + 'tls.detailed.client_hello.supported_compression_methods': { + category: 'tls', + description: + 'The list of compression methods the client supports. See https://www.iana.org/assignments/comp-meth-ids/comp-meth-ids.xhtml ', + name: 'tls.detailed.client_hello.supported_compression_methods', + type: 'keyword', + }, + 'tls.detailed.client_hello.extensions.server_name_indication': { + category: 'tls', + description: 'List of hostnames', + name: 'tls.detailed.client_hello.extensions.server_name_indication', + type: 'keyword', + }, + 'tls.detailed.client_hello.extensions.application_layer_protocol_negotiation': { + category: 'tls', + description: 'List of application-layer protocols the client is willing to use. ', + name: 'tls.detailed.client_hello.extensions.application_layer_protocol_negotiation', + type: 'keyword', + }, + 'tls.detailed.client_hello.extensions.session_ticket': { + category: 'tls', + description: + 'Length of the session ticket, if provided, or an empty string to advertise support for tickets. ', + name: 'tls.detailed.client_hello.extensions.session_ticket', + type: 'keyword', + }, + 'tls.detailed.client_hello.extensions.supported_versions': { + category: 'tls', + description: 'List of TLS versions that the client is willing to use. ', + name: 'tls.detailed.client_hello.extensions.supported_versions', + type: 'keyword', + }, + 'tls.detailed.client_hello.extensions.supported_groups': { + category: 'tls', + description: 'List of Elliptic Curve Cryptography (ECC) curve groups supported by the client. ', + name: 'tls.detailed.client_hello.extensions.supported_groups', + type: 'keyword', + }, + 'tls.detailed.client_hello.extensions.signature_algorithms': { + category: 'tls', + description: 'List of signature algorithms that may be use in digital signatures. ', + name: 'tls.detailed.client_hello.extensions.signature_algorithms', + type: 'keyword', + }, + 'tls.detailed.client_hello.extensions.ec_points_formats': { + category: 'tls', + description: + 'List of Elliptic Curve (EC) point formats. Indicates the set of point formats that the client can parse. ', + name: 'tls.detailed.client_hello.extensions.ec_points_formats', + type: 'keyword', + }, + 'tls.detailed.client_hello.extensions._unparsed_': { + category: 'tls', + description: 'List of extensions that were left unparsed by Packetbeat. ', + name: 'tls.detailed.client_hello.extensions._unparsed_', + type: 'keyword', + }, + 'tls.detailed.server_hello.version': { + category: 'tls', + description: + 'The version of the TLS protocol that is used for this session. It is the highest version supported by the server not exceeding the version requested in the client hello. ', + name: 'tls.detailed.server_hello.version', + type: 'keyword', + }, + 'tls.detailed.server_hello.selected_compression_method': { + category: 'tls', + description: + 'The compression method selected by the server from the list provided in the client hello. ', + name: 'tls.detailed.server_hello.selected_compression_method', + type: 'keyword', + }, + 'tls.detailed.server_hello.session_id': { + category: 'tls', + description: + 'Unique number to identify the session for the corresponding connection with the client. ', + name: 'tls.detailed.server_hello.session_id', + type: 'keyword', + }, + 'tls.detailed.server_hello.extensions.application_layer_protocol_negotiation': { + category: 'tls', + description: 'Negotiated application layer protocol', + name: 'tls.detailed.server_hello.extensions.application_layer_protocol_negotiation', + type: 'keyword', + }, + 'tls.detailed.server_hello.extensions.session_ticket': { + category: 'tls', + description: + 'Used to announce that a session ticket will be provided by the server. Always an empty string. ', + name: 'tls.detailed.server_hello.extensions.session_ticket', + type: 'keyword', + }, + 'tls.detailed.server_hello.extensions.supported_versions': { + category: 'tls', + description: 'Negotiated TLS version to be used. ', + name: 'tls.detailed.server_hello.extensions.supported_versions', + type: 'keyword', + }, + 'tls.detailed.server_hello.extensions.ec_points_formats': { + category: 'tls', + description: + 'List of Elliptic Curve (EC) point formats. Indicates the set of point formats that the server can parse. ', + name: 'tls.detailed.server_hello.extensions.ec_points_formats', + type: 'keyword', + }, + 'tls.detailed.server_hello.extensions._unparsed_': { + category: 'tls', + description: 'List of extensions that were left unparsed by Packetbeat. ', + name: 'tls.detailed.server_hello.extensions._unparsed_', + type: 'keyword', + }, + 'tls.detailed.client_certificate.version': { + category: 'tls', + description: 'X509 format version.', + name: 'tls.detailed.client_certificate.version', + type: 'long', + }, + 'tls.detailed.client_certificate.version_number': { + category: 'tls', + description: 'Version of x509 format.', + example: 3, + name: 'tls.detailed.client_certificate.version_number', + type: 'keyword', + }, + 'tls.detailed.client_certificate.serial_number': { + category: 'tls', + description: "The certificate's serial number.", + name: 'tls.detailed.client_certificate.serial_number', + type: 'keyword', + }, + 'tls.detailed.client_certificate.not_before': { + category: 'tls', + description: 'Date before which the certificate is not valid.', + name: 'tls.detailed.client_certificate.not_before', + type: 'date', + }, + 'tls.detailed.client_certificate.not_after': { + category: 'tls', + description: 'Date after which the certificate expires.', + name: 'tls.detailed.client_certificate.not_after', + type: 'date', + }, + 'tls.detailed.client_certificate.public_key_algorithm': { + category: 'tls', + description: "The algorithm used for this certificate's public key. One of RSA, DSA or ECDSA. ", + name: 'tls.detailed.client_certificate.public_key_algorithm', + type: 'keyword', + }, + 'tls.detailed.client_certificate.public_key_size': { + category: 'tls', + description: 'Size of the public key.', + name: 'tls.detailed.client_certificate.public_key_size', + type: 'long', + }, + 'tls.detailed.client_certificate.signature_algorithm': { + category: 'tls', + description: "The algorithm used for the certificate's signature. ", + name: 'tls.detailed.client_certificate.signature_algorithm', + type: 'keyword', + }, + 'tls.detailed.client_certificate.alternative_names': { + category: 'tls', + description: 'Subject Alternative Names for this certificate.', + name: 'tls.detailed.client_certificate.alternative_names', + type: 'keyword', + }, + 'tls.detailed.client_certificate.subject.country': { + category: 'tls', + description: 'Country code.', + name: 'tls.detailed.client_certificate.subject.country', + type: 'keyword', + }, + 'tls.detailed.client_certificate.subject.organization': { + category: 'tls', + description: 'Organization name.', + name: 'tls.detailed.client_certificate.subject.organization', + type: 'keyword', + }, + 'tls.detailed.client_certificate.subject.organizational_unit': { + category: 'tls', + description: 'Unit within organization.', + name: 'tls.detailed.client_certificate.subject.organizational_unit', + type: 'keyword', + }, + 'tls.detailed.client_certificate.subject.province': { + category: 'tls', + description: 'Province or region within country.', + name: 'tls.detailed.client_certificate.subject.province', + type: 'keyword', + }, + 'tls.detailed.client_certificate.subject.common_name': { + category: 'tls', + description: 'Name or host name identified by the certificate.', + name: 'tls.detailed.client_certificate.subject.common_name', + type: 'keyword', + }, + 'tls.detailed.client_certificate.subject.locality': { + category: 'tls', + description: 'Locality.', + name: 'tls.detailed.client_certificate.subject.locality', + type: 'keyword', + }, + 'tls.detailed.client_certificate.subject.distinguished_name': { + category: 'tls', + description: 'Distinguished name (DN) of the certificate subject entity.', + example: 'C=US, ST=California, L=San Francisco, O=Fastly, Inc., CN=r2.shared.global.fastly.net', + name: 'tls.detailed.client_certificate.subject.distinguished_name', + type: 'keyword', + }, + 'tls.detailed.client_certificate.issuer.country': { + category: 'tls', + description: 'Country code.', + name: 'tls.detailed.client_certificate.issuer.country', + type: 'keyword', + }, + 'tls.detailed.client_certificate.issuer.organization': { + category: 'tls', + description: 'Organization name.', + name: 'tls.detailed.client_certificate.issuer.organization', + type: 'keyword', + }, + 'tls.detailed.client_certificate.issuer.organizational_unit': { + category: 'tls', + description: 'Unit within organization.', + name: 'tls.detailed.client_certificate.issuer.organizational_unit', + type: 'keyword', + }, + 'tls.detailed.client_certificate.issuer.province': { + category: 'tls', + description: 'Province or region within country.', + name: 'tls.detailed.client_certificate.issuer.province', + type: 'keyword', + }, + 'tls.detailed.client_certificate.issuer.common_name': { + category: 'tls', + description: 'Name or host name identified by the certificate.', + name: 'tls.detailed.client_certificate.issuer.common_name', + type: 'keyword', + }, + 'tls.detailed.client_certificate.issuer.locality': { + category: 'tls', + description: 'Locality.', + name: 'tls.detailed.client_certificate.issuer.locality', + type: 'keyword', + }, + 'tls.detailed.client_certificate.issuer.distinguished_name': { + category: 'tls', + description: 'Distinguished name (DN) of the certificate issuer entity.', + example: 'C=US, ST=California, L=San Francisco, O=Fastly, Inc., CN=r2.shared.global.fastly.net', + name: 'tls.detailed.client_certificate.issuer.distinguished_name', + type: 'keyword', + }, + 'tls.detailed.server_certificate.version': { + category: 'tls', + description: 'X509 format version.', + name: 'tls.detailed.server_certificate.version', + type: 'long', + }, + 'tls.detailed.server_certificate.version_number': { + category: 'tls', + description: 'Version of x509 format.', + example: 3, + name: 'tls.detailed.server_certificate.version_number', + type: 'keyword', + }, + 'tls.detailed.server_certificate.serial_number': { + category: 'tls', + description: "The certificate's serial number.", + name: 'tls.detailed.server_certificate.serial_number', + type: 'keyword', + }, + 'tls.detailed.server_certificate.not_before': { + category: 'tls', + description: 'Date before which the certificate is not valid.', + name: 'tls.detailed.server_certificate.not_before', + type: 'date', + }, + 'tls.detailed.server_certificate.not_after': { + category: 'tls', + description: 'Date after which the certificate expires.', + name: 'tls.detailed.server_certificate.not_after', + type: 'date', + }, + 'tls.detailed.server_certificate.public_key_algorithm': { + category: 'tls', + description: "The algorithm used for this certificate's public key. One of RSA, DSA or ECDSA. ", + name: 'tls.detailed.server_certificate.public_key_algorithm', + type: 'keyword', + }, + 'tls.detailed.server_certificate.public_key_size': { + category: 'tls', + description: 'Size of the public key.', + name: 'tls.detailed.server_certificate.public_key_size', + type: 'long', + }, + 'tls.detailed.server_certificate.signature_algorithm': { + category: 'tls', + description: "The algorithm used for the certificate's signature. ", + name: 'tls.detailed.server_certificate.signature_algorithm', + type: 'keyword', + }, + 'tls.detailed.server_certificate.alternative_names': { + category: 'tls', + description: 'Subject Alternative Names for this certificate.', + name: 'tls.detailed.server_certificate.alternative_names', + type: 'keyword', + }, + 'tls.detailed.server_certificate.subject.country': { + category: 'tls', + description: 'Country code.', + name: 'tls.detailed.server_certificate.subject.country', + type: 'keyword', + }, + 'tls.detailed.server_certificate.subject.organization': { + category: 'tls', + description: 'Organization name.', + name: 'tls.detailed.server_certificate.subject.organization', + type: 'keyword', + }, + 'tls.detailed.server_certificate.subject.organizational_unit': { + category: 'tls', + description: 'Unit within organization.', + name: 'tls.detailed.server_certificate.subject.organizational_unit', + type: 'keyword', + }, + 'tls.detailed.server_certificate.subject.province': { + category: 'tls', + description: 'Province or region within country.', + name: 'tls.detailed.server_certificate.subject.province', + type: 'keyword', + }, + 'tls.detailed.server_certificate.subject.state_or_province': { + category: 'tls', + description: 'Province or region within country.', + name: 'tls.detailed.server_certificate.subject.state_or_province', + type: 'keyword', + }, + 'tls.detailed.server_certificate.subject.common_name': { + category: 'tls', + description: 'Name or host name identified by the certificate.', + name: 'tls.detailed.server_certificate.subject.common_name', + type: 'keyword', + }, + 'tls.detailed.server_certificate.subject.locality': { + category: 'tls', + description: 'Locality.', + name: 'tls.detailed.server_certificate.subject.locality', + type: 'keyword', + }, + 'tls.detailed.server_certificate.subject.distinguished_name': { + category: 'tls', + description: 'Distinguished name (DN) of the certificate subject entity.', + example: 'C=US, ST=California, L=San Francisco, O=Fastly, Inc., CN=r2.shared.global.fastly.net', + name: 'tls.detailed.server_certificate.subject.distinguished_name', + type: 'keyword', + }, + 'tls.detailed.server_certificate.issuer.country': { + category: 'tls', + description: 'Country code.', + name: 'tls.detailed.server_certificate.issuer.country', + type: 'keyword', + }, + 'tls.detailed.server_certificate.issuer.organization': { + category: 'tls', + description: 'Organization name.', + name: 'tls.detailed.server_certificate.issuer.organization', + type: 'keyword', + }, + 'tls.detailed.server_certificate.issuer.organizational_unit': { + category: 'tls', + description: 'Unit within organization.', + name: 'tls.detailed.server_certificate.issuer.organizational_unit', + type: 'keyword', + }, + 'tls.detailed.server_certificate.issuer.province': { + category: 'tls', + description: 'Province or region within country.', + name: 'tls.detailed.server_certificate.issuer.province', + type: 'keyword', + }, + 'tls.detailed.server_certificate.issuer.state_or_province': { + category: 'tls', + description: 'Province or region within country.', + name: 'tls.detailed.server_certificate.issuer.state_or_province', + type: 'keyword', + }, + 'tls.detailed.server_certificate.issuer.common_name': { + category: 'tls', + description: 'Name or host name identified by the certificate.', + name: 'tls.detailed.server_certificate.issuer.common_name', + type: 'keyword', + }, + 'tls.detailed.server_certificate.issuer.locality': { + category: 'tls', + description: 'Locality.', + name: 'tls.detailed.server_certificate.issuer.locality', + type: 'keyword', + }, + 'tls.detailed.server_certificate.issuer.distinguished_name': { + category: 'tls', + description: 'Distinguished name (DN) of the certificate issuer entity.', + example: 'C=US, ST=California, L=San Francisco, O=Fastly, Inc., CN=r2.shared.global.fastly.net', + name: 'tls.detailed.server_certificate.issuer.distinguished_name', + type: 'keyword', + }, + 'tls.detailed.server_certificate_chain': { + category: 'tls', + description: 'Chain of trust for the server certificate.', + name: 'tls.detailed.server_certificate_chain', + type: 'array', + }, + 'tls.detailed.client_certificate_chain': { + category: 'tls', + description: 'Chain of trust for the client certificate.', + name: 'tls.detailed.client_certificate_chain', + type: 'array', + }, + 'tls.detailed.alert_types': { + category: 'tls', + description: 'An array containing the TLS alert type for every alert received. ', + name: 'tls.detailed.alert_types', + type: 'keyword', + }, + 'tls.handshake_completed': { + category: 'tls', + name: 'tls.handshake_completed', + type: 'alias', + }, + 'tls.client_hello.supported_ciphers': { + category: 'tls', + name: 'tls.client_hello.supported_ciphers', + type: 'alias', + }, + 'tls.server_hello.selected_cipher': { + category: 'tls', + name: 'tls.server_hello.selected_cipher', + type: 'alias', + }, + 'tls.fingerprints.ja3': { + category: 'tls', + name: 'tls.fingerprints.ja3', + type: 'alias', + }, + 'tls.resumption_method': { + category: 'tls', + name: 'tls.resumption_method', + type: 'alias', + }, + 'tls.client_certificate_requested': { + category: 'tls', + name: 'tls.client_certificate_requested', + type: 'alias', + }, + 'tls.client_hello.version': { + category: 'tls', + name: 'tls.client_hello.version', + type: 'alias', + }, + 'tls.client_hello.session_id': { + category: 'tls', + name: 'tls.client_hello.session_id', + type: 'alias', + }, + 'tls.client_hello.supported_compression_methods': { + category: 'tls', + name: 'tls.client_hello.supported_compression_methods', + type: 'alias', + }, + 'tls.client_hello.extensions.server_name_indication': { + category: 'tls', + name: 'tls.client_hello.extensions.server_name_indication', + type: 'alias', + }, + 'tls.client_hello.extensions.application_layer_protocol_negotiation': { + category: 'tls', + name: 'tls.client_hello.extensions.application_layer_protocol_negotiation', + type: 'alias', + }, + 'tls.client_hello.extensions.session_ticket': { + category: 'tls', + name: 'tls.client_hello.extensions.session_ticket', + type: 'alias', + }, + 'tls.client_hello.extensions.supported_versions': { + category: 'tls', + name: 'tls.client_hello.extensions.supported_versions', + type: 'alias', + }, + 'tls.client_hello.extensions.supported_groups': { + category: 'tls', + name: 'tls.client_hello.extensions.supported_groups', + type: 'alias', + }, + 'tls.client_hello.extensions.signature_algorithms': { + category: 'tls', + name: 'tls.client_hello.extensions.signature_algorithms', + type: 'alias', + }, + 'tls.client_hello.extensions.ec_points_formats': { + category: 'tls', + name: 'tls.client_hello.extensions.ec_points_formats', + type: 'alias', + }, + 'tls.client_hello.extensions._unparsed_': { + category: 'tls', + name: 'tls.client_hello.extensions._unparsed_', + type: 'alias', + }, + 'tls.server_hello.version': { + category: 'tls', + name: 'tls.server_hello.version', + type: 'alias', + }, + 'tls.server_hello.selected_compression_method': { + category: 'tls', + name: 'tls.server_hello.selected_compression_method', + type: 'alias', + }, + 'tls.server_hello.session_id': { + category: 'tls', + name: 'tls.server_hello.session_id', + type: 'alias', + }, + 'tls.server_hello.extensions.application_layer_protocol_negotiation': { + category: 'tls', + name: 'tls.server_hello.extensions.application_layer_protocol_negotiation', + type: 'alias', + }, + 'tls.server_hello.extensions.session_ticket': { + category: 'tls', + name: 'tls.server_hello.extensions.session_ticket', + type: 'alias', + }, + 'tls.server_hello.extensions.supported_versions': { + category: 'tls', + name: 'tls.server_hello.extensions.supported_versions', + type: 'alias', + }, + 'tls.server_hello.extensions.ec_points_formats': { + category: 'tls', + name: 'tls.server_hello.extensions.ec_points_formats', + type: 'alias', + }, + 'tls.server_hello.extensions._unparsed_': { + category: 'tls', + name: 'tls.server_hello.extensions._unparsed_', + type: 'alias', + }, + 'tls.client_certificate.version': { + category: 'tls', + name: 'tls.client_certificate.version', + type: 'alias', + }, + 'tls.client_certificate.serial_number': { + category: 'tls', + name: 'tls.client_certificate.serial_number', + type: 'alias', + }, + 'tls.client_certificate.not_before': { + category: 'tls', + name: 'tls.client_certificate.not_before', + type: 'alias', + }, + 'tls.client_certificate.not_after': { + category: 'tls', + name: 'tls.client_certificate.not_after', + type: 'alias', + }, + 'tls.client_certificate.public_key_algorithm': { + category: 'tls', + name: 'tls.client_certificate.public_key_algorithm', + type: 'alias', + }, + 'tls.client_certificate.public_key_size': { + category: 'tls', + name: 'tls.client_certificate.public_key_size', + type: 'alias', + }, + 'tls.client_certificate.signature_algorithm': { + category: 'tls', + name: 'tls.client_certificate.signature_algorithm', + type: 'alias', + }, + 'tls.client_certificate.alternative_names': { + category: 'tls', + name: 'tls.client_certificate.alternative_names', + type: 'alias', + }, + 'tls.client_certificate.subject.country': { + category: 'tls', + name: 'tls.client_certificate.subject.country', + type: 'alias', + }, + 'tls.client_certificate.subject.organization': { + category: 'tls', + name: 'tls.client_certificate.subject.organization', + type: 'alias', + }, + 'tls.client_certificate.subject.organizational_unit': { + category: 'tls', + name: 'tls.client_certificate.subject.organizational_unit', + type: 'alias', + }, + 'tls.client_certificate.subject.province': { + category: 'tls', + name: 'tls.client_certificate.subject.province', + type: 'alias', + }, + 'tls.client_certificate.subject.common_name': { + category: 'tls', + name: 'tls.client_certificate.subject.common_name', + type: 'alias', + }, + 'tls.client_certificate.subject.locality': { + category: 'tls', + name: 'tls.client_certificate.subject.locality', + type: 'alias', + }, + 'tls.client_certificate.issuer.country': { + category: 'tls', + name: 'tls.client_certificate.issuer.country', + type: 'alias', + }, + 'tls.client_certificate.issuer.organization': { + category: 'tls', + name: 'tls.client_certificate.issuer.organization', + type: 'alias', + }, + 'tls.client_certificate.issuer.organizational_unit': { + category: 'tls', + name: 'tls.client_certificate.issuer.organizational_unit', + type: 'alias', + }, + 'tls.client_certificate.issuer.province': { + category: 'tls', + name: 'tls.client_certificate.issuer.province', + type: 'alias', + }, + 'tls.client_certificate.issuer.common_name': { + category: 'tls', + name: 'tls.client_certificate.issuer.common_name', + type: 'alias', + }, + 'tls.client_certificate.issuer.locality': { + category: 'tls', + name: 'tls.client_certificate.issuer.locality', + type: 'alias', + }, + 'tls.server_certificate.version': { + category: 'tls', + name: 'tls.server_certificate.version', + type: 'alias', + }, + 'tls.server_certificate.serial_number': { + category: 'tls', + name: 'tls.server_certificate.serial_number', + type: 'alias', + }, + 'tls.server_certificate.not_before': { + category: 'tls', + name: 'tls.server_certificate.not_before', + type: 'alias', + }, + 'tls.server_certificate.not_after': { + category: 'tls', + name: 'tls.server_certificate.not_after', + type: 'alias', + }, + 'tls.server_certificate.public_key_algorithm': { + category: 'tls', + name: 'tls.server_certificate.public_key_algorithm', + type: 'alias', + }, + 'tls.server_certificate.public_key_size': { + category: 'tls', + name: 'tls.server_certificate.public_key_size', + type: 'alias', + }, + 'tls.server_certificate.signature_algorithm': { + category: 'tls', + name: 'tls.server_certificate.signature_algorithm', + type: 'alias', + }, + 'tls.server_certificate.alternative_names': { + category: 'tls', + name: 'tls.server_certificate.alternative_names', + type: 'alias', + }, + 'tls.server_certificate.subject.country': { + category: 'tls', + name: 'tls.server_certificate.subject.country', + type: 'alias', + }, + 'tls.server_certificate.subject.organization': { + category: 'tls', + name: 'tls.server_certificate.subject.organization', + type: 'alias', + }, + 'tls.server_certificate.subject.organizational_unit': { + category: 'tls', + name: 'tls.server_certificate.subject.organizational_unit', + type: 'alias', + }, + 'tls.server_certificate.subject.province': { + category: 'tls', + name: 'tls.server_certificate.subject.province', + type: 'alias', + }, + 'tls.server_certificate.subject.common_name': { + category: 'tls', + name: 'tls.server_certificate.subject.common_name', + type: 'alias', + }, + 'tls.server_certificate.subject.locality': { + category: 'tls', + name: 'tls.server_certificate.subject.locality', + type: 'alias', + }, + 'tls.server_certificate.issuer.country': { + category: 'tls', + name: 'tls.server_certificate.issuer.country', + type: 'alias', + }, + 'tls.server_certificate.issuer.organization': { + category: 'tls', + name: 'tls.server_certificate.issuer.organization', + type: 'alias', + }, + 'tls.server_certificate.issuer.organizational_unit': { + category: 'tls', + name: 'tls.server_certificate.issuer.organizational_unit', + type: 'alias', + }, + 'tls.server_certificate.issuer.province': { + category: 'tls', + name: 'tls.server_certificate.issuer.province', + type: 'alias', + }, + 'tls.server_certificate.issuer.common_name': { + category: 'tls', + name: 'tls.server_certificate.issuer.common_name', + type: 'alias', + }, + 'tls.server_certificate.issuer.locality': { + category: 'tls', + name: 'tls.server_certificate.issuer.locality', + type: 'alias', + }, + 'tls.alert_types': { + category: 'tls', + name: 'tls.alert_types', + type: 'alias', + }, + 'winlog.api': { + category: 'winlog', + description: + 'The event log API type used to read the record. The possible values are "wineventlog" for the Windows Event Log API or "eventlogging" for the Event Logging API. The Event Logging API was designed for Windows Server 2003 or Windows 2000 operating systems. In Windows Vista, the event logging infrastructure was redesigned. On Windows Vista or later operating systems, the Windows Event Log API is used. Winlogbeat automatically detects which API to use for reading event logs. ', + name: 'winlog.api', + }, + 'winlog.activity_id': { + category: 'winlog', + description: + 'A globally unique identifier that identifies the current activity. The events that are published with this identifier are part of the same activity. ', + name: 'winlog.activity_id', + type: 'keyword', + }, + 'winlog.computer_name': { + category: 'winlog', + description: + 'The name of the computer that generated the record. When using Windows event forwarding, this name can differ from `agent.hostname`. ', + name: 'winlog.computer_name', + type: 'keyword', + }, + 'winlog.event_data': { + category: 'winlog', + description: + 'The event-specific data. This field is mutually exclusive with `user_data`. If you are capturing event data on versions prior to Windows Vista, the parameters in `event_data` are named `param1`, `param2`, and so on, because event log parameters are unnamed in earlier versions of Windows. ', + name: 'winlog.event_data', + type: 'object', + }, + 'winlog.event_data.AuthenticationPackageName': { + category: 'winlog', + name: 'winlog.event_data.AuthenticationPackageName', + type: 'keyword', + }, + 'winlog.event_data.Binary': { + category: 'winlog', + name: 'winlog.event_data.Binary', + type: 'keyword', + }, + 'winlog.event_data.BitlockerUserInputTime': { + category: 'winlog', + name: 'winlog.event_data.BitlockerUserInputTime', + type: 'keyword', + }, + 'winlog.event_data.BootMode': { + category: 'winlog', + name: 'winlog.event_data.BootMode', + type: 'keyword', + }, + 'winlog.event_data.BootType': { + category: 'winlog', + name: 'winlog.event_data.BootType', + type: 'keyword', + }, + 'winlog.event_data.BuildVersion': { + category: 'winlog', + name: 'winlog.event_data.BuildVersion', + type: 'keyword', + }, + 'winlog.event_data.Company': { + category: 'winlog', + name: 'winlog.event_data.Company', + type: 'keyword', + }, + 'winlog.event_data.CorruptionActionState': { + category: 'winlog', + name: 'winlog.event_data.CorruptionActionState', + type: 'keyword', + }, + 'winlog.event_data.CreationUtcTime': { + category: 'winlog', + name: 'winlog.event_data.CreationUtcTime', + type: 'keyword', + }, + 'winlog.event_data.Description': { + category: 'winlog', + name: 'winlog.event_data.Description', + type: 'keyword', + }, + 'winlog.event_data.Detail': { + category: 'winlog', + name: 'winlog.event_data.Detail', + type: 'keyword', + }, + 'winlog.event_data.DeviceName': { + category: 'winlog', + name: 'winlog.event_data.DeviceName', + type: 'keyword', + }, + 'winlog.event_data.DeviceNameLength': { + category: 'winlog', + name: 'winlog.event_data.DeviceNameLength', + type: 'keyword', + }, + 'winlog.event_data.DeviceTime': { + category: 'winlog', + name: 'winlog.event_data.DeviceTime', + type: 'keyword', + }, + 'winlog.event_data.DeviceVersionMajor': { + category: 'winlog', + name: 'winlog.event_data.DeviceVersionMajor', + type: 'keyword', + }, + 'winlog.event_data.DeviceVersionMinor': { + category: 'winlog', + name: 'winlog.event_data.DeviceVersionMinor', + type: 'keyword', + }, + 'winlog.event_data.DriveName': { + category: 'winlog', + name: 'winlog.event_data.DriveName', + type: 'keyword', + }, + 'winlog.event_data.DriverName': { + category: 'winlog', + name: 'winlog.event_data.DriverName', + type: 'keyword', + }, + 'winlog.event_data.DriverNameLength': { + category: 'winlog', + name: 'winlog.event_data.DriverNameLength', + type: 'keyword', + }, + 'winlog.event_data.DwordVal': { + category: 'winlog', + name: 'winlog.event_data.DwordVal', + type: 'keyword', + }, + 'winlog.event_data.EntryCount': { + category: 'winlog', + name: 'winlog.event_data.EntryCount', + type: 'keyword', + }, + 'winlog.event_data.ExtraInfo': { + category: 'winlog', + name: 'winlog.event_data.ExtraInfo', + type: 'keyword', + }, + 'winlog.event_data.FailureName': { + category: 'winlog', + name: 'winlog.event_data.FailureName', + type: 'keyword', + }, + 'winlog.event_data.FailureNameLength': { + category: 'winlog', + name: 'winlog.event_data.FailureNameLength', + type: 'keyword', + }, + 'winlog.event_data.FileVersion': { + category: 'winlog', + name: 'winlog.event_data.FileVersion', + type: 'keyword', + }, + 'winlog.event_data.FinalStatus': { + category: 'winlog', + name: 'winlog.event_data.FinalStatus', + type: 'keyword', + }, + 'winlog.event_data.Group': { + category: 'winlog', + name: 'winlog.event_data.Group', + type: 'keyword', + }, + 'winlog.event_data.IdleImplementation': { + category: 'winlog', + name: 'winlog.event_data.IdleImplementation', + type: 'keyword', + }, + 'winlog.event_data.IdleStateCount': { + category: 'winlog', + name: 'winlog.event_data.IdleStateCount', + type: 'keyword', + }, + 'winlog.event_data.ImpersonationLevel': { + category: 'winlog', + name: 'winlog.event_data.ImpersonationLevel', + type: 'keyword', + }, + 'winlog.event_data.IntegrityLevel': { + category: 'winlog', + name: 'winlog.event_data.IntegrityLevel', + type: 'keyword', + }, + 'winlog.event_data.IpAddress': { + category: 'winlog', + name: 'winlog.event_data.IpAddress', + type: 'keyword', + }, + 'winlog.event_data.IpPort': { + category: 'winlog', + name: 'winlog.event_data.IpPort', + type: 'keyword', + }, + 'winlog.event_data.KeyLength': { + category: 'winlog', + name: 'winlog.event_data.KeyLength', + type: 'keyword', + }, + 'winlog.event_data.LastBootGood': { + category: 'winlog', + name: 'winlog.event_data.LastBootGood', + type: 'keyword', + }, + 'winlog.event_data.LastShutdownGood': { + category: 'winlog', + name: 'winlog.event_data.LastShutdownGood', + type: 'keyword', + }, + 'winlog.event_data.LmPackageName': { + category: 'winlog', + name: 'winlog.event_data.LmPackageName', + type: 'keyword', + }, + 'winlog.event_data.LogonGuid': { + category: 'winlog', + name: 'winlog.event_data.LogonGuid', + type: 'keyword', + }, + 'winlog.event_data.LogonId': { + category: 'winlog', + name: 'winlog.event_data.LogonId', + type: 'keyword', + }, + 'winlog.event_data.LogonProcessName': { + category: 'winlog', + name: 'winlog.event_data.LogonProcessName', + type: 'keyword', + }, + 'winlog.event_data.LogonType': { + category: 'winlog', + name: 'winlog.event_data.LogonType', + type: 'keyword', + }, + 'winlog.event_data.MajorVersion': { + category: 'winlog', + name: 'winlog.event_data.MajorVersion', + type: 'keyword', + }, + 'winlog.event_data.MaximumPerformancePercent': { + category: 'winlog', + name: 'winlog.event_data.MaximumPerformancePercent', + type: 'keyword', + }, + 'winlog.event_data.MemberName': { + category: 'winlog', + name: 'winlog.event_data.MemberName', + type: 'keyword', + }, + 'winlog.event_data.MemberSid': { + category: 'winlog', + name: 'winlog.event_data.MemberSid', + type: 'keyword', + }, + 'winlog.event_data.MinimumPerformancePercent': { + category: 'winlog', + name: 'winlog.event_data.MinimumPerformancePercent', + type: 'keyword', + }, + 'winlog.event_data.MinimumThrottlePercent': { + category: 'winlog', + name: 'winlog.event_data.MinimumThrottlePercent', + type: 'keyword', + }, + 'winlog.event_data.MinorVersion': { + category: 'winlog', + name: 'winlog.event_data.MinorVersion', + type: 'keyword', + }, + 'winlog.event_data.NewProcessId': { + category: 'winlog', + name: 'winlog.event_data.NewProcessId', + type: 'keyword', + }, + 'winlog.event_data.NewProcessName': { + category: 'winlog', + name: 'winlog.event_data.NewProcessName', + type: 'keyword', + }, + 'winlog.event_data.NewSchemeGuid': { + category: 'winlog', + name: 'winlog.event_data.NewSchemeGuid', + type: 'keyword', + }, + 'winlog.event_data.NewTime': { + category: 'winlog', + name: 'winlog.event_data.NewTime', + type: 'keyword', + }, + 'winlog.event_data.NominalFrequency': { + category: 'winlog', + name: 'winlog.event_data.NominalFrequency', + type: 'keyword', + }, + 'winlog.event_data.Number': { + category: 'winlog', + name: 'winlog.event_data.Number', + type: 'keyword', + }, + 'winlog.event_data.OldSchemeGuid': { + category: 'winlog', + name: 'winlog.event_data.OldSchemeGuid', + type: 'keyword', + }, + 'winlog.event_data.OldTime': { + category: 'winlog', + name: 'winlog.event_data.OldTime', + type: 'keyword', + }, + 'winlog.event_data.OriginalFileName': { + category: 'winlog', + name: 'winlog.event_data.OriginalFileName', + type: 'keyword', + }, + 'winlog.event_data.Path': { + category: 'winlog', + name: 'winlog.event_data.Path', + type: 'keyword', + }, + 'winlog.event_data.PerformanceImplementation': { + category: 'winlog', + name: 'winlog.event_data.PerformanceImplementation', + type: 'keyword', + }, + 'winlog.event_data.PreviousCreationUtcTime': { + category: 'winlog', + name: 'winlog.event_data.PreviousCreationUtcTime', + type: 'keyword', + }, + 'winlog.event_data.PreviousTime': { + category: 'winlog', + name: 'winlog.event_data.PreviousTime', + type: 'keyword', + }, + 'winlog.event_data.PrivilegeList': { + category: 'winlog', + name: 'winlog.event_data.PrivilegeList', + type: 'keyword', + }, + 'winlog.event_data.ProcessId': { + category: 'winlog', + name: 'winlog.event_data.ProcessId', + type: 'keyword', + }, + 'winlog.event_data.ProcessName': { + category: 'winlog', + name: 'winlog.event_data.ProcessName', + type: 'keyword', + }, + 'winlog.event_data.ProcessPath': { + category: 'winlog', + name: 'winlog.event_data.ProcessPath', + type: 'keyword', + }, + 'winlog.event_data.ProcessPid': { + category: 'winlog', + name: 'winlog.event_data.ProcessPid', + type: 'keyword', + }, + 'winlog.event_data.Product': { + category: 'winlog', + name: 'winlog.event_data.Product', + type: 'keyword', + }, + 'winlog.event_data.PuaCount': { + category: 'winlog', + name: 'winlog.event_data.PuaCount', + type: 'keyword', + }, + 'winlog.event_data.PuaPolicyId': { + category: 'winlog', + name: 'winlog.event_data.PuaPolicyId', + type: 'keyword', + }, + 'winlog.event_data.QfeVersion': { + category: 'winlog', + name: 'winlog.event_data.QfeVersion', + type: 'keyword', + }, + 'winlog.event_data.Reason': { + category: 'winlog', + name: 'winlog.event_data.Reason', + type: 'keyword', + }, + 'winlog.event_data.SchemaVersion': { + category: 'winlog', + name: 'winlog.event_data.SchemaVersion', + type: 'keyword', + }, + 'winlog.event_data.ScriptBlockText': { + category: 'winlog', + name: 'winlog.event_data.ScriptBlockText', + type: 'keyword', + }, + 'winlog.event_data.ServiceName': { + category: 'winlog', + name: 'winlog.event_data.ServiceName', + type: 'keyword', + }, + 'winlog.event_data.ServiceVersion': { + category: 'winlog', + name: 'winlog.event_data.ServiceVersion', + type: 'keyword', + }, + 'winlog.event_data.ShutdownActionType': { + category: 'winlog', + name: 'winlog.event_data.ShutdownActionType', + type: 'keyword', + }, + 'winlog.event_data.ShutdownEventCode': { + category: 'winlog', + name: 'winlog.event_data.ShutdownEventCode', + type: 'keyword', + }, + 'winlog.event_data.ShutdownReason': { + category: 'winlog', + name: 'winlog.event_data.ShutdownReason', + type: 'keyword', + }, + 'winlog.event_data.Signature': { + category: 'winlog', + name: 'winlog.event_data.Signature', + type: 'keyword', + }, + 'winlog.event_data.SignatureStatus': { + category: 'winlog', + name: 'winlog.event_data.SignatureStatus', + type: 'keyword', + }, + 'winlog.event_data.Signed': { + category: 'winlog', + name: 'winlog.event_data.Signed', + type: 'keyword', + }, + 'winlog.event_data.StartTime': { + category: 'winlog', + name: 'winlog.event_data.StartTime', + type: 'keyword', + }, + 'winlog.event_data.State': { + category: 'winlog', + name: 'winlog.event_data.State', + type: 'keyword', + }, + 'winlog.event_data.Status': { + category: 'winlog', + name: 'winlog.event_data.Status', + type: 'keyword', + }, + 'winlog.event_data.StopTime': { + category: 'winlog', + name: 'winlog.event_data.StopTime', + type: 'keyword', + }, + 'winlog.event_data.SubjectDomainName': { + category: 'winlog', + name: 'winlog.event_data.SubjectDomainName', + type: 'keyword', + }, + 'winlog.event_data.SubjectLogonId': { + category: 'winlog', + name: 'winlog.event_data.SubjectLogonId', + type: 'keyword', + }, + 'winlog.event_data.SubjectUserName': { + category: 'winlog', + name: 'winlog.event_data.SubjectUserName', + type: 'keyword', + }, + 'winlog.event_data.SubjectUserSid': { + category: 'winlog', + name: 'winlog.event_data.SubjectUserSid', + type: 'keyword', + }, + 'winlog.event_data.TSId': { + category: 'winlog', + name: 'winlog.event_data.TSId', + type: 'keyword', + }, + 'winlog.event_data.TargetDomainName': { + category: 'winlog', + name: 'winlog.event_data.TargetDomainName', + type: 'keyword', + }, + 'winlog.event_data.TargetInfo': { + category: 'winlog', + name: 'winlog.event_data.TargetInfo', + type: 'keyword', + }, + 'winlog.event_data.TargetLogonGuid': { + category: 'winlog', + name: 'winlog.event_data.TargetLogonGuid', + type: 'keyword', + }, + 'winlog.event_data.TargetLogonId': { + category: 'winlog', + name: 'winlog.event_data.TargetLogonId', + type: 'keyword', + }, + 'winlog.event_data.TargetServerName': { + category: 'winlog', + name: 'winlog.event_data.TargetServerName', + type: 'keyword', + }, + 'winlog.event_data.TargetUserName': { + category: 'winlog', + name: 'winlog.event_data.TargetUserName', + type: 'keyword', + }, + 'winlog.event_data.TargetUserSid': { + category: 'winlog', + name: 'winlog.event_data.TargetUserSid', + type: 'keyword', + }, + 'winlog.event_data.TerminalSessionId': { + category: 'winlog', + name: 'winlog.event_data.TerminalSessionId', + type: 'keyword', + }, + 'winlog.event_data.TokenElevationType': { + category: 'winlog', + name: 'winlog.event_data.TokenElevationType', + type: 'keyword', + }, + 'winlog.event_data.TransmittedServices': { + category: 'winlog', + name: 'winlog.event_data.TransmittedServices', + type: 'keyword', + }, + 'winlog.event_data.UserSid': { + category: 'winlog', + name: 'winlog.event_data.UserSid', + type: 'keyword', + }, + 'winlog.event_data.Version': { + category: 'winlog', + name: 'winlog.event_data.Version', + type: 'keyword', + }, + 'winlog.event_data.Workstation': { + category: 'winlog', + name: 'winlog.event_data.Workstation', + type: 'keyword', + }, + 'winlog.event_data.param1': { + category: 'winlog', + name: 'winlog.event_data.param1', + type: 'keyword', + }, + 'winlog.event_data.param2': { + category: 'winlog', + name: 'winlog.event_data.param2', + type: 'keyword', + }, + 'winlog.event_data.param3': { + category: 'winlog', + name: 'winlog.event_data.param3', + type: 'keyword', + }, + 'winlog.event_data.param4': { + category: 'winlog', + name: 'winlog.event_data.param4', + type: 'keyword', + }, + 'winlog.event_data.param5': { + category: 'winlog', + name: 'winlog.event_data.param5', + type: 'keyword', + }, + 'winlog.event_data.param6': { + category: 'winlog', + name: 'winlog.event_data.param6', + type: 'keyword', + }, + 'winlog.event_data.param7': { + category: 'winlog', + name: 'winlog.event_data.param7', + type: 'keyword', + }, + 'winlog.event_data.param8': { + category: 'winlog', + name: 'winlog.event_data.param8', + type: 'keyword', + }, + 'winlog.event_id': { + category: 'winlog', + description: 'The event identifier. The value is specific to the source of the event. ', + name: 'winlog.event_id', + type: 'keyword', + }, + 'winlog.keywords': { + category: 'winlog', + description: 'The keywords are used to classify an event. ', + name: 'winlog.keywords', + type: 'keyword', + }, + 'winlog.channel': { + category: 'winlog', + description: + 'The name of the channel from which this record was read. This value is one of the names from the `event_logs` collection in the configuration. ', + name: 'winlog.channel', + type: 'keyword', + }, + 'winlog.record_id': { + category: 'winlog', + description: + 'The record ID of the event log record. The first record written to an event log is record number 1, and other records are numbered sequentially. If the record number reaches the maximum value (2^32^ for the Event Logging API and 2^64^ for the Windows Event Log API), the next record number will be 0. ', + name: 'winlog.record_id', + type: 'keyword', + }, + 'winlog.related_activity_id': { + category: 'winlog', + description: + 'A globally unique identifier that identifies the activity to which control was transferred to. The related events would then have this identifier as their `activity_id` identifier. ', + name: 'winlog.related_activity_id', + type: 'keyword', + }, + 'winlog.opcode': { + category: 'winlog', + description: + 'The opcode defined in the event. Task and opcode are typically used to identify the location in the application from where the event was logged. ', + name: 'winlog.opcode', + type: 'keyword', + }, + 'winlog.provider_guid': { + category: 'winlog', + description: + 'A globally unique identifier that identifies the provider that logged the event. ', + name: 'winlog.provider_guid', + type: 'keyword', + }, + 'winlog.process.pid': { + category: 'winlog', + description: 'The process_id of the Client Server Runtime Process. ', + name: 'winlog.process.pid', + type: 'long', + }, + 'winlog.provider_name': { + category: 'winlog', + description: + 'The source of the event log record (the application or service that logged the record). ', + name: 'winlog.provider_name', + type: 'keyword', + }, + 'winlog.task': { + category: 'winlog', + description: + 'The task defined in the event. Task and opcode are typically used to identify the location in the application from where the event was logged. The category used by the Event Logging API (on pre Windows Vista operating systems) is written to this field. ', + name: 'winlog.task', + type: 'keyword', + }, + 'winlog.process.thread.id': { + category: 'winlog', + name: 'winlog.process.thread.id', + type: 'long', + }, + 'winlog.user_data': { + category: 'winlog', + description: 'The event specific data. This field is mutually exclusive with `event_data`. ', + name: 'winlog.user_data', + type: 'object', + }, + 'winlog.user.identifier': { + category: 'winlog', + description: + 'The Windows security identifier (SID) of the account associated with this event. If Winlogbeat cannot resolve the SID to a name, then the `user.name`, `user.domain`, and `user.type` fields will be omitted from the event. If you discover Winlogbeat not resolving SIDs, review the log for clues as to what the problem may be. ', + example: 'S-1-5-21-3541430928-2051711210-1391384369-1001', + name: 'winlog.user.identifier', + type: 'keyword', + }, + 'winlog.user.name': { + category: 'winlog', + description: 'Name of the user associated with this event. ', + name: 'winlog.user.name', + type: 'keyword', + }, + 'winlog.user.domain': { + category: 'winlog', + description: 'The domain that the account associated with this event is a member of. ', + name: 'winlog.user.domain', + type: 'keyword', + }, + 'winlog.user.type': { + category: 'winlog', + description: 'The type of account associated with this event. ', + name: 'winlog.user.type', + type: 'keyword', + }, + 'winlog.version': { + category: 'winlog', + description: "The version number of the event's definition.", + name: 'winlog.version', + type: 'long', + }, + activity_id: { + category: 'base', + name: 'activity_id', + type: 'alias', + }, + computer_name: { + category: 'base', + name: 'computer_name', + type: 'alias', + }, + event_id: { + category: 'base', + name: 'event_id', + type: 'alias', + }, + keywords: { + category: 'base', + name: 'keywords', + type: 'alias', + }, + log_name: { + category: 'base', + name: 'log_name', + type: 'alias', + }, + message_error: { + category: 'base', + name: 'message_error', + type: 'alias', + }, + record_number: { + category: 'base', + name: 'record_number', + type: 'alias', + }, + related_activity_id: { + category: 'base', + name: 'related_activity_id', + type: 'alias', + }, + opcode: { + category: 'base', + name: 'opcode', + type: 'alias', + }, + provider_guid: { + category: 'base', + name: 'provider_guid', + type: 'alias', + }, + process_id: { + category: 'base', + name: 'process_id', + type: 'alias', + }, + source_name: { + category: 'base', + name: 'source_name', + type: 'alias', + }, + task: { + category: 'base', + name: 'task', + type: 'alias', + }, + thread_id: { + category: 'base', + name: 'thread_id', + type: 'alias', + }, + 'user.identifier': { + category: 'user', + name: 'user.identifier', + type: 'alias', + }, + 'user.type': { + category: 'user', + name: 'user.type', + type: 'alias', + }, + version: { + category: 'base', + name: 'version', + type: 'alias', + }, + xml: { + category: 'base', + name: 'xml', + type: 'alias', + }, + 'powershell.id': { + category: 'powershell', + description: 'Shell Id.', + example: 'Microsoft Powershell', + name: 'powershell.id', + type: 'keyword', + }, + 'powershell.pipeline_id': { + category: 'powershell', + description: 'Pipeline id.', + example: '1', + name: 'powershell.pipeline_id', + type: 'keyword', + }, + 'powershell.runspace_id': { + category: 'powershell', + description: 'Runspace id.', + example: '4fa9074d-45ab-4e53-9195-e91981ac2bbb', + name: 'powershell.runspace_id', + type: 'keyword', + }, + 'powershell.sequence': { + category: 'powershell', + description: 'Sequence number of the powershell execution.', + example: 1, + name: 'powershell.sequence', + type: 'long', + }, + 'powershell.total': { + category: 'powershell', + description: 'Total number of messages in the sequence.', + example: 10, + name: 'powershell.total', + type: 'long', + }, + 'powershell.command.path': { + category: 'powershell', + description: 'Path of the executed command.', + example: 'C:\\Windows\\system32\\cmd.exe', + name: 'powershell.command.path', + type: 'keyword', + }, + 'powershell.command.name': { + category: 'powershell', + description: 'Name of the executed command.', + example: 'cmd.exe', + name: 'powershell.command.name', + type: 'keyword', + }, + 'powershell.command.type': { + category: 'powershell', + description: 'Type of the executed command.', + example: 'Application', + name: 'powershell.command.type', + type: 'keyword', + }, + 'powershell.command.value': { + category: 'powershell', + description: 'The invoked command.', + example: 'Import-LocalizedData LocalizedData -filename ArchiveResources', + name: 'powershell.command.value', + type: 'text', + }, + 'powershell.command.invocation_details': { + category: 'powershell', + description: 'An array of objects containing detailed information of the executed command. ', + name: 'powershell.command.invocation_details', + type: 'array', + }, + 'powershell.command.invocation_details.type': { + category: 'powershell', + description: 'The type of detail.', + example: 'CommandInvocation', + name: 'powershell.command.invocation_details.type', + type: 'keyword', + }, + 'powershell.command.invocation_details.related_command': { + category: 'powershell', + description: 'The command to which the detail is related to.', + example: 'Add-Type', + name: 'powershell.command.invocation_details.related_command', + type: 'keyword', + }, + 'powershell.command.invocation_details.name': { + category: 'powershell', + description: 'Only used for ParameterBinding detail type. Indicates the parameter name. ', + example: 'AssemblyName', + name: 'powershell.command.invocation_details.name', + type: 'keyword', + }, + 'powershell.command.invocation_details.value': { + category: 'powershell', + description: 'The value of the detail. The meaning of it will depend on the detail type. ', + example: 'System.IO.Compression.FileSystem', + name: 'powershell.command.invocation_details.value', + type: 'text', + }, + 'powershell.connected_user.domain': { + category: 'powershell', + description: 'User domain.', + example: 'VAGRANT', + name: 'powershell.connected_user.domain', + type: 'keyword', + }, + 'powershell.connected_user.name': { + category: 'powershell', + description: 'User name.', + example: 'vagrant', + name: 'powershell.connected_user.name', + type: 'keyword', + }, + 'powershell.engine.version': { + category: 'powershell', + description: 'Version of the PowerShell engine version used to execute the command.', + example: '5.1.17763.1007', + name: 'powershell.engine.version', + type: 'keyword', + }, + 'powershell.engine.previous_state': { + category: 'powershell', + description: 'Previous state of the PowerShell engine. ', + example: 'Available', + name: 'powershell.engine.previous_state', + type: 'keyword', + }, + 'powershell.engine.new_state': { + category: 'powershell', + description: 'New state of the PowerShell engine. ', + example: 'Stopped', + name: 'powershell.engine.new_state', + type: 'keyword', + }, + 'powershell.file.script_block_id': { + category: 'powershell', + description: 'Id of the executed script block.', + example: '50d2dbda-7361-4926-a94d-d9eadfdb43fa', + name: 'powershell.file.script_block_id', + type: 'keyword', + }, + 'powershell.file.script_block_text': { + category: 'powershell', + description: 'Text of the executed script block. ', + example: '.\\a_script.ps1', + name: 'powershell.file.script_block_text', + type: 'text', + }, + 'powershell.process.executable_version': { + category: 'powershell', + description: 'Version of the engine hosting process executable.', + example: '5.1.17763.1007', + name: 'powershell.process.executable_version', + type: 'keyword', + }, + 'powershell.provider.new_state': { + category: 'powershell', + description: 'New state of the PowerShell provider. ', + example: 'Active', + name: 'powershell.provider.new_state', + type: 'keyword', + }, + 'powershell.provider.name': { + category: 'powershell', + description: 'Provider name. ', + example: 'Variable', + name: 'powershell.provider.name', + type: 'keyword', + }, + 'winlog.logon.type': { + category: 'winlog', + description: + 'Logon type name. This is the descriptive version of the `winlog.event_data.LogonType` ordinal. This is an enrichment added by the Security module. ', + example: 'RemoteInteractive', + name: 'winlog.logon.type', + type: 'keyword', + }, + 'winlog.logon.id': { + category: 'winlog', + description: + 'Logon ID that can be used to associate this logon with other events related to the same logon session. ', + name: 'winlog.logon.id', + type: 'keyword', + }, + 'winlog.logon.failure.reason': { + category: 'winlog', + description: 'The reason the logon failed. ', + name: 'winlog.logon.failure.reason', + type: 'keyword', + }, + 'winlog.logon.failure.status': { + category: 'winlog', + description: + 'The reason the logon failed. This is textual description based on the value of the hexadecimal `Status` field. ', + name: 'winlog.logon.failure.status', + type: 'keyword', + }, + 'winlog.logon.failure.sub_status': { + category: 'winlog', + description: + 'Additional information about the logon failure. This is a textual description based on the value of the hexidecimal `SubStatus` field. ', + name: 'winlog.logon.failure.sub_status', + type: 'keyword', + }, + 'sysmon.dns.status': { + category: 'sysmon', + description: 'Windows status code returned for the DNS query.', + name: 'sysmon.dns.status', + type: 'keyword', + }, + 'sysmon.file.archived': { + category: 'sysmon', + description: 'Indicates if the deleted file was archived.', + name: 'sysmon.file.archived', + type: 'boolean', + }, + 'sysmon.file.is_executable': { + category: 'sysmon', + description: 'Indicates if the deleted file was an executable.', + name: 'sysmon.file.is_executable', + type: 'boolean', + }, +}; diff --git a/x-pack/plugins/timelines/server/utils/build_query.ts b/x-pack/plugins/timelines/server/utils/build_query.ts new file mode 100644 index 00000000000000..bc7c48a538664d --- /dev/null +++ b/x-pack/plugins/timelines/server/utils/build_query.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEmpty, isString } from 'lodash/fp'; + +import { ESQuery } from '../../common/typed_json'; + +export const createQueryFilterClauses = (filterQuery: ESQuery | string | undefined) => + !isEmpty(filterQuery) ? [isString(filterQuery) ? JSON.parse(filterQuery) : filterQuery] : []; + +export const inspectStringifyObject = (obj: unknown) => { + try { + return JSON.stringify(obj, null, 2); + } catch { + return 'Sorry about that, something went wrong.'; + } +}; diff --git a/x-pack/plugins/timelines/server/utils/filters.ts b/x-pack/plugins/timelines/server/utils/filters.ts new file mode 100644 index 00000000000000..166c70400d5b2a --- /dev/null +++ b/x-pack/plugins/timelines/server/utils/filters.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEmpty, isString } from 'lodash/fp'; +import { ESQuery } from '../../common/typed_json'; + +export const createQueryFilterClauses = (filterQuery: ESQuery | string | undefined) => + !isEmpty(filterQuery) ? [isString(filterQuery) ? JSON.parse(filterQuery) : filterQuery] : []; diff --git a/x-pack/plugins/timelines/tsconfig.json b/x-pack/plugins/timelines/tsconfig.json index 67e606e798c03c..1bc60a696fceff 100644 --- a/x-pack/plugins/timelines/tsconfig.json +++ b/x-pack/plugins/timelines/tsconfig.json @@ -1,19 +1,29 @@ + { - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "composite": true, - "outDir": "./target/types", - "emitDeclarationOnly": true, - "declaration": true, - "declarationMap": true - }, - "include": [ - // add all the folders contains files to be compiled - "common/**/*", - "public/**/*", - "server/**/*" - ], - "references": [ - { "path": "../../../src/core/tsconfig.json" }, - ] -} + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "common/**/*", + "public/**/*", + "server/**/*", + // have to declare *.json explicitly due to https://github.com/microsoft/TypeScript/issues/25636 + "server/**/*.json", + "public/**/*.json", + "../../../typings/**/*" + ], + "references": [ + { "path": "../../../src/core/tsconfig.json" }, + { "path": "../../../src/plugins/data/tsconfig.json" }, + { "path": "../../../src/plugins/home/tsconfig.json" }, + { "path": "../data_enhanced/tsconfig.json" }, + { "path": "../features/tsconfig.json" }, + { "path": "../licensing/tsconfig.json" }, + { "path": "../spaces/tsconfig.json" } + ] + } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index bc8318e803c8f5..75bf27f9617139 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9795,8 +9795,6 @@ "xpack.idxMgmt.home.componentTemplates.emptyPromptDocumentionLink": "詳細情報", "xpack.idxMgmt.home.componentTemplates.emptyPromptTitle": "コンポーネントテンプレートを作成して開始", "xpack.idxMgmt.home.componentTemplates.list.componentTemplatesDescription": "コンポーネントテンプレートを使用して、複数のインデックステンプレートで設定、マッピング、エイリアス構成を再利用します。{learnMoreLink}", - "xpack.idxMgmt.home.componentTemplates.list.loadErrorReloadLinkLabel": "再試行してください。", - "xpack.idxMgmt.home.componentTemplates.list.loadErrorTitle": "コンポーネントテンプレートを読み込めません。{reloadLink}", "xpack.idxMgmt.home.componentTemplates.list.loadingMessage": "コンポーネントテンプレートを読み込んでいます…", "xpack.idxMgmt.home.componentTemplatesTabTitle": "コンポーネントテンプレート", "xpack.idxMgmt.home.dataStreamsTabTitle": "データストリーム", @@ -12737,7 +12735,6 @@ "xpack.lens.indexPattern.terms.orderByHelp": "上位の値がランク付けされる条件となるディメンションを指定します。", "xpack.lens.indexPattern.terms.orderDescending": "降順", "xpack.lens.indexPattern.terms.orderDirection": "ランク方向", - "xpack.lens.indexPattern.terms.orderDirectionHelp": "上位の値のランク順序を指定します。", "xpack.lens.indexPattern.terms.otherBucketDescription": "他の値を「その他」としてグループ化", "xpack.lens.indexPattern.terms.otherLabel": "その他", "xpack.lens.indexPattern.terms.size": "値の数", @@ -20322,7 +20319,6 @@ "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.versionTitle": "バージョン", "xpack.securitySolution.eventsViewer.errorFetchingEventsData": "イベントデータをクエリできませんでした", "xpack.securitySolution.eventsViewer.eventsLabel": "イベント", - "xpack.securitySolution.eventsViewer.footer.loadingEventsDataLabel": "イベントを読み込み中", "xpack.securitySolution.eventsViewer.showingLabel": "表示中", "xpack.securitySolution.exceptions.addException.addEndpointException": "エンドポイント例外の追加", "xpack.securitySolution.exceptions.addException.addException": "ルール例外の追加", @@ -20449,8 +20445,6 @@ "xpack.securitySolution.header.editableTitle.cancel": "キャンセル", "xpack.securitySolution.header.editableTitle.editButtonAria": "クリックすると {title} を編集できます", "xpack.securitySolution.header.editableTitle.save": "保存", - "xpack.securitySolution.headerGlobal.buttonAddData": "データの追加", - "xpack.securitySolution.headerGlobal.securitySolution": "セキュリティソリューション", "xpack.securitySolution.headerPage.pageSubtitle": "前回のイベント:{beat}", "xpack.securitySolution.hooks.useAddToTimeline.addedFieldMessage": "{fieldOrValue}をタイムラインに追加しました", "xpack.securitySolution.hooks.useAddToTimeline.template.addedFieldMessage": "{fieldOrValue}をタイムラインテンプレートに追加しました", @@ -20540,8 +20534,6 @@ "xpack.securitySolution.kpiNetwork.uniquePrivateIps.title": "固有のプライベート IP", "xpack.securitySolution.lastEventTime.errorSearchDescription": "前回のイベント時刻検索でエラーが発生しました。", "xpack.securitySolution.lastEventTime.failSearchDescription": "前回のイベント時刻で検索を実行できませんでした", - "xpack.securitySolution.lastUpdated.updated": "更新しました", - "xpack.securitySolution.lastUpdated.updating": "更新中...", "xpack.securitySolution.licensing.unsupportedMachineLearningMessage": "ご使用のライセンスは機械翻訳をサポートしていません。ライセンスをアップグレードしてください。", "xpack.securitySolution.lists.cancelValueListsUploadTitle": "アップロードのキャンセル", "xpack.securitySolution.lists.closeValueListsModalTitle": "閉じる", @@ -22345,7 +22337,6 @@ "xpack.stackAlerts.threshold.ui.visualization.loadingAlertVisualizationDescription": "アラートビジュアライゼーションを読み込み中…", "xpack.stackAlerts.threshold.ui.visualization.thresholdPreviewChart.dataDoesNotExistTextMessage": "時間範囲とフィルターが正しいことを確認してください。", "xpack.stackAlerts.threshold.ui.visualization.thresholdPreviewChart.noDataTitle": "このクエリに一致するデータはありません", - "xpack.timelines.placeholder": "プラグイン:{name} タイムライン:{timelineId}", "xpack.transform.actionDeleteTransform.bulkDeleteDestinationIndexTitle": "ディスティネーションインデックスの削除", "xpack.transform.actionDeleteTransform.bulkDeleteDestIndexPatternTitle": "ディスティネーションインデックスパターンの削除", "xpack.transform.actionDeleteTransform.deleteDestinationIndexTitle": "ディスティネーションインデックス{destinationIndex}の削除", @@ -23492,7 +23483,6 @@ "xpack.uptime.alerts.tls.criteriaExpression.ariaLabel": "このアラートで監視されるモニターの条件を示す式", "xpack.uptime.alerts.tls.criteriaExpression.description": "タイミング", "xpack.uptime.alerts.tls.criteriaExpression.value": "任意のモニター", - "xpack.uptime.alerts.tls.defaultActionMessage": "期限切れになるか古くなりすぎた{count} TLS個のTLS証明書証明書を検知しました。\n\n{expiringConditionalOpen}\n期限切れになる証明書数:{expiringCount}\n期限切れになる証明書:{expiringCommonNameAndDate}\n{expiringConditionalClose}\n\n{agingConditionalOpen}\n古い証明書数:{agingCount}\n古い証明書:{agingCommonNameAndDate}\n{agingConditionalClose}\n", "xpack.uptime.alerts.tls.description": "アップタイム監視の TLS 証明書の有効期限が近いときにアラートを発行します。", "xpack.uptime.alerts.tls.expirationExpression.ariaLabel": "証明書有効期限の TLS アラートをトリガーするしきい値を示す式", "xpack.uptime.alerts.tls.expirationExpression.description": "証明書が", @@ -24343,4 +24333,4 @@ "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "フィールドを選択してください。", "xpack.watcher.watcherDescription": "アラートの作成、管理、監視によりデータへの変更を検知します。" } -} +} \ No newline at end of file diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index f867407ff2d9b8..d3f5b9c4bce8b9 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9902,8 +9902,6 @@ "xpack.idxMgmt.home.componentTemplates.emptyPromptDocumentionLink": "了解详情。", "xpack.idxMgmt.home.componentTemplates.emptyPromptTitle": "首先创建组件模板", "xpack.idxMgmt.home.componentTemplates.list.componentTemplatesDescription": "使用组件模板可在多个索引模板中重复使用设置、映射和别名。{learnMoreLink}", - "xpack.idxMgmt.home.componentTemplates.list.loadErrorReloadLinkLabel": "请重试。", - "xpack.idxMgmt.home.componentTemplates.list.loadErrorTitle": "无法加载组件模板。{reloadLink}", "xpack.idxMgmt.home.componentTemplates.list.loadingMessage": "正在加载组件模板……", "xpack.idxMgmt.home.componentTemplatesTabTitle": "组件模板", "xpack.idxMgmt.home.dataStreamsTabTitle": "数据流", @@ -12908,7 +12906,6 @@ "xpack.lens.indexPattern.terms.orderByHelp": "指定排名靠前值排名所依据的维度。", "xpack.lens.indexPattern.terms.orderDescending": "降序", "xpack.lens.indexPattern.terms.orderDirection": "排名方向", - "xpack.lens.indexPattern.terms.orderDirectionHelp": "指定排名靠前值的排名顺序。", "xpack.lens.indexPattern.terms.otherBucketDescription": "将其他值分组为“其他”", "xpack.lens.indexPattern.terms.otherLabel": "其他", "xpack.lens.indexPattern.terms.size": "值数目", @@ -20623,7 +20620,6 @@ "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.versionTitle": "版本", "xpack.securitySolution.eventsViewer.errorFetchingEventsData": "无法查询事件数据", "xpack.securitySolution.eventsViewer.eventsLabel": "事件", - "xpack.securitySolution.eventsViewer.footer.loadingEventsDataLabel": "正在加载事件", "xpack.securitySolution.eventsViewer.showingLabel": "正在显示", "xpack.securitySolution.eventsViewer.unit": "{totalCount, plural, other {个事件}}", "xpack.securitySolution.exceptions.addException.addEndpointException": "添加终端例外", @@ -20758,8 +20754,6 @@ "xpack.securitySolution.header.editableTitle.cancel": "取消", "xpack.securitySolution.header.editableTitle.editButtonAria": "通过单击,可以编辑 {title}", "xpack.securitySolution.header.editableTitle.save": "保存", - "xpack.securitySolution.headerGlobal.buttonAddData": "添加数据", - "xpack.securitySolution.headerGlobal.securitySolution": "安全解决方案", "xpack.securitySolution.headerPage.pageSubtitle": "上一事件:{beat}", "xpack.securitySolution.hooks.useAddToTimeline.addedFieldMessage": "已将 {fieldOrValue} 添加到时间线", "xpack.securitySolution.hooks.useAddToTimeline.template.addedFieldMessage": "已将 {fieldOrValue} 添加到时间线模板", @@ -20851,8 +20845,6 @@ "xpack.securitySolution.kpiNetwork.uniquePrivateIps.title": "唯一专用 IP", "xpack.securitySolution.lastEventTime.errorSearchDescription": "搜索上次事件时间时发生错误", "xpack.securitySolution.lastEventTime.failSearchDescription": "无法对上次事件时间执行搜索", - "xpack.securitySolution.lastUpdated.updated": "更新时间", - "xpack.securitySolution.lastUpdated.updating": "正在更新......", "xpack.securitySolution.licensing.unsupportedMachineLearningMessage": "您的许可证不支持 Machine Learning。请升级您的许可证。", "xpack.securitySolution.lists.cancelValueListsUploadTitle": "取消上传", "xpack.securitySolution.lists.closeValueListsModalTitle": "关闭", @@ -22699,7 +22691,6 @@ "xpack.stackAlerts.threshold.ui.visualization.loadingAlertVisualizationDescription": "正在加载告警可视化……", "xpack.stackAlerts.threshold.ui.visualization.thresholdPreviewChart.dataDoesNotExistTextMessage": "确认您的时间范围和筛选正确。", "xpack.stackAlerts.threshold.ui.visualization.thresholdPreviewChart.noDataTitle": "没有数据匹配此查询", - "xpack.timelines.placeholder": "插件:{name} 时间线:{timelineId}", "xpack.transform.actionDeleteTransform.bulkDeleteDestinationIndexTitle": "删除目标索引", "xpack.transform.actionDeleteTransform.bulkDeleteDestIndexPatternTitle": "删除目标索引模式", "xpack.transform.actionDeleteTransform.deleteDestinationIndexTitle": "删除目标索引 {destinationIndex}", @@ -23858,7 +23849,6 @@ "xpack.uptime.alerts.tls.criteriaExpression.ariaLabel": "显示此告警监视的监测条件的表达式", "xpack.uptime.alerts.tls.criteriaExpression.description": "当", "xpack.uptime.alerts.tls.criteriaExpression.value": "任意监测", - "xpack.uptime.alerts.tls.defaultActionMessage": "已检测到 {count} 个即将过期或即将过时的 TLS 证书。\n\n{expiringConditionalOpen}\n即将过期的证书计数:{expiringCount}\n即将过期的证书:{expiringCommonNameAndDate}\n{expiringConditionalClose}\n\n{agingConditionalOpen}\n过时的证书计数:{agingCount}\n过时的证书:{agingCommonNameAndDate}\n{agingConditionalClose}\n", "xpack.uptime.alerts.tls.description": "运行时间监测的 TLS 证书即将过期时告警。", "xpack.uptime.alerts.tls.expirationExpression.ariaLabel": "显示将触发证书过期 TLS 告警的阈值的表达式", "xpack.uptime.alerts.tls.expirationExpression.description": "具有将在", @@ -24719,4 +24709,4 @@ "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "此字段必填。", "xpack.watcher.watcherDescription": "通过创建、管理和监测警报来检测数据中的更改。" } -} +} \ No newline at end of file diff --git a/x-pack/plugins/uptime/common/constants/alerts.ts b/x-pack/plugins/uptime/common/constants/alerts.ts index 37258fca3bc4d3..cb31d838395900 100644 --- a/x-pack/plugins/uptime/common/constants/alerts.ts +++ b/x-pack/plugins/uptime/common/constants/alerts.ts @@ -8,7 +8,8 @@ import { ActionGroup } from '../../../alerting/common'; export type MonitorStatusActionGroup = ActionGroup<'xpack.uptime.alerts.actionGroups.monitorStatus'>; -export type TLSActionGroup = ActionGroup<'xpack.uptime.alerts.actionGroups.tls'>; +export type TLSLegacyActionGroup = ActionGroup<'xpack.uptime.alerts.actionGroups.tls'>; +export type TLSActionGroup = ActionGroup<'xpack.uptime.alerts.actionGroups.tlsCertificate'>; export type DurationAnomalyActionGroup = ActionGroup<'xpack.uptime.alerts.actionGroups.durationAnomaly'>; export const MONITOR_STATUS: MonitorStatusActionGroup = { @@ -16,8 +17,13 @@ export const MONITOR_STATUS: MonitorStatusActionGroup = { name: 'Uptime Down Monitor', }; -export const TLS: TLSActionGroup = { +export const TLS_LEGACY: TLSLegacyActionGroup = { id: 'xpack.uptime.alerts.actionGroups.tls', + name: 'Uptime TLS Alert (Legacy)', +}; + +export const TLS: TLSActionGroup = { + id: 'xpack.uptime.alerts.actionGroups.tlsCertificate', name: 'Uptime TLS Alert', }; @@ -28,16 +34,19 @@ export const DURATION_ANOMALY: DurationAnomalyActionGroup = { export const ACTION_GROUP_DEFINITIONS: { MONITOR_STATUS: MonitorStatusActionGroup; + TLS_LEGACY: TLSLegacyActionGroup; TLS: TLSActionGroup; DURATION_ANOMALY: DurationAnomalyActionGroup; } = { MONITOR_STATUS, + TLS_LEGACY, TLS, DURATION_ANOMALY, }; export const CLIENT_ALERT_TYPES = { MONITOR_STATUS: 'xpack.uptime.alerts.monitorStatus', - TLS: 'xpack.uptime.alerts.tls', + TLS_LEGACY: 'xpack.uptime.alerts.tls', + TLS: 'xpack.uptime.alerts.tlsCertificate', DURATION_ANOMALY: 'xpack.uptime.alerts.durationAnomaly', }; diff --git a/x-pack/plugins/uptime/public/lib/alert_types/index.ts b/x-pack/plugins/uptime/public/lib/alert_types/index.ts index 36c84fe4c64cdf..406b730fa1e6ce 100644 --- a/x-pack/plugins/uptime/public/lib/alert_types/index.ts +++ b/x-pack/plugins/uptime/public/lib/alert_types/index.ts @@ -9,6 +9,7 @@ import { CoreStart } from 'kibana/public'; import { AlertTypeModel } from '../../../../triggers_actions_ui/public'; import { initMonitorStatusAlertType } from './monitor_status'; import { initTlsAlertType } from './tls'; +import { initTlsLegacyAlertType } from './tls_legacy'; import { ClientPluginsStart } from '../../apps/plugin'; import { initDurationAnomalyAlertType } from './duration_anomaly'; @@ -20,5 +21,6 @@ export type AlertTypeInitializer = (dependenies: { export const alertTypeInitializers: AlertTypeInitializer[] = [ initMonitorStatusAlertType, initTlsAlertType, + initTlsLegacyAlertType, initDurationAnomalyAlertType, ]; diff --git a/x-pack/plugins/uptime/public/lib/alert_types/tls_legacy.tsx b/x-pack/plugins/uptime/public/lib/alert_types/tls_legacy.tsx new file mode 100644 index 00000000000000..1abcdb2c98662e --- /dev/null +++ b/x-pack/plugins/uptime/public/lib/alert_types/tls_legacy.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { AlertTypeModel } from '../../../../triggers_actions_ui/public'; +import { CLIENT_ALERT_TYPES } from '../../../common/constants/alerts'; +import { TlsTranslationsLegacy } from './translations'; +import { AlertTypeInitializer } from '.'; + +const { defaultActionMessage, description } = TlsTranslationsLegacy; +const TLSAlert = React.lazy(() => import('./lazy_wrapper/tls_alert')); +export const initTlsLegacyAlertType: AlertTypeInitializer = ({ + core, + plugins, +}): AlertTypeModel => ({ + id: CLIENT_ALERT_TYPES.TLS_LEGACY, + iconClass: 'uptimeApp', + documentationUrl(docLinks) { + return `${docLinks.ELASTIC_WEBSITE_URL}guide/en/uptime/${docLinks.DOC_LINK_VERSION}/uptime-alerting.html#_tls_alerts`; + }, + alertParamsExpression: (params: any) => ( + + ), + description, + validate: () => ({ errors: {} }), + defaultActionMessage, + requiresAppContext: false, +}); diff --git a/x-pack/plugins/uptime/public/lib/alert_types/translations.ts b/x-pack/plugins/uptime/public/lib/alert_types/translations.ts index ea445e3d63c092..bb4af761d240d0 100644 --- a/x-pack/plugins/uptime/public/lib/alert_types/translations.ts +++ b/x-pack/plugins/uptime/public/lib/alert_types/translations.ts @@ -8,14 +8,32 @@ import { i18n } from '@kbn/i18n'; export const TlsTranslations = { + defaultActionMessage: i18n.translate('xpack.uptime.alerts.tls.legacy.defaultActionMessage', { + defaultMessage: `Detected TLS certificate {commonName} from issuer {issuer} is {status}. Certificate {summary} +`, + values: { + commonName: '{{state.commonName}}', + issuer: '{{state.issuer}}', + summary: '{{state.summary}}', + status: '{{state.status}}', + }, + }), + name: i18n.translate('xpack.uptime.alerts.tls.legacy.clientName', { + defaultMessage: 'Uptime TLS (Legacy)', + }), + description: i18n.translate('xpack.uptime.alerts.tls.legacy.description', { + defaultMessage: + 'Alert when the TLS certificate of an Uptime monitor is about to expire. This alert will be deprecated in a future version.', + }), +}; + +export const TlsTranslationsLegacy = { defaultActionMessage: i18n.translate('xpack.uptime.alerts.tls.defaultActionMessage', { defaultMessage: `Detected {count} TLS certificates expiring or becoming too old. - {expiringConditionalOpen} Expiring cert count: {expiringCount} Expiring Certificates: {expiringCommonNameAndDate} {expiringConditionalClose} - {agingConditionalOpen} Aging cert count: {agingCount} Aging Certificates: {agingCommonNameAndDate} diff --git a/x-pack/plugins/uptime/server/lib/alerts/index.ts b/x-pack/plugins/uptime/server/lib/alerts/index.ts index 1559ceaae8bb65..c695a4b052cd96 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/index.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/index.ts @@ -8,6 +8,7 @@ import { UptimeAlertTypeFactory } from './types'; import { statusCheckAlertFactory, ActionGroupIds as statusCheckActionGroup } from './status_check'; import { tlsAlertFactory, ActionGroupIds as tlsActionGroup } from './tls'; +import { tlsLegacyAlertFactory, ActionGroupIds as tlsLegacyActionGroup } from './tls_legacy'; import { durationAnomalyAlertFactory, ActionGroupIds as durationAnomalyActionGroup, @@ -16,5 +17,6 @@ import { export const uptimeAlertTypeFactories: [ UptimeAlertTypeFactory, UptimeAlertTypeFactory, + UptimeAlertTypeFactory, UptimeAlertTypeFactory -] = [statusCheckAlertFactory, tlsAlertFactory, durationAnomalyAlertFactory]; +] = [statusCheckAlertFactory, tlsAlertFactory, tlsLegacyAlertFactory, durationAnomalyAlertFactory]; diff --git a/x-pack/plugins/uptime/server/lib/alerts/tls.test.ts b/x-pack/plugins/uptime/server/lib/alerts/tls.test.ts index dde6ef8535365a..a77fe10f0b9a4d 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/tls.test.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/tls.test.ts @@ -23,6 +23,7 @@ describe('tls alert', () => { common_name: 'Common-One', monitors: [{ name: 'monitor-one', id: 'monitor1' }], sha256: 'abc', + issuer: 'Cloudflare Inc ECC CA-3', }, { not_after: '2020-07-18T03:15:39.000Z', @@ -30,6 +31,7 @@ describe('tls alert', () => { common_name: 'Common-Two', monitors: [{ name: 'monitor-two', id: 'monitor2' }], sha256: 'bcd', + issuer: 'Cloudflare Inc ECC CA-3', }, { not_after: '2020-07-19T03:15:39.000Z', @@ -37,6 +39,7 @@ describe('tls alert', () => { common_name: 'Common-Three', monitors: [{ name: 'monitor-three', id: 'monitor3' }], sha256: 'cde', + issuer: 'Cloudflare Inc ECC CA-3', }, { not_after: '2020-07-25T03:15:39.000Z', @@ -44,6 +47,7 @@ describe('tls alert', () => { common_name: 'Common-Four', monitors: [{ name: 'monitor-four', id: 'monitor4' }], sha256: 'def', + issuer: 'Cloudflare Inc ECC CA-3', }, ]; }); @@ -52,88 +56,66 @@ describe('tls alert', () => { jest.clearAllMocks(); }); - it('sorts expiring certs appropriately when creating summary', () => { - diffSpy.mockReturnValueOnce(900).mockReturnValueOnce(901).mockReturnValueOnce(902); + it('handles positive diffs for expired certs appropriately', () => { + diffSpy.mockReturnValueOnce(900); const result = getCertSummary( - mockCerts, + mockCerts[0], new Date('2020-07-20T05:00:00.000Z').valueOf(), new Date('2019-03-01T00:00:00.000Z').valueOf() ); - expect(result).toMatchInlineSnapshot(` - Object { - "agingCommonNameAndDate": "", - "agingCount": 0, - "count": 4, - "expiringCommonNameAndDate": "Common-One, expired on 2020-07-16T03:15:39.000Z 900 days ago.; Common-Two, expired on 2020-07-18T03:15:39.000Z 901 days ago.; Common-Three, expired on 2020-07-19T03:15:39.000Z 902 days ago.", - "expiringCount": 3, - "hasAging": null, - "hasExpired": true, - } - `); + expect(result).toEqual({ + commonName: mockCerts[0].common_name, + issuer: mockCerts[0].issuer, + summary: 'expired on Jul 15, 2020 EDT, 900 days ago.', + status: 'expired', + }); }); - it('sorts aging certs appropriate when creating summary', () => { - diffSpy.mockReturnValueOnce(702).mockReturnValueOnce(701).mockReturnValueOnce(700); + it('handles positive diffs for agining certs appropriately', () => { + diffSpy.mockReturnValueOnce(702); const result = getCertSummary( - mockCerts, + mockCerts[0], new Date('2020-07-01T12:00:00.000Z').valueOf(), new Date('2019-09-01T03:00:00.000Z').valueOf() ); - expect(result).toMatchInlineSnapshot(` - Object { - "agingCommonNameAndDate": "Common-Two, valid since 2019-07-20T03:15:39.000Z, 702 days ago.; Common-Three, valid since 2019-07-22T03:15:39.000Z, 701 days ago.; Common-One, valid since 2019-07-24T03:15:39.000Z, 700 days ago.", - "agingCount": 4, - "count": 4, - "expiringCommonNameAndDate": "", - "expiringCount": 0, - "hasAging": true, - "hasExpired": null, - } - `); + expect(result).toEqual({ + commonName: mockCerts[0].common_name, + issuer: mockCerts[0].issuer, + summary: 'valid since Jul 23, 2019 EDT, 702 days ago.', + status: 'becoming too old', + }); }); it('handles negative diff values appropriately for aging certs', () => { - diffSpy.mockReturnValueOnce(700).mockReturnValueOnce(-90).mockReturnValueOnce(-80); + diffSpy.mockReturnValueOnce(-90); const result = getCertSummary( - mockCerts, + mockCerts[0], new Date('2020-07-01T12:00:00.000Z').valueOf(), new Date('2019-09-01T03:00:00.000Z').valueOf() ); - expect(result).toMatchInlineSnapshot(` - Object { - "agingCommonNameAndDate": "Common-Two, valid since 2019-07-20T03:15:39.000Z, 700 days ago.; Common-Three, invalid until 2019-07-22T03:15:39.000Z, 90 days from now.; Common-One, invalid until 2019-07-24T03:15:39.000Z, 80 days from now.", - "agingCount": 4, - "count": 4, - "expiringCommonNameAndDate": "", - "expiringCount": 0, - "hasAging": true, - "hasExpired": null, - } - `); + expect(result).toEqual({ + commonName: mockCerts[0].common_name, + issuer: mockCerts[0].issuer, + summary: 'invalid until Jul 23, 2019 EDT, 90 days from now.', + status: 'invalid', + }); }); it('handles negative diff values appropriately for expiring certs', () => { diffSpy // negative days are in the future, positive days are in the past - .mockReturnValueOnce(-96) - .mockReturnValueOnce(-94) - .mockReturnValueOnce(2); + .mockReturnValueOnce(-96); const result = getCertSummary( - mockCerts, + mockCerts[0], new Date('2020-07-20T05:00:00.000Z').valueOf(), new Date('2019-03-01T00:00:00.000Z').valueOf() ); - expect(result).toMatchInlineSnapshot(` - Object { - "agingCommonNameAndDate": "", - "agingCount": 0, - "count": 4, - "expiringCommonNameAndDate": "Common-One, expires on 2020-07-16T03:15:39.000Z in 96 days.; Common-Two, expires on 2020-07-18T03:15:39.000Z in 94 days.; Common-Three, expired on 2020-07-19T03:15:39.000Z 2 days ago.", - "expiringCount": 3, - "hasAging": null, - "hasExpired": true, - } - `); + expect(result).toEqual({ + commonName: mockCerts[0].common_name, + issuer: mockCerts[0].issuer, + summary: 'expires on Jul 15, 2020 EDT in 96 days.', + status: 'expiring', + }); }); }); }); diff --git a/x-pack/plugins/uptime/server/lib/alerts/tls.ts b/x-pack/plugins/uptime/server/lib/alerts/tls.ts index 2a2406a3629d0f..f29744fdbb70f5 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/tls.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/tls.ts @@ -22,71 +22,80 @@ export type ActionGroupIds = ActionGroupIdsOf; const DEFAULT_SIZE = 20; interface TlsAlertState { - count: number; - agingCount: number; - agingCommonNameAndDate: string; - expiringCount: number; - expiringCommonNameAndDate: string; - hasAging: true | null; - hasExpired: true | null; + commonName: string; + issuer: string; + summary: string; + status: string; } -const sortCerts = (a: string, b: string) => new Date(a).valueOf() - new Date(b).valueOf(); +interface TLSContent { + summary: string; + status?: string; +} const mapCertsToSummaryString = ( - certs: Cert[], - certLimitMessage: (cert: Cert) => string, - maxSummaryItems: number -): string => - certs - .slice(0, maxSummaryItems) - .map((cert) => `${cert.common_name}, ${certLimitMessage(cert)}`) - .reduce((prev, cur) => (prev === '' ? cur : prev.concat(`; ${cur}`)), ''); - -const getValidAfter = ({ not_after: date }: Cert) => { - if (!date) return 'Error, missing `certificate_not_valid_after` date.'; + cert: Cert, + certLimitMessage: (cert: Cert) => TLSContent +): TLSContent => certLimitMessage(cert); + +const getValidAfter = ({ not_after: date }: Cert): TLSContent => { + if (!date) return { summary: 'Error, missing `certificate_not_valid_after` date.' }; const relativeDate = moment().diff(date, 'days'); + const formattedDate = moment(date).format('MMM D, YYYY z'); return relativeDate >= 0 - ? tlsTranslations.validAfterExpiredString(date, relativeDate) - : tlsTranslations.validAfterExpiringString(date, Math.abs(relativeDate)); + ? { + summary: tlsTranslations.validAfterExpiredString(formattedDate, relativeDate), + status: tlsTranslations.expiredLabel, + } + : { + summary: tlsTranslations.validAfterExpiringString(formattedDate, Math.abs(relativeDate)), + status: tlsTranslations.expiringLabel, + }; }; -const getValidBefore = ({ not_before: date }: Cert): string => { - if (!date) return 'Error, missing `certificate_not_valid_before` date.'; +const getValidBefore = ({ not_before: date }: Cert): TLSContent => { + if (!date) return { summary: 'Error, missing `certificate_not_valid_before` date.' }; const relativeDate = moment().diff(date, 'days'); + const formattedDate = moment(date).format('MMM D, YYYY z'); return relativeDate >= 0 - ? tlsTranslations.validBeforeExpiredString(date, relativeDate) - : tlsTranslations.validBeforeExpiringString(date, Math.abs(relativeDate)); + ? { + summary: tlsTranslations.validBeforeExpiredString(formattedDate, relativeDate), + status: tlsTranslations.agingLabel, + } + : { + summary: tlsTranslations.validBeforeExpiringString(formattedDate, Math.abs(relativeDate)), + status: tlsTranslations.invalidLabel, + }; }; export const getCertSummary = ( - certs: Cert[], + cert: Cert, expirationThreshold: number, - ageThreshold: number, - maxSummaryItems: number = 3 + ageThreshold: number ): TlsAlertState => { - certs.sort((a, b) => sortCerts(a.not_after ?? '', b.not_after ?? '')); - const expiring = certs.filter( - (cert) => new Date(cert.not_after ?? '').valueOf() < expirationThreshold - ); + const isExpiring = new Date(cert.not_after ?? '').valueOf() < expirationThreshold; + const isAging = new Date(cert.not_before ?? '').valueOf() < ageThreshold; + let content: TLSContent | null = null; + + if (isExpiring) { + content = mapCertsToSummaryString(cert, getValidAfter); + } else if (isAging) { + content = mapCertsToSummaryString(cert, getValidBefore); + } - certs.sort((a, b) => sortCerts(a.not_before ?? '', b.not_before ?? '')); - const aging = certs.filter((cert) => new Date(cert.not_before ?? '').valueOf() < ageThreshold); + const { summary = '', status = '' } = content || {}; return { - count: certs.length, - agingCount: aging.length, - agingCommonNameAndDate: mapCertsToSummaryString(aging, getValidBefore, maxSummaryItems), - expiringCommonNameAndDate: mapCertsToSummaryString(expiring, getValidAfter, maxSummaryItems), - expiringCount: expiring.length, - hasAging: aging.length > 0 ? true : null, - hasExpired: expiring.length > 0 ? true : null, + commonName: cert.common_name ?? '', + issuer: cert.issuer ?? '', + summary, + status, }; }; export const tlsAlertFactory: UptimeAlertTypeFactory = (_server, libs) => uptimeAlertWrapper({ - id: 'xpack.uptime.alerts.tls', + id: 'xpack.uptime.alerts.tlsCertificate', name: tlsTranslations.alertFactoryName, validate: { params: schema.object({}), @@ -129,26 +138,30 @@ export const tlsAlertFactory: UptimeAlertTypeFactory = (_server, const foundCerts = total > 0; if (foundCerts) { - const absoluteExpirationThreshold = moment() - .add( - dynamicSettings.certExpirationThreshold ?? - DYNAMIC_SETTINGS_DEFAULTS.certExpirationThreshold, - 'd' - ) - .valueOf(); - const absoluteAgeThreshold = moment() - .subtract( - dynamicSettings.certAgeThreshold ?? DYNAMIC_SETTINGS_DEFAULTS.certAgeThreshold, - 'd' - ) - .valueOf(); - const alertInstance = alertInstanceFactory(TLS.id); - const summary = getCertSummary(certs, absoluteExpirationThreshold, absoluteAgeThreshold); - alertInstance.replaceState({ - ...updateState(state, foundCerts), - ...summary, + certs.forEach((cert) => { + const absoluteExpirationThreshold = moment() + .add( + dynamicSettings.certExpirationThreshold ?? + DYNAMIC_SETTINGS_DEFAULTS.certExpirationThreshold, + 'd' + ) + .valueOf(); + const absoluteAgeThreshold = moment() + .subtract( + dynamicSettings.certAgeThreshold ?? DYNAMIC_SETTINGS_DEFAULTS.certAgeThreshold, + 'd' + ) + .valueOf(); + const alertInstance = alertInstanceFactory( + `${cert.common_name}-${cert.issuer?.replace(/\s/g, '_')}-${cert.sha256}` + ); + const summary = getCertSummary(cert, absoluteExpirationThreshold, absoluteAgeThreshold); + alertInstance.replaceState({ + ...updateState(state, foundCerts), + ...summary, + }); + alertInstance.scheduleActions(TLS.id); }); - alertInstance.scheduleActions(TLS.id); } return updateState(state, foundCerts); diff --git a/x-pack/plugins/uptime/server/lib/alerts/tls_legacy.test.ts b/x-pack/plugins/uptime/server/lib/alerts/tls_legacy.test.ts new file mode 100644 index 00000000000000..4c6a721e921590 --- /dev/null +++ b/x-pack/plugins/uptime/server/lib/alerts/tls_legacy.test.ts @@ -0,0 +1,139 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import moment from 'moment'; +import { getCertSummary } from './tls_legacy'; +import { Cert } from '../../../common/runtime_types'; + +describe('tls alert', () => { + describe('getCertSummary', () => { + let mockCerts: Cert[]; + let diffSpy: jest.SpyInstance; + + beforeEach(() => { + diffSpy = jest.spyOn(moment.prototype, 'diff'); + mockCerts = [ + { + not_after: '2020-07-16T03:15:39.000Z', + not_before: '2019-07-24T03:15:39.000Z', + common_name: 'Common-One', + monitors: [{ name: 'monitor-one', id: 'monitor1' }], + sha256: 'abc', + }, + { + not_after: '2020-07-18T03:15:39.000Z', + not_before: '2019-07-20T03:15:39.000Z', + common_name: 'Common-Two', + monitors: [{ name: 'monitor-two', id: 'monitor2' }], + sha256: 'bcd', + }, + { + not_after: '2020-07-19T03:15:39.000Z', + not_before: '2019-07-22T03:15:39.000Z', + common_name: 'Common-Three', + monitors: [{ name: 'monitor-three', id: 'monitor3' }], + sha256: 'cde', + }, + { + not_after: '2020-07-25T03:15:39.000Z', + not_before: '2019-07-25T03:15:39.000Z', + common_name: 'Common-Four', + monitors: [{ name: 'monitor-four', id: 'monitor4' }], + sha256: 'def', + }, + ]; + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('sorts expiring certs appropriately when creating summary', () => { + diffSpy.mockReturnValueOnce(900).mockReturnValueOnce(901).mockReturnValueOnce(902); + const result = getCertSummary( + mockCerts, + new Date('2020-07-20T05:00:00.000Z').valueOf(), + new Date('2019-03-01T00:00:00.000Z').valueOf() + ); + expect(result).toMatchInlineSnapshot(` + Object { + "agingCommonNameAndDate": "", + "agingCount": 0, + "count": 4, + "expiringCommonNameAndDate": "Common-One, expired on 2020-07-16T03:15:39.000Z, 900 days ago.; Common-Two, expired on 2020-07-18T03:15:39.000Z, 901 days ago.; Common-Three, expired on 2020-07-19T03:15:39.000Z, 902 days ago.", + "expiringCount": 3, + "hasAging": null, + "hasExpired": true, + } + `); + }); + + it('sorts aging certs appropriate when creating summary', () => { + diffSpy.mockReturnValueOnce(702).mockReturnValueOnce(701).mockReturnValueOnce(700); + const result = getCertSummary( + mockCerts, + new Date('2020-07-01T12:00:00.000Z').valueOf(), + new Date('2019-09-01T03:00:00.000Z').valueOf() + ); + expect(result).toMatchInlineSnapshot(` + Object { + "agingCommonNameAndDate": "Common-Two, valid since 2019-07-20T03:15:39.000Z, 702 days ago.; Common-Three, valid since 2019-07-22T03:15:39.000Z, 701 days ago.; Common-One, valid since 2019-07-24T03:15:39.000Z, 700 days ago.", + "agingCount": 4, + "count": 4, + "expiringCommonNameAndDate": "", + "expiringCount": 0, + "hasAging": true, + "hasExpired": null, + } + `); + }); + + it('handles negative diff values appropriately for aging certs', () => { + diffSpy.mockReturnValueOnce(700).mockReturnValueOnce(-90).mockReturnValueOnce(-80); + const result = getCertSummary( + mockCerts, + new Date('2020-07-01T12:00:00.000Z').valueOf(), + new Date('2019-09-01T03:00:00.000Z').valueOf() + ); + expect(result).toMatchInlineSnapshot(` + Object { + "agingCommonNameAndDate": "Common-Two, valid since 2019-07-20T03:15:39.000Z, 700 days ago.; Common-Three, invalid until 2019-07-22T03:15:39.000Z, 90 days from now.; Common-One, invalid until 2019-07-24T03:15:39.000Z, 80 days from now.", + "agingCount": 4, + "count": 4, + "expiringCommonNameAndDate": "", + "expiringCount": 0, + "hasAging": true, + "hasExpired": null, + } + `); + }); + + it('handles negative diff values appropriately for expiring certs', () => { + diffSpy + // negative days are in the future, positive days are in the past + .mockReturnValueOnce(-96) + .mockReturnValueOnce(-94) + .mockReturnValueOnce(2); + const result = getCertSummary( + mockCerts, + new Date('2020-07-20T05:00:00.000Z').valueOf(), + new Date('2019-03-01T00:00:00.000Z').valueOf() + ); + expect(result).toMatchInlineSnapshot(` + Object { + "agingCommonNameAndDate": "", + "agingCount": 0, + "count": 4, + "expiringCommonNameAndDate": "Common-One, expires on 2020-07-16T03:15:39.000Z in 96 days.; Common-Two, expires on 2020-07-18T03:15:39.000Z in 94 days.; Common-Three, expired on 2020-07-19T03:15:39.000Z, 2 days ago.", + "expiringCount": 3, + "hasAging": null, + "hasExpired": true, + } + `); + }); + }); +}); diff --git a/x-pack/plugins/uptime/server/lib/alerts/tls_legacy.ts b/x-pack/plugins/uptime/server/lib/alerts/tls_legacy.ts new file mode 100644 index 00000000000000..8f1c0093e60ac8 --- /dev/null +++ b/x-pack/plugins/uptime/server/lib/alerts/tls_legacy.ts @@ -0,0 +1,156 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import moment from 'moment'; +import { schema } from '@kbn/config-schema'; +import { UptimeAlertTypeFactory } from './types'; +import { updateState } from './common'; +import { TLS_LEGACY } from '../../../common/constants/alerts'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants'; +import { Cert, CertResult } from '../../../common/runtime_types'; +import { commonStateTranslations, tlsTranslations } from './translations'; +import { DEFAULT_FROM, DEFAULT_TO } from '../../rest_api/certs/certs'; +import { uptimeAlertWrapper } from './uptime_alert_wrapper'; +import { ActionGroupIdsOf } from '../../../../alerting/common'; + +export type ActionGroupIds = ActionGroupIdsOf; + +const DEFAULT_SIZE = 20; + +interface TlsAlertState { + count: number; + agingCount: number; + agingCommonNameAndDate: string; + expiringCount: number; + expiringCommonNameAndDate: string; + hasAging: true | null; + hasExpired: true | null; +} + +const sortCerts = (a: string, b: string) => new Date(a).valueOf() - new Date(b).valueOf(); + +const mapCertsToSummaryString = ( + certs: Cert[], + certLimitMessage: (cert: Cert) => string, + maxSummaryItems: number +): string => + certs + .slice(0, maxSummaryItems) + .map((cert) => `${cert.common_name}, ${certLimitMessage(cert)}`) + .reduce((prev, cur) => (prev === '' ? cur : prev.concat(`; ${cur}`)), ''); + +const getValidAfter = ({ not_after: date }: Cert) => { + if (!date) return 'Error, missing `certificate_not_valid_after` date.'; + const relativeDate = moment().diff(date, 'days'); + return relativeDate >= 0 + ? tlsTranslations.validAfterExpiredString(date, relativeDate) + : tlsTranslations.validAfterExpiringString(date, Math.abs(relativeDate)); +}; + +const getValidBefore = ({ not_before: date }: Cert): string => { + if (!date) return 'Error, missing `certificate_not_valid_before` date.'; + const relativeDate = moment().diff(date, 'days'); + return relativeDate >= 0 + ? tlsTranslations.validBeforeExpiredString(date, relativeDate) + : tlsTranslations.validBeforeExpiringString(date, Math.abs(relativeDate)); +}; + +export const getCertSummary = ( + certs: Cert[], + expirationThreshold: number, + ageThreshold: number, + maxSummaryItems: number = 3 +): TlsAlertState => { + certs.sort((a, b) => sortCerts(a.not_after ?? '', b.not_after ?? '')); + const expiring = certs.filter( + (cert) => new Date(cert.not_after ?? '').valueOf() < expirationThreshold + ); + + certs.sort((a, b) => sortCerts(a.not_before ?? '', b.not_before ?? '')); + const aging = certs.filter((cert) => new Date(cert.not_before ?? '').valueOf() < ageThreshold); + + return { + count: certs.length, + agingCount: aging.length, + agingCommonNameAndDate: mapCertsToSummaryString(aging, getValidBefore, maxSummaryItems), + expiringCommonNameAndDate: mapCertsToSummaryString(expiring, getValidAfter, maxSummaryItems), + expiringCount: expiring.length, + hasAging: aging.length > 0 ? true : null, + hasExpired: expiring.length > 0 ? true : null, + }; +}; + +export const tlsLegacyAlertFactory: UptimeAlertTypeFactory = (_server, libs) => + uptimeAlertWrapper({ + id: 'xpack.uptime.alerts.tls', + name: tlsTranslations.legacyAlertFactoryName, + validate: { + params: schema.object({}), + }, + defaultActionGroupId: TLS_LEGACY.id, + actionGroups: [ + { + id: TLS_LEGACY.id, + name: TLS_LEGACY.name, + }, + ], + actionVariables: { + context: [], + state: [...tlsTranslations.actionVariables, ...commonStateTranslations], + }, + minimumLicenseRequired: 'basic', + async executor({ options, dynamicSettings, uptimeEsClient }) { + const { + services: { alertInstanceFactory }, + state, + } = options; + + const { certs, total }: CertResult = await libs.requests.getCerts({ + uptimeEsClient, + from: DEFAULT_FROM, + to: DEFAULT_TO, + index: 0, + size: DEFAULT_SIZE, + notValidAfter: `now+${ + dynamicSettings?.certExpirationThreshold ?? + DYNAMIC_SETTINGS_DEFAULTS.certExpirationThreshold + }d`, + notValidBefore: `now-${ + dynamicSettings?.certAgeThreshold ?? DYNAMIC_SETTINGS_DEFAULTS.certAgeThreshold + }d`, + sortBy: 'common_name', + direction: 'desc', + }); + + const foundCerts = total > 0; + + if (foundCerts) { + const absoluteExpirationThreshold = moment() + .add( + dynamicSettings.certExpirationThreshold ?? + DYNAMIC_SETTINGS_DEFAULTS.certExpirationThreshold, + 'd' + ) + .valueOf(); + const absoluteAgeThreshold = moment() + .subtract( + dynamicSettings.certAgeThreshold ?? DYNAMIC_SETTINGS_DEFAULTS.certAgeThreshold, + 'd' + ) + .valueOf(); + const alertInstance = alertInstanceFactory(TLS_LEGACY.id); + const summary = getCertSummary(certs, absoluteExpirationThreshold, absoluteAgeThreshold); + alertInstance.replaceState({ + ...updateState(state, foundCerts), + ...summary, + }); + alertInstance.scheduleActions(TLS_LEGACY.id); + } + + return updateState(state, foundCerts); + }, + }); diff --git a/x-pack/plugins/uptime/server/lib/alerts/translations.ts b/x-pack/plugins/uptime/server/lib/alerts/translations.ts index 3630185e19ab02..ee356eb68a626d 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/translations.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/translations.ts @@ -151,6 +151,9 @@ export const tlsTranslations = { alertFactoryName: i18n.translate('xpack.uptime.alerts.tls', { defaultMessage: 'Uptime TLS', }), + legacyAlertFactoryName: i18n.translate('xpack.uptime.alerts.tlsLegacy', { + defaultMessage: 'Uptime TLS (Legacy)', + }), actionVariables: [ { name: 'count', @@ -191,7 +194,7 @@ export const tlsTranslations = { ], validAfterExpiredString: (date: string, relativeDate: number) => i18n.translate('xpack.uptime.alerts.tls.validAfterExpiredString', { - defaultMessage: `expired on {date} {relativeDate} days ago.`, + defaultMessage: `expired on {date}, {relativeDate} days ago.`, values: { date, relativeDate, @@ -221,6 +224,18 @@ export const tlsTranslations = { relativeDate, }, }), + expiredLabel: i18n.translate('xpack.uptime.alerts.tls.expiredLabel', { + defaultMessage: 'expired', + }), + expiringLabel: i18n.translate('xpack.uptime.alerts.tls.expiringLabel', { + defaultMessage: 'expiring', + }), + agingLabel: i18n.translate('xpack.uptime.alerts.tls.agingLabel', { + defaultMessage: 'becoming too old', + }), + invalidLabel: i18n.translate('xpack.uptime.alerts.tls.invalidLabel', { + defaultMessage: 'invalid', + }), }; export const durationAnomalyTranslations = { diff --git a/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts b/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts index 0d64008a49688a..4c639d3a166cd6 100644 --- a/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts +++ b/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts @@ -97,7 +97,8 @@ export default ({ getService }: FtrProviderContext) => { return body; } - describe('close_jobs', function () { + // failing ES snapshot promotion after backend change, see https://github.com/elastic/kibana/issues/103023 + describe.skip('close_jobs', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); diff --git a/x-pack/test/api_integration/apis/search/session.ts b/x-pack/test/api_integration/apis/search/session.ts index d47199a0f1c1e2..06be7c6759bc05 100644 --- a/x-pack/test/api_integration/apis/search/session.ts +++ b/x-pack/test/api_integration/apis/search/session.ts @@ -403,7 +403,12 @@ export default function ({ getService }: FtrProviderContext) { const { id: id1 } = searchRes1.body; // it might take the session a moment to be created - await new Promise((resolve) => setTimeout(resolve, 2500)); + await retry.waitFor('search session created', async () => { + const response = await supertest + .get(`/internal/session/${sessionId}`) + .set('kbn-xsrf', 'foo'); + return response.body.statusCode === undefined; + }); const getSessionFirstTime = await supertest .get(`/internal/session/${sessionId}`) diff --git a/x-pack/test/api_integration/apis/security_solution/events.ts b/x-pack/test/api_integration/apis/security_solution/events.ts index 2135bdafd70ec7..ff4256f1a1adf7 100644 --- a/x-pack/test/api_integration/apis/security_solution/events.ts +++ b/x-pack/test/api_integration/apis/security_solution/events.ts @@ -415,7 +415,7 @@ export default function ({ getService }: FtrProviderContext) { it('Make sure that we get Timeline data', async () => { await retry.try(async () => { const resp = await supertest - .post('/internal/search/securitySolutionTimelineSearchStrategy/') + .post('/internal/search/timelineSearchStrategy/') .set('kbn-xsrf', 'true') .set('Content-Type', 'application/json') .send({ @@ -457,7 +457,7 @@ export default function ({ getService }: FtrProviderContext) { it('Make sure that pagination is working in Timeline query', async () => { await retry.try(async () => { const resp = await supertest - .post('/internal/search/securitySolutionTimelineSearchStrategy/') + .post('/internal/search/timelineSearchStrategy/') .set('kbn-xsrf', 'true') .set('Content-Type', 'application/json') .send({ diff --git a/x-pack/test/api_integration/apis/security_solution/sources.ts b/x-pack/test/api_integration/apis/security_solution/sources.ts index db9156a53048b4..7f5c46610d6070 100644 --- a/x-pack/test/api_integration/apis/security_solution/sources.ts +++ b/x-pack/test/api_integration/apis/security_solution/sources.ts @@ -19,7 +19,7 @@ export default function ({ getService }: FtrProviderContext) { it('Make sure that we get source information when auditbeat indices is there', async () => { const { body: sourceStatus } = await supertest - .post('/internal/search/securitySolutionIndexFields/') + .post('/internal/search/indexFields/') .set('kbn-xsrf', 'true') .send({ indices: ['auditbeat-*'], @@ -34,7 +34,7 @@ export default function ({ getService }: FtrProviderContext) { it('should find indexes as being available when they exist', async () => { const { body: sourceStatus } = await supertest - .post('/internal/search/securitySolutionIndexFields/') + .post('/internal/search/indexFields/') .set('kbn-xsrf', 'true') .send({ indices: ['auditbeat-*', 'filebeat-*'], @@ -48,7 +48,7 @@ export default function ({ getService }: FtrProviderContext) { it('should not find indexes as existing when there is an empty array of them', async () => { const { body: sourceStatus } = await supertest - .post('/internal/search/securitySolutionIndexFields/') + .post('/internal/search/indexFields/') .set('kbn-xsrf', 'true') .send({ indices: [], @@ -62,7 +62,7 @@ export default function ({ getService }: FtrProviderContext) { it('should not find indexes as existing when there is a _all within it', async () => { const { body: sourceStatus } = await supertest - .post('/internal/search/securitySolutionIndexFields/') + .post('/internal/search/indexFields/') .set('kbn-xsrf', 'true') .send({ indices: ['_all'], @@ -76,7 +76,7 @@ export default function ({ getService }: FtrProviderContext) { it('should not find indexes as existing when there are empty strings within it', async () => { const { body: sourceStatus } = await supertest - .post('/internal/search/securitySolutionIndexFields/') + .post('/internal/search/indexFields/') .set('kbn-xsrf', 'true') .send({ indices: [''], @@ -90,7 +90,7 @@ export default function ({ getService }: FtrProviderContext) { it('should not find indexes as existing when there are blank spaces within it', async () => { const { body: sourceStatus } = await supertest - .post('/internal/search/securitySolutionIndexFields/') + .post('/internal/search/indexFields/') .set('kbn-xsrf', 'true') .send({ indices: [' '], @@ -104,7 +104,7 @@ export default function ({ getService }: FtrProviderContext) { it('should find indexes when one is an empty index but the others are valid', async () => { const { body: sourceStatus } = await supertest - .post('/internal/search/securitySolutionIndexFields/') + .post('/internal/search/indexFields/') .set('kbn-xsrf', 'true') .send({ indices: ['', 'auditbeat-*'], diff --git a/x-pack/test/api_integration/apis/security_solution/timeline_details.ts b/x-pack/test/api_integration/apis/security_solution/timeline_details.ts index e1eaef823d2e0c..3aefd9f8b597ab 100644 --- a/x-pack/test/api_integration/apis/security_solution/timeline_details.ts +++ b/x-pack/test/api_integration/apis/security_solution/timeline_details.ts @@ -681,7 +681,7 @@ export default function ({ getService }: FtrProviderContext) { const { body: { data: detailsData }, } = await supertest - .post('/internal/search/securitySolutionTimelineSearchStrategy/') + .post('/internal/search/timelineSearchStrategy/') .set('kbn-xsrf', 'true') .send({ factoryQueryType: TimelineEventsQueries.details, @@ -701,7 +701,7 @@ export default function ({ getService }: FtrProviderContext) { const { body: { destinationIpCount, hostCount, processCount, sourceIpCount, userCount }, } = await supertest - .post('/internal/search/securitySolutionTimelineSearchStrategy/') + .post('/internal/search/timelineSearchStrategy/') .set('kbn-xsrf', 'true') .send({ factoryQueryType: TimelineEventsQueries.kpi, diff --git a/x-pack/test/fleet_api_integration/apis/epm/__snapshots__/install_by_upload.snap b/x-pack/test/fleet_api_integration/apis/epm/__snapshots__/install_by_upload.snap index 7584dfcc8a6c06..13c2dd24f91037 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/__snapshots__/install_by_upload.snap +++ b/x-pack/test/fleet_api_integration/apis/epm/__snapshots__/install_by_upload.snap @@ -341,14 +341,26 @@ Object { "id": "logs-apache.access", "type": "index_template", }, + Object { + "id": "logs-apache.access@custom", + "type": "component_template", + }, Object { "id": "metrics-apache.status", "type": "index_template", }, + Object { + "id": "metrics-apache.status@custom", + "type": "component_template", + }, Object { "id": "logs-apache.error", "type": "index_template", }, + Object { + "id": "logs-apache.error@custom", + "type": "component_template", + }, ], "installed_kibana": Array [ Object { diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts b/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts index 71cf7ed79fa2ba..182838f21dbda4 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_by_upload.ts @@ -70,7 +70,7 @@ export default function (providerContext: FtrProviderContext) { .type('application/gzip') .send(buf) .expect(200); - expect(res.body.response.length).to.be(23); + expect(res.body.response.length).to.be(26); }); it('should install a zip archive correctly and package info should return correctly after validation', async function () { @@ -81,7 +81,7 @@ export default function (providerContext: FtrProviderContext) { .type('application/zip') .send(buf) .expect(200); - expect(res.body.response.length).to.be(23); + expect(res.body.response.length).to.be(26); const packageInfoRes = await supertest .get(`/api/fleet/epm/packages/${testPkgKey}`) diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_overrides.ts b/x-pack/test/fleet_api_integration/apis/epm/install_overrides.ts index 1b916dff573af9..204ee8508f468c 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_overrides.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_overrides.ts @@ -7,22 +7,22 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; -import { warnAndSkipTest } from '../../helpers'; +import { skipIfNoDockerRegistry } from '../../helpers'; -export default function ({ getService }: FtrProviderContext) { +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; const supertest = getService('supertest'); const es = getService('es'); const dockerServers = getService('dockerServers'); - const log = getService('log'); const mappingsPackage = 'overrides-0.1.0'; const server = dockerServers.get('registry'); - const deletePackage = async (pkgkey: string) => { - await supertest.delete(`/api/fleet/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); - }; + const deletePackage = async (pkgkey: string) => + supertest.delete(`/api/fleet/epm/packages/${pkgkey}`).set('kbn-xsrf', 'xxxx'); describe('installs packages that include settings and mappings overrides', async () => { + skipIfNoDockerRegistry(providerContext); after(async () => { if (server.enabled) { // remove the package just in case it being installed will affect other tests @@ -31,50 +31,107 @@ export default function ({ getService }: FtrProviderContext) { }); it('should install the overrides package correctly', async function () { - if (server.enabled) { - let { body } = await supertest - .post(`/api/fleet/epm/packages/${mappingsPackage}`) - .set('kbn-xsrf', 'xxxx') - .expect(200); - - const templateName = body.response[0].id; - - ({ body } = await es.transport.request({ - method: 'GET', - path: `/_index_template/${templateName}`, - })); - - // make sure it has the right composed_of array, the contents should be the component templates - // that were installed - expect(body.index_templates[0].index_template.composed_of).to.contain( - `${templateName}-mappings` - ); - expect(body.index_templates[0].index_template.composed_of).to.contain( - `${templateName}-settings` - ); - - ({ body } = await es.transport.request({ - method: 'GET', - path: `/_component_template/${templateName}-mappings`, - })); - - // Make sure that the `dynamic` field exists and is set to false (as it is in the package) - expect(body.component_templates[0].component_template.template.mappings.dynamic).to.be( - false - ); - - ({ body } = await es.transport.request({ - method: 'GET', - path: `/_component_template/${templateName}-settings`, - })); - - // Make sure that the lifecycle name gets set correct in the settings - expect( - body.component_templates[0].component_template.template.settings.index.lifecycle.name - ).to.be('reference'); - } else { - warnAndSkipTest(this, log); - } + let { body } = await supertest + .post(`/api/fleet/epm/packages/${mappingsPackage}`) + .set('kbn-xsrf', 'xxxx') + .expect(200); + + const templateName = body.response[0].id; + + const { body: indexTemplateResponse } = await es.transport.request({ + method: 'GET', + path: `/_index_template/${templateName}`, + }); + + // the index template composed_of has the correct component templates in the correct order + const indexTemplate = indexTemplateResponse.index_templates[0].index_template; + expect(indexTemplate.composed_of).to.eql([ + `${templateName}@mappings`, + `${templateName}@settings`, + `${templateName}@custom`, + ]); + + ({ body } = await es.transport.request({ + method: 'GET', + path: `/_component_template/${templateName}@mappings`, + })); + + // The mappings override provided in the package is set in the mappings component template + expect(body.component_templates[0].component_template.template.mappings.dynamic).to.be(false); + + ({ body } = await es.transport.request({ + method: 'GET', + path: `/_component_template/${templateName}@settings`, + })); + + // The settings override provided in the package is set in the settings component template + expect( + body.component_templates[0].component_template.template.settings.index.lifecycle.name + ).to.be('reference'); + + ({ body } = await es.transport.request({ + method: 'GET', + path: `/_component_template/${templateName}@custom`, + })); + + // The user_settings component template is an empty/stub template at first + const storedTemplate = body.component_templates[0].component_template.template.settings; + expect(storedTemplate).to.eql({}); + + // Update the user_settings component template + ({ body } = await es.transport.request({ + method: 'PUT', + path: `/_component_template/${templateName}@custom`, + body: { + template: { + settings: { + number_of_shards: 3, + index: { + lifecycle: { name: 'overridden by user' }, + number_of_shards: 123, + }, + }, + }, + }, + })); + + // simulate the result + ({ body } = await es.transport.request({ + method: 'POST', + path: `/_index_template/_simulate/${templateName}`, + // body: indexTemplate, // I *think* this should work, but it doesn't + body: { + index_patterns: [`${templateName}-*`], + composed_of: [ + `${templateName}@mappings`, + `${templateName}@settings`, + `${templateName}@custom`, + ], + }, + })); + + expect(body).to.eql({ + template: { + settings: { + index: { + lifecycle: { + name: 'overridden by user', + }, + number_of_shards: '3', + }, + }, + mappings: { + dynamic: 'false', + }, + aliases: {}, + }, + overlapping: [ + { + name: 'logs', + index_patterns: ['logs-*-*'], + }, + ], + }); }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts b/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts index 8e09e331bf8678..85573560177eea 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_remove_assets.ts @@ -87,6 +87,40 @@ export default function (providerContext: FtrProviderContext) { ); expect(resMetricsTemplate.statusCode).equal(404); }); + it('should have uninstalled the component templates', async function () { + const resMappings = await es.transport.request( + { + method: 'GET', + path: `/_component_template/${logsTemplateName}@mappings`, + }, + { + ignore: [404], + } + ); + expect(resMappings.statusCode).equal(404); + + const resSettings = await es.transport.request( + { + method: 'GET', + path: `/_component_template/${logsTemplateName}@settings`, + }, + { + ignore: [404], + } + ); + expect(resSettings.statusCode).equal(404); + + const resUserSettings = await es.transport.request( + { + method: 'GET', + path: `/_component_template/${logsTemplateName}@custom`, + }, + { + ignore: [404], + } + ); + expect(resUserSettings.statusCode).equal(404); + }); it('should have uninstalled the pipelines', async function () { const res = await es.transport.request( { @@ -328,17 +362,22 @@ const expectAssetsInstalled = ({ }); expect(resPipeline2.statusCode).equal(200); }); - it('should have installed the template components', async function () { - const res = await es.transport.request({ + it('should have installed the component templates', async function () { + const resMappings = await es.transport.request({ method: 'GET', - path: `/_component_template/${logsTemplateName}-mappings`, + path: `/_component_template/${logsTemplateName}@mappings`, }); - expect(res.statusCode).equal(200); + expect(resMappings.statusCode).equal(200); const resSettings = await es.transport.request({ method: 'GET', - path: `/_component_template/${logsTemplateName}-settings`, + path: `/_component_template/${logsTemplateName}@settings`, }); expect(resSettings.statusCode).equal(200); + const resUserSettings = await es.transport.request({ + method: 'GET', + path: `/_component_template/${logsTemplateName}@custom`, + }); + expect(resUserSettings.statusCode).equal(200); }); it('should have installed the transform components', async function () { const res = await es.transport.request({ @@ -487,6 +526,22 @@ const expectAssetsInstalled = ({ }, ], installed_es: [ + { + id: 'logs-all_assets.test_logs@mappings', + type: 'component_template', + }, + { + id: 'logs-all_assets.test_logs@settings', + type: 'component_template', + }, + { + id: 'logs-all_assets.test_logs@custom', + type: 'component_template', + }, + { + id: 'metrics-all_assets.test_metrics@custom', + type: 'component_template', + }, { id: 'logs-all_assets.test_logs-all_assets', type: 'data_stream_ilm_policy', diff --git a/x-pack/test/fleet_api_integration/apis/epm/update_assets.ts b/x-pack/test/fleet_api_integration/apis/epm/update_assets.ts index a6f79414ab8c01..6b4d104423144d 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/update_assets.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/update_assets.ts @@ -199,23 +199,45 @@ export default function (providerContext: FtrProviderContext) { ); expect(resPipeline2.statusCode).equal(404); }); - it('should have updated the template components', async function () { - const res = await es.transport.request({ + it('should have updated the component templates', async function () { + const resMappings = await es.transport.request({ method: 'GET', - path: `/_component_template/${logsTemplateName}-mappings`, + path: `/_component_template/${logsTemplateName}@mappings`, }); - expect(res.statusCode).equal(200); - expect(res.body.component_templates[0].component_template.template.mappings).eql({ + expect(resMappings.statusCode).equal(200); + expect(resMappings.body.component_templates[0].component_template.template.mappings).eql({ dynamic: true, }); const resSettings = await es.transport.request({ method: 'GET', - path: `/_component_template/${logsTemplateName}-settings`, + path: `/_component_template/${logsTemplateName}@settings`, }); - expect(res.statusCode).equal(200); + expect(resSettings.statusCode).equal(200); expect(resSettings.body.component_templates[0].component_template.template.settings).eql({ index: { lifecycle: { name: 'reference2' } }, }); + const resUserSettings = await es.transport.request({ + method: 'GET', + path: `/_component_template/${logsTemplateName}@custom`, + }); + expect(resUserSettings.statusCode).equal(200); + expect(resUserSettings.body).eql({ + component_templates: [ + { + name: 'logs-all_assets.test_logs@custom', + component_template: { + _meta: { + package: { + name: 'all_assets', + }, + }, + template: { + settings: {}, + }, + }, + }, + ], + }); }); it('should have updated the index patterns', async function () { const resIndexPatternLogs = await kibanaServer.savedObjects.get({ @@ -321,14 +343,34 @@ export default function (providerContext: FtrProviderContext) { id: 'logs-all_assets.test_logs', type: 'index_template', }, + { + id: 'logs-all_assets.test_logs@mappings', + type: 'component_template', + }, + { + id: 'logs-all_assets.test_logs@settings', + type: 'component_template', + }, + { + id: 'logs-all_assets.test_logs@custom', + type: 'component_template', + }, { id: 'logs-all_assets.test_logs2', type: 'index_template', }, + { + id: 'logs-all_assets.test_logs2@custom', + type: 'component_template', + }, { id: 'metrics-all_assets.test_metrics', type: 'index_template', }, + { + id: 'metrics-all_assets.test_metrics@custom', + type: 'component_template', + }, ], es_index_patterns: { test_logs: 'logs-all_assets.test_logs-*', diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.1.0/img/logo_overrides_64_color.svg b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.1.0/img/logo_overrides_64_color.svg new file mode 100644 index 00000000000000..b03007a76ffcc5 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.1.0/img/logo_overrides_64_color.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.1.0/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.1.0/manifest.yml index bba1a6a4c347d1..312cd2874804ce 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.1.0/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.1.0/manifest.yml @@ -1,7 +1,7 @@ format_version: 1.0.0 -name: error_handling +name: error_handling title: Error handling -description: tests error handling and rollback +description: tests error handling and rollback version: 0.1.0 categories: [] release: beta @@ -17,4 +17,4 @@ requirement: icons: - src: '/img/logo_overrides_64_color.svg' size: '16x16' - type: 'image/svg+xml' \ No newline at end of file + type: 'image/svg+xml' diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.2.0/img/logo_overrides_64_color.svg b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.2.0/img/logo_overrides_64_color.svg new file mode 100644 index 00000000000000..b03007a76ffcc5 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.2.0/img/logo_overrides_64_color.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.2.0/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.2.0/manifest.yml index 2eb6a41a77ede8..c92f0ab5ae7f3f 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.2.0/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/error_handling/0.2.0/manifest.yml @@ -1,7 +1,7 @@ format_version: 1.0.0 -name: error_handling +name: error_handling title: Error handling -description: tests error handling and rollback +description: tests error handling and rollback version: 0.2.0 categories: [] release: beta @@ -16,4 +16,4 @@ requirement: icons: - src: '/img/logo_overrides_64_color.svg' - size: '16x16' \ No newline at end of file + size: '16x16' diff --git a/x-pack/test/fleet_api_integration/config.ts b/x-pack/test/fleet_api_integration/config.ts index 52c9760d66c198..d18ba9c55ca968 100644 --- a/x-pack/test/fleet_api_integration/config.ts +++ b/x-pack/test/fleet_api_integration/config.ts @@ -51,17 +51,11 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { waitForLogLine: 'package manifests loaded', }, }), - services: { - ...xPackAPITestsConfig.get('services'), - }, + services: xPackAPITestsConfig.get('services'), junit: { reportName: 'X-Pack EPM API Integration Tests', }, - - esTestCluster: { - ...xPackAPITestsConfig.get('esTestCluster'), - }, - + esTestCluster: xPackAPITestsConfig.get('esTestCluster'), kbnTestServer: { ...xPackAPITestsConfig.get('kbnTestServer'), serverArgs: [ diff --git a/x-pack/test/functional/apps/dashboard/reporting/download_csv.ts b/x-pack/test/functional/apps/dashboard/reporting/download_csv.ts index e736fe08eba998..94540aa8b4c464 100644 --- a/x-pack/test/functional/apps/dashboard/reporting/download_csv.ts +++ b/x-pack/test/functional/apps/dashboard/reporting/download_csv.ts @@ -17,10 +17,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const dashboardPanelActions = getService('dashboardPanelActions'); const log = getService('log'); const testSubjects = getService('testSubjects'); + const kibanaServer = getService('kibanaServer'); const filterBar = getService('filterBar'); const find = getService('find'); const retry = getService('retry'); const PageObjects = getPageObjects(['reporting', 'common', 'dashboard', 'timePicker']); + const ecommerceSOPath = 'x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json'; const getCsvPath = (name: string) => path.resolve(REPO_ROOT, `target/functional-tests/downloads/${name}.csv`); @@ -67,11 +69,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('E-Commerce Data', () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.load(ecommerceSOPath); }); after(async () => { await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.unload(ecommerceSOPath); }); it('Download CSV export of a saved search panel', async function () { diff --git a/x-pack/test/functional/apps/dashboard/reporting/screenshots.ts b/x-pack/test/functional/apps/dashboard/reporting/screenshots.ts index 7c5e4b2d12baaf..7eb2ef74000e09 100644 --- a/x-pack/test/functional/apps/dashboard/reporting/screenshots.ts +++ b/x-pack/test/functional/apps/dashboard/reporting/screenshots.ts @@ -27,13 +27,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const es = getService('es'); const testSubjects = getService('testSubjects'); const kibanaServer = getService('kibanaServer'); + const ecommerceSOPath = 'x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json'; - describe('Dashboard Reporting Screenshots', () => { + // https://github.com/elastic/kibana/issues/102911 + describe.skip('Dashboard Reporting Screenshots', () => { before('initialize tests', async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.loadIfNeeded( - 'x-pack/test/functional/es_archives/reporting/ecommerce_kibana' - ); + await kibanaServer.importExport.load(ecommerceSOPath); await browser.setWindowSize(1600, 850); await security.role.create('test_reporting_user', { @@ -61,7 +61,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); after('clean up archives', async () => { await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.unload(ecommerceSOPath); await es.deleteByQuery({ index: '.reporting-*', refresh: true, diff --git a/x-pack/test/functional/apps/discover/reporting.ts b/x-pack/test/functional/apps/discover/reporting.ts index 2b424b94b72368..3eb66204df5640 100644 --- a/x-pack/test/functional/apps/discover/reporting.ts +++ b/x-pack/test/functional/apps/discover/reporting.ts @@ -16,6 +16,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const browser = getService('browser'); const PageObjects = getPageObjects(['reporting', 'common', 'discover', 'timePicker']); const filterBar = getService('filterBar'); + const ecommerceSOPath = 'x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json'; const setFieldsFromSource = async (setValue: boolean) => { await kibanaServer.uiSettings.update({ 'discover:searchFieldsFromSource': setValue }); @@ -25,12 +26,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before('initialize tests', async () => { log.debug('ReportingPage:initTests'); await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.load(ecommerceSOPath); await browser.setWindowSize(1600, 850); }); after('clean up archives', async () => { await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.unload(ecommerceSOPath); await es.deleteByQuery({ index: '.reporting-*', refresh: true, @@ -74,7 +75,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Generate CSV: new search', () => { beforeEach(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); // reload the archive to wipe out changes made by each test + await kibanaServer.importExport.load(ecommerceSOPath); await PageObjects.common.navigateToApp('discover'); }); @@ -151,12 +152,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.load(ecommerceSOPath); }); after(async () => { await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.unload(ecommerceSOPath); }); beforeEach(() => PageObjects.common.navigateToApp('discover')); diff --git a/x-pack/test/functional/apps/discover/saved_searches.ts b/x-pack/test/functional/apps/discover/saved_searches.ts index 5df9bf99491284..1d8de9fe9fb6d9 100644 --- a/x-pack/test/functional/apps/discover/saved_searches.ts +++ b/x-pack/test/functional/apps/discover/saved_searches.ts @@ -16,16 +16,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const dataGrid = getService('dataGrid'); const panelActions = getService('dashboardPanelActions'); const panelActionsTimeRange = getService('dashboardPanelTimeRange'); + const ecommerceSOPath = 'x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json'; describe('Discover Saved Searches', () => { before('initialize tests', async () => { await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.load(ecommerceSOPath); await kibanaServer.uiSettings.update({ 'doc_table:legacy': false }); }); after('clean up archives', async () => { await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.unload(ecommerceSOPath); await kibanaServer.uiSettings.unset('doc_table:legacy'); }); diff --git a/x-pack/test/functional/apps/grok_debugger/grok_debugger.js b/x-pack/test/functional/apps/grok_debugger/grok_debugger.js index 0162b660a14081..68cd5820e2a32f 100644 --- a/x-pack/test/functional/apps/grok_debugger/grok_debugger.js +++ b/x-pack/test/functional/apps/grok_debugger/grok_debugger.js @@ -11,7 +11,8 @@ export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); const PageObjects = getPageObjects(['grokDebugger']); - describe('grok debugger app', function () { + // FLAKY: https://github.com/elastic/kibana/issues/84440 + describe.skip('grok debugger app', function () { this.tags('includeFirefox'); before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'); diff --git a/x-pack/test/functional/apps/visualize/reporting.ts b/x-pack/test/functional/apps/visualize/reporting.ts index 799006337300fb..c43747c346ca75 100644 --- a/x-pack/test/functional/apps/visualize/reporting.ts +++ b/x-pack/test/functional/apps/visualize/reporting.ts @@ -13,6 +13,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const browser = getService('browser'); const log = getService('log'); + const kibanaServer = getService('kibanaServer'); + const ecommerceSOPath = 'x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json'; + const PageObjects = getPageObjects([ 'reporting', 'common', @@ -25,14 +28,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before('initialize tests', async () => { log.debug('ReportingPage:initTests'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.loadIfNeeded( - 'x-pack/test/functional/es_archives/reporting/ecommerce_kibana' - ); + await kibanaServer.importExport.load(ecommerceSOPath); await browser.setWindowSize(1600, 850); }); after('clean up archives', async () => { await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.unload(ecommerceSOPath); await es.deleteByQuery({ index: '.reporting-*', refresh: true, diff --git a/x-pack/test/functional/es_archives/reporting/ecommerce_kibana/data.json b/x-pack/test/functional/es_archives/reporting/ecommerce_kibana/data.json deleted file mode 100644 index f0e7d7ae6d1d5b..00000000000000 --- a/x-pack/test/functional/es_archives/reporting/ecommerce_kibana/data.json +++ /dev/null @@ -1,788 +0,0 @@ -{ - "type": "doc", - "value": { - "id": "config:7.0.0", - "index": ".kibana_1", - "source": { - "config": { - "buildNum": 9007199254740991, - "dateFormat:tz": "UTC", - "defaultIndex": "5193f870-d861-11e9-a311-0fa548c5f953" - }, - "migrationVersion": { - "config": "7.13.0" - }, - "references": [], - "type": "config", - "updated_at": "2019-09-16T09:06:51.201Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "config:8.0.0", - "index": ".kibana_1", - "source": { - "config": { - "accessibility:disableAnimations": true, - "visualization:visualize:legacyChartsLibrary": true, - "buildNum": 9007199254740991, - "dateFormat:tz": "UTC", - "defaultIndex": "5193f870-d861-11e9-a311-0fa548c5f953" - }, - "migrationVersion": { - "config": "7.13.0" - }, - "references": [], - "type": "config", - "updated_at": "2021-05-03T18:23:19.891Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "index-pattern:5193f870-d861-11e9-a311-0fa548c5f953", - "index": ".kibana_1", - "source": { - "index-pattern": { - "fields": "[{\"name\":\"_id\",\"type\":\"string\",\"esTypes\":[\"_id\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_index\",\"type\":\"string\",\"esTypes\":[\"_index\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_source\",\"type\":\"_source\",\"esTypes\":[\"_source\"],\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_type\",\"type\":\"string\",\"esTypes\":[\"_type\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"category\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"category.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"category\"}}},{\"name\":\"currency\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"customer_birth_date\",\"type\":\"date\",\"esTypes\":[\"date\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"customer_first_name\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"customer_first_name.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"customer_first_name\"}}},{\"name\":\"customer_full_name\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"customer_full_name.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"customer_full_name\"}}},{\"name\":\"customer_gender\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"customer_id\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"customer_last_name\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"customer_last_name.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"customer_last_name\"}}},{\"name\":\"customer_phone\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"day_of_week\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"day_of_week_i\",\"type\":\"number\",\"esTypes\":[\"integer\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"email\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geoip.city_name\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geoip.continent_name\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geoip.country_iso_code\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geoip.location\",\"type\":\"geo_point\",\"esTypes\":[\"geo_point\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geoip.region_name\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"manufacturer\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"manufacturer.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"manufacturer\"}}},{\"name\":\"order_date\",\"type\":\"date\",\"esTypes\":[\"date\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"order_id\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products._id\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"products._id.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"products._id\"}}},{\"name\":\"products.base_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.base_unit_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.category\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"products.category.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"products.category\"}}},{\"name\":\"products.created_on\",\"type\":\"date\",\"esTypes\":[\"date\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.discount_amount\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.discount_percentage\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.manufacturer\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"products.manufacturer.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"products.manufacturer\"}}},{\"name\":\"products.min_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.product_id\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.product_name\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"products.product_name.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"products.product_name\"}}},{\"name\":\"products.quantity\",\"type\":\"number\",\"esTypes\":[\"integer\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.sku\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.tax_amount\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.taxful_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.taxless_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.unit_discount_amount\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"sku\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"taxful_total_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"taxless_total_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"total_quantity\",\"type\":\"number\",\"esTypes\":[\"integer\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"total_unique_products\",\"type\":\"number\",\"esTypes\":[\"integer\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"type\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"user\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]", - "timeFieldName": "order_date", - "title": "ecommerce" - }, - "migrationVersion": { - "index-pattern": "7.11.0" - }, - "references": [], - "type": "index-pattern", - "updated_at": "2019-12-11T23:24:13.381Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "search:6091ead0-1c6d-11ea-a100-8589bb9d7c6b", - "index": ".kibana_1", - "source": { - "migrationVersion": { - "search": "7.9.3" - }, - "references": [ - { - "id": "5193f870-d861-11e9-a311-0fa548c5f953", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern" - } - ], - "search": { - "columns": [ - "order_date", - "category", - "currency", - "customer_id", - "order_id", - "day_of_week_i", - "products.created_on", - "sku" - ], - "description": "", - "hits": 0, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" - }, - "sort": [ - [ - "order_date", - "desc" - ] - ], - "title": "Ecommerce Data", - "version": 1 - }, - "type": "search", - "updated_at": "2019-12-11T23:24:28.540Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "dashboard:constructed-sample-saved-object-id", - "index": ".kibana_1", - "source": { - "dashboard": { - "description": "", - "hits": 0, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}" - }, - "optionsJSON": "{\"hidePanelTitles\":true,\"useMargins\":true}", - "panelsJSON": "[{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1c12c2f2-80c2-4d5c-b722-55b2415006e1\"},\"panelIndex\":\"1c12c2f2-80c2-4d5c-b722-55b2415006e1\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1c4b99e1-7785-444f-a1c5-f592893b1a96\"},\"panelIndex\":\"1c4b99e1-7785-444f-a1c5-f592893b1a96\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_1\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":15,\"w\":48,\"h\":18,\"i\":\"94eab06f-60ac-4a85-b771-3a8ed475c9bb\"},\"panelIndex\":\"94eab06f-60ac-4a85-b771-3a8ed475c9bb\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_2\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":33,\"w\":48,\"h\":8,\"i\":\"52c19b6b-7117-42ac-a74e-c507a1c3ffc0\"},\"panelIndex\":\"52c19b6b-7117-42ac-a74e-c507a1c3ffc0\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_3\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":41,\"w\":11,\"h\":10,\"i\":\"a1e889dc-b80e-4937-a576-979f34d1859b\"},\"panelIndex\":\"a1e889dc-b80e-4937-a576-979f34d1859b\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_4\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":11,\"y\":41,\"w\":5,\"h\":10,\"i\":\"4930b035-d756-4cc5-9a18-1af9e67d6f31\"},\"panelIndex\":\"4930b035-d756-4cc5-9a18-1af9e67d6f31\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_5\"}]", - "refreshInterval": { - "pause": true, - "value": 0 - }, - "timeFrom": "2019-06-26T06:20:28.066Z", - "timeRestore": true, - "timeTo": "2019-06-26T07:27:58.573Z", - "title": "Ecom Dashboard Hidden Panel Titles", - "version": 1 - }, - "migrationVersion": { - "dashboard": "7.11.0" - }, - "references": [ - { - "id": "0a464230-79f0-11ea-ae7f-13c5d6e410a0", - "name": "panel_0", - "type": "visualization" - }, - { - "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", - "name": "panel_1", - "type": "visualization" - }, - { - "id": "6091ead0-1c6d-11ea-a100-8589bb9d7c6b", - "name": "panel_2", - "type": "search" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "panel_3", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "panel_4", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "panel_5", - "type": "visualization" - } - ], - "type": "dashboard", - "updated_at": "2020-04-10T00:37:48.462Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "visualization:0a464230-79f0-11ea-ae7f-13c5d6e410a0", - "index": ".kibana_1", - "source": { - "migrationVersion": { - "visualization": "7.13.0" - }, - "references": [ - { - "id": "5193f870-d861-11e9-a311-0fa548c5f953", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern" - } - ], - "type": "visualization", - "updated_at": "2020-04-08T23:24:05.971Z", - "visualization": { - "description": "", - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" - }, - "title": "e-commerce area chart", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\"type\":\"area\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"order_date\",\"timeRange\":{\"from\":\"2019-06-26T06:20:28.066Z\",\"to\":\"2019-06-26T07:27:58.573Z\"},\"useNormalizedEsInterval\":true,\"scaleMetricValues\":false,\"interval\":\"auto\",\"drop_partials\":false,\"min_doc_count\":1,\"extended_bounds\":{}}}],\"params\":{\"type\":\"area\",\"grid\":{\"categoryLines\":false},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"filter\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":true,\"type\":\"area\",\"mode\":\"stacked\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"drawLinesBetweenPoints\":true,\"lineWidth\":2,\"showCircles\":true,\"interpolate\":\"linear\",\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false,\"thresholdLine\":{\"show\":false,\"value\":10,\"width\":1,\"style\":\"full\",\"color\":\"#E7664C\"},\"labels\":{},\"isVislibVis\":true,\"detailedTooltip\":true,\"fittingFunction\":\"zero\"},\"title\":\"e-commerce area chart\"}" - } - } - } -} - -{ - "type": "doc", - "value": { - "id": "visualization:200609c0-79f0-11ea-ae7f-13c5d6e410a0", - "index": ".kibana_1", - "source": { - "migrationVersion": { - "visualization": "7.13.0" - }, - "references": [ - { - "id": "5193f870-d861-11e9-a311-0fa548c5f953", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern" - } - ], - "type": "visualization", - "updated_at": "2020-04-08T23:24:42.460Z", - "visualization": { - "description": "", - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" - }, - "title": "e-commerce pie chart", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\"type\":\"pie\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"order_date\",\"timeRange\":{\"from\":\"2019-06-26T06:20:28.066Z\",\"to\":\"2019-06-26T07:27:58.573Z\"},\"useNormalizedEsInterval\":true,\"scaleMetricValues\":false,\"interval\":\"auto\",\"drop_partials\":false,\"min_doc_count\":1,\"extended_bounds\":{}}}],\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100}},\"title\":\"e-commerce pie chart\"}" - } - } - } -} - -{ - "type": "doc", - "value": { - "id": "visualization:ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "index": ".kibana_1", - "source": { - "migrationVersion": { - "visualization": "7.13.0" - }, - "references": [ - { - "id": "5193f870-d861-11e9-a311-0fa548c5f953", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern" - } - ], - "type": "visualization", - "updated_at": "2020-04-10T00:33:44.909Z", - "visualization": { - "description": "", - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"filter\":[]}" - }, - "title": "게이지", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\"type\":\"gauge\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}}],\"params\":{\"type\":\"gauge\",\"addTooltip\":true,\"addLegend\":true,\"isDisplayWarning\":false,\"gauge\":{\"alignment\":\"automatic\",\"extendRange\":true,\"percentageMode\":false,\"gaugeType\":\"Arc\",\"gaugeStyle\":\"Full\",\"backStyle\":\"Full\",\"orientation\":\"vertical\",\"colorSchema\":\"Green to Red\",\"gaugeColorMode\":\"Labels\",\"colorsRange\":[{\"from\":0,\"to\":50},{\"from\":50,\"to\":75},{\"from\":75,\"to\":100}],\"invertColors\":false,\"labels\":{\"show\":true,\"color\":\"black\"},\"scale\":{\"show\":true,\"labels\":false,\"color\":\"rgba(105,112,125,0.2)\"},\"type\":\"meter\",\"style\":{\"bgWidth\":0.9,\"width\":0.9,\"mask\":false,\"bgMask\":false,\"maskBars\":50,\"bgFill\":\"rgba(105,112,125,0.2)\",\"bgColor\":true,\"subText\":\"\",\"fontSize\":60}}},\"title\":\"게이지\"}" - } - } - } -} - -{ - "type": "doc", - "value": { - "id": "visualization:132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "index": ".kibana_1", - "source": { - "migrationVersion": { - "visualization": "7.13.0" - }, - "references": [ - { - "id": "5193f870-d861-11e9-a311-0fa548c5f953", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern" - } - ], - "type": "visualization", - "updated_at": "2020-04-10T00:34:44.700Z", - "visualization": { - "description": "", - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"filter\":[]}" - }, - "title": "Українська", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\"type\":\"metric\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}}],\"params\":{\"addTooltip\":true,\"addLegend\":false,\"type\":\"metric\",\"metric\":{\"percentageMode\":false,\"useRanges\":false,\"colorSchema\":\"Green to Red\",\"metricColorMode\":\"None\",\"colorsRange\":[{\"from\":0,\"to\":10000}],\"labels\":{\"show\":true},\"invertColors\":false,\"style\":{\"bgFill\":\"#000\",\"bgColor\":false,\"labelColor\":false,\"subText\":\"\",\"fontSize\":60}}},\"title\":\"Українська\"}" - } - } - } -} - -{ - "type": "doc", - "value": { - "id": "visualization:4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "index": ".kibana_1", - "source": { - "migrationVersion": { - "visualization": "7.13.0" - }, - "references": [], - "type": "visualization", - "updated_at": "2020-04-10T00:36:17.053Z", - "visualization": { - "description": "", - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}" - }, - "title": "Tiểu thuyết", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\"type\":\"markdown\",\"aggs\":[],\"params\":{\"fontSize\":12,\"openLinksInNewTab\":false,\"markdown\":\"Tiểu thuyết là một thể loại văn xuôi có hư cấu, thông qua nhân vật, hoàn cảnh, sự việc để phản ánh bức tranh xã hội rộng lớn và những vấn đề của cuộc sống con người, biểu hiện tính chất tường thuật, tính chất kể chuyện bằng ngôn ngữ văn xuôi theo những chủ đề xác định.\\n\\nTrong một cách hiểu khác, nhận định của Belinski: \\\"tiểu thuyết là sử thi của đời tư\\\" chỉ ra khái quát nhất về một dạng thức tự sự, trong đó sự trần thuật tập trung vào số phận của một cá nhân trong quá trình hình thành và phát triển của nó. Sự trần thuật ở đây được khai triển trong không gian và thời gian nghệ thuật đến mức đủ để truyền đạt cơ cấu của nhân cách[1].\\n\\n\\n[1]^ Mục từ Tiểu thuyết trong cuốn 150 thuật ngữ văn học, Lại Nguyên Ân biên soạn, Nhà xuất bản Đại học Quốc gia Hà Nội, in lần thứ 2 có sửa đổi bổ sung. H. 2003. Trang 326.\"},\"title\":\"Tiểu thuyết\"}" - } - } - } -} - -{ - "type": "doc", - "value": { - "id": "space:default", - "index": ".kibana_1", - "source": { - "space": { - "_reserved": true, - "description": "This is the default space", - "disabledFeatures": [], - "name": "Default Space" - }, - "type": "space", - "updated_at": "2021-01-07T00:17:12.785Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "dashboard:6c263e00-1c6d-11ea-a100-8589bb9d7c6b", - "index": ".kibana_1", - "source": { - "dashboard": { - "description": "", - "hits": 0, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}" - }, - "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}", - "panelsJSON": "[{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1c12c2f2-80c2-4d5c-b722-55b2415006e1\"},\"panelIndex\":\"1c12c2f2-80c2-4d5c-b722-55b2415006e1\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1c4b99e1-7785-444f-a1c5-f592893b1a96\"},\"panelIndex\":\"1c4b99e1-7785-444f-a1c5-f592893b1a96\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_1\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":35,\"w\":48,\"h\":18,\"i\":\"94eab06f-60ac-4a85-b771-3a8ed475c9bb\"},\"panelIndex\":\"94eab06f-60ac-4a85-b771-3a8ed475c9bb\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_2\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":15,\"w\":48,\"h\":8,\"i\":\"52c19b6b-7117-42ac-a74e-c507a1c3ffc0\"},\"panelIndex\":\"52c19b6b-7117-42ac-a74e-c507a1c3ffc0\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_3\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":23,\"w\":16,\"h\":12,\"i\":\"a1e889dc-b80e-4937-a576-979f34d1859b\"},\"panelIndex\":\"a1e889dc-b80e-4937-a576-979f34d1859b\",\"embeddableConfig\":{\"enhancements\":{},\"vis\":null},\"panelRefName\":\"panel_4\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":16,\"y\":23,\"w\":12,\"h\":12,\"i\":\"4930b035-d756-4cc5-9a18-1af9e67d6f31\"},\"panelIndex\":\"4930b035-d756-4cc5-9a18-1af9e67d6f31\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_5\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":28,\"y\":23,\"w\":20,\"h\":12,\"i\":\"55112375-d6f0-44f7-a8fb-867c8f7d464d\"},\"panelIndex\":\"55112375-d6f0-44f7-a8fb-867c8f7d464d\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_6\"}]", - "refreshInterval": { - "pause": true, - "value": 0 - }, - "timeFrom": "2019-03-23T03:06:17.785Z", - "timeRestore": true, - "timeTo": "2019-10-04T02:33:16.708Z", - "title": "Ecom Dashboard", - "version": 1 - }, - "migrationVersion": { - "dashboard": "7.11.0" - }, - "references": [ - { - "id": "0a464230-79f0-11ea-ae7f-13c5d6e410a0", - "name": "panel_0", - "type": "visualization" - }, - { - "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", - "name": "panel_1", - "type": "visualization" - }, - { - "id": "6091ead0-1c6d-11ea-a100-8589bb9d7c6b", - "name": "panel_2", - "type": "search" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "panel_3", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "panel_4", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "panel_5", - "type": "visualization" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "panel_6", - "type": "visualization" - } - ], - "type": "dashboard", - "updated_at": "2021-01-07T00:22:16.102Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "visualization:1bba55f0-507e-11eb-9c0d-97106882b997", - "index": ".kibana_1", - "source": { - "migrationVersion": { - "visualization": "7.13.0" - }, - "references": [ - { - "id": "6091ead0-1c6d-11ea-a100-8589bb9d7c6b", - "name": "search_0", - "type": "search" - } - ], - "type": "visualization", - "updated_at": "2021-01-07T00:23:04.624Z", - "visualization": { - "description": "", - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}" - }, - "savedSearchRefName": "search_0", - "title": "Tag Cloud of Names", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\"title\":\"Tag Cloud of Names\",\"type\":\"tagcloud\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"params\":{},\"schema\":\"metric\"},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"params\":{\"field\":\"customer_first_name.keyword\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":10,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"},\"schema\":\"segment\"}],\"params\":{\"scale\":\"linear\",\"orientation\":\"single\",\"minFontSize\":18,\"maxFontSize\":72,\"showLabel\":true}}" - } - } - } -} - -{ - "type": "doc", - "value": { - "id": "search:e5bfe380-ac3e-11eb-8f24-bffe9ba4af2b", - "index": ".kibana_1", - "source": { - "migrationVersion": { - "search": "7.9.3" - }, - "references": [ - { - "id": "5193f870-d861-11e9-a311-0fa548c5f953", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern" - } - ], - "search": { - "columns": [ - "order_date", - "category", - "currency", - "customer_id", - "order_id", - "day_of_week_i", - "products.created_on", - "sku" - ], - "description": "", - "hits": 0, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" - }, - "sort": [ - [ - "order_date", - "desc" - ] - ], - "title": "Ecommerce Data (copy)", - "version": 1 - }, - "type": "search", - "updated_at": "2021-05-03T18:39:30.751Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "dashboard:f7192e90-ac3c-11eb-8f24-bffe9ba4af2b", - "index": ".kibana_1", - "source": { - "dashboard": { - "description": "", - "hits": 0, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}" - }, - "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}", - "panelsJSON": "[{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":9,\"y\":0,\"w\":24,\"h\":15,\"i\":\"914ac161-94d4-4d93-a287-c21fca46a974\"},\"panelIndex\":\"914ac161-94d4-4d93-a287-c21fca46a974\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_914ac161-94d4-4d93-a287-c21fca46a974\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":22,\"y\":15,\"w\":24,\"h\":15,\"i\":\"c4cec7d1-97e3-4101-adc4-c3f15102511c\"},\"panelIndex\":\"c4cec7d1-97e3-4101-adc4-c3f15102511c\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_c4cec7d1-97e3-4101-adc4-c3f15102511c\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":30,\"w\":24,\"h\":15,\"i\":\"09f7de68-0d07-4661-8fda-73ea8b577ac7\"},\"panelIndex\":\"09f7de68-0d07-4661-8fda-73ea8b577ac7\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_09f7de68-0d07-4661-8fda-73ea8b577ac7\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":45,\"w\":24,\"h\":15,\"i\":\"6c25ca6e-6aa1-4f06-9a96-e83ffd9f52e8\"},\"panelIndex\":\"6c25ca6e-6aa1-4f06-9a96-e83ffd9f52e8\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_6c25ca6e-6aa1-4f06-9a96-e83ffd9f52e8\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":60,\"w\":24,\"h\":15,\"i\":\"37764cf9-3c89-454a-bd7e-ae4c242dc624\"},\"panelIndex\":\"37764cf9-3c89-454a-bd7e-ae4c242dc624\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_37764cf9-3c89-454a-bd7e-ae4c242dc624\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":15,\"y\":75,\"w\":24,\"h\":15,\"i\":\"990422fd-a9cf-446f-ba2f-ea9178a7b2e0\"},\"panelIndex\":\"990422fd-a9cf-446f-ba2f-ea9178a7b2e0\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_990422fd-a9cf-446f-ba2f-ea9178a7b2e0\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":90,\"w\":24,\"h\":15,\"i\":\"0cdc13ec-2775-4da9-9a47-1e833bb807eb\"},\"panelIndex\":\"0cdc13ec-2775-4da9-9a47-1e833bb807eb\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0cdc13ec-2775-4da9-9a47-1e833bb807eb\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":18,\"y\":105,\"w\":24,\"h\":15,\"i\":\"eee160de-5777-40c8-9c2c-e75f64bf208a\"},\"panelIndex\":\"eee160de-5777-40c8-9c2c-e75f64bf208a\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_eee160de-5777-40c8-9c2c-e75f64bf208a\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":120,\"w\":24,\"h\":15,\"i\":\"b36f6a97-5d3d-4fc4-b076-b3e514f8f7bb\"},\"panelIndex\":\"b36f6a97-5d3d-4fc4-b076-b3e514f8f7bb\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_b36f6a97-5d3d-4fc4-b076-b3e514f8f7bb\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":135,\"w\":24,\"h\":15,\"i\":\"2e72acbf-7ade-451e-a5e4-7414f12facf2\"},\"panelIndex\":\"2e72acbf-7ade-451e-a5e4-7414f12facf2\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_2e72acbf-7ade-451e-a5e4-7414f12facf2\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":150,\"w\":24,\"h\":15,\"i\":\"4119e9b0-5d03-482d-9356-89bb62b6a851\"},\"panelIndex\":\"4119e9b0-5d03-482d-9356-89bb62b6a851\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_4119e9b0-5d03-482d-9356-89bb62b6a851\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":165,\"w\":24,\"h\":15,\"i\":\"42b4a37c-8b04-4510-9f27-831355221b65\"},\"panelIndex\":\"42b4a37c-8b04-4510-9f27-831355221b65\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_42b4a37c-8b04-4510-9f27-831355221b65\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":14,\"y\":180,\"w\":24,\"h\":15,\"i\":\"dc676050-d752-4c3e-a1ae-73ef2f1bcdc6\"},\"panelIndex\":\"dc676050-d752-4c3e-a1ae-73ef2f1bcdc6\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_dc676050-d752-4c3e-a1ae-73ef2f1bcdc6\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":17,\"y\":195,\"w\":24,\"h\":15,\"i\":\"6602e0e0-9e66-4e0e-90c1-f66b9c3d2340\"},\"panelIndex\":\"6602e0e0-9e66-4e0e-90c1-f66b9c3d2340\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_6602e0e0-9e66-4e0e-90c1-f66b9c3d2340\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":210,\"w\":24,\"h\":15,\"i\":\"c9c65725-9b4d-4343-93db-7efa4a7a2d60\"},\"panelIndex\":\"c9c65725-9b4d-4343-93db-7efa4a7a2d60\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_c9c65725-9b4d-4343-93db-7efa4a7a2d60\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":225,\"w\":24,\"h\":15,\"i\":\"69141f9b-5c23-409d-9c96-7f94c243f79e\"},\"panelIndex\":\"69141f9b-5c23-409d-9c96-7f94c243f79e\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_69141f9b-5c23-409d-9c96-7f94c243f79e\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":17,\"y\":240,\"w\":24,\"h\":15,\"i\":\"6feeec2c-34ab-4844-8445-e417c8e0595b\"},\"panelIndex\":\"6feeec2c-34ab-4844-8445-e417c8e0595b\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_6feeec2c-34ab-4844-8445-e417c8e0595b\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":15,\"y\":255,\"w\":24,\"h\":15,\"i\":\"985d9dc1-de44-4803-afad-f1d497d050a1\"},\"panelIndex\":\"985d9dc1-de44-4803-afad-f1d497d050a1\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_985d9dc1-de44-4803-afad-f1d497d050a1\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":270,\"w\":24,\"h\":15,\"i\":\"d7ef9e23-d0dd-4c7c-90b3-f611bbfcd1b0\"},\"panelIndex\":\"d7ef9e23-d0dd-4c7c-90b3-f611bbfcd1b0\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_d7ef9e23-d0dd-4c7c-90b3-f611bbfcd1b0\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":20,\"y\":285,\"w\":24,\"h\":15,\"i\":\"6b0768b1-0cd2-47f0-a639-b369e7318d44\"},\"panelIndex\":\"6b0768b1-0cd2-47f0-a639-b369e7318d44\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_6b0768b1-0cd2-47f0-a639-b369e7318d44\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":20,\"y\":300,\"w\":24,\"h\":15,\"i\":\"c9cc2835-06a8-4448-b703-2d41a6692feb\"},\"panelIndex\":\"c9cc2835-06a8-4448-b703-2d41a6692feb\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_c9cc2835-06a8-4448-b703-2d41a6692feb\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":315,\"w\":24,\"h\":15,\"i\":\"af2a55b1-8b3d-478a-96b1-72e4f12585e4\"},\"panelIndex\":\"af2a55b1-8b3d-478a-96b1-72e4f12585e4\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_af2a55b1-8b3d-478a-96b1-72e4f12585e4\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":330,\"w\":24,\"h\":15,\"i\":\"ee92986a-adab-4d66-ad4e-a43a608f52f7\"},\"panelIndex\":\"ee92986a-adab-4d66-ad4e-a43a608f52f7\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_ee92986a-adab-4d66-ad4e-a43a608f52f7\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":22,\"y\":345,\"w\":24,\"h\":15,\"i\":\"3b4e1fd0-2acb-444a-b478-42d7bd10b96c\"},\"panelIndex\":\"3b4e1fd0-2acb-444a-b478-42d7bd10b96c\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_3b4e1fd0-2acb-444a-b478-42d7bd10b96c\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":360,\"w\":24,\"h\":15,\"i\":\"04d7056d-88a4-4b00-b8f4-33f79f1b6f7a\"},\"panelIndex\":\"04d7056d-88a4-4b00-b8f4-33f79f1b6f7a\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_04d7056d-88a4-4b00-b8f4-33f79f1b6f7a\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":21,\"y\":375,\"w\":24,\"h\":15,\"i\":\"51122bae-427e-45a6-904e-6c821447cc46\"},\"panelIndex\":\"51122bae-427e-45a6-904e-6c821447cc46\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_51122bae-427e-45a6-904e-6c821447cc46\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":20,\"y\":390,\"w\":24,\"h\":15,\"i\":\"4efab22c-1892-4013-8406-5e5d924a8a21\"},\"panelIndex\":\"4efab22c-1892-4013-8406-5e5d924a8a21\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_4efab22c-1892-4013-8406-5e5d924a8a21\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":405,\"w\":24,\"h\":15,\"i\":\"4c3c1b29-100e-474c-8290-9470684ae407\"},\"panelIndex\":\"4c3c1b29-100e-474c-8290-9470684ae407\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_4c3c1b29-100e-474c-8290-9470684ae407\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":18,\"y\":420,\"w\":24,\"h\":15,\"i\":\"b4501df0-d759-4513-9e87-5dd8eefe4a4f\"},\"panelIndex\":\"b4501df0-d759-4513-9e87-5dd8eefe4a4f\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_b4501df0-d759-4513-9e87-5dd8eefe4a4f\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":20,\"y\":435,\"w\":24,\"h\":15,\"i\":\"4fbff0ec-b3a6-4ee7-8734-9b177c3e51c6\"},\"panelIndex\":\"4fbff0ec-b3a6-4ee7-8734-9b177c3e51c6\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_4fbff0ec-b3a6-4ee7-8734-9b177c3e51c6\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":450,\"w\":24,\"h\":15,\"i\":\"13d9982e-2745-44b1-af94-fa4b9f6761a9\"},\"panelIndex\":\"13d9982e-2745-44b1-af94-fa4b9f6761a9\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_13d9982e-2745-44b1-af94-fa4b9f6761a9\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":17,\"y\":465,\"w\":24,\"h\":15,\"i\":\"efa18320-9650-4bfe-9418-ac29b7979f70\"},\"panelIndex\":\"efa18320-9650-4bfe-9418-ac29b7979f70\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_efa18320-9650-4bfe-9418-ac29b7979f70\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":21,\"y\":480,\"w\":24,\"h\":15,\"i\":\"1f03bc70-0545-4a3a-bebc-ad477674b841\"},\"panelIndex\":\"1f03bc70-0545-4a3a-bebc-ad477674b841\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_1f03bc70-0545-4a3a-bebc-ad477674b841\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":495,\"w\":24,\"h\":15,\"i\":\"d766ce3a-9ec5-4ead-8698-6a2e66e729bb\"},\"panelIndex\":\"d766ce3a-9ec5-4ead-8698-6a2e66e729bb\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_d766ce3a-9ec5-4ead-8698-6a2e66e729bb\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":510,\"w\":24,\"h\":15,\"i\":\"de93deb0-6c16-45ae-8fae-de0b2e1c4ae0\"},\"panelIndex\":\"de93deb0-6c16-45ae-8fae-de0b2e1c4ae0\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_de93deb0-6c16-45ae-8fae-de0b2e1c4ae0\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":525,\"w\":24,\"h\":15,\"i\":\"b93cc5e1-084a-42d9-9958-a3f569573d43\"},\"panelIndex\":\"b93cc5e1-084a-42d9-9958-a3f569573d43\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_b93cc5e1-084a-42d9-9958-a3f569573d43\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":20,\"y\":540,\"w\":24,\"h\":15,\"i\":\"0b6c380f-3536-4f03-8dbd-95c53be69263\"},\"panelIndex\":\"0b6c380f-3536-4f03-8dbd-95c53be69263\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0b6c380f-3536-4f03-8dbd-95c53be69263\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":23,\"y\":555,\"w\":24,\"h\":15,\"i\":\"5c68b67a-ac42-48b8-85de-2409aaa0cdc6\"},\"panelIndex\":\"5c68b67a-ac42-48b8-85de-2409aaa0cdc6\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_5c68b67a-ac42-48b8-85de-2409aaa0cdc6\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":24,\"y\":570,\"w\":24,\"h\":15,\"i\":\"098a69b8-c9a0-40c8-8703-62838e0ec4a9\"},\"panelIndex\":\"098a69b8-c9a0-40c8-8703-62838e0ec4a9\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_098a69b8-c9a0-40c8-8703-62838e0ec4a9\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":1,\"y\":585,\"w\":24,\"h\":15,\"i\":\"a0f4b9ce-2e36-4d22-8dd9-8988f1a3b883\"},\"panelIndex\":\"a0f4b9ce-2e36-4d22-8dd9-8988f1a3b883\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_a0f4b9ce-2e36-4d22-8dd9-8988f1a3b883\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":15,\"y\":600,\"w\":24,\"h\":15,\"i\":\"eb651411-ea02-4506-a674-f0125d0b2a4a\"},\"panelIndex\":\"eb651411-ea02-4506-a674-f0125d0b2a4a\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_eb651411-ea02-4506-a674-f0125d0b2a4a\"},{\"version\":\"8.0.0\",\"type\":\"search\",\"gridData\":{\"x\":0,\"y\":615,\"w\":48,\"h\":111,\"i\":\"8ec9b67a-5d08-4006-bccc-a7341b88bb63\"},\"panelIndex\":\"8ec9b67a-5d08-4006-bccc-a7341b88bb63\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_8ec9b67a-5d08-4006-bccc-a7341b88bb63\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":4,\"y\":852,\"w\":24,\"h\":15,\"i\":\"1201144d-5c9c-4015-89a3-0cb803405986\"},\"panelIndex\":\"1201144d-5c9c-4015-89a3-0cb803405986\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_1201144d-5c9c-4015-89a3-0cb803405986\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":24,\"y\":837,\"w\":24,\"h\":15,\"i\":\"913c1c46-ded4-4e04-81ff-e683f725d3a5\"},\"panelIndex\":\"913c1c46-ded4-4e04-81ff-e683f725d3a5\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_913c1c46-ded4-4e04-81ff-e683f725d3a5\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":867,\"w\":24,\"h\":15,\"i\":\"f49dfd93-ce95-4a65-b9ec-531f340da083\"},\"panelIndex\":\"f49dfd93-ce95-4a65-b9ec-531f340da083\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_f49dfd93-ce95-4a65-b9ec-531f340da083\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":18,\"y\":882,\"w\":24,\"h\":15,\"i\":\"0705993c-492c-4ce0-83e0-a481c90bd432\"},\"panelIndex\":\"0705993c-492c-4ce0-83e0-a481c90bd432\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0705993c-492c-4ce0-83e0-a481c90bd432\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":24,\"y\":897,\"w\":24,\"h\":15,\"i\":\"02de39d3-6839-4198-94e3-cc91f61d0c6e\"},\"panelIndex\":\"02de39d3-6839-4198-94e3-cc91f61d0c6e\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_02de39d3-6839-4198-94e3-cc91f61d0c6e\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":5,\"y\":912,\"w\":24,\"h\":15,\"i\":\"e6b958fa-931f-4358-94fc-07934419066d\"},\"panelIndex\":\"e6b958fa-931f-4358-94fc-07934419066d\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_e6b958fa-931f-4358-94fc-07934419066d\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":927,\"w\":24,\"h\":15,\"i\":\"e6d70fc7-1bdc-4743-9a15-615dff91a5c1\"},\"panelIndex\":\"e6d70fc7-1bdc-4743-9a15-615dff91a5c1\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_e6d70fc7-1bdc-4743-9a15-615dff91a5c1\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":22,\"y\":942,\"w\":24,\"h\":15,\"i\":\"9db5f35e-ab94-4a5a-8c0f-70bf2aa095aa\"},\"panelIndex\":\"9db5f35e-ab94-4a5a-8c0f-70bf2aa095aa\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_9db5f35e-ab94-4a5a-8c0f-70bf2aa095aa\"},{\"version\":\"8.0.0\",\"type\":\"search\",\"gridData\":{\"x\":0,\"y\":726,\"w\":48,\"h\":111,\"i\":\"e985d8b0-4a76-46d0-af01-3edab5995b97\"},\"panelIndex\":\"e985d8b0-4a76-46d0-af01-3edab5995b97\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_e985d8b0-4a76-46d0-af01-3edab5995b97\"}]", - "refreshInterval": { - "pause": true, - "value": 0 - }, - "timeFrom": "2019-06-01T03:59:54.350Z", - "timeRestore": true, - "timeTo": "2019-08-01T14:52:40.436Z", - "title": "Large Dashboard", - "version": 1 - }, - "migrationVersion": { - "dashboard": "7.11.0" - }, - "references": [ - { - "id": "0a464230-79f0-11ea-ae7f-13c5d6e410a0", - "name": "914ac161-94d4-4d93-a287-c21fca46a974:panel_914ac161-94d4-4d93-a287-c21fca46a974", - "type": "visualization" - }, - { - "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", - "name": "c4cec7d1-97e3-4101-adc4-c3f15102511c:panel_c4cec7d1-97e3-4101-adc4-c3f15102511c", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "09f7de68-0d07-4661-8fda-73ea8b577ac7:panel_09f7de68-0d07-4661-8fda-73ea8b577ac7", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "6c25ca6e-6aa1-4f06-9a96-e83ffd9f52e8:panel_6c25ca6e-6aa1-4f06-9a96-e83ffd9f52e8", - "type": "visualization" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "37764cf9-3c89-454a-bd7e-ae4c242dc624:panel_37764cf9-3c89-454a-bd7e-ae4c242dc624", - "type": "visualization" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "990422fd-a9cf-446f-ba2f-ea9178a7b2e0:panel_990422fd-a9cf-446f-ba2f-ea9178a7b2e0", - "type": "visualization" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "0cdc13ec-2775-4da9-9a47-1e833bb807eb:panel_0cdc13ec-2775-4da9-9a47-1e833bb807eb", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "eee160de-5777-40c8-9c2c-e75f64bf208a:panel_eee160de-5777-40c8-9c2c-e75f64bf208a", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "b36f6a97-5d3d-4fc4-b076-b3e514f8f7bb:panel_b36f6a97-5d3d-4fc4-b076-b3e514f8f7bb", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "2e72acbf-7ade-451e-a5e4-7414f12facf2:panel_2e72acbf-7ade-451e-a5e4-7414f12facf2", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "4119e9b0-5d03-482d-9356-89bb62b6a851:panel_4119e9b0-5d03-482d-9356-89bb62b6a851", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "42b4a37c-8b04-4510-9f27-831355221b65:panel_42b4a37c-8b04-4510-9f27-831355221b65", - "type": "visualization" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "dc676050-d752-4c3e-a1ae-73ef2f1bcdc6:panel_dc676050-d752-4c3e-a1ae-73ef2f1bcdc6", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "6602e0e0-9e66-4e0e-90c1-f66b9c3d2340:panel_6602e0e0-9e66-4e0e-90c1-f66b9c3d2340", - "type": "visualization" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "c9c65725-9b4d-4343-93db-7efa4a7a2d60:panel_c9c65725-9b4d-4343-93db-7efa4a7a2d60", - "type": "visualization" - }, - { - "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", - "name": "69141f9b-5c23-409d-9c96-7f94c243f79e:panel_69141f9b-5c23-409d-9c96-7f94c243f79e", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "6feeec2c-34ab-4844-8445-e417c8e0595b:panel_6feeec2c-34ab-4844-8445-e417c8e0595b", - "type": "visualization" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "985d9dc1-de44-4803-afad-f1d497d050a1:panel_985d9dc1-de44-4803-afad-f1d497d050a1", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "d7ef9e23-d0dd-4c7c-90b3-f611bbfcd1b0:panel_d7ef9e23-d0dd-4c7c-90b3-f611bbfcd1b0", - "type": "visualization" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "6b0768b1-0cd2-47f0-a639-b369e7318d44:panel_6b0768b1-0cd2-47f0-a639-b369e7318d44", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "c9cc2835-06a8-4448-b703-2d41a6692feb:panel_c9cc2835-06a8-4448-b703-2d41a6692feb", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "af2a55b1-8b3d-478a-96b1-72e4f12585e4:panel_af2a55b1-8b3d-478a-96b1-72e4f12585e4", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "ee92986a-adab-4d66-ad4e-a43a608f52f7:panel_ee92986a-adab-4d66-ad4e-a43a608f52f7", - "type": "visualization" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "3b4e1fd0-2acb-444a-b478-42d7bd10b96c:panel_3b4e1fd0-2acb-444a-b478-42d7bd10b96c", - "type": "visualization" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "04d7056d-88a4-4b00-b8f4-33f79f1b6f7a:panel_04d7056d-88a4-4b00-b8f4-33f79f1b6f7a", - "type": "visualization" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "51122bae-427e-45a6-904e-6c821447cc46:panel_51122bae-427e-45a6-904e-6c821447cc46", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "4efab22c-1892-4013-8406-5e5d924a8a21:panel_4efab22c-1892-4013-8406-5e5d924a8a21", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "4c3c1b29-100e-474c-8290-9470684ae407:panel_4c3c1b29-100e-474c-8290-9470684ae407", - "type": "visualization" - }, - { - "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", - "name": "b4501df0-d759-4513-9e87-5dd8eefe4a4f:panel_b4501df0-d759-4513-9e87-5dd8eefe4a4f", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "4fbff0ec-b3a6-4ee7-8734-9b177c3e51c6:panel_4fbff0ec-b3a6-4ee7-8734-9b177c3e51c6", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "13d9982e-2745-44b1-af94-fa4b9f6761a9:panel_13d9982e-2745-44b1-af94-fa4b9f6761a9", - "type": "visualization" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "efa18320-9650-4bfe-9418-ac29b7979f70:panel_efa18320-9650-4bfe-9418-ac29b7979f70", - "type": "visualization" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "1f03bc70-0545-4a3a-bebc-ad477674b841:panel_1f03bc70-0545-4a3a-bebc-ad477674b841", - "type": "visualization" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "d766ce3a-9ec5-4ead-8698-6a2e66e729bb:panel_d766ce3a-9ec5-4ead-8698-6a2e66e729bb", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "de93deb0-6c16-45ae-8fae-de0b2e1c4ae0:panel_de93deb0-6c16-45ae-8fae-de0b2e1c4ae0", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "b93cc5e1-084a-42d9-9958-a3f569573d43:panel_b93cc5e1-084a-42d9-9958-a3f569573d43", - "type": "visualization" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "0b6c380f-3536-4f03-8dbd-95c53be69263:panel_0b6c380f-3536-4f03-8dbd-95c53be69263", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "5c68b67a-ac42-48b8-85de-2409aaa0cdc6:panel_5c68b67a-ac42-48b8-85de-2409aaa0cdc6", - "type": "visualization" - }, - { - "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", - "name": "098a69b8-c9a0-40c8-8703-62838e0ec4a9:panel_098a69b8-c9a0-40c8-8703-62838e0ec4a9", - "type": "visualization" - }, - { - "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", - "name": "a0f4b9ce-2e36-4d22-8dd9-8988f1a3b883:panel_a0f4b9ce-2e36-4d22-8dd9-8988f1a3b883", - "type": "visualization" - }, - { - "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "eb651411-ea02-4506-a674-f0125d0b2a4a:panel_eb651411-ea02-4506-a674-f0125d0b2a4a", - "type": "visualization" - }, - { - "id": "6091ead0-1c6d-11ea-a100-8589bb9d7c6b", - "name": "8ec9b67a-5d08-4006-bccc-a7341b88bb63:panel_8ec9b67a-5d08-4006-bccc-a7341b88bb63", - "type": "search" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "1201144d-5c9c-4015-89a3-0cb803405986:panel_1201144d-5c9c-4015-89a3-0cb803405986", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "913c1c46-ded4-4e04-81ff-e683f725d3a5:panel_913c1c46-ded4-4e04-81ff-e683f725d3a5", - "type": "visualization" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "f49dfd93-ce95-4a65-b9ec-531f340da083:panel_f49dfd93-ce95-4a65-b9ec-531f340da083", - "type": "visualization" - }, - { - "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", - "name": "0705993c-492c-4ce0-83e0-a481c90bd432:panel_0705993c-492c-4ce0-83e0-a481c90bd432", - "type": "visualization" - }, - { - "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", - "name": "02de39d3-6839-4198-94e3-cc91f61d0c6e:panel_02de39d3-6839-4198-94e3-cc91f61d0c6e", - "type": "visualization" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "e6b958fa-931f-4358-94fc-07934419066d:panel_e6b958fa-931f-4358-94fc-07934419066d", - "type": "visualization" - }, - { - "id": "1bba55f0-507e-11eb-9c0d-97106882b997", - "name": "e6d70fc7-1bdc-4743-9a15-615dff91a5c1:panel_e6d70fc7-1bdc-4743-9a15-615dff91a5c1", - "type": "visualization" - }, - { - "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", - "name": "9db5f35e-ab94-4a5a-8c0f-70bf2aa095aa:panel_9db5f35e-ab94-4a5a-8c0f-70bf2aa095aa", - "type": "visualization" - }, - { - "id": "e5bfe380-ac3e-11eb-8f24-bffe9ba4af2b", - "name": "e985d8b0-4a76-46d0-af01-3edab5995b97:panel_e985d8b0-4a76-46d0-af01-3edab5995b97", - "type": "search" - } - ], - "type": "dashboard", - "updated_at": "2021-05-03T18:39:45.983Z" - } - } -} diff --git a/x-pack/test/functional/es_archives/reporting/ecommerce_kibana/mappings.json b/x-pack/test/functional/es_archives/reporting/ecommerce_kibana/mappings.json deleted file mode 100644 index 8ee08f968d0720..00000000000000 --- a/x-pack/test/functional/es_archives/reporting/ecommerce_kibana/mappings.json +++ /dev/null @@ -1,2730 +0,0 @@ -{ - "type": "index", - "value": { - "aliases": { - ".kibana": { - } - }, - "index": ".kibana_1", - "mappings": { - "_meta": { - "migrationMappingPropertyHashes": { - "action": "6e96ac5e648f57523879661ea72525b7", - "action_task_params": "a9d49f184ee89641044be0ca2950fa3a", - "alert": "49eb3350984bd2a162914d3776e70cfb", - "api_key_pending_invalidation": "16f515278a295f6245149ad7c5ddedb7", - "apm-indices": "9bb9b2bf1fa636ed8619cbab5ce6a1dd", - "apm-telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "app_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "application_usage_daily": "43b8830d5d0df85a6823d290885fc9fd", - "application_usage_totals": "3d1b76c39bfb2cc8296b024d73854724", - "application_usage_transactional": "3d1b76c39bfb2cc8296b024d73854724", - "background-session": "dfd06597e582fdbbbc09f1a3615e6ce0", - "canvas-element": "7390014e1091044523666d97247392fc", - "canvas-workpad": "b0a1706d356228dbdcb4a17e6b9eb231", - "canvas-workpad-template": "ae2673f678281e2c055d764b153e9715", - "cases": "0b7746a97518ec67b787d141886ad3c1", - "cases-comments": "8a50736330e953bca91747723a319593", - "cases-configure": "387c5f3a3bda7e0ae0dd4e106f914a69", - "cases-connector-mappings": "6bc7e49411d38be4969dc6aa8bd43776", - "cases-user-actions": "32277330ec6b721abe3b846cfd939a71", - "config": "c63748b75f39d0c54de12d12c1ccbc20", - "core-usage-stats": "3d1b76c39bfb2cc8296b024d73854724", - "dashboard": "40554caf09725935e2c02e02563a2d07", - "endpoint:user-artifact": "4a11183eee21e6fbad864f7a30b39ad0", - "endpoint:user-artifact-manifest": "a0d7b04ad405eed54d76e279c3727862", - "enterprise_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "epm-packages": "0cbbb16506734d341a96aaed65ec6413", - "epm-packages-assets": "44621b2f6052ef966da47b7c3a00f33b", - "exception-list": "67f055ab8c10abd7b2ebfd969b836788", - "exception-list-agnostic": "67f055ab8c10abd7b2ebfd969b836788", - "file-upload-telemetry": "0ed4d3e1983d1217a30982630897092e", - "fleet-agent-actions": "9511b565b1cc6441a42033db3d5de8e9", - "fleet-agent-events": "e20a508b6e805189356be381dbfac8db", - "fleet-agents": "cb661e8ede2b640c42c8e5ef99db0683", - "fleet-enrollment-api-keys": "a69ef7ae661dab31561d6c6f052ef2a7", - "graph-workspace": "27a94b2edcb0610c6aea54a7c56d7752", - "index-pattern": "45915a1ad866812242df474eb0479052", - "infrastructure-ui-source": "3d1b76c39bfb2cc8296b024d73854724", - "ingest-agent-policies": "8b0733cce189659593659dad8db426f0", - "ingest-outputs": "8854f34453a47e26f86a29f8f3b80b4e", - "ingest-package-policies": "c91ca97b1ff700f0fc64dc6b13d65a85", - "ingest_manager_settings": "02a03095f0e05b7a538fa801b88a217f", - "inventory-view": "3d1b76c39bfb2cc8296b024d73854724", - "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", - "lens": "52346cfec69ff7b47d5f0c12361a2797", - "lens-ui-telemetry": "509bfa5978586998e05f9e303c07a327", - "map": "9134b47593116d7953f6adba096fc463", - "maps-telemetry": "5ef305b18111b77789afefbd36b66171", - "metrics-explorer-view": "3d1b76c39bfb2cc8296b024d73854724", - "migrationVersion": "4a1746014a75ade3a714e1db5763276f", - "ml-job": "3bb64c31915acf93fc724af137a0891b", - "ml-telemetry": "257fd1d4b4fdbb9cb4b8a3b27da201e9", - "monitoring-telemetry": "2669d5ec15e82391cf58df4294ee9c68", - "namespace": "2f4316de49999235636386fe51dc06c1", - "namespaces": "2f4316de49999235636386fe51dc06c1", - "originId": "2f4316de49999235636386fe51dc06c1", - "query": "11aaeb7f5f7fa5bb43f25e18ce26e7d9", - "references": "7997cf5a56cc02bdc9c93361bde732b0", - "sample-data-telemetry": "7d3cfeb915303c9641c59681967ffeb4", - "search": "959dde12a55b3118eab009d8b2b72ad6", - "search-telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "security-solution-signals-migration": "72761fd374ca11122ac8025a92b84fca", - "siem-detection-engine-rule-actions": "6569b288c169539db10cb262bf79de18", - "siem-detection-engine-rule-status": "ae783f41c6937db6b7a2ef5c93a9e9b0", - "siem-ui-timeline": "d12c5474364d737d17252acf1dc4585c", - "siem-ui-timeline-note": "8874706eedc49059d4cf0f5094559084", - "siem-ui-timeline-pinned-event": "20638091112f0e14f0e443d512301c29", - "space": "c5ca8acafa0beaa4d08d014a97b6bc6b", - "spaces-usage-stats": "3d1b76c39bfb2cc8296b024d73854724", - "tag": "83d55da58f6530f7055415717ec06474", - "telemetry": "36a616f7026dfa617d6655df850fe16d", - "timelion-sheet": "9a2a2748877c7a7b582fef201ab1d4cf", - "tsvb-validation-telemetry": "3a37ef6c8700ae6fc97d5c7da00e9215", - "type": "2f4316de49999235636386fe51dc06c1", - "ui-counter": "0d409297dc5ebe1e3a1da691c6ee32e3", - "ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3", - "updated_at": "00da57df13e94e9d98437d13ace4bfe0", - "upgrade-assistant-reindex-operation": "215107c281839ea9b3ad5f6419819763", - "upgrade-assistant-telemetry": "56702cec857e0a9dacfb696655b4ff7b", - "uptime-dynamic-settings": "3d1b76c39bfb2cc8296b024d73854724", - "url": "c7f66a0df8b1b52f17c28c4adb111105", - "visualization": "f819cf6636b75c9e76ba733a0c6ef355", - "workplace_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724" - } - }, - "dynamic": "strict", - "properties": { - "action": { - "properties": { - "actionTypeId": { - "type": "keyword" - }, - "config": { - "enabled": false, - "type": "object" - }, - "name": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "secrets": { - "type": "binary" - } - } - }, - "action_task_params": { - "properties": { - "actionId": { - "type": "keyword" - }, - "apiKey": { - "type": "binary" - }, - "params": { - "enabled": false, - "type": "object" - } - } - }, - "agent_actions": { - "dynamic": "false", - "type": "object" - }, - "agent_configs": { - "dynamic": "false", - "type": "object" - }, - "agent_events": { - "dynamic": "false", - "type": "object" - }, - "agents": { - "dynamic": "false", - "type": "object" - }, - "alert": { - "properties": { - "actions": { - "properties": { - "actionRef": { - "type": "keyword" - }, - "actionTypeId": { - "type": "keyword" - }, - "group": { - "type": "keyword" - }, - "params": { - "enabled": false, - "type": "object" - } - }, - "type": "nested" - }, - "alertTypeId": { - "type": "keyword" - }, - "apiKey": { - "type": "binary" - }, - "apiKeyOwner": { - "type": "keyword" - }, - "consumer": { - "type": "keyword" - }, - "createdAt": { - "type": "date" - }, - "createdBy": { - "type": "keyword" - }, - "enabled": { - "type": "boolean" - }, - "executionStatus": { - "properties": { - "error": { - "properties": { - "message": { - "type": "keyword" - }, - "reason": { - "type": "keyword" - } - } - }, - "lastExecutionDate": { - "type": "date" - }, - "status": { - "type": "keyword" - } - } - }, - "meta": { - "properties": { - "versionApiKeyLastmodified": { - "type": "keyword" - } - } - }, - "muteAll": { - "type": "boolean" - }, - "mutedInstanceIds": { - "type": "keyword" - }, - "name": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "notifyWhen": { - "type": "keyword" - }, - "params": { - "enabled": false, - "type": "object" - }, - "schedule": { - "properties": { - "interval": { - "type": "keyword" - } - } - }, - "scheduledTaskId": { - "type": "keyword" - }, - "tags": { - "type": "keyword" - }, - "throttle": { - "type": "keyword" - }, - "updatedAt": { - "type": "date" - }, - "updatedBy": { - "type": "keyword" - } - } - }, - "api_key_pending_invalidation": { - "properties": { - "apiKeyId": { - "type": "keyword" - }, - "createdAt": { - "type": "date" - } - } - }, - "apm-indices": { - "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } - } - } - }, - "apm-services-telemetry": { - "dynamic": "false", - "type": "object" - }, - "apm-telemetry": { - "dynamic": "false", - "type": "object" - }, - "app_search_telemetry": { - "dynamic": "false", - "type": "object" - }, - "application_usage_daily": { - "dynamic": "false", - "properties": { - "timestamp": { - "type": "date" - } - } - }, - "application_usage_totals": { - "dynamic": "false", - "type": "object" - }, - "application_usage_transactional": { - "dynamic": "false", - "type": "object" - }, - "background-session": { - "properties": { - "appId": { - "type": "keyword" - }, - "created": { - "type": "date" - }, - "expires": { - "type": "date" - }, - "idMapping": { - "enabled": false, - "type": "object" - }, - "initialState": { - "enabled": false, - "type": "object" - }, - "name": { - "type": "keyword" - }, - "restoreState": { - "enabled": false, - "type": "object" - }, - "sessionId": { - "type": "keyword" - }, - "status": { - "type": "keyword" - }, - "urlGeneratorId": { - "type": "keyword" - } - } - }, - "canvas-element": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "content": { - "type": "text" - }, - "help": { - "type": "text" - }, - "image": { - "type": "text" - }, - "name": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "canvas-workpad": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "name": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "canvas-workpad-template": { - "dynamic": "false", - "properties": { - "help": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "name": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "tags": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "template_key": { - "type": "keyword" - } - } - }, - "cases": { - "properties": { - "closed_at": { - "type": "date" - }, - "closed_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "connector": { - "properties": { - "fields": { - "properties": { - "key": { - "type": "text" - }, - "value": { - "type": "text" - } - } - }, - "id": { - "type": "keyword" - }, - "name": { - "type": "text" - }, - "type": { - "type": "keyword" - } - } - }, - "created_at": { - "type": "date" - }, - "created_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "description": { - "type": "text" - }, - "external_service": { - "properties": { - "connector_id": { - "type": "keyword" - }, - "connector_name": { - "type": "keyword" - }, - "external_id": { - "type": "keyword" - }, - "external_title": { - "type": "text" - }, - "external_url": { - "type": "text" - }, - "pushed_at": { - "type": "date" - }, - "pushed_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - } - } - }, - "settings": { - "properties": { - "syncAlerts": { - "type": "boolean" - } - } - }, - "status": { - "type": "keyword" - }, - "tags": { - "type": "keyword" - }, - "title": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - } - } - }, - "cases-comments": { - "properties": { - "alertId": { - "type": "keyword" - }, - "comment": { - "type": "text" - }, - "created_at": { - "type": "date" - }, - "created_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "index": { - "type": "keyword" - }, - "pushed_at": { - "type": "date" - }, - "pushed_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - } - } - }, - "cases-configure": { - "properties": { - "closure_type": { - "type": "keyword" - }, - "connector": { - "properties": { - "fields": { - "properties": { - "key": { - "type": "text" - }, - "value": { - "type": "text" - } - } - }, - "id": { - "type": "keyword" - }, - "name": { - "type": "text" - }, - "type": { - "type": "keyword" - } - } - }, - "created_at": { - "type": "date" - }, - "created_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - } - } - }, - "cases-connector-mappings": { - "properties": { - "mappings": { - "properties": { - "action_type": { - "type": "keyword" - }, - "source": { - "type": "keyword" - }, - "target": { - "type": "keyword" - } - } - } - } - }, - "cases-user-actions": { - "properties": { - "action": { - "type": "keyword" - }, - "action_at": { - "type": "date" - }, - "action_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "action_field": { - "type": "keyword" - }, - "new_value": { - "type": "text" - }, - "old_value": { - "type": "text" - } - } - }, - "config": { - "dynamic": "false", - "properties": { - "buildNum": { - "type": "keyword" - } - } - }, - "core-usage-stats": { - "dynamic": "false", - "type": "object" - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "doc_values": false, - "index": false, - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "index": false, - "type": "text" - } - } - }, - "optionsJSON": { - "index": false, - "type": "text" - }, - "panelsJSON": { - "index": false, - "type": "text" - }, - "refreshInterval": { - "properties": { - "display": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "pause": { - "doc_values": false, - "index": false, - "type": "boolean" - }, - "section": { - "doc_values": false, - "index": false, - "type": "integer" - }, - "value": { - "doc_values": false, - "index": false, - "type": "integer" - } - } - }, - "timeFrom": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "timeRestore": { - "doc_values": false, - "index": false, - "type": "boolean" - }, - "timeTo": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "datasources": { - "dynamic": "false", - "type": "object" - }, - "endpoint:user-artifact": { - "properties": { - "body": { - "type": "binary" - }, - "compressionAlgorithm": { - "index": false, - "type": "keyword" - }, - "created": { - "index": false, - "type": "date" - }, - "decodedSha256": { - "index": false, - "type": "keyword" - }, - "decodedSize": { - "index": false, - "type": "long" - }, - "encodedSha256": { - "type": "keyword" - }, - "encodedSize": { - "index": false, - "type": "long" - }, - "encryptionAlgorithm": { - "index": false, - "type": "keyword" - }, - "identifier": { - "type": "keyword" - } - } - }, - "endpoint:user-artifact-manifest": { - "properties": { - "created": { - "index": false, - "type": "date" - }, - "schemaVersion": { - "type": "keyword" - }, - "semanticVersion": { - "index": false, - "type": "keyword" - }, - "artifacts": { - "type": "nested", - "properties": { - "policyId": { - "type": "keyword", - "index": false - }, - "artifactId": { - "type": "keyword", - "index": false - } - } - } - } - }, - "enrollment_api_keys": { - "dynamic": "false", - "type": "object" - }, - "enterprise_search_telemetry": { - "dynamic": "false", - "type": "object" - }, - "epm-package": { - "dynamic": "false", - "type": "object" - }, - "epm-packages": { - "properties": { - "es_index_patterns": { - "enabled": false, - "type": "object" - }, - "install_source": { - "type": "keyword" - }, - "install_started_at": { - "type": "date" - }, - "install_status": { - "type": "keyword" - }, - "install_version": { - "type": "keyword" - }, - "installed_es": { - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - }, - "type": "nested" - }, - "installed_kibana": { - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - }, - "type": "nested" - }, - "internal": { - "type": "boolean" - }, - "name": { - "type": "keyword" - }, - "package_assets": { - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - }, - "type": "nested" - }, - "removable": { - "type": "boolean" - }, - "version": { - "type": "keyword" - } - } - }, - "epm-packages-assets": { - "properties": { - "asset_path": { - "type": "keyword" - }, - "data_base64": { - "type": "binary" - }, - "data_utf8": { - "index": false, - "type": "text" - }, - "install_source": { - "type": "keyword" - }, - "media_type": { - "type": "keyword" - }, - "package_name": { - "type": "keyword" - }, - "package_version": { - "type": "keyword" - } - } - }, - "exception-list": { - "properties": { - "_tags": { - "type": "keyword" - }, - "comments": { - "properties": { - "comment": { - "type": "keyword" - }, - "created_at": { - "type": "keyword" - }, - "created_by": { - "type": "keyword" - }, - "id": { - "type": "keyword" - }, - "updated_at": { - "type": "keyword" - }, - "updated_by": { - "type": "keyword" - } - } - }, - "created_at": { - "type": "keyword" - }, - "created_by": { - "type": "keyword" - }, - "description": { - "type": "keyword" - }, - "entries": { - "properties": { - "entries": { - "properties": { - "field": { - "type": "keyword" - }, - "operator": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" - } - } - }, - "field": { - "type": "keyword" - }, - "list": { - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "operator": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" - } - } - }, - "immutable": { - "type": "boolean" - }, - "item_id": { - "type": "keyword" - }, - "list_id": { - "type": "keyword" - }, - "list_type": { - "type": "keyword" - }, - "meta": { - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "os_types": { - "type": "keyword" - }, - "tags": { - "type": "keyword" - }, - "tie_breaker_id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "updated_by": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - }, - "exception-list-agnostic": { - "properties": { - "_tags": { - "type": "keyword" - }, - "comments": { - "properties": { - "comment": { - "type": "keyword" - }, - "created_at": { - "type": "keyword" - }, - "created_by": { - "type": "keyword" - }, - "id": { - "type": "keyword" - }, - "updated_at": { - "type": "keyword" - }, - "updated_by": { - "type": "keyword" - } - } - }, - "created_at": { - "type": "keyword" - }, - "created_by": { - "type": "keyword" - }, - "description": { - "type": "keyword" - }, - "entries": { - "properties": { - "entries": { - "properties": { - "field": { - "type": "keyword" - }, - "operator": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" - } - } - }, - "field": { - "type": "keyword" - }, - "list": { - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "operator": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" - } - } - }, - "immutable": { - "type": "boolean" - }, - "item_id": { - "type": "keyword" - }, - "list_id": { - "type": "keyword" - }, - "list_type": { - "type": "keyword" - }, - "meta": { - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "os_types": { - "type": "keyword" - }, - "tags": { - "type": "keyword" - }, - "tie_breaker_id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "updated_by": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - }, - "file-upload-telemetry": { - "properties": { - "filesUploadedTotalCount": { - "type": "long" - } - } - }, - "fleet-agent-actions": { - "properties": { - "ack_data": { - "type": "text" - }, - "agent_id": { - "type": "keyword" - }, - "created_at": { - "type": "date" - }, - "data": { - "type": "binary" - }, - "policy_id": { - "type": "keyword" - }, - "policy_revision": { - "type": "integer" - }, - "sent_at": { - "type": "date" - }, - "type": { - "type": "keyword" - } - } - }, - "fleet-agent-events": { - "properties": { - "action_id": { - "type": "keyword" - }, - "agent_id": { - "type": "keyword" - }, - "data": { - "type": "text" - }, - "message": { - "type": "text" - }, - "payload": { - "type": "text" - }, - "policy_id": { - "type": "keyword" - }, - "stream_id": { - "type": "keyword" - }, - "subtype": { - "type": "keyword" - }, - "timestamp": { - "type": "date" - }, - "type": { - "type": "keyword" - } - } - }, - "fleet-agents": { - "properties": { - "access_api_key_id": { - "type": "keyword" - }, - "active": { - "type": "boolean" - }, - "current_error_events": { - "index": false, - "type": "text" - }, - "default_api_key": { - "type": "binary" - }, - "default_api_key_id": { - "type": "keyword" - }, - "enrolled_at": { - "type": "date" - }, - "last_checkin": { - "type": "date" - }, - "last_checkin_status": { - "type": "keyword" - }, - "last_updated": { - "type": "date" - }, - "local_metadata": { - "type": "flattened" - }, - "packages": { - "type": "keyword" - }, - "policy_id": { - "type": "keyword" - }, - "policy_revision": { - "type": "integer" - }, - "shared_id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "unenrolled_at": { - "type": "date" - }, - "unenrollment_started_at": { - "type": "date" - }, - "updated_at": { - "type": "date" - }, - "upgrade_started_at": { - "type": "date" - }, - "upgraded_at": { - "type": "date" - }, - "user_provided_metadata": { - "type": "flattened" - }, - "version": { - "type": "keyword" - } - } - }, - "fleet-enrollment-api-keys": { - "properties": { - "active": { - "type": "boolean" - }, - "api_key": { - "type": "binary" - }, - "api_key_id": { - "type": "keyword" - }, - "created_at": { - "type": "date" - }, - "expire_at": { - "type": "date" - }, - "name": { - "type": "keyword" - }, - "policy_id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - } - } - }, - "graph-workspace": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "legacyIndexPatternRef": { - "index": false, - "type": "text" - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" - } - } - }, - "index-pattern": { - "dynamic": "false", - "properties": { - "title": { - "type": "text" - }, - "type": { - "type": "keyword" - } - } - }, - "infrastructure-ui-source": { - "dynamic": "false", - "type": "object" - }, - "ingest-agent-policies": { - "properties": { - "description": { - "type": "text" - }, - "is_default": { - "type": "boolean" - }, - "monitoring_enabled": { - "index": false, - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "namespace": { - "type": "keyword" - }, - "package_policies": { - "type": "keyword" - }, - "revision": { - "type": "integer" - }, - "status": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "type": "keyword" - } - } - }, - "ingest-outputs": { - "properties": { - "ca_sha256": { - "index": false, - "type": "keyword" - }, - "config": { - "type": "flattened" - }, - "config_yaml": { - "type": "text" - }, - "fleet_enroll_password": { - "type": "binary" - }, - "fleet_enroll_username": { - "type": "binary" - }, - "hosts": { - "type": "keyword" - }, - "is_default": { - "type": "boolean" - }, - "name": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "ingest-package-policies": { - "properties": { - "created_at": { - "type": "date" - }, - "created_by": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "enabled": { - "type": "boolean" - }, - "inputs": { - "enabled": false, - "properties": { - "compiled_input": { - "type": "flattened" - }, - "config": { - "type": "flattened" - }, - "enabled": { - "type": "boolean" - }, - "streams": { - "properties": { - "compiled_stream": { - "type": "flattened" - }, - "config": { - "type": "flattened" - }, - "data_stream": { - "properties": { - "dataset": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "enabled": { - "type": "boolean" - }, - "id": { - "type": "keyword" - }, - "vars": { - "type": "flattened" - } - }, - "type": "nested" - }, - "type": { - "type": "keyword" - }, - "vars": { - "type": "flattened" - } - }, - "type": "nested" - }, - "name": { - "type": "keyword" - }, - "namespace": { - "type": "keyword" - }, - "output_id": { - "type": "keyword" - }, - "package": { - "properties": { - "name": { - "type": "keyword" - }, - "title": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - }, - "policy_id": { - "type": "keyword" - }, - "revision": { - "type": "integer" - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "type": "keyword" - } - } - }, - "ingest_manager_settings": { - "properties": { - "agent_auto_upgrade": { - "type": "keyword" - }, - "has_seen_add_data_notice": { - "index": false, - "type": "boolean" - }, - "kibana_ca_sha256": { - "type": "keyword" - }, - "kibana_urls": { - "type": "keyword" - }, - "package_auto_upgrade": { - "type": "keyword" - } - } - }, - "inventory-view": { - "dynamic": "false", - "type": "object" - }, - "kql-telemetry": { - "properties": { - "optInCount": { - "type": "long" - }, - "optOutCount": { - "type": "long" - } - } - }, - "lens": { - "properties": { - "description": { - "type": "text" - }, - "expression": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "state": { - "type": "flattened" - }, - "title": { - "type": "text" - }, - "visualizationType": { - "type": "keyword" - } - } - }, - "lens-ui-telemetry": { - "properties": { - "count": { - "type": "integer" - }, - "date": { - "type": "date" - }, - "name": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "map": { - "properties": { - "bounds": { - "dynamic": "false", - "type": "object" - }, - "description": { - "type": "text" - }, - "layerListJSON": { - "type": "text" - }, - "mapStateJSON": { - "type": "text" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "maps-telemetry": { - "enabled": false, - "type": "object" - }, - "metrics-explorer-view": { - "dynamic": "false", - "type": "object" - }, - "migrationVersion": { - "dynamic": "true", - "properties": { - "config": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "dashboard": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "index-pattern": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "search": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "visualization": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "ml-job": { - "properties": { - "datafeed_id": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "job_id": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "type": { - "type": "keyword" - } - } - }, - "ml-telemetry": { - "properties": { - "file_data_visualizer": { - "properties": { - "index_creation_count": { - "type": "long" - } - } - } - } - }, - "monitoring-telemetry": { - "properties": { - "reportedClusterUuids": { - "type": "keyword" - } - } - }, - "namespace": { - "type": "keyword" - }, - "namespaces": { - "type": "keyword" - }, - "originId": { - "type": "keyword" - }, - "outputs": { - "dynamic": "false", - "type": "object" - }, - "query": { - "properties": { - "description": { - "type": "text" - }, - "filters": { - "enabled": false, - "type": "object" - }, - "query": { - "properties": { - "language": { - "type": "keyword" - }, - "query": { - "index": false, - "type": "keyword" - } - } - }, - "timefilter": { - "enabled": false, - "type": "object" - }, - "title": { - "type": "text" - } - } - }, - "references": { - "properties": { - "id": { - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - }, - "type": "nested" - }, - "sample-data-telemetry": { - "properties": { - "installCount": { - "type": "long" - }, - "unInstallCount": { - "type": "long" - } - } - }, - "search": { - "properties": { - "columns": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "description": { - "type": "text" - }, - "grid": { - "enabled": false, - "type": "object" - }, - "hits": { - "doc_values": false, - "index": false, - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "index": false, - "type": "text" - } - } - }, - "sort": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "search-telemetry": { - "dynamic": "false", - "type": "object" - }, - "security-solution-signals-migration": { - "properties": { - "created": { - "index": false, - "type": "date" - }, - "createdBy": { - "index": false, - "type": "text" - }, - "destinationIndex": { - "index": false, - "type": "keyword" - }, - "error": { - "index": false, - "type": "text" - }, - "sourceIndex": { - "type": "keyword" - }, - "status": { - "index": false, - "type": "keyword" - }, - "taskId": { - "index": false, - "type": "keyword" - }, - "updated": { - "index": false, - "type": "date" - }, - "updatedBy": { - "index": false, - "type": "text" - }, - "version": { - "type": "long" - } - } - }, - "server": { - "dynamic": "false", - "type": "object" - }, - "siem-detection-engine-rule-actions": { - "properties": { - "actions": { - "properties": { - "action_type_id": { - "type": "keyword" - }, - "group": { - "type": "keyword" - }, - "id": { - "type": "keyword" - }, - "params": { - "enabled": false, - "type": "object" - } - } - }, - "alertThrottle": { - "type": "keyword" - }, - "ruleAlertId": { - "type": "keyword" - }, - "ruleThrottle": { - "type": "keyword" - } - } - }, - "siem-detection-engine-rule-status": { - "properties": { - "alertId": { - "type": "keyword" - }, - "bulkCreateTimeDurations": { - "type": "float" - }, - "gap": { - "type": "text" - }, - "lastFailureAt": { - "type": "date" - }, - "lastFailureMessage": { - "type": "text" - }, - "lastLookBackDate": { - "type": "date" - }, - "lastSuccessAt": { - "type": "date" - }, - "lastSuccessMessage": { - "type": "text" - }, - "searchAfterTimeDurations": { - "type": "float" - }, - "status": { - "type": "keyword" - }, - "statusDate": { - "type": "date" - } - } - }, - "siem-ui-timeline": { - "properties": { - "columns": { - "properties": { - "aggregatable": { - "type": "boolean" - }, - "category": { - "type": "keyword" - }, - "columnHeaderType": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "example": { - "type": "text" - }, - "id": { - "type": "keyword" - }, - "indexes": { - "type": "keyword" - }, - "name": { - "type": "text" - }, - "placeholder": { - "type": "text" - }, - "searchable": { - "type": "boolean" - }, - "type": { - "type": "keyword" - } - } - }, - "created": { - "type": "date" - }, - "createdBy": { - "type": "text" - }, - "dataProviders": { - "properties": { - "and": { - "properties": { - "enabled": { - "type": "boolean" - }, - "excluded": { - "type": "boolean" - }, - "id": { - "type": "keyword" - }, - "kqlQuery": { - "type": "text" - }, - "name": { - "type": "text" - }, - "queryMatch": { - "properties": { - "displayField": { - "type": "text" - }, - "displayValue": { - "type": "text" - }, - "field": { - "type": "text" - }, - "operator": { - "type": "text" - }, - "value": { - "type": "text" - } - } - }, - "type": { - "type": "text" - } - } - }, - "enabled": { - "type": "boolean" - }, - "excluded": { - "type": "boolean" - }, - "id": { - "type": "keyword" - }, - "kqlQuery": { - "type": "text" - }, - "name": { - "type": "text" - }, - "queryMatch": { - "properties": { - "displayField": { - "type": "text" - }, - "displayValue": { - "type": "text" - }, - "field": { - "type": "text" - }, - "operator": { - "type": "text" - }, - "value": { - "type": "text" - } - } - }, - "type": { - "type": "text" - } - } - }, - "dateRange": { - "properties": { - "end": { - "type": "date" - }, - "start": { - "type": "date" - } - } - }, - "description": { - "type": "text" - }, - "eventType": { - "type": "keyword" - }, - "excludedRowRendererIds": { - "type": "text" - }, - "favorite": { - "properties": { - "favoriteDate": { - "type": "date" - }, - "fullName": { - "type": "text" - }, - "keySearch": { - "type": "text" - }, - "userName": { - "type": "text" - } - } - }, - "filters": { - "properties": { - "exists": { - "type": "text" - }, - "match_all": { - "type": "text" - }, - "meta": { - "properties": { - "alias": { - "type": "text" - }, - "controlledBy": { - "type": "text" - }, - "disabled": { - "type": "boolean" - }, - "field": { - "type": "text" - }, - "formattedValue": { - "type": "text" - }, - "index": { - "type": "keyword" - }, - "key": { - "type": "keyword" - }, - "negate": { - "type": "boolean" - }, - "params": { - "type": "text" - }, - "type": { - "type": "keyword" - }, - "value": { - "type": "text" - } - } - }, - "missing": { - "type": "text" - }, - "query": { - "type": "text" - }, - "range": { - "type": "text" - }, - "script": { - "type": "text" - } - } - }, - "indexNames": { - "type": "text" - }, - "kqlMode": { - "type": "keyword" - }, - "kqlQuery": { - "properties": { - "filterQuery": { - "properties": { - "kuery": { - "properties": { - "expression": { - "type": "text" - }, - "kind": { - "type": "keyword" - } - } - }, - "serializedQuery": { - "type": "text" - } - } - } - } - }, - "savedQueryId": { - "type": "keyword" - }, - "sort": { - "properties": { - "columnId": { - "type": "keyword" - }, - "sortDirection": { - "type": "keyword" - } - } - }, - "status": { - "type": "keyword" - }, - "templateTimelineId": { - "type": "text" - }, - "templateTimelineVersion": { - "type": "integer" - }, - "timelineType": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "updated": { - "type": "date" - }, - "updatedBy": { - "type": "text" - } - } - }, - "siem-ui-timeline-note": { - "properties": { - "created": { - "type": "date" - }, - "createdBy": { - "type": "text" - }, - "eventId": { - "type": "keyword" - }, - "note": { - "type": "text" - }, - "timelineId": { - "type": "keyword" - }, - "updated": { - "type": "date" - }, - "updatedBy": { - "type": "text" - } - } - }, - "siem-ui-timeline-pinned-event": { - "properties": { - "created": { - "type": "date" - }, - "createdBy": { - "type": "text" - }, - "eventId": { - "type": "keyword" - }, - "timelineId": { - "type": "keyword" - }, - "updated": { - "type": "date" - }, - "updatedBy": { - "type": "text" - } - } - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "imageUrl": { - "index": false, - "type": "text" - }, - "initials": { - "type": "keyword" - }, - "name": { - "fields": { - "keyword": { - "ignore_above": 2048, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "spaces-usage-stats": { - "dynamic": "false", - "type": "object" - }, - "tag": { - "properties": { - "color": { - "type": "text" - }, - "description": { - "type": "text" - }, - "name": { - "type": "text" - } - } - }, - "telemetry": { - "properties": { - "allowChangingOptInStatus": { - "type": "boolean" - }, - "enabled": { - "type": "boolean" - }, - "lastReported": { - "type": "date" - }, - "lastVersionChecked": { - "type": "keyword" - }, - "reportFailureCount": { - "type": "integer" - }, - "reportFailureVersion": { - "type": "keyword" - }, - "sendUsageFrom": { - "type": "keyword" - }, - "userHasSeenNotice": { - "type": "boolean" - } - } - }, - "timelion-sheet": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "timelion_chart_height": { - "type": "integer" - }, - "timelion_columns": { - "type": "integer" - }, - "timelion_interval": { - "type": "keyword" - }, - "timelion_other_interval": { - "type": "keyword" - }, - "timelion_rows": { - "type": "integer" - }, - "timelion_sheet": { - "type": "text" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "tsvb-validation-telemetry": { - "properties": { - "failedRequests": { - "type": "long" - } - } - }, - "type": { - "type": "keyword" - }, - "ui-counter": { - "properties": { - "count": { - "type": "integer" - } - } - }, - "ui-metric": { - "properties": { - "count": { - "type": "integer" - } - } - }, - "updated_at": { - "type": "date" - }, - "upgrade-assistant-reindex-operation": { - "properties": { - "errorMessage": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "indexName": { - "type": "keyword" - }, - "lastCompletedStep": { - "type": "long" - }, - "locked": { - "type": "date" - }, - "newIndexName": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "reindexOptions": { - "properties": { - "openAndClose": { - "type": "boolean" - }, - "queueSettings": { - "properties": { - "queuedAt": { - "type": "long" - }, - "startedAt": { - "type": "long" - } - } - } - } - }, - "reindexTaskId": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "reindexTaskPercComplete": { - "type": "float" - }, - "runningReindexCount": { - "type": "integer" - }, - "status": { - "type": "integer" - } - } - }, - "upgrade-assistant-telemetry": { - "properties": { - "features": { - "properties": { - "deprecation_logging": { - "properties": { - "enabled": { - "null_value": true, - "type": "boolean" - } - } - } - } - }, - "ui_open": { - "properties": { - "cluster": { - "null_value": 0, - "type": "long" - }, - "indices": { - "null_value": 0, - "type": "long" - }, - "overview": { - "null_value": 0, - "type": "long" - } - } - }, - "ui_reindex": { - "properties": { - "close": { - "null_value": 0, - "type": "long" - }, - "open": { - "null_value": 0, - "type": "long" - }, - "start": { - "null_value": 0, - "type": "long" - }, - "stop": { - "null_value": 0, - "type": "long" - } - } - } - } - }, - "uptime-dynamic-settings": { - "dynamic": "false", - "type": "object" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "fields": { - "keyword": { - "ignore_above": 2048, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "index": false, - "type": "text" - } - } - }, - "savedSearchRefName": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "index": false, - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "index": false, - "type": "text" - } - } - }, - "workplace_search_telemetry": { - "dynamic": "false", - "type": "object" - } - } - }, - "settings": { - "index": { - "auto_expand_replicas": "0-1", - "number_of_replicas": "0", - "number_of_shards": "1" - } - } - } -} diff --git a/x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json b/x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json new file mode 100644 index 00000000000000..568b2e17a93328 --- /dev/null +++ b/x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json @@ -0,0 +1,678 @@ +{ + "attributes": { + "fields": "[{\"name\":\"_id\",\"type\":\"string\",\"esTypes\":[\"_id\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_index\",\"type\":\"string\",\"esTypes\":[\"_index\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_source\",\"type\":\"_source\",\"esTypes\":[\"_source\"],\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_type\",\"type\":\"string\",\"esTypes\":[\"_type\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"category\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"category.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"category\"}}},{\"name\":\"currency\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"customer_birth_date\",\"type\":\"date\",\"esTypes\":[\"date\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"customer_first_name\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"customer_first_name.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"customer_first_name\"}}},{\"name\":\"customer_full_name\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"customer_full_name.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"customer_full_name\"}}},{\"name\":\"customer_gender\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"customer_id\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"customer_last_name\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"customer_last_name.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"customer_last_name\"}}},{\"name\":\"customer_phone\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"day_of_week\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"day_of_week_i\",\"type\":\"number\",\"esTypes\":[\"integer\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"email\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geoip.city_name\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geoip.continent_name\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geoip.country_iso_code\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geoip.location\",\"type\":\"geo_point\",\"esTypes\":[\"geo_point\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geoip.region_name\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"manufacturer\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"manufacturer.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"manufacturer\"}}},{\"name\":\"order_date\",\"type\":\"date\",\"esTypes\":[\"date\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"order_id\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products._id\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"products._id.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"products._id\"}}},{\"name\":\"products.base_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.base_unit_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.category\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"products.category.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"products.category\"}}},{\"name\":\"products.created_on\",\"type\":\"date\",\"esTypes\":[\"date\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.discount_amount\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.discount_percentage\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.manufacturer\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"products.manufacturer.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"products.manufacturer\"}}},{\"name\":\"products.min_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.product_id\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.product_name\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"products.product_name.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"products.product_name\"}}},{\"name\":\"products.quantity\",\"type\":\"number\",\"esTypes\":[\"integer\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.sku\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.tax_amount\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.taxful_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.taxless_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"products.unit_discount_amount\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"sku\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"taxful_total_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"taxless_total_price\",\"type\":\"number\",\"esTypes\":[\"half_float\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"total_quantity\",\"type\":\"number\",\"esTypes\":[\"integer\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"total_unique_products\",\"type\":\"number\",\"esTypes\":[\"integer\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"type\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"user\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]", + "timeFieldName": "order_date", + "title": "ecommerce" + }, + "coreMigrationVersion": "8.0.0", + "id": "5193f870-d861-11e9-a311-0fa548c5f953", + "migrationVersion": { + "index-pattern": "7.11.0" + }, + "references": [], + "type": "index-pattern", + "updated_at": "2019-12-11T23:24:13.381Z", + "version": "WzE3LDJd" +} + +{ + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "e-commerce area chart", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"type\":\"area\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"order_date\",\"timeRange\":{\"from\":\"2019-06-26T06:20:28.066Z\",\"to\":\"2019-06-26T07:27:58.573Z\"},\"useNormalizedEsInterval\":true,\"scaleMetricValues\":false,\"interval\":\"auto\",\"drop_partials\":false,\"min_doc_count\":1,\"extended_bounds\":{}}}],\"params\":{\"type\":\"area\",\"grid\":{\"categoryLines\":false},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"filter\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":true,\"type\":\"area\",\"mode\":\"stacked\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"drawLinesBetweenPoints\":true,\"lineWidth\":2,\"showCircles\":true,\"interpolate\":\"linear\",\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false,\"thresholdLine\":{\"show\":false,\"value\":10,\"width\":1,\"style\":\"full\",\"color\":\"#E7664C\"},\"labels\":{},\"isVislibVis\":true,\"detailedTooltip\":true,\"fittingFunction\":\"zero\"},\"title\":\"e-commerce area chart\"}" + }, + "coreMigrationVersion": "8.0.0", + "id": "0a464230-79f0-11ea-ae7f-13c5d6e410a0", + "migrationVersion": { + "visualization": "7.14.0" + }, + "references": [ + { + "id": "5193f870-d861-11e9-a311-0fa548c5f953", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2020-04-08T23:24:05.971Z", + "version": "WzIwLDJd" +} + +{ + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"filter\":[]}" + }, + "title": "Українська", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"type\":\"metric\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}}],\"params\":{\"addTooltip\":true,\"addLegend\":false,\"type\":\"metric\",\"metric\":{\"percentageMode\":false,\"useRanges\":false,\"colorSchema\":\"Green to Red\",\"metricColorMode\":\"None\",\"colorsRange\":[{\"from\":0,\"to\":10000}],\"labels\":{\"show\":true},\"invertColors\":false,\"style\":{\"bgFill\":\"#000\",\"bgColor\":false,\"labelColor\":false,\"subText\":\"\",\"fontSize\":60}}},\"title\":\"Українська\"}" + }, + "coreMigrationVersion": "8.0.0", + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "migrationVersion": { + "visualization": "7.14.0" + }, + "references": [ + { + "id": "5193f870-d861-11e9-a311-0fa548c5f953", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2020-04-10T00:34:44.700Z", + "version": "WzIzLDJd" +} + +{ + "attributes": { + "columns": [ + "order_date", + "category", + "currency", + "customer_id", + "order_id", + "day_of_week_i", + "products.created_on", + "sku" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "sort": [ + [ + "order_date", + "desc" + ] + ], + "title": "Ecommerce Data", + "version": 1 + }, + "coreMigrationVersion": "8.0.0", + "id": "6091ead0-1c6d-11ea-a100-8589bb9d7c6b", + "migrationVersion": { + "search": "7.9.3" + }, + "references": [ + { + "id": "5193f870-d861-11e9-a311-0fa548c5f953", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "search", + "updated_at": "2019-12-11T23:24:28.540Z", + "version": "WzE4LDJd" +} + +{ + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}" + }, + "savedSearchRefName": "search_0", + "title": "Tag Cloud of Names", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Tag Cloud of Names\",\"type\":\"tagcloud\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"params\":{},\"schema\":\"metric\"},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"params\":{\"field\":\"customer_first_name.keyword\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":10,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"},\"schema\":\"segment\"}],\"params\":{\"scale\":\"linear\",\"orientation\":\"single\",\"minFontSize\":18,\"maxFontSize\":72,\"showLabel\":true,\"palette\":{\"type\":\"palette\",\"name\":\"kibana_palette\"}}}" + }, + "coreMigrationVersion": "8.0.0", + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "migrationVersion": { + "visualization": "7.14.0" + }, + "references": [ + { + "id": "6091ead0-1c6d-11ea-a100-8589bb9d7c6b", + "name": "search_0", + "type": "search" + } + ], + "type": "visualization", + "updated_at": "2021-01-07T00:23:04.624Z", + "version": "WzI3LDJd" +} + +{ + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "e-commerce pie chart", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"type\":\"pie\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"order_date\",\"timeRange\":{\"from\":\"2019-06-26T06:20:28.066Z\",\"to\":\"2019-06-26T07:27:58.573Z\"},\"useNormalizedEsInterval\":true,\"scaleMetricValues\":false,\"interval\":\"auto\",\"drop_partials\":false,\"min_doc_count\":1,\"extended_bounds\":{}}}],\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100},\"palette\":{\"type\":\"palette\",\"name\":\"kibana_palette\"},\"distinctColors\":true},\"title\":\"e-commerce pie chart\"}" + }, + "coreMigrationVersion": "8.0.0", + "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", + "migrationVersion": { + "visualization": "7.14.0" + }, + "references": [ + { + "id": "5193f870-d861-11e9-a311-0fa548c5f953", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2020-04-08T23:24:42.460Z", + "version": "WzIxLDJd" +} + +{ + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}" + }, + "title": "Tiểu thuyết", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"type\":\"markdown\",\"aggs\":[],\"params\":{\"fontSize\":12,\"openLinksInNewTab\":false,\"markdown\":\"Tiểu thuyết là một thể loại văn xuôi có hư cấu, thông qua nhân vật, hoàn cảnh, sự việc để phản ánh bức tranh xã hội rộng lớn và những vấn đề của cuộc sống con người, biểu hiện tính chất tường thuật, tính chất kể chuyện bằng ngôn ngữ văn xuôi theo những chủ đề xác định.\\n\\nTrong một cách hiểu khác, nhận định của Belinski: \\\"tiểu thuyết là sử thi của đời tư\\\" chỉ ra khái quát nhất về một dạng thức tự sự, trong đó sự trần thuật tập trung vào số phận của một cá nhân trong quá trình hình thành và phát triển của nó. Sự trần thuật ở đây được khai triển trong không gian và thời gian nghệ thuật đến mức đủ để truyền đạt cơ cấu của nhân cách[1].\\n\\n\\n[1]^ Mục từ Tiểu thuyết trong cuốn 150 thuật ngữ văn học, Lại Nguyên Ân biên soạn, Nhà xuất bản Đại học Quốc gia Hà Nội, in lần thứ 2 có sửa đổi bổ sung. H. 2003. Trang 326.\"},\"title\":\"Tiểu thuyết\"}" + }, + "coreMigrationVersion": "8.0.0", + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "migrationVersion": { + "visualization": "7.14.0" + }, + "references": [], + "type": "visualization", + "updated_at": "2020-04-10T00:36:17.053Z", + "version": "WzI0LDJd" +} + +{ + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\",\"filter\":[]}" + }, + "title": "게이지", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"type\":\"gauge\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}}],\"params\":{\"type\":\"gauge\",\"addTooltip\":true,\"addLegend\":true,\"isDisplayWarning\":false,\"gauge\":{\"alignment\":\"automatic\",\"extendRange\":true,\"percentageMode\":false,\"gaugeType\":\"Arc\",\"gaugeStyle\":\"Full\",\"backStyle\":\"Full\",\"orientation\":\"vertical\",\"colorSchema\":\"Green to Red\",\"gaugeColorMode\":\"Labels\",\"colorsRange\":[{\"from\":0,\"to\":50},{\"from\":50,\"to\":75},{\"from\":75,\"to\":100}],\"invertColors\":false,\"labels\":{\"show\":true,\"color\":\"black\"},\"scale\":{\"show\":true,\"labels\":false,\"color\":\"rgba(105,112,125,0.2)\"},\"type\":\"meter\",\"style\":{\"bgWidth\":0.9,\"width\":0.9,\"mask\":false,\"bgMask\":false,\"maskBars\":50,\"bgFill\":\"rgba(105,112,125,0.2)\",\"bgColor\":true,\"subText\":\"\",\"fontSize\":60}}},\"title\":\"게이지\"}" + }, + "coreMigrationVersion": "8.0.0", + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "migrationVersion": { + "visualization": "7.14.0" + }, + "references": [ + { + "id": "5193f870-d861-11e9-a311-0fa548c5f953", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2020-04-10T00:33:44.909Z", + "version": "WzIyLDJd" +} + +{ + "attributes": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}" + }, + "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}", + "panelsJSON": "[{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1c12c2f2-80c2-4d5c-b722-55b2415006e1\"},\"panelIndex\":\"1c12c2f2-80c2-4d5c-b722-55b2415006e1\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1c4b99e1-7785-444f-a1c5-f592893b1a96\"},\"panelIndex\":\"1c4b99e1-7785-444f-a1c5-f592893b1a96\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_1\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":35,\"w\":48,\"h\":18,\"i\":\"94eab06f-60ac-4a85-b771-3a8ed475c9bb\"},\"panelIndex\":\"94eab06f-60ac-4a85-b771-3a8ed475c9bb\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_2\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":15,\"w\":48,\"h\":8,\"i\":\"52c19b6b-7117-42ac-a74e-c507a1c3ffc0\"},\"panelIndex\":\"52c19b6b-7117-42ac-a74e-c507a1c3ffc0\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_3\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":23,\"w\":16,\"h\":12,\"i\":\"a1e889dc-b80e-4937-a576-979f34d1859b\"},\"panelIndex\":\"a1e889dc-b80e-4937-a576-979f34d1859b\",\"embeddableConfig\":{\"enhancements\":{},\"vis\":null},\"panelRefName\":\"panel_4\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":16,\"y\":23,\"w\":12,\"h\":12,\"i\":\"4930b035-d756-4cc5-9a18-1af9e67d6f31\"},\"panelIndex\":\"4930b035-d756-4cc5-9a18-1af9e67d6f31\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_5\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":28,\"y\":23,\"w\":20,\"h\":12,\"i\":\"55112375-d6f0-44f7-a8fb-867c8f7d464d\"},\"panelIndex\":\"55112375-d6f0-44f7-a8fb-867c8f7d464d\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_6\"}]", + "refreshInterval": { + "pause": true, + "value": 0 + }, + "timeFrom": "2019-03-23T03:06:17.785Z", + "timeRestore": true, + "timeTo": "2019-10-04T02:33:16.708Z", + "title": "Ecom Dashboard", + "version": 1 + }, + "coreMigrationVersion": "8.0.0", + "id": "6c263e00-1c6d-11ea-a100-8589bb9d7c6b", + "migrationVersion": { + "dashboard": "7.14.0" + }, + "references": [ + { + "id": "0a464230-79f0-11ea-ae7f-13c5d6e410a0", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "6091ead0-1c6d-11ea-a100-8589bb9d7c6b", + "name": "panel_2", + "type": "search" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "panel_3", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "panel_4", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "panel_5", + "type": "visualization" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "panel_6", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2021-01-07T00:22:16.102Z", + "version": "WzI2LDJd" +} + +{ + "attributes": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}" + }, + "optionsJSON": "{\"hidePanelTitles\":true,\"useMargins\":true}", + "panelsJSON": "[{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1c12c2f2-80c2-4d5c-b722-55b2415006e1\"},\"panelIndex\":\"1c12c2f2-80c2-4d5c-b722-55b2415006e1\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1c4b99e1-7785-444f-a1c5-f592893b1a96\"},\"panelIndex\":\"1c4b99e1-7785-444f-a1c5-f592893b1a96\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_1\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":15,\"w\":48,\"h\":18,\"i\":\"94eab06f-60ac-4a85-b771-3a8ed475c9bb\"},\"panelIndex\":\"94eab06f-60ac-4a85-b771-3a8ed475c9bb\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_2\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":33,\"w\":48,\"h\":8,\"i\":\"52c19b6b-7117-42ac-a74e-c507a1c3ffc0\"},\"panelIndex\":\"52c19b6b-7117-42ac-a74e-c507a1c3ffc0\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_3\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":41,\"w\":11,\"h\":10,\"i\":\"a1e889dc-b80e-4937-a576-979f34d1859b\"},\"panelIndex\":\"a1e889dc-b80e-4937-a576-979f34d1859b\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_4\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":11,\"y\":41,\"w\":5,\"h\":10,\"i\":\"4930b035-d756-4cc5-9a18-1af9e67d6f31\"},\"panelIndex\":\"4930b035-d756-4cc5-9a18-1af9e67d6f31\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_5\"}]", + "refreshInterval": { + "pause": true, + "value": 0 + }, + "timeFrom": "2019-06-26T06:20:28.066Z", + "timeRestore": true, + "timeTo": "2019-06-26T07:27:58.573Z", + "title": "Ecom Dashboard Hidden Panel Titles", + "version": 1 + }, + "coreMigrationVersion": "8.0.0", + "id": "constructed-sample-saved-object-id", + "migrationVersion": { + "dashboard": "7.14.0" + }, + "references": [ + { + "id": "0a464230-79f0-11ea-ae7f-13c5d6e410a0", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "6091ead0-1c6d-11ea-a100-8589bb9d7c6b", + "name": "panel_2", + "type": "search" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "panel_3", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "panel_4", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "panel_5", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2020-04-10T00:37:48.462Z", + "version": "WzE5LDJd" +} + +{ + "attributes": { + "columns": [ + "order_date", + "category", + "currency", + "customer_id", + "order_id", + "day_of_week_i", + "products.created_on", + "sku" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "sort": [ + [ + "order_date", + "desc" + ] + ], + "title": "Ecommerce Data (copy)", + "version": 1 + }, + "coreMigrationVersion": "8.0.0", + "id": "e5bfe380-ac3e-11eb-8f24-bffe9ba4af2b", + "migrationVersion": { + "search": "7.9.3" + }, + "references": [ + { + "id": "5193f870-d861-11e9-a311-0fa548c5f953", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "search", + "updated_at": "2021-05-03T18:39:30.751Z", + "version": "WzI4LDJd" +} + +{ + "attributes": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}" + }, + "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}", + "panelsJSON": "[{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":9,\"y\":0,\"w\":24,\"h\":15,\"i\":\"914ac161-94d4-4d93-a287-c21fca46a974\"},\"panelIndex\":\"914ac161-94d4-4d93-a287-c21fca46a974\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_914ac161-94d4-4d93-a287-c21fca46a974\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":22,\"y\":15,\"w\":24,\"h\":15,\"i\":\"c4cec7d1-97e3-4101-adc4-c3f15102511c\"},\"panelIndex\":\"c4cec7d1-97e3-4101-adc4-c3f15102511c\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_c4cec7d1-97e3-4101-adc4-c3f15102511c\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":30,\"w\":24,\"h\":15,\"i\":\"09f7de68-0d07-4661-8fda-73ea8b577ac7\"},\"panelIndex\":\"09f7de68-0d07-4661-8fda-73ea8b577ac7\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_09f7de68-0d07-4661-8fda-73ea8b577ac7\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":45,\"w\":24,\"h\":15,\"i\":\"6c25ca6e-6aa1-4f06-9a96-e83ffd9f52e8\"},\"panelIndex\":\"6c25ca6e-6aa1-4f06-9a96-e83ffd9f52e8\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_6c25ca6e-6aa1-4f06-9a96-e83ffd9f52e8\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":60,\"w\":24,\"h\":15,\"i\":\"37764cf9-3c89-454a-bd7e-ae4c242dc624\"},\"panelIndex\":\"37764cf9-3c89-454a-bd7e-ae4c242dc624\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_37764cf9-3c89-454a-bd7e-ae4c242dc624\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":15,\"y\":75,\"w\":24,\"h\":15,\"i\":\"990422fd-a9cf-446f-ba2f-ea9178a7b2e0\"},\"panelIndex\":\"990422fd-a9cf-446f-ba2f-ea9178a7b2e0\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_990422fd-a9cf-446f-ba2f-ea9178a7b2e0\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":90,\"w\":24,\"h\":15,\"i\":\"0cdc13ec-2775-4da9-9a47-1e833bb807eb\"},\"panelIndex\":\"0cdc13ec-2775-4da9-9a47-1e833bb807eb\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0cdc13ec-2775-4da9-9a47-1e833bb807eb\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":18,\"y\":105,\"w\":24,\"h\":15,\"i\":\"eee160de-5777-40c8-9c2c-e75f64bf208a\"},\"panelIndex\":\"eee160de-5777-40c8-9c2c-e75f64bf208a\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_eee160de-5777-40c8-9c2c-e75f64bf208a\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":120,\"w\":24,\"h\":15,\"i\":\"b36f6a97-5d3d-4fc4-b076-b3e514f8f7bb\"},\"panelIndex\":\"b36f6a97-5d3d-4fc4-b076-b3e514f8f7bb\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_b36f6a97-5d3d-4fc4-b076-b3e514f8f7bb\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":135,\"w\":24,\"h\":15,\"i\":\"2e72acbf-7ade-451e-a5e4-7414f12facf2\"},\"panelIndex\":\"2e72acbf-7ade-451e-a5e4-7414f12facf2\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_2e72acbf-7ade-451e-a5e4-7414f12facf2\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":150,\"w\":24,\"h\":15,\"i\":\"4119e9b0-5d03-482d-9356-89bb62b6a851\"},\"panelIndex\":\"4119e9b0-5d03-482d-9356-89bb62b6a851\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_4119e9b0-5d03-482d-9356-89bb62b6a851\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":165,\"w\":24,\"h\":15,\"i\":\"42b4a37c-8b04-4510-9f27-831355221b65\"},\"panelIndex\":\"42b4a37c-8b04-4510-9f27-831355221b65\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_42b4a37c-8b04-4510-9f27-831355221b65\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":14,\"y\":180,\"w\":24,\"h\":15,\"i\":\"dc676050-d752-4c3e-a1ae-73ef2f1bcdc6\"},\"panelIndex\":\"dc676050-d752-4c3e-a1ae-73ef2f1bcdc6\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_dc676050-d752-4c3e-a1ae-73ef2f1bcdc6\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":17,\"y\":195,\"w\":24,\"h\":15,\"i\":\"6602e0e0-9e66-4e0e-90c1-f66b9c3d2340\"},\"panelIndex\":\"6602e0e0-9e66-4e0e-90c1-f66b9c3d2340\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_6602e0e0-9e66-4e0e-90c1-f66b9c3d2340\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":210,\"w\":24,\"h\":15,\"i\":\"c9c65725-9b4d-4343-93db-7efa4a7a2d60\"},\"panelIndex\":\"c9c65725-9b4d-4343-93db-7efa4a7a2d60\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_c9c65725-9b4d-4343-93db-7efa4a7a2d60\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":225,\"w\":24,\"h\":15,\"i\":\"69141f9b-5c23-409d-9c96-7f94c243f79e\"},\"panelIndex\":\"69141f9b-5c23-409d-9c96-7f94c243f79e\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_69141f9b-5c23-409d-9c96-7f94c243f79e\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":17,\"y\":240,\"w\":24,\"h\":15,\"i\":\"6feeec2c-34ab-4844-8445-e417c8e0595b\"},\"panelIndex\":\"6feeec2c-34ab-4844-8445-e417c8e0595b\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_6feeec2c-34ab-4844-8445-e417c8e0595b\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":15,\"y\":255,\"w\":24,\"h\":15,\"i\":\"985d9dc1-de44-4803-afad-f1d497d050a1\"},\"panelIndex\":\"985d9dc1-de44-4803-afad-f1d497d050a1\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_985d9dc1-de44-4803-afad-f1d497d050a1\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":270,\"w\":24,\"h\":15,\"i\":\"d7ef9e23-d0dd-4c7c-90b3-f611bbfcd1b0\"},\"panelIndex\":\"d7ef9e23-d0dd-4c7c-90b3-f611bbfcd1b0\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_d7ef9e23-d0dd-4c7c-90b3-f611bbfcd1b0\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":20,\"y\":285,\"w\":24,\"h\":15,\"i\":\"6b0768b1-0cd2-47f0-a639-b369e7318d44\"},\"panelIndex\":\"6b0768b1-0cd2-47f0-a639-b369e7318d44\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_6b0768b1-0cd2-47f0-a639-b369e7318d44\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":20,\"y\":300,\"w\":24,\"h\":15,\"i\":\"c9cc2835-06a8-4448-b703-2d41a6692feb\"},\"panelIndex\":\"c9cc2835-06a8-4448-b703-2d41a6692feb\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_c9cc2835-06a8-4448-b703-2d41a6692feb\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":315,\"w\":24,\"h\":15,\"i\":\"af2a55b1-8b3d-478a-96b1-72e4f12585e4\"},\"panelIndex\":\"af2a55b1-8b3d-478a-96b1-72e4f12585e4\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_af2a55b1-8b3d-478a-96b1-72e4f12585e4\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":330,\"w\":24,\"h\":15,\"i\":\"ee92986a-adab-4d66-ad4e-a43a608f52f7\"},\"panelIndex\":\"ee92986a-adab-4d66-ad4e-a43a608f52f7\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_ee92986a-adab-4d66-ad4e-a43a608f52f7\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":22,\"y\":345,\"w\":24,\"h\":15,\"i\":\"3b4e1fd0-2acb-444a-b478-42d7bd10b96c\"},\"panelIndex\":\"3b4e1fd0-2acb-444a-b478-42d7bd10b96c\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_3b4e1fd0-2acb-444a-b478-42d7bd10b96c\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":360,\"w\":24,\"h\":15,\"i\":\"04d7056d-88a4-4b00-b8f4-33f79f1b6f7a\"},\"panelIndex\":\"04d7056d-88a4-4b00-b8f4-33f79f1b6f7a\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_04d7056d-88a4-4b00-b8f4-33f79f1b6f7a\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":21,\"y\":375,\"w\":24,\"h\":15,\"i\":\"51122bae-427e-45a6-904e-6c821447cc46\"},\"panelIndex\":\"51122bae-427e-45a6-904e-6c821447cc46\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_51122bae-427e-45a6-904e-6c821447cc46\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":20,\"y\":390,\"w\":24,\"h\":15,\"i\":\"4efab22c-1892-4013-8406-5e5d924a8a21\"},\"panelIndex\":\"4efab22c-1892-4013-8406-5e5d924a8a21\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_4efab22c-1892-4013-8406-5e5d924a8a21\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":405,\"w\":24,\"h\":15,\"i\":\"4c3c1b29-100e-474c-8290-9470684ae407\"},\"panelIndex\":\"4c3c1b29-100e-474c-8290-9470684ae407\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_4c3c1b29-100e-474c-8290-9470684ae407\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":18,\"y\":420,\"w\":24,\"h\":15,\"i\":\"b4501df0-d759-4513-9e87-5dd8eefe4a4f\"},\"panelIndex\":\"b4501df0-d759-4513-9e87-5dd8eefe4a4f\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_b4501df0-d759-4513-9e87-5dd8eefe4a4f\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":20,\"y\":435,\"w\":24,\"h\":15,\"i\":\"4fbff0ec-b3a6-4ee7-8734-9b177c3e51c6\"},\"panelIndex\":\"4fbff0ec-b3a6-4ee7-8734-9b177c3e51c6\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_4fbff0ec-b3a6-4ee7-8734-9b177c3e51c6\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":450,\"w\":24,\"h\":15,\"i\":\"13d9982e-2745-44b1-af94-fa4b9f6761a9\"},\"panelIndex\":\"13d9982e-2745-44b1-af94-fa4b9f6761a9\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_13d9982e-2745-44b1-af94-fa4b9f6761a9\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":17,\"y\":465,\"w\":24,\"h\":15,\"i\":\"efa18320-9650-4bfe-9418-ac29b7979f70\"},\"panelIndex\":\"efa18320-9650-4bfe-9418-ac29b7979f70\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_efa18320-9650-4bfe-9418-ac29b7979f70\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":21,\"y\":480,\"w\":24,\"h\":15,\"i\":\"1f03bc70-0545-4a3a-bebc-ad477674b841\"},\"panelIndex\":\"1f03bc70-0545-4a3a-bebc-ad477674b841\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_1f03bc70-0545-4a3a-bebc-ad477674b841\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":495,\"w\":24,\"h\":15,\"i\":\"d766ce3a-9ec5-4ead-8698-6a2e66e729bb\"},\"panelIndex\":\"d766ce3a-9ec5-4ead-8698-6a2e66e729bb\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_d766ce3a-9ec5-4ead-8698-6a2e66e729bb\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":19,\"y\":510,\"w\":24,\"h\":15,\"i\":\"de93deb0-6c16-45ae-8fae-de0b2e1c4ae0\"},\"panelIndex\":\"de93deb0-6c16-45ae-8fae-de0b2e1c4ae0\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_de93deb0-6c16-45ae-8fae-de0b2e1c4ae0\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":525,\"w\":24,\"h\":15,\"i\":\"b93cc5e1-084a-42d9-9958-a3f569573d43\"},\"panelIndex\":\"b93cc5e1-084a-42d9-9958-a3f569573d43\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_b93cc5e1-084a-42d9-9958-a3f569573d43\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":20,\"y\":540,\"w\":24,\"h\":15,\"i\":\"0b6c380f-3536-4f03-8dbd-95c53be69263\"},\"panelIndex\":\"0b6c380f-3536-4f03-8dbd-95c53be69263\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0b6c380f-3536-4f03-8dbd-95c53be69263\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":23,\"y\":555,\"w\":24,\"h\":15,\"i\":\"5c68b67a-ac42-48b8-85de-2409aaa0cdc6\"},\"panelIndex\":\"5c68b67a-ac42-48b8-85de-2409aaa0cdc6\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_5c68b67a-ac42-48b8-85de-2409aaa0cdc6\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":24,\"y\":570,\"w\":24,\"h\":15,\"i\":\"098a69b8-c9a0-40c8-8703-62838e0ec4a9\"},\"panelIndex\":\"098a69b8-c9a0-40c8-8703-62838e0ec4a9\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_098a69b8-c9a0-40c8-8703-62838e0ec4a9\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":1,\"y\":585,\"w\":24,\"h\":15,\"i\":\"a0f4b9ce-2e36-4d22-8dd9-8988f1a3b883\"},\"panelIndex\":\"a0f4b9ce-2e36-4d22-8dd9-8988f1a3b883\",\"embeddableConfig\":{\"vis\":null,\"enhancements\":{}},\"panelRefName\":\"panel_a0f4b9ce-2e36-4d22-8dd9-8988f1a3b883\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":15,\"y\":600,\"w\":24,\"h\":15,\"i\":\"eb651411-ea02-4506-a674-f0125d0b2a4a\"},\"panelIndex\":\"eb651411-ea02-4506-a674-f0125d0b2a4a\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_eb651411-ea02-4506-a674-f0125d0b2a4a\"},{\"version\":\"8.0.0\",\"type\":\"search\",\"gridData\":{\"x\":0,\"y\":615,\"w\":48,\"h\":111,\"i\":\"8ec9b67a-5d08-4006-bccc-a7341b88bb63\"},\"panelIndex\":\"8ec9b67a-5d08-4006-bccc-a7341b88bb63\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_8ec9b67a-5d08-4006-bccc-a7341b88bb63\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":4,\"y\":852,\"w\":24,\"h\":15,\"i\":\"1201144d-5c9c-4015-89a3-0cb803405986\"},\"panelIndex\":\"1201144d-5c9c-4015-89a3-0cb803405986\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_1201144d-5c9c-4015-89a3-0cb803405986\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":24,\"y\":837,\"w\":24,\"h\":15,\"i\":\"913c1c46-ded4-4e04-81ff-e683f725d3a5\"},\"panelIndex\":\"913c1c46-ded4-4e04-81ff-e683f725d3a5\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_913c1c46-ded4-4e04-81ff-e683f725d3a5\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":867,\"w\":24,\"h\":15,\"i\":\"f49dfd93-ce95-4a65-b9ec-531f340da083\"},\"panelIndex\":\"f49dfd93-ce95-4a65-b9ec-531f340da083\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_f49dfd93-ce95-4a65-b9ec-531f340da083\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":18,\"y\":882,\"w\":24,\"h\":15,\"i\":\"0705993c-492c-4ce0-83e0-a481c90bd432\"},\"panelIndex\":\"0705993c-492c-4ce0-83e0-a481c90bd432\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0705993c-492c-4ce0-83e0-a481c90bd432\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":24,\"y\":897,\"w\":24,\"h\":15,\"i\":\"02de39d3-6839-4198-94e3-cc91f61d0c6e\"},\"panelIndex\":\"02de39d3-6839-4198-94e3-cc91f61d0c6e\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_02de39d3-6839-4198-94e3-cc91f61d0c6e\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":5,\"y\":912,\"w\":24,\"h\":15,\"i\":\"e6b958fa-931f-4358-94fc-07934419066d\"},\"panelIndex\":\"e6b958fa-931f-4358-94fc-07934419066d\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_e6b958fa-931f-4358-94fc-07934419066d\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":927,\"w\":24,\"h\":15,\"i\":\"e6d70fc7-1bdc-4743-9a15-615dff91a5c1\"},\"panelIndex\":\"e6d70fc7-1bdc-4743-9a15-615dff91a5c1\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_e6d70fc7-1bdc-4743-9a15-615dff91a5c1\"},{\"version\":\"8.0.0\",\"type\":\"visualization\",\"gridData\":{\"x\":22,\"y\":942,\"w\":24,\"h\":15,\"i\":\"9db5f35e-ab94-4a5a-8c0f-70bf2aa095aa\"},\"panelIndex\":\"9db5f35e-ab94-4a5a-8c0f-70bf2aa095aa\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_9db5f35e-ab94-4a5a-8c0f-70bf2aa095aa\"},{\"version\":\"8.0.0\",\"type\":\"search\",\"gridData\":{\"x\":0,\"y\":726,\"w\":48,\"h\":111,\"i\":\"e985d8b0-4a76-46d0-af01-3edab5995b97\"},\"panelIndex\":\"e985d8b0-4a76-46d0-af01-3edab5995b97\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_e985d8b0-4a76-46d0-af01-3edab5995b97\"}]", + "refreshInterval": { + "pause": true, + "value": 0 + }, + "timeFrom": "2019-06-01T03:59:54.350Z", + "timeRestore": true, + "timeTo": "2019-08-01T14:52:40.436Z", + "title": "Large Dashboard", + "version": 1 + }, + "coreMigrationVersion": "8.0.0", + "id": "f7192e90-ac3c-11eb-8f24-bffe9ba4af2b", + "migrationVersion": { + "dashboard": "7.14.0" + }, + "references": [ + { + "id": "0a464230-79f0-11ea-ae7f-13c5d6e410a0", + "name": "914ac161-94d4-4d93-a287-c21fca46a974:panel_914ac161-94d4-4d93-a287-c21fca46a974", + "type": "visualization" + }, + { + "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", + "name": "c4cec7d1-97e3-4101-adc4-c3f15102511c:panel_c4cec7d1-97e3-4101-adc4-c3f15102511c", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "09f7de68-0d07-4661-8fda-73ea8b577ac7:panel_09f7de68-0d07-4661-8fda-73ea8b577ac7", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "6c25ca6e-6aa1-4f06-9a96-e83ffd9f52e8:panel_6c25ca6e-6aa1-4f06-9a96-e83ffd9f52e8", + "type": "visualization" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "37764cf9-3c89-454a-bd7e-ae4c242dc624:panel_37764cf9-3c89-454a-bd7e-ae4c242dc624", + "type": "visualization" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "990422fd-a9cf-446f-ba2f-ea9178a7b2e0:panel_990422fd-a9cf-446f-ba2f-ea9178a7b2e0", + "type": "visualization" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "0cdc13ec-2775-4da9-9a47-1e833bb807eb:panel_0cdc13ec-2775-4da9-9a47-1e833bb807eb", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "eee160de-5777-40c8-9c2c-e75f64bf208a:panel_eee160de-5777-40c8-9c2c-e75f64bf208a", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "b36f6a97-5d3d-4fc4-b076-b3e514f8f7bb:panel_b36f6a97-5d3d-4fc4-b076-b3e514f8f7bb", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "2e72acbf-7ade-451e-a5e4-7414f12facf2:panel_2e72acbf-7ade-451e-a5e4-7414f12facf2", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "4119e9b0-5d03-482d-9356-89bb62b6a851:panel_4119e9b0-5d03-482d-9356-89bb62b6a851", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "42b4a37c-8b04-4510-9f27-831355221b65:panel_42b4a37c-8b04-4510-9f27-831355221b65", + "type": "visualization" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "dc676050-d752-4c3e-a1ae-73ef2f1bcdc6:panel_dc676050-d752-4c3e-a1ae-73ef2f1bcdc6", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "6602e0e0-9e66-4e0e-90c1-f66b9c3d2340:panel_6602e0e0-9e66-4e0e-90c1-f66b9c3d2340", + "type": "visualization" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "c9c65725-9b4d-4343-93db-7efa4a7a2d60:panel_c9c65725-9b4d-4343-93db-7efa4a7a2d60", + "type": "visualization" + }, + { + "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", + "name": "69141f9b-5c23-409d-9c96-7f94c243f79e:panel_69141f9b-5c23-409d-9c96-7f94c243f79e", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "6feeec2c-34ab-4844-8445-e417c8e0595b:panel_6feeec2c-34ab-4844-8445-e417c8e0595b", + "type": "visualization" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "985d9dc1-de44-4803-afad-f1d497d050a1:panel_985d9dc1-de44-4803-afad-f1d497d050a1", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "d7ef9e23-d0dd-4c7c-90b3-f611bbfcd1b0:panel_d7ef9e23-d0dd-4c7c-90b3-f611bbfcd1b0", + "type": "visualization" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "6b0768b1-0cd2-47f0-a639-b369e7318d44:panel_6b0768b1-0cd2-47f0-a639-b369e7318d44", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "c9cc2835-06a8-4448-b703-2d41a6692feb:panel_c9cc2835-06a8-4448-b703-2d41a6692feb", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "af2a55b1-8b3d-478a-96b1-72e4f12585e4:panel_af2a55b1-8b3d-478a-96b1-72e4f12585e4", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "ee92986a-adab-4d66-ad4e-a43a608f52f7:panel_ee92986a-adab-4d66-ad4e-a43a608f52f7", + "type": "visualization" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "3b4e1fd0-2acb-444a-b478-42d7bd10b96c:panel_3b4e1fd0-2acb-444a-b478-42d7bd10b96c", + "type": "visualization" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "04d7056d-88a4-4b00-b8f4-33f79f1b6f7a:panel_04d7056d-88a4-4b00-b8f4-33f79f1b6f7a", + "type": "visualization" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "51122bae-427e-45a6-904e-6c821447cc46:panel_51122bae-427e-45a6-904e-6c821447cc46", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "4efab22c-1892-4013-8406-5e5d924a8a21:panel_4efab22c-1892-4013-8406-5e5d924a8a21", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "4c3c1b29-100e-474c-8290-9470684ae407:panel_4c3c1b29-100e-474c-8290-9470684ae407", + "type": "visualization" + }, + { + "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", + "name": "b4501df0-d759-4513-9e87-5dd8eefe4a4f:panel_b4501df0-d759-4513-9e87-5dd8eefe4a4f", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "4fbff0ec-b3a6-4ee7-8734-9b177c3e51c6:panel_4fbff0ec-b3a6-4ee7-8734-9b177c3e51c6", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "13d9982e-2745-44b1-af94-fa4b9f6761a9:panel_13d9982e-2745-44b1-af94-fa4b9f6761a9", + "type": "visualization" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "efa18320-9650-4bfe-9418-ac29b7979f70:panel_efa18320-9650-4bfe-9418-ac29b7979f70", + "type": "visualization" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "1f03bc70-0545-4a3a-bebc-ad477674b841:panel_1f03bc70-0545-4a3a-bebc-ad477674b841", + "type": "visualization" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "d766ce3a-9ec5-4ead-8698-6a2e66e729bb:panel_d766ce3a-9ec5-4ead-8698-6a2e66e729bb", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "de93deb0-6c16-45ae-8fae-de0b2e1c4ae0:panel_de93deb0-6c16-45ae-8fae-de0b2e1c4ae0", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "b93cc5e1-084a-42d9-9958-a3f569573d43:panel_b93cc5e1-084a-42d9-9958-a3f569573d43", + "type": "visualization" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "0b6c380f-3536-4f03-8dbd-95c53be69263:panel_0b6c380f-3536-4f03-8dbd-95c53be69263", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "5c68b67a-ac42-48b8-85de-2409aaa0cdc6:panel_5c68b67a-ac42-48b8-85de-2409aaa0cdc6", + "type": "visualization" + }, + { + "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", + "name": "098a69b8-c9a0-40c8-8703-62838e0ec4a9:panel_098a69b8-c9a0-40c8-8703-62838e0ec4a9", + "type": "visualization" + }, + { + "id": "ef8757d0-7ac2-11ea-b69c-cf0d7935cd67", + "name": "a0f4b9ce-2e36-4d22-8dd9-8988f1a3b883:panel_a0f4b9ce-2e36-4d22-8dd9-8988f1a3b883", + "type": "visualization" + }, + { + "id": "4a36acd0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "eb651411-ea02-4506-a674-f0125d0b2a4a:panel_eb651411-ea02-4506-a674-f0125d0b2a4a", + "type": "visualization" + }, + { + "id": "6091ead0-1c6d-11ea-a100-8589bb9d7c6b", + "name": "8ec9b67a-5d08-4006-bccc-a7341b88bb63:panel_8ec9b67a-5d08-4006-bccc-a7341b88bb63", + "type": "search" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "1201144d-5c9c-4015-89a3-0cb803405986:panel_1201144d-5c9c-4015-89a3-0cb803405986", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "913c1c46-ded4-4e04-81ff-e683f725d3a5:panel_913c1c46-ded4-4e04-81ff-e683f725d3a5", + "type": "visualization" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "f49dfd93-ce95-4a65-b9ec-531f340da083:panel_f49dfd93-ce95-4a65-b9ec-531f340da083", + "type": "visualization" + }, + { + "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", + "name": "0705993c-492c-4ce0-83e0-a481c90bd432:panel_0705993c-492c-4ce0-83e0-a481c90bd432", + "type": "visualization" + }, + { + "id": "132ab9c0-7ac3-11ea-b69c-cf0d7935cd67", + "name": "02de39d3-6839-4198-94e3-cc91f61d0c6e:panel_02de39d3-6839-4198-94e3-cc91f61d0c6e", + "type": "visualization" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "e6b958fa-931f-4358-94fc-07934419066d:panel_e6b958fa-931f-4358-94fc-07934419066d", + "type": "visualization" + }, + { + "id": "1bba55f0-507e-11eb-9c0d-97106882b997", + "name": "e6d70fc7-1bdc-4743-9a15-615dff91a5c1:panel_e6d70fc7-1bdc-4743-9a15-615dff91a5c1", + "type": "visualization" + }, + { + "id": "200609c0-79f0-11ea-ae7f-13c5d6e410a0", + "name": "9db5f35e-ab94-4a5a-8c0f-70bf2aa095aa:panel_9db5f35e-ab94-4a5a-8c0f-70bf2aa095aa", + "type": "visualization" + }, + { + "id": "e5bfe380-ac3e-11eb-8f24-bffe9ba4af2b", + "name": "e985d8b0-4a76-46d0-af01-3edab5995b97:panel_e985d8b0-4a76-46d0-af01-3edab5995b97", + "type": "search" + } + ], + "type": "dashboard", + "updated_at": "2021-05-03T18:39:45.983Z", + "version": "WzI5LDJd" +} \ No newline at end of file diff --git a/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts index bbd212b61e4394..afc6dca936bbfe 100644 --- a/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts +++ b/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts @@ -201,7 +201,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { } = alert; try { expect(actions).to.eql([]); - expect(alertTypeId).to.eql('xpack.uptime.alerts.tls'); + expect(alertTypeId).to.eql('xpack.uptime.alerts.tlsCertificate'); expect(consumer).to.eql('uptime'); expect(tags).to.eql(['uptime', 'certs']); expect(params).to.eql({}); diff --git a/x-pack/test/osquery_cypress/cli_config.ts b/x-pack/test/osquery_cypress/cli_config.ts new file mode 100644 index 00000000000000..d0de73151952db --- /dev/null +++ b/x-pack/test/osquery_cypress/cli_config.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrConfigProviderContext } from '@kbn/test'; + +import { OsqueryCypressCliTestRunner } from './runner'; + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const osqueryCypressConfig = await readConfigFile(require.resolve('./config.ts')); + return { + ...osqueryCypressConfig.getAll(), + + testRunner: OsqueryCypressCliTestRunner, + }; +} diff --git a/x-pack/test/osquery_cypress/config.ts b/x-pack/test/osquery_cypress/config.ts new file mode 100644 index 00000000000000..18b4605fb9d8bf --- /dev/null +++ b/x-pack/test/osquery_cypress/config.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrConfigProviderContext } from '@kbn/test'; + +import { CA_CERT_PATH } from '@kbn/dev-utils'; + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const kibanaCommonTestsConfig = await readConfigFile( + require.resolve('../../../test/common/config.js') + ); + const xpackFunctionalTestsConfig = await readConfigFile( + require.resolve('../functional/config.js') + ); + + return { + ...kibanaCommonTestsConfig.getAll(), + + esTestCluster: { + ...xpackFunctionalTestsConfig.get('esTestCluster'), + serverArgs: [ + ...xpackFunctionalTestsConfig.get('esTestCluster.serverArgs'), + // define custom es server here + // API Keys is enabled at the top level + 'xpack.security.enabled=true', + ], + }, + + kbnTestServer: { + ...xpackFunctionalTestsConfig.get('kbnTestServer'), + serverArgs: [ + ...xpackFunctionalTestsConfig.get('kbnTestServer.serverArgs'), + '--csp.strict=false', + // define custom kibana server args here + `--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`, + ], + }, + }; +} diff --git a/x-pack/test/osquery_cypress/ftr_provider_context.d.ts b/x-pack/test/osquery_cypress/ftr_provider_context.d.ts new file mode 100644 index 00000000000000..aa56557c09df82 --- /dev/null +++ b/x-pack/test/osquery_cypress/ftr_provider_context.d.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { GenericFtrProviderContext } from '@kbn/test'; + +import { services } from './services'; + +export type FtrProviderContext = GenericFtrProviderContext; diff --git a/x-pack/test/osquery_cypress/runner.ts b/x-pack/test/osquery_cypress/runner.ts new file mode 100644 index 00000000000000..32c84af5faf76d --- /dev/null +++ b/x-pack/test/osquery_cypress/runner.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { resolve } from 'path'; +import Url from 'url'; + +import { withProcRunner } from '@kbn/dev-utils'; + +import { FtrProviderContext } from './ftr_provider_context'; + +export async function OsqueryCypressCliTestRunner({ getService }: FtrProviderContext) { + const log = getService('log'); + const config = getService('config'); + + await withProcRunner(log, async (procs) => { + await procs.run('cypress', { + cmd: 'yarn', + args: ['cypress:run'], + cwd: resolve(__dirname, '../../plugins/osquery'), + env: { + FORCE_COLOR: '1', + // eslint-disable-next-line @typescript-eslint/naming-convention + CYPRESS_baseUrl: Url.format(config.get('servers.kibana')), + // eslint-disable-next-line @typescript-eslint/naming-convention + CYPRESS_protocol: config.get('servers.kibana.protocol'), + // eslint-disable-next-line @typescript-eslint/naming-convention + CYPRESS_hostname: config.get('servers.kibana.hostname'), + // eslint-disable-next-line @typescript-eslint/naming-convention + CYPRESS_configport: config.get('servers.kibana.port'), + CYPRESS_ELASTICSEARCH_URL: Url.format(config.get('servers.elasticsearch')), + CYPRESS_ELASTICSEARCH_USERNAME: config.get('servers.elasticsearch.username'), + CYPRESS_ELASTICSEARCH_PASSWORD: config.get('servers.elasticsearch.password'), + CYPRESS_KIBANA_URL: Url.format({ + protocol: config.get('servers.kibana.protocol'), + hostname: config.get('servers.kibana.hostname'), + port: config.get('servers.kibana.port'), + }), + ...process.env, + }, + wait: true, + }); + }); +} + +export async function OsqueryCypressVisualTestRunner({ getService }: FtrProviderContext) { + const log = getService('log'); + const config = getService('config'); + + await withProcRunner(log, async (procs) => { + await procs.run('cypress', { + cmd: 'yarn', + args: ['cypress:open'], + cwd: resolve(__dirname, '../../plugins/osquery'), + env: { + FORCE_COLOR: '1', + // eslint-disable-next-line @typescript-eslint/naming-convention + CYPRESS_baseUrl: Url.format(config.get('servers.kibana')), + // eslint-disable-next-line @typescript-eslint/naming-convention + CYPRESS_protocol: config.get('servers.kibana.protocol'), + // eslint-disable-next-line @typescript-eslint/naming-convention + CYPRESS_hostname: config.get('servers.kibana.hostname'), + // eslint-disable-next-line @typescript-eslint/naming-convention + CYPRESS_configport: config.get('servers.kibana.port'), + CYPRESS_ELASTICSEARCH_URL: Url.format(config.get('servers.elasticsearch')), + CYPRESS_ELASTICSEARCH_USERNAME: config.get('servers.elasticsearch.username'), + CYPRESS_ELASTICSEARCH_PASSWORD: config.get('servers.elasticsearch.password'), + CYPRESS_KIBANA_URL: Url.format({ + protocol: config.get('servers.kibana.protocol'), + hostname: config.get('servers.kibana.hostname'), + port: config.get('servers.kibana.port'), + }), + ...process.env, + }, + wait: true, + }); + }); +} diff --git a/x-pack/test/osquery_cypress/services.ts b/x-pack/test/osquery_cypress/services.ts new file mode 100644 index 00000000000000..5e063134081ad2 --- /dev/null +++ b/x-pack/test/osquery_cypress/services.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from '../../../test/common/services'; diff --git a/x-pack/test/osquery_cypress/visual_config.ts b/x-pack/test/osquery_cypress/visual_config.ts new file mode 100644 index 00000000000000..35ffe311fdc27c --- /dev/null +++ b/x-pack/test/osquery_cypress/visual_config.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrConfigProviderContext } from '@kbn/test'; + +import { OsqueryCypressVisualTestRunner } from './runner'; + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const osqueryCypressConfig = await readConfigFile(require.resolve('./config.ts')); + return { + ...osqueryCypressConfig.getAll(), + + testRunner: OsqueryCypressVisualTestRunner, + }; +} diff --git a/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx b/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx index a6772c3b0bb5be..084b79d6a32b30 100644 --- a/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx +++ b/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx @@ -11,7 +11,7 @@ import ReactDOM from 'react-dom'; import { AppMountParameters, CoreStart } from 'kibana/public'; import { I18nProvider } from '@kbn/i18n/react'; import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public'; -import { TimelinesPluginSetup } from '../../../../../../../plugins/timelines/public'; +import { TimelinesUIStart } from '../../../../../../../plugins/timelines/public'; /** * Render the Timeline Test app. Returns a cleanup function. @@ -19,7 +19,7 @@ import { TimelinesPluginSetup } from '../../../../../../../plugins/timelines/pub export function renderApp( coreStart: CoreStart, parameters: AppMountParameters, - timelinesPluginSetup: TimelinesPluginSetup + timelinesPluginSetup: TimelinesUIStart | null ) { ReactDOM.render( { return ( - {(timelinesPluginSetup.getTimeline && - timelinesPluginSetup.getTimeline({ timelineId: 'test' })) ?? + {(timelinesPluginSetup && + timelinesPluginSetup.getTGrid && + timelinesPluginSetup.getTGrid<'standalone'>({ + type: 'standalone', + columns: [], + indexNames: [], + deletedEventIds: [], + filters: [], + itemsPerPage: 50, + itemsPerPageOptions: [1, 2, 3], + end: '', + renderCellValue: () =>
test
, + sort: [], + leadingControlColumns: [], + trailingControlColumns: [], + query: { + query: '', + language: 'kuery', + }, + start: '', + rowRenderers: [], + })) ?? null}
diff --git a/x-pack/test/plugin_functional/plugins/timelines_test/public/plugin.ts b/x-pack/test/plugin_functional/plugins/timelines_test/public/plugin.ts index 5cf900e194d0c1..b3b9c7ecbf6e01 100644 --- a/x-pack/test/plugin_functional/plugins/timelines_test/public/plugin.ts +++ b/x-pack/test/plugin_functional/plugins/timelines_test/public/plugin.ts @@ -5,19 +5,19 @@ * 2.0. */ -import { Plugin, CoreSetup, AppMountParameters } from 'kibana/public'; +import { Plugin, CoreStart, CoreSetup, AppMountParameters } from 'kibana/public'; import { i18n } from '@kbn/i18n'; -import { TimelinesPluginSetup } from '../../../../../plugins/timelines/public'; +import { TimelinesUIStart } from '../../../../../plugins/timelines/public'; import { renderApp } from './applications/timelines_test'; export type TimelinesTestPluginSetup = void; export type TimelinesTestPluginStart = void; -export interface TimelinesTestPluginSetupDependencies { - timelines: TimelinesPluginSetup; -} - // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface TimelinesTestPluginStartDependencies {} +export interface TimelinesTestPluginSetupDependencies {} + +export interface TimelinesTestPluginStartDependencies { + timelines: TimelinesUIStart; +} export class TimelinesTestPlugin implements @@ -27,6 +27,7 @@ export class TimelinesTestPlugin TimelinesTestPluginSetupDependencies, TimelinesTestPluginStartDependencies > { + private timelinesPlugin: TimelinesUIStart | null = null; public setup( core: CoreSetup, setupDependencies: TimelinesTestPluginSetupDependencies @@ -39,12 +40,12 @@ export class TimelinesTestPlugin mount: async (params: AppMountParameters) => { const startServices = await core.getStartServices(); const [coreStart] = startServices; - const { timelines } = setupDependencies; - - return renderApp(coreStart, params, timelines); + return renderApp(coreStart, params, this.timelinesPlugin); }, }); } - public start() {} + public start(core: CoreStart, { timelines }: TimelinesTestPluginStartDependencies) { + this.timelinesPlugin = timelines; + } } diff --git a/x-pack/test/plugin_functional/test_suites/timelines/index.ts b/x-pack/test/plugin_functional/test_suites/timelines/index.ts index 655ed9dc3898a5..2ca8d81132ab3e 100644 --- a/x-pack/test/plugin_functional/test_suites/timelines/index.ts +++ b/x-pack/test/plugin_functional/test_suites/timelines/index.ts @@ -18,7 +18,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await pageObjects.common.navigateToApp('timelineTest'); }); it('shows the timeline component on navigation', async () => { - await testSubjects.existOrFail('timeline-wrapper'); + await testSubjects.existOrFail('events-viewer-panel'); }); }); }); diff --git a/x-pack/test/reporting_api_integration/services/scenarios.ts b/x-pack/test/reporting_api_integration/services/scenarios.ts index bfbf030b0887a1..e45af4bd140b02 100644 --- a/x-pack/test/reporting_api_integration/services/scenarios.ts +++ b/x-pack/test/reporting_api_integration/services/scenarios.ts @@ -22,8 +22,10 @@ export function createScenarios({ getService }: Pick { await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.load(ecommerceSOPath); }; const teardownEcommerce = async () => { await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce'); - await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.unload(ecommerceSOPath); await deleteAllReports(); }; diff --git a/x-pack/test/reporting_functional/reporting_without_security/management.ts b/x-pack/test/reporting_functional/reporting_without_security/management.ts index 030c890c963b15..a97cb211b7c0e9 100644 --- a/x-pack/test/reporting_functional/reporting_without_security/management.ts +++ b/x-pack/test/reporting_functional/reporting_without_security/management.ts @@ -14,10 +14,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const PageObjects = getPageObjects(['common', 'reporting']); const log = getService('log'); const supertest = getService('supertestWithoutAuth'); - + const kibanaServer = getService('kibanaServer'); const testSubjects = getService('testSubjects'); const esArchiver = getService('esArchiver'); const reportingApi = getService('reportingAPI'); + const ecommerceSOPath = 'x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json'; const postJobJSON = async ( apiPath: string, @@ -31,12 +32,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('Polling for jobs', () => { beforeEach(async () => { await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'); - await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.load(ecommerceSOPath); }); afterEach(async () => { await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana'); - await esArchiver.unload('x-pack/test/functional/es_archives/reporting/ecommerce_kibana'); + await kibanaServer.importExport.unload(ecommerceSOPath); await reportingApi.deleteAllReports(); }); diff --git a/x-pack/yarn.lock b/x-pack/yarn.lock new file mode 100644 index 00000000000000..def2ba279bfff5 --- /dev/null +++ b/x-pack/yarn.lock @@ -0,0 +1,31 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@kbn/interpreter@link:../packages/kbn-interpreter": + version "0.0.0" + uid "" + +"@kbn/optimizer@link:../packages/kbn-optimizer": + version "0.0.0" + uid "" + +"@kbn/plugin-helpers@link:../packages/kbn-plugin-helpers": + version "0.0.0" + uid "" + +"@kbn/storybook@link:../packages/kbn-storybook": + version "0.0.0" + uid "" + +"@kbn/test@link:../packages/kbn-test": + version "0.0.0" + uid "" + +"@kbn/ui-framework@link:../packages/kbn-ui-framework": + version "0.0.0" + uid "" + +"@kbn/ui-shared-deps@link:../packages/kbn-ui-shared-deps": + version "0.0.0" + uid "" diff --git a/yarn.lock b/yarn.lock index 953e7907590e77..7b0cd4dfe67acd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2692,7 +2692,7 @@ version "0.0.0" uid "" -"@kbn/optimizer@link:packages/kbn-optimizer": +"@kbn/optimizer@link:bazel-bin/packages/kbn-optimizer": version "0.0.0" uid "" @@ -2752,6 +2752,10 @@ version "0.0.0" uid "" +"@kbn/securitysolution-t-grid@link:bazel-bin/packages/kbn-securitysolution-t-grid": + version "0.0.0" + uid "" + "@kbn/securitysolution-utils@link:bazel-bin/packages/kbn-securitysolution-utils": version "0.0.0" uid "" @@ -4818,6 +4822,18 @@ resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-1.2.7.tgz#34dc654d34fc058c41c31dbca1ed68071a8fcc17" integrity sha512-51vHWuUyDOi+8XuwPrTw3cFqyh2Slg9y8COYkRfjCPG9TfYqY0hoNPzv/8BrcAy0FeQBzqEo/D/8Nk2caOQJnA== +"@types/d3-color@*": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-2.0.1.tgz#570ea7f8b853461301804efa52bd790a640a26db" + integrity sha512-u7LTCL7RnaavFSmob2rIAJLNwu50i6gFwY9cHFr80BrQURYQBRkJ+Yv47nA3Fm7FeRhdWTiVTeqvSeOuMAOzBQ== + +"@types/d3-interpolate@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-2.0.0.tgz#325029216dc722c1c68c33ccda759f1209d35823" + integrity sha512-Wt1v2zTlEN8dSx8hhx6MoOhWQgTkz0Ukj7owAEIOF2QtI0e219paFX9rf/SLOr/UExWb1TcUzatU8zWwFby6gg== + dependencies: + "@types/d3-color" "*" + "@types/d3-path@*": version "1.0.7" resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.7.tgz#a0736fceed688a695f48265a82ff7a3369414b81" @@ -10877,7 +10893,7 @@ d3-array@>=2.5, d3-array@^2.3.0, d3-array@^2.7.1: resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.8.0.tgz#f76e10ad47f1f4f75f33db5fc322eb9ffde5ef23" integrity sha512-6V272gsOeg7+9pTW1jSYOR1QE37g95I3my1hBmY+vOUNHRrk9yt4OTz/gK7PMkVAVDrYYq4mq3grTiZ8iJdNIw== -d3-cloud@^1.2.5: +d3-cloud@1.2.5, d3-cloud@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/d3-cloud/-/d3-cloud-1.2.5.tgz#3e91564f2d27fba47fcc7d812eb5081ea24c603d" integrity sha512-4s2hXZgvs0CoUIw31oBAGrHt9Kt/7P9Ik5HIVzISFiWkD0Ga2VLAuO/emO/z1tYIpE7KG2smB4PhMPfFMJpahw== @@ -10894,6 +10910,11 @@ d3-color@1, "d3-color@1 - 2", d3-color@^1.0.3, d3-color@^1.4.0: resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== +"d3-color@1 - 3": + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.0.1.tgz#03316e595955d1fcd39d9f3610ad41bb90194d0a" + integrity sha512-6/SlHkDOBLyQSJ1j1Ghs82OIUXpKWlR0hCsw0XrLSQhuUPuCSmLQ1QPH98vpnQxMUQM2/gfAkUEWsupVpd9JGw== + d3-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" @@ -11008,6 +11029,13 @@ d3-interpolate@^2.0.1: dependencies: d3-color "1 - 2" +d3-interpolate@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + d3-path@1: version "1.0.9" resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf"