diff --git a/.eslintrc.js b/.eslintrc.js index b12dc63066370..08af34d24e7f5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1242,132 +1242,6 @@ module.exports = { }, }, - /** - * Metrics entities overrides. These rules below are maintained and owned by - * the people within the security-solution-platform team. Please see ping them - * or check with them if you are encountering issues, have suggestions, or would - * like to add, change, or remove any particular rule. Linters, Typescript, and rules - * evolve and change over time just like coding styles, so please do not hesitate to - * reach out. - */ - { - // front end and common typescript and javascript files only - files: [ - 'x-pack/plugins/metrics_entities/public/**/*.{js,mjs,ts,tsx}', - 'x-pack/plugins/metrics_entities/common/**/*.{js,mjs,ts,tsx}', - ], - rules: { - 'import/no-nodejs-modules': 'error', - 'no-restricted-imports': [ - 'error', - { - // prevents UI code from importing server side code and then webpack including it when doing builds - patterns: ['**/server/*'], - }, - ], - }, - }, - { - // typescript and javascript for front and back end - files: ['x-pack/plugins/metrics_entities/**/*.{js,mjs,ts,tsx}'], - plugins: ['eslint-plugin-node'], - env: { - jest: true, - }, - rules: { - 'accessor-pairs': 'error', - 'array-callback-return': 'error', - 'no-array-constructor': 'error', - complexity: 'error', - 'consistent-return': 'error', - 'func-style': ['error', 'expression'], - 'import/order': [ - 'error', - { - groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'], - 'newlines-between': 'always', - }, - ], - 'sort-imports': [ - 'error', - { - ignoreDeclarationSort: true, - }, - ], - 'node/no-deprecated-api': 'error', - 'no-bitwise': 'error', - 'no-continue': 'error', - 'no-dupe-keys': 'error', - 'no-duplicate-case': 'error', - 'no-duplicate-imports': 'error', - 'no-empty-character-class': 'error', - 'no-empty-pattern': 'error', - 'no-ex-assign': 'error', - 'no-extend-native': 'error', - 'no-extra-bind': 'error', - 'no-extra-boolean-cast': 'error', - 'no-extra-label': 'error', - 'no-func-assign': 'error', - 'no-implicit-globals': 'error', - 'no-implied-eval': 'error', - 'no-invalid-regexp': 'error', - 'no-inner-declarations': 'error', - 'no-lone-blocks': 'error', - 'no-multi-assign': 'error', - 'no-misleading-character-class': 'error', - 'no-new-symbol': 'error', - 'no-obj-calls': 'error', - 'no-param-reassign': ['error', { props: true }], - 'no-process-exit': 'error', - 'no-prototype-builtins': 'error', - 'no-return-await': 'error', - 'no-self-compare': 'error', - 'no-shadow-restricted-names': 'error', - 'no-sparse-arrays': 'error', - 'no-this-before-super': 'error', - // rely on typescript - 'no-undef': 'off', - 'no-unreachable': 'error', - 'no-unsafe-finally': 'error', - 'no-useless-call': 'error', - 'no-useless-catch': 'error', - 'no-useless-concat': 'error', - 'no-useless-computed-key': 'error', - 'no-useless-escape': 'error', - 'no-useless-rename': 'error', - 'no-useless-return': 'error', - 'no-void': 'error', - 'one-var-declaration-per-line': 'error', - 'prefer-object-spread': 'error', - 'prefer-promise-reject-errors': 'error', - 'prefer-rest-params': 'error', - 'prefer-spread': 'error', - 'prefer-template': 'error', - 'require-atomic-updates': 'error', - 'symbol-description': 'error', - 'vars-on-top': 'error', - '@typescript-eslint/explicit-member-accessibility': 'error', - '@typescript-eslint/no-this-alias': 'error', - '@typescript-eslint/no-explicit-any': 'error', - '@typescript-eslint/no-useless-constructor': 'error', - '@typescript-eslint/unified-signatures': 'error', - '@typescript-eslint/explicit-function-return-type': 'error', - '@typescript-eslint/no-non-null-assertion': 'error', - '@typescript-eslint/no-unused-vars': 'error', - 'no-template-curly-in-string': 'error', - 'sort-keys': 'error', - 'prefer-destructuring': 'error', - 'no-restricted-imports': [ - 'error', - { - // prevents code from importing files that contain the name "legacy" within their name. This is a mechanism - // to help deprecation and prevent accidental re-use/continued use of code we plan on removing. If you are - // finding yourself turning this off a lot for "new code" consider renaming the file and functions if it has valid uses. - patterns: ['*legacy*'], - }, - ], - }, - }, /** * Alerting Services overrides */ diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3c991e6a61d53..b846bc0801870 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -394,7 +394,6 @@ /x-pack/test/plugin_functional/plugins/resolver_test/ @elastic/security-solution /x-pack/test/plugin_functional/test_suites/resolver/ @elastic/security-solution /x-pack/plugins/security_solution/ @elastic/security-solution -/x-pack/plugins/metrics_entities/ @elastic/security-solution /x-pack/test/detection_engine_api_integration @elastic/security-solution /x-pack/test/lists_api_integration @elastic/security-solution /x-pack/test/api_integration/apis/security_solution @elastic/security-solution diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 04b21bf737815..e96f1cd819186 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -524,12 +524,6 @@ using the CURL scripts in the scripts folder. |Visualize geo data from Elasticsearch or 3rd party geo-services. -|{kib-repo}blob/{branch}/x-pack/plugins/metrics_entities/README.md[metricsEntities] -|This is the metrics and entities plugin where you add can add transforms for your project -and group those transforms into modules. You can also re-use existing transforms in your -newly created modules as well. - - |{kib-repo}blob/{branch}/x-pack/plugins/ml/readme.md[ml] |This plugin provides access to the machine learning features provided by Elastic. diff --git a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts index 25bc59bf78458..12074bf493218 100644 --- a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts +++ b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts @@ -76,7 +76,6 @@ it('produces the right watch and ignore list', () => { /x-pack/plugins/lists/server/scripts, /x-pack/plugins/security_solution/scripts, /x-pack/plugins/security_solution/server/lib/detection_engine/scripts, - /x-pack/plugins/metrics_entities/server/scripts, /x-pack/plugins/uptime/e2e, ] `); diff --git a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts index acfc9aeecdc80..8f2363b398d6e 100644 --- a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts +++ b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts @@ -66,7 +66,6 @@ export function getServerWatchPaths({ pluginPaths, pluginScanDirs }: Options) { fromRoot('x-pack/plugins/lists/server/scripts'), fromRoot('x-pack/plugins/security_solution/scripts'), fromRoot('x-pack/plugins/security_solution/server/lib/detection_engine/scripts'), - fromRoot('x-pack/plugins/metrics_entities/server/scripts'), fromRoot('x-pack/plugins/uptime/e2e'), ]; diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index fe2f3dea0017a..3960cdd76a761 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -38,7 +38,6 @@ "xpack.logstash": ["plugins/logstash"], "xpack.main": "legacy/plugins/xpack_main", "xpack.maps": ["plugins/maps"], - "xpack.metricsEntities": "plugins/metrics_entities", "xpack.ml": ["plugins/ml"], "xpack.monitoring": ["plugins/monitoring"], "xpack.osquery": ["plugins/osquery"], diff --git a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts index d6fc1bfec8058..85dbd76e7b7c4 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts @@ -96,13 +96,34 @@ import { findExceptionListsItemPointInTimeFinder } from './find_exception_list_i import { findValueListExceptionListItemsPointInTimeFinder } from './find_value_list_exception_list_items_point_in_time_finder'; import { findExceptionListItemPointInTimeFinder } from './find_exception_list_item_point_in_time_finder'; +/** + * Class for use for exceptions that are with trusted applications or + * with rules. + */ export class ExceptionListClient { + /** User creating, modifying, deleting, or updating an exception list */ private readonly user: string; + + /** Saved objects client to create, modify, delete, an exception list */ private readonly savedObjectsClient: SavedObjectsClientContract; + + /** server extensions client that can be useful for injecting domain specific rules */ private readonly serverExtensionsClient: ExtensionPointStorageClientInterface; + + /** Set to true to enable the server extension points, otherwise false */ private readonly enableServerExtensionPoints: boolean; + + /** Optionally, the Kibana request which is useful for extension points */ private readonly request?: KibanaRequest; + /** + * Constructs the exception list + * @param options + * @param options.user The user associated with the action for exception list + * @param options.savedObjectsClient The saved objects client to create, modify, delete, an exception list + * @param options.serverExtensionsClient The server extensions client that can be useful for injecting domain specific rules + * @param options.request optionally, the Kibana request which is useful for extension points + */ constructor({ user, savedObjectsClient, @@ -142,10 +163,11 @@ export class ExceptionListClient { /** * Fetch an exception list parent container - * @params listId {string | undefined} the "list_id" of an exception list - * @params id {string | undefined} the "id" of an exception list - * @params namespaceType {string | undefined} saved object namespace (single | agnostic) - * @return {ExceptionListSchema | null} the found exception list or null if none exists + * @param options + * @param options.listId the "list_id" of an exception list + * @param options.id the "id" of an exception list + * @param options.namespaceType saved object namespace (single | agnostic) + * @returns The found exception list or null if none exists */ public getExceptionList = async ({ listId, @@ -158,11 +180,12 @@ export class ExceptionListClient { /** * Fetch an exception list parent container - * @params filter {sting | undefined} kql "filter" expression - * @params listId {string | undefined} the "list_id" of an exception list - * @params id {string | undefined} the "id" of an exception list - * @params namespaceType {string | undefined} saved object namespace (single | agnostic) - * @return {ExceptionListSummarySchema | null} summary of exception list item os types + * @param options + * @param options.filter kql "filter" expression + * @param options.listId the "list_id" of an exception list + * @param options.id the "id" of an exception list + * @param options.namespaceType saved object namespace (single | agnostic) + * @returns Summary of exception list item os types */ public getExceptionListSummary = async ({ filter, @@ -190,10 +213,11 @@ export class ExceptionListClient { /** * Fetch an exception list item container - * @params listId {string | undefined} the "list_id" of an exception list - * @params id {string | undefined} the "id" of an exception list - * @params namespaceType {string | undefined} saved object namespace (single | agnostic) - * @return {ExceptionListSummarySchema | null} the found exception list item or null if none exists + * @param options + * @param options.itemId the "item_id" of an exception list (Either this or id has to be defined) + * @param options.id the "id" of an exception list (Either this or itemId has to be defined) + * @param options.namespaceType saved object namespace (single | agnostic) + * @returns the found exception list item or null if none exists */ public getExceptionListItem = async ({ itemId, @@ -230,6 +254,7 @@ export class ExceptionListClient { /** * Create the Trusted Apps Agnostic list if it does not yet exist (`null` is returned if it does exist) + * @returns The exception list schema or null if it does not exist */ public createTrustedAppsList = async (): Promise => { const { savedObjectsClient, user } = this; @@ -244,6 +269,17 @@ export class ExceptionListClient { * This is the same as "createListItem" except it applies specifically to the agnostic endpoint list and will * auto-call the "createEndpointList" for you so that you have the best chance of the agnostic endpoint * being there and existing before the item is inserted into the agnostic endpoint list. + * @param options + * @param options.comments The comments of the endpoint list item + * @param options.description The description of the endpoint list item + * @param options.entries The entries of the endpoint list item + * @param options.itemId The item id of the list item + * @param options.meta Optional meta data of the list item + * @param options.name The name of the list item + * @param options.osTypes The OS type of the list item + * @param options.tags Tags of the endpoint list item + * @param options.type The type of the endpoint list item (Default is "simple") + * @returns The exception list item created, otherwise null if not created */ public createEndpointListItem = async ({ comments, @@ -280,6 +316,19 @@ export class ExceptionListClient { * auto-call the "createEndpointList" for you so that you have the best chance of the endpoint * being there if it did not exist before. If the list did not exist before, then creating it here will still cause a * return of null but at least the list exists again. + * @param options + * @param options._version The version to update the endpoint list item to + * @param options.comments The comments of the endpoint list item + * @param options.description The description of the endpoint list item + * @param options.entries The entries of the endpoint list item + * @param options.id The id of the list item (Either this or itemId has to be defined) + * @param options.itemId The item id of the list item (Either this or id has to be defined) + * @param options.meta Optional meta data of the list item + * @param options.name The name of the list item + * @param options.osTypes The OS type of the list item + * @param options.tags Tags of the endpoint list item + * @param options.type The type of the endpoint list item (Default is "simple") + * @returns The exception list item updated, otherwise null if not updated */ public updateEndpointListItem = async ({ _version, @@ -316,6 +365,10 @@ export class ExceptionListClient { /** * This is the same as "getExceptionListItem" except it applies specifically to the endpoint list. + * @param options + * @param options.itemId The item id (Either this or id has to be defined) + * @param options.id The id (Either this or itemId has to be defined) + * @returns The exception list item found, otherwise null */ public getEndpointListItem = async ({ itemId, @@ -327,16 +380,17 @@ export class ExceptionListClient { /** * Create an exception list container - * @params description {string} a description of the exception list - * @params immutable {boolean} a description of the exception list - * @params listId {string} the "list_id" of the exception list - * @params meta {object | undefined} - * @params name {string} the "name" of the exception list - * @params namespaceType {string} saved object namespace (single | agnostic) - * @params tags {array} user assigned tags of exception list - * @params type {string} container type - * @params version {number} document version - * @return {ExceptionListSchema} the created exception list parent container + * @param options + * @param options.description a description of the exception list + * @param options.immutable True if it's a immutable list, otherwise false + * @param options.listId the "list_id" of the exception list + * @param options.meta Optional meta data to add to the exception list + * @param options.name the "name" of the exception list + * @param options.namespaceType saved object namespace (single | agnostic) + * @param options.tags user assigned tags of exception list + * @param options.type container type + * @param options.version document version + * @returns the created exception list parent container */ public createExceptionList = async ({ description, @@ -367,17 +421,18 @@ export class ExceptionListClient { /** * Update an existing exception list container - * @params _version {string | undefined} document version - * @params id {string | undefined} the "id" of the exception list - * @params description {string | undefined} a description of the exception list - * @params listId {string | undefined} the "list_id" of the exception list - * @params meta {object | undefined} - * @params name {string | undefined} the "name" of the exception list - * @params namespaceType {string} saved object namespace (single | agnostic) - * @params tags {array | undefined} user assigned tags of exception list - * @params type {string | undefined} container type - * @params version {number | undefined} document version - * @return {ExceptionListSchema | null} the updated exception list parent container + * @param options + * @param options._version document version + * @param options.id the "id" of the exception list + * @param options.description a description of the exception list + * @param options.listId the "list_id" of the exception list + * @param options.meta Optional meta object + * @param options.name the "name" of the exception list + * @param options.namespaceType saved object namespace (single | agnostic) + * @param options.tags user assigned tags of exception list + * @param options.type container type + * @param options.version document version, if undefined the current version number will be auto-incremented + * @returns the updated exception list parent container */ public updateExceptionList = async ({ _version, @@ -410,10 +465,11 @@ export class ExceptionListClient { /** * Delete an exception list container by either id or list_id - * @params listId {string | undefined} the "list_id" of an exception list - * @params id {string | undefined} the "id" of an exception list - * @params namespaceType {string} saved object namespace (single | agnostic) - * @return {ExceptionListSchema | null} the deleted exception list or null if none exists + * @param options + * @param options.listId the "list_id" of an exception list (Either this or id has to be defined) + * @param options.id the "id" of an exception list (Either this or listId has to be defined) + * @param options.namespaceType saved object namespace (single | agnostic) + * @returns the deleted exception list or null if none exists */ public deleteExceptionList = async ({ id, @@ -431,17 +487,19 @@ export class ExceptionListClient { /** * Create an exception list item container - * @params description {string} a description of the exception list - * @params entries {array} an array with the exception list item entries - * @params itemId {string} the "item_id" of the exception list item - * @params listId {string} the "list_id" of the parent exception list - * @params meta {object | undefined} - * @params name {string} the "name" of the exception list - * @params namespaceType {string} saved object namespace (single | agnostic) - * @params osTypes {array} item os types to apply - * @params tags {array} user assigned tags of exception list - * @params type {string} container type - * @return {ExceptionListItemSchema} the created exception list item container + * @param options + * @param options.comments User comments for the exception list item + * @param options.description a description of the exception list + * @param options.entries an array with the exception list item entries + * @param options.itemId the "item_id" of the exception list item + * @param options.listId the "list_id" of the parent exception list + * @param options.meta Optional meta data about the list item + * @param options.name the "name" of the exception list + * @param options.namespaceType saved object namespace (single | agnostic) + * @param options.osTypes item os types to apply + * @param options.tags user assigned tags of exception list + * @param options.type container type + * @returns the created exception list item container */ public createExceptionListItem = async ({ comments, @@ -494,19 +552,20 @@ export class ExceptionListClient { /** * Update an existing exception list item - * @params _version {string | undefined} document version - * @params comments {array} user comments attached to item - * @params entries {array} item exception entries logic - * @params id {string | undefined} the "id" of the exception list item - * @params description {string | undefined} a description of the exception list - * @params itemId {string | undefined} the "item_id" of the exception list item - * @params meta {object | undefined} - * @params name {string | undefined} the "name" of the exception list - * @params namespaceType {string} saved object namespace (single | agnostic) - * @params osTypes {array} item os types to apply - * @params tags {array | undefined} user assigned tags of exception list - * @params type {string | undefined} container type - * @return {ExceptionListItemSchema | null} the updated exception list item or null if none exists + * @param options + * @param options._version document version + * @param options.comments user comments attached to item + * @param options.entries item exception entries logic + * @param options.id the "id" of the exception list item + * @param options.description a description of the exception list + * @param options.itemId the "item_id" of the exception list item + * @param options.meta Optional meta data about the exception list item + * @param options.name the "name" of the exception list + * @param options.namespaceType saved object namespace (single | agnostic) + * @param options.osTypes item os types to apply + * @param options.tags user assigned tags of exception list + * @param options.type container type + * @returns the updated exception list item or null if none exists */ public updateExceptionListItem = async ({ _version, @@ -561,10 +620,11 @@ export class ExceptionListClient { /** * Delete an exception list item by either id or item_id - * @params itemId {string | undefined} the "item_id" of an exception list item - * @params id {string | undefined} the "id" of an exception list item - * @params namespaceType {string} saved object namespace (single | agnostic) - * @return {ExceptionListItemSchema | null} the deleted exception list item or null if none exists + * @param options + * @param options.itemId the "item_id" of an exception list item (Either this or id has to be defined) + * @param options.id the "id" of an exception list item (Either this or itemId has to be defined) + * @param options.namespaceType saved object namespace (single | agnostic) + * @returns the deleted exception list item or null if none exists */ public deleteExceptionListItem = async ({ id, @@ -591,9 +651,9 @@ export class ExceptionListClient { /** * Delete an exception list item by id - * @params id {string | undefined} the "id" of an exception list item - * @params namespaceType {string} saved object namespace (single | agnostic) - * @return {void} + * @param options + * @param options.id the "id" of an exception list item + * @param options.namespaceType saved object namespace (single | agnostic) */ public deleteExceptionListItemById = async ({ id, @@ -618,6 +678,11 @@ export class ExceptionListClient { /** * This is the same as "deleteExceptionListItem" except it applies specifically to the endpoint list. + * Either id or itemId has to be defined to delete but not both is required. If both are provided, the id + * is preferred. + * @param options + * @param options.id The id of the endpoint list item (Either this or itemId has to be defined) + * @param options.itemId The item id of the endpoint list item (Either this or id has to be defined) */ public deleteEndpointListItem = async ({ id, @@ -632,6 +697,20 @@ export class ExceptionListClient { }); }; + /** + * Finds an exception list item given a set of criteria. + * @param options + * @param options.listId The single list id to do the search against + * @param options.filter The filter to apply in the search + * @param options.perPage How many per page to return + * @param options.pit The Point in Time (pit) id if there is one, otherwise "undefined" can be send in + * @param options.page The page number or "undefined" if there is no page number to continue from + * @param options.searchAfter The search_after parameter if there is one, otherwise "undefined" can be sent in + * @param options.sortField The sort field string if there is one, otherwise "undefined" can be sent in + * @param options.sortOder The sort order string of "asc", "desc", otherwise "undefined" if there is no preference + * @param options.namespaceType Set the list type of either "agnostic" | "single" + * @returns The found exception list items or null if nothing is found + */ public findExceptionListItem = async ({ listId, filter, @@ -677,6 +756,20 @@ export class ExceptionListClient { }); }; + /** + * Finds exception lists items given a set of criteria. + * @param options + * @param options.listId The multiple list id's to do the search against + * @param options.filter The filter to apply in the search + * @param options.perPage How many per page to return + * @param options.pit The Point in Time (pit) id if there is one, otherwise "undefined" can be sent in + * @param options.page The page number or "undefined" if there is no page number to continue from + * @param options.searchAfter The search_after parameter if there is one, otherwise "undefined" can be sent in + * @param options.sortField The sort field string if there is one, otherwise "undefined" can be sent in + * @param options.sortOder The sort order string of "asc", "desc", otherwise "undefined" if there is no preference + * @param options.namespaceType Set the list type of either "agnostic" | "single" + * @returns The found exception lists items or null if nothing is found + */ public findExceptionListsItem = async ({ listId, filter, @@ -722,6 +815,18 @@ export class ExceptionListClient { }); }; + /** + * Finds value list exception items given a set of criteria. + * @param options + * @param options.perPage How many per page to return + * @param options.pit The Point in Time (pit) id if there is one, otherwise "undefined" can be send in + * @param options.page The page number or "undefined" if there is no page number to continue from + * @param options.searchAfter The search_after parameter if there is one, otherwise "undefined" can be sent in + * @param options.sortField The sort field string if there is one, otherwise "undefined" can be sent in + * @param options.sortOrder The sort order of "asc" or "desc", otherwise "undefined" can be sent in if there is no preference + * @param options.valueListId The value list id + * @returns The found value list exception list item or null if nothing is found + */ public findValueListExceptionListItems = async ({ perPage, pit, @@ -744,6 +849,19 @@ export class ExceptionListClient { }); }; + /** + * Finds exception lists given a set of criteria. + * @param options + * @param options.filter The filter to apply in the search + * @param options.perPage How many per page to return + * @param options.page The page number or "undefined" if there is no page number to continue from + * @param options.pit The Point in Time (pit) id if there is one, otherwise "undefined" can be sent in + * @param options.searchAfter The search_after parameter if there is one, otherwise "undefined" can be sent in + * @param options.sortField The sort field string if there is one, otherwise "undefined" can be sent in + * @param options.sortOrder The sort order of "asc" or "desc", otherwise "undefined" can be sent in + * @param options.namespaceType Set the list type of either "agnostic" | "single" + * @returns The found exception lists or null if nothing is found + */ public findExceptionList = async ({ filter, perPage, @@ -775,6 +893,15 @@ export class ExceptionListClient { * a good guarantee that you will get an empty record set rather than null. I keep the null as the return value in * the off chance that you still might somehow not get into a race condition where the endpoint list does * not exist because someone deleted it in-between the initial create and then the find. + * @param options + * @param options.filter The filter to apply in the search + * @param options.perPage How many per page to return + * @param options.page The page number or "undefined" if there is no page number to continue from + * @param options.pit The Point in Time (pit) id if there is one, otherwise "undefined" can be sent in + * @param options.searchAfter The search_after parameter if there is one, otherwise "undefined" can be sent in + * @param options.sortField The sort field string if there is one, otherwise "undefined" can be sent in + * @param options.sortOrder The sort order of "asc" or "desc", otherwise "undefined" can be sent in + * @returns The found exception list items or null if nothing is found */ public findEndpointListItem = async ({ filter, @@ -803,10 +930,11 @@ export class ExceptionListClient { /** * Export an exception list parent container and it's items - * @params listId {string | undefined} the "list_id" of an exception list - * @params id {string | undefined} the "id" of an exception list - * @params namespaceType {string | undefined} saved object namespace (single | agnostic) - * @return {ExportExceptionListAndItemsReturn | null} the ndjson of the list and items to export or null if none exists + * @param options + * @param options.listId the "list_id" of an exception list + * @param options.id the "id" of an exception list + * @param options.namespaceType saved object namespace (single | agnostic) + * @returns the ndjson of the list and items to export or null if none exists */ public exportExceptionListAndItems = async ({ listId, @@ -837,10 +965,11 @@ export class ExceptionListClient { /** * Import exception lists parent containers and items as stream - * @params exceptionsToImport {stream} ndjson stream of lists and items - * @params maxExceptionsImportSize {number} the max number of lists and items to import, defaults to 10,000 - * @params overwrite {boolean} whether or not to overwrite an exception list with imported list if a matching list_id found - * @return {ImportExceptionsResponseSchema} summary of imported count and errors + * @param options + * @param options.exceptionsToImport ndjson stream of lists and items + * @param options.maxExceptionsImportSize the max number of lists and items to import, defaults to 10,000 + * @param options.overwrite whether or not to overwrite an exception list with imported list if a matching list_id found + * @returns summary of imported count and errors */ public importExceptionListAndItems = async ({ exceptionsToImport, @@ -874,10 +1003,11 @@ export class ExceptionListClient { /** * Import exception lists parent containers and items as array - * @params exceptionsToImport {array} array of lists and items - * @params maxExceptionsImportSize {number} the max number of lists and items to import, defaults to 10,000 - * @params overwrite {boolean} whether or not to overwrite an exception list with imported list if a matching list_id found - * @return {ImportExceptionsResponseSchema} summary of imported count and errors + * @param options + * @param options.exceptionsToImport array of lists and items + * @param options.maxExceptionsImportSize the max number of lists and items to import, defaults to 10,000 + * @param options.overwrite whether or not to overwrite an exception list with imported list if a matching list_id found + * @returns summary of imported count and errors */ public importExceptionListAndItemsAsArray = async ({ exceptionsToImport, @@ -908,9 +1038,10 @@ export class ExceptionListClient { /** * Opens a point in time (PIT) for either exception lists or exception list items. * See: https://www.elastic.co/guide/en/elasticsearch/reference/current/point-in-time-api.html - * @params namespaceType {string} "agnostic" or "single" depending on which namespace you are targeting - * @params options {Object} The saved object PIT options - * @return {SavedObjectsOpenPointInTimeResponse} The point in time (PIT) + * @param options + * @param options.namespaceType "agnostic" or "single" depending on which namespace you are targeting + * @param options.options The saved object PIT options + * @returns The point in time (PIT) */ public openPointInTime = async ({ namespaceType, @@ -927,8 +1058,9 @@ export class ExceptionListClient { /** * Closes a point in time (PIT) for either exception lists or exception list items. * See: https://www.elastic.co/guide/en/elasticsearch/reference/current/point-in-time-api.html - * @params pit {string} The point in time to close - * @return {SavedObjectsOpenPointInTimeResponse} The point in time (PIT) + * @param options + * @param options.pit The point in time to close + * @returns The point in time (PIT) */ public closePointInTime = async ({ pit, @@ -965,12 +1097,15 @@ export class ExceptionListClient { * exe * }); * ``` - * @param filter {string} Your filter - * @param namespaceType {string} "agnostic" | "single" of your namespace - * @param perPage {number} The number of items per page. Typical value should be 1_000 here. Never go above 10_000 - * @param maxSize {number of undefined} If given a max size, this will not exceeded. Otherwise if undefined is passed down, all records will be processed. - * @param sortField {string} String of the field to sort against - * @param sortOrder "asc" | "desc" The order to sort against + * @param options + * @param options.filter The filter to apply in the search + * @param options.listId The "list_id" to filter against and find against + * @param options.namespaceType "agnostic" | "single" of your namespace + * @param options.perPage The number of items per page. Typical value should be 1_000 here. Never go above 10_000 + * @param options.maxSize If given a max size, this will not exceeded. Otherwise if undefined is passed down, all records will be processed. + * @param options.sortField String of the field to sort against + * @param options.sortOrder "asc" | "desc" The order to sort against, "undefined" if the order does not matter + * @param options.executeFunctionOnStream The function to execute which will have the streamed results */ public findExceptionListItemPointInTimeFinder = async ({ executeFunctionOnStream, @@ -1021,12 +1156,14 @@ export class ExceptionListClient { * exe * }); * ``` - * @param filter {string} Your filter - * @param namespaceType {string} "agnostic" | "single" of your namespace - * @param perPage {number} The number of items per page. Typical value should be 1_000 here. Never go above 10_000 - * @param maxSize {number of undefined} If given a max size, this will not exceeded. Otherwise if undefined is passed down, all records will be processed. - * @param sortField {string} String of the field to sort against - * @param sortOrder "asc" | "desc" The order to sort against + * @param options + * @param options.filter The filter to apply in the search + * @param options.namespaceType "agnostic" | "single" of your namespace + * @param options.perPage The number of items per page. Typical value should be 1_000 here. Never go above 10_000 + * @param options.maxSize If given a max size, this will not be exceeded. Otherwise if undefined is passed down, all records will be processed. + * @param options.sortField String of the field to sort against + * @param options.sortOrder "asc" | "desc" The order to sort against, "undefined" if the order does not matter + * @param options.executeFunctionOnStream The function to execute which will have the streamed results */ public findExceptionListPointInTimeFinder = async ({ executeFunctionOnStream, @@ -1075,12 +1212,15 @@ export class ExceptionListClient { * exe * }); * ``` - * @param filter {string} Your filter - * @param namespaceType {string} "agnostic" | "single" of your namespace - * @param perPage {number} The number of items per page. Typical value should be 1_000 here. Never go above 10_000 - * @param maxSize {number of undefined} If given a max size, this will not exceeded. Otherwise if undefined is passed down, all records will be processed. - * @param sortField {string} String of the field to sort against - * @param sortOrder "asc" | "desc" The order to sort against + * @param options + * @param options.listId The "list_id" to find against + * @param options.filter The filter to apply in the search + * @param options.namespaceType "agnostic" | "single" of your namespace + * @param options.perPage The number of items per page. Typical value should be 1_000 here. Never go above 10_000 + * @param options.maxSize If given a max size, this will not exceeded. Otherwise if undefined is passed down, all records will be processed. + * @param options.sortField String of the field to sort against + * @param options.sortOrder "asc" | "desc" The order to sort against, "undefined" if the order does not matter + * @param options.executeFunctionOnStream The function to execute which will have the streamed results */ public findExceptionListsItemPointInTimeFinder = async ({ listId, @@ -1131,12 +1271,13 @@ export class ExceptionListClient { * exe * }); * ``` - * @param valueListId {string} Your value list id - * @param namespaceType {string} "agnostic" | "single" of your namespace - * @param perPage {number} The number of items per page. Typical value should be 1_000 here. Never go above 10_000 - * @param maxSize {number of undefined} If given a max size, this will not exceeded. Otherwise if undefined is passed down, all records will be processed. - * @param sortField {string} String of the field to sort against - * @param sortOrder "asc" | "desc" The order to sort against + * @param options + * @param options.valueListId The value list id + * @param options.namespaceType "agnostic" | "single" of your namespace + * @param options.perPage The number of items per page. Typical value should be 1_000 here. Never go above 10_000 + * @param options.maxSize If given a max size, this will not exceeded. Otherwise if undefined is passed down, all records will be processed. + * @param options.sortField String of the field to sort against + * @param options.sortOrder "asc" | "desc" The order to sort against, "undefined" if the order does not matter */ public findValueListExceptionListItemsPointInTimeFinder = async ({ valueListId, diff --git a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts index 4c7820fc05f94..1f440415fef40 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts @@ -62,9 +62,15 @@ import type { import type { ExtensionPointStorageClientInterface } from '../extension_points'; +/** + * Constructor options to {@link ExceptionListClient:constructor} + */ export interface ConstructorOptions { + /** User creating, modifying, deleting, or updating an exception list */ user: string; + /** Saved objects client to create, modify, delete, an exception list */ savedObjectsClient: SavedObjectsClientContract; + /** server extensions client that can be useful for injecting domain specific rules */ serverExtensionsClient: ExtensionPointStorageClientInterface; /** Set to `false` if wanting to disable executing registered server extension points. Default is true. */ enableServerExtensionPoints?: boolean; @@ -72,257 +78,552 @@ export interface ConstructorOptions { request?: KibanaRequest; } +/** + * ExceptionListClient.getExceptionList + * {@link ExceptionListClient.getExceptionList} + */ export interface GetExceptionListOptions { + /** the "list_id" of an exception list */ listId: ListIdOrUndefined; + /** the "id" of an exception list */ id: IdOrUndefined; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; } +/** + * ExceptionListClient.getExceptionListSummary + * {@link ExceptionListClient.getExceptionListSummary} + */ export interface GetExceptionListSummaryOptions { + /** kql "filter" expression */ filter: FilterOrUndefined; + /** the "list_id" of an exception list */ listId: ListIdOrUndefined; + /** the "id" of an exception list */ id: IdOrUndefined; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; } +/** + * ExceptionListClient.createExceptionList + * {@link ExceptionListClient.createExceptionList} + */ export interface CreateExceptionListOptions { + /** the "list_id" of the exception list */ listId: ListId; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; + /** the "name" of the exception list */ name: Name; + /** a description of the exception list */ description: Description; + /** Optional meta data to add to the exception list */ meta: MetaOrUndefined; + /** user assigned tags of exception list */ tags: Tags; + /** container type */ type: ExceptionListType; + /** True if it's a immutable list, otherwise false */ immutable: Immutable; + /** document version */ version: Version; } +/** + * ExceptionListClient.updateExceptionList + * {@link ExceptionListClient.updateExceptionList} + */ export interface UpdateExceptionListOptions { + /** document version */ _version: _VersionOrUndefined; + /** the "id" of the exception list */ id: IdOrUndefined; + /** the "list_id" of the exception list */ listId: ListIdOrUndefined; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; + /** the "name" of the exception list */ name: NameOrUndefined; + /** item os types to apply */ osTypes: OsTypeArray; + /** a description of the exception list */ description: DescriptionOrUndefined; + /** Optional meta object */ meta: MetaOrUndefined; + /** user assigned tags of exception list */ tags: TagsOrUndefined; + /** container type */ type: ExceptionListTypeOrUndefined; + /** document version, if undefined the current version number will be auto-incremented */ version: VersionOrUndefined; } +/** + * ExceptionListClient.deleteExceptionList + * {@link ExceptionListClient.deleteExceptionList} + */ export interface DeleteExceptionListOptions { + /* the "id" of an exception list (Either this or listId has to be defined) */ id: IdOrUndefined; + /** the "list_id" of an exception list (Either this or id has to be defined) */ listId: ListIdOrUndefined; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; } +/** + * ExceptionListClient.deleteExceptionListItem + * {@link ExceptionListClient.deleteExceptionListItem} + */ export interface DeleteExceptionListItemOptions { + /** the "id" of an exception list item (Either this or itemId has to be defined) */ id: IdOrUndefined; + /** the "item_id" of an exception list item (Either this or id has to be defined) */ itemId: ItemIdOrUndefined; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; } +/** + * ExceptionListClient.deleteExceptionListItemById + * {@link ExceptionListClient.deleteExceptionListItemById} + */ export interface DeleteExceptionListItemByIdOptions { + /** the "id" of an exception list item */ id: Id; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; } +/** + * ExceptionListClient.deleteEndpointListItem + * {@link ExceptionListClient.deleteEndpointListItem} + */ export interface DeleteEndpointListItemOptions { + /** The id of the endpoint list item (Either this or itemId has to be defined) */ id: IdOrUndefined; + /** The item id of the endpoint list item (Either this or id has to be defined) */ itemId: ItemIdOrUndefined; } +/** + * ExceptionListClient.getExceptionListItem + * {@link ExceptionListClient.getExceptionListItem} + */ export interface GetExceptionListItemOptions { + /** the "item_id" of an exception list (Either this or id has to be defined) */ itemId: ItemIdOrUndefined; + /** the "id" of an exception list (Either this or itemId has to be defined) */ id: IdOrUndefined; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; } +/** + * ExceptionListClient.getEndpointListItem + * {@link ExceptionListClient.getEndpointListItem} + */ export interface GetEndpointListItemOptions { + /** The item id (Either this or id has to be defined) */ itemId: ItemIdOrUndefined; + /** The id (Either this or itemId has to be defined) */ id: IdOrUndefined; } +/** + * ExceptionListClient.createExceptionListItem + * {@link ExceptionListClient.createExceptionListItem} + */ export interface CreateExceptionListItemOptions { + /** User comments for the exception list item */ comments: CreateCommentsArray; + /** an array with the exception list item entries */ entries: EntriesArray; + /** the "item_id" of the exception list item */ itemId: ItemId; + /** the "list_id" of the parent exception list */ listId: ListId; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; + /** the "name" of the exception list */ name: Name; + /** item os types to apply */ osTypes: OsTypeArray; + /** a description of the exception list */ description: Description; + /** Optional meta data about the list item */ meta: MetaOrUndefined; + /** user assigned tags of exception list */ tags: Tags; + /** container type */ type: ExceptionListItemType; } +/** + * ExceptionListClient.createEndpointListItem + * {@link ExceptionListClient.createEndpointListItem} + */ export interface CreateEndpointListItemOptions { + /** The comments of the endpoint list item */ comments: CreateCommentsArray; + /** The entries of the endpoint list item */ entries: EntriesArray; + /** The item id of the list item */ itemId: ItemId; + /** The name of the list item */ name: Name; + /** The description of the endpoint list item */ description: Description; + /** Optional meta data of the list item */ meta: MetaOrUndefined; + /** The OS type of the list item */ osTypes: OsTypeArray; + /** Tags of the endpoint list item */ tags: Tags; + /** The type of the endpoint list item (Default is "simple") */ type: ExceptionListItemType; } +/** + * ExceptionListClient.updateExceptionListItem + * {@link ExceptionListClient.updateExceptionListItem} + */ export interface UpdateExceptionListItemOptions { + /** document version */ _version: _VersionOrUndefined; + /** user comments attached to item */ comments: UpdateCommentsArray; + /** item exception entries logic */ entries: EntriesArray; + /** the "id" of the exception list item */ id: IdOrUndefined; + /** the "item_id" of the exception list item */ itemId: ItemIdOrUndefined; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; + /** the "name" of the exception list */ name: NameOrUndefined; + /** item os types to apply */ osTypes: OsTypeArray; + /** a description of the exception list */ description: DescriptionOrUndefined; + /** Optional meta data about the exception list item */ meta: MetaOrUndefined; + /** user assigned tags of exception list */ tags: TagsOrUndefined; + /** container type */ type: ExceptionListItemTypeOrUndefined; } +/** + * ExceptionListClient.updateEndpointListItem + * {@link ExceptionListClient.updateEndpointListItem} + */ export interface UpdateEndpointListItemOptions { + /** The version to update the endpoint list item to */ _version: _VersionOrUndefined; + /** The comments of the endpoint list item */ comments: UpdateCommentsArray; + /** The entries of the endpoint list item */ entries: EntriesArray; + /** The id of the list item (Either this or itemId has to be defined) */ id: IdOrUndefined; + /** The item id of the list item (Either this or id has to be defined) */ itemId: ItemIdOrUndefined; + /** The name of the list item */ name: NameOrUndefined; + /** The OS type of the list item */ osTypes: OsTypeArray; + /** The description of the endpoint list item */ description: DescriptionOrUndefined; + /** Optional meta data of the list item */ meta: MetaOrUndefined; + /** Tags of the endpoint list item */ tags: TagsOrUndefined; + /** The type of the endpoint list item (Default is "simple") */ type: ExceptionListItemTypeOrUndefined; } +/** + * ExceptionListClient.findExceptionListItem + * {@link ExceptionListClient.findExceptionListItem} + */ export interface FindExceptionListItemOptions { + /** The single list id to do the search against */ listId: ListId; + /** Set the list type of either "agnostic" | "single" */ namespaceType: NamespaceType; + /** The filter to apply in the search */ filter: FilterOrUndefined; + /** How many per page to return */ perPage: PerPageOrUndefined; + /** The Point in Time (pit) id if there is one, otherwise "undefined" can be send in */ pit?: PitOrUndefined; + /** The search_after parameter if there is one, otherwise "undefined" can be sent in */ searchAfter?: SearchAfterOrUndefined; + /** The page number or "undefined" if there is no page number to continue from */ page: PageOrUndefined; + /** The sort field string if there is one, otherwise "undefined" can be sent in */ sortField: SortFieldOrUndefined; + /** The sort order string of "asc", "desc", otherwise "undefined" if there is no preference */ sortOrder: SortOrderOrUndefined; } +/** + * ExceptionListClient.findEndpointListItem + * {@link ExceptionListClient.findEndpointListItem} + */ export interface FindEndpointListItemOptions { + /** The filter to apply in the search */ filter: FilterOrUndefined; + /** How many per page to return */ perPage: PerPageOrUndefined; + /** The Point in Time (pit) id if there is one, otherwise "undefined" can be sent in */ pit?: PitOrUndefined; + /** The search_after parameter if there is one, otherwise "undefined" can be sent in */ searchAfter?: SearchAfterOrUndefined; + /** The page number or "undefined" if there is no page number to continue from */ page: PageOrUndefined; + /** The sort field string if there is one, otherwise "undefined" can be sent in */ sortField: SortFieldOrUndefined; + /** The sort order of "asc" or "desc", otherwise "undefined" can be sent in */ sortOrder: SortOrderOrUndefined; } +/** + * ExceptionListClient.findExceptionListsItem + * {@link ExceptionListClient.findExceptionListsItem} + */ export interface FindExceptionListsItemOptions { + /** The multiple list id's to do the search against */ listId: NonEmptyStringArrayDecoded; + /** Set the list type of either "agnostic" | "single" */ namespaceType: NamespaceTypeArray; + /** The filter to apply in the search */ filter: EmptyStringArrayDecoded; + /** How many per page to return */ perPage: PerPageOrUndefined; + /** The Point in Time (pit) id if there is one, otherwise "undefined" can be sent in */ pit?: PitOrUndefined; + /** The search_after parameter if there is one, otherwise "undefined" can be sent in */ searchAfter?: SearchAfterOrUndefined; + /** The page number or "undefined" if there is no page number to continue from */ page: PageOrUndefined; + /** The sort field string if there is one, otherwise "undefined" can be sent in */ sortField: SortFieldOrUndefined; + /** The sort order string of "asc", "desc", otherwise "undefined" if there is no preference */ sortOrder: SortOrderOrUndefined; } +/** + * ExceptionListClient.findValueListExceptionListItems + * {@link ExceptionListClient.findValueListExceptionListItems} + */ export interface FindValueListExceptionListsItems { + /** The value list id */ valueListId: Id; + /** How many per page to return */ perPage: PerPageOrUndefined; + /** The Point in Time (pit) id if there is one, otherwise "undefined" can be send in */ pit?: PitOrUndefined; + /** The search_after parameter if there is one, otherwise "undefined" can be sent in */ searchAfter?: SearchAfterOrUndefined; + /** The page number or "undefined" if there is no page number to continue from */ page: PageOrUndefined; + /** The sort field string if there is one, otherwise "undefined" can be sent in */ sortField: SortFieldOrUndefined; + /** The sort order of "asc" or "desc", otherwise "undefined" can be sent in if there is no preference */ sortOrder: SortOrderOrUndefined; } +/** + * ExceptionListClient.findExceptionList + * {@link ExceptionListClient.findExceptionList} + */ export interface FindExceptionListOptions { + /** Set the list type of either "agnostic" | "single" */ namespaceType: NamespaceTypeArray; + /** The filter to apply in the search */ filter: FilterOrUndefined; + /** How many per page to return */ perPage: PerPageOrUndefined; + /** The page number or "undefined" if there is no page number to continue from */ page: PageOrUndefined; + /** The Point in Time (pit) id if there is one, otherwise "undefined" can be sent in */ pit?: PitOrUndefined; + /** The search_after parameter if there is one, otherwise "undefined" can be sent in */ searchAfter?: SearchAfterOrUndefined; + /** The sort field string if there is one, otherwise "undefined" can be sent in */ sortField: SortFieldOrUndefined; + /** The sort order of "asc" or "desc", otherwise "undefined" can be sent in */ sortOrder: SortOrderOrUndefined; } +/** + * ExceptionListClient.exportExceptionListAndItems + * {@link ExceptionListClient.exportExceptionListAndItems} + */ export interface ExportExceptionListAndItemsOptions { + /** the "list_id" of an exception list */ listId: ListIdOrUndefined; + /** the "id" of an exception list */ id: IdOrUndefined; + /** saved object namespace (single | agnostic) */ namespaceType: NamespaceType; } +/** + * Used to export list and items + */ export interface ExportExceptionListAndItemsReturn { + /** The exported data as ndjson */ exportData: string; + /** The exported data details such as counts and missing data */ exportDetails: ExportExceptionDetails; } +/** + * ExceptionListClient.importExceptionListAndItems + * {@link ExceptionListClient.importExceptionListAndItems} + */ export interface ImportExceptionListAndItemsOptions { + /** ndjson stream of lists and items */ exceptionsToImport: Readable; + /** the max number of lists and items to import, defaults to 10,000 */ maxExceptionsImportSize: number; + /** whether or not to overwrite an exception list with imported list if a matching list_id found */ overwrite: boolean; } +/** + * ExceptionListClient.importExceptionListAndItemsAsArray + * {@link ExceptionListClient.importExceptionListAndItemsAsArray} + */ export interface ImportExceptionListAndItemsAsArrayOptions { + /** array of lists and items */ exceptionsToImport: Array; + /** the max number of lists and items to import, defaults to 10,000 */ maxExceptionsImportSize: number; + /** whether or not to overwrite an exception list with imported list if a matching list_id found */ overwrite: boolean; } +/** + * ExceptionListClient.openPointInTime + * {@link ExceptionListClient.openPointInTime} + */ export interface OpenPointInTimeOptions { + /** "agnostic" or "single" depending on which namespace you are targeting */ namespaceType: NamespaceType; + /** The saved object PIT options */ options: SavedObjectsOpenPointInTimeOptions | undefined; } +/** + * ExceptionListClient.closePointInTime + * {@link ExceptionListClient.closePointInTime} + */ export interface ClosePointInTimeOptions { + /** The point in time to close */ pit: PitId; } +/** + * ExceptionListClient.findExceptionListItemPointInTimeFinder + * {@link ExceptionListClient.findExceptionListItemPointInTimeFinder} + */ export interface FindExceptionListItemPointInTimeFinderOptions { + /** The "list_id" to filter against and find against */ listId: ListId; + /** "agnostic" | "single" of your namespace */ namespaceType: NamespaceType; + /** The filter to apply in the search */ filter: FilterOrUndefined; + /** The number of items per page. Typical value should be 1_000 here. Never go above 10_000 */ perPage: PerPageOrUndefined; + /** String of the field to sort against */ sortField: SortFieldOrUndefined; + /** "asc" | "desc" The order to sort against, "undefined" if the order does not matter */ sortOrder: SortOrderOrUndefined; + /** + * The function to execute which will have the streamed results + * @param response The streaming response + */ executeFunctionOnStream: (response: FoundExceptionListItemSchema) => void; + /** If given a max size, this will not be exceeded. Otherwise if undefined is passed down, all records will be processed. */ maxSize: MaxSizeOrUndefined; } +/** + * ExceptionListClient.findExceptionListPointInTimeFinder + * {@link ExceptionListClient.findExceptionListPointInTimeFinder} + */ export interface FindExceptionListPointInTimeFinderOptions { + /** If given a max size, this will not be exceeded. Otherwise if undefined is passed down, all records will be processed. */ maxSize: MaxSizeOrUndefined; + /** "agnostic" | "single" of your namespace */ namespaceType: NamespaceTypeArray; + /** The filter to apply in the search */ filter: FilterOrUndefined; + /** The number of items per page. Typical value should be 1_000 here. Never go above 10_000 */ perPage: PerPageOrUndefined; + /** String of the field to sort against */ sortField: SortFieldOrUndefined; + /** "asc" | "desc" The order to sort against, "undefined" if the order does not matter */ sortOrder: SortOrderOrUndefined; + /** + * The function to execute which will have the streamed results + * @param response The streaming response + */ executeFunctionOnStream: (response: FoundExceptionListSchema) => void; } +/** + * ExceptionListClient.findExceptionListsItemPointInTimeFinder + * {@link ExceptionListClient.findExceptionListsItemPointInTimeFinder} + */ export interface FindExceptionListItemsPointInTimeFinderOptions { + /** The "list_id" to find against */ listId: NonEmptyStringArrayDecoded; + /** "agnostic" | "single" of your namespace */ namespaceType: NamespaceTypeArray; + /** The filter to apply in the search */ filter: EmptyStringArrayDecoded; + /** The number of items per page. Typical value should be 1_000 here. Never go above 10_000 */ perPage: PerPageOrUndefined; + /** String of the field to sort against */ sortField: SortFieldOrUndefined; + /* "asc" | "desc" The order to sort against */ sortOrder: SortOrderOrUndefined; + /** + * The function to execute which will have the streamed results + * @param response The streaming response + */ executeFunctionOnStream: (response: FoundExceptionListItemSchema) => void; + /** If given a max size, this will not exceeded. Otherwise if undefined is passed down, all records will be processed. */ maxSize: MaxSizeOrUndefined; } +/** + * ExceptionListClient.findValueListExceptionListItemsPointInTimeFinder + * {@link ExceptionListClient.findValueListExceptionListItemsPointInTimeFinder} + */ export interface FindValueListExceptionListsItemsPointInTimeFinder { + /** The value list id */ valueListId: Id; + /** The number of items per page. Typical value should be 1_000 here. Never go above 10_000 */ perPage: PerPageOrUndefined; + /** String of the field to sort against */ sortField: SortFieldOrUndefined; + /** "asc" | "desc" The order to sort against, "undefined" if the order does not matter */ sortOrder: SortOrderOrUndefined; + /** + * The function to execute which will have the streamed results + * @param response The streaming response + */ executeFunctionOnStream: (response: FoundExceptionListItemSchema) => void; + /** If given a max size, this will not exceeded. Otherwise if undefined is passed down, all records will be processed. */ maxSize: MaxSizeOrUndefined; } diff --git a/x-pack/plugins/metrics_entities/README.md b/x-pack/plugins/metrics_entities/README.md deleted file mode 100755 index 71ac2730f3831..0000000000000 --- a/x-pack/plugins/metrics_entities/README.md +++ /dev/null @@ -1,322 +0,0 @@ -# metrics_entities - -This is the metrics and entities plugin where you add can add transforms for your project -and group those transforms into modules. You can also re-use existing transforms in your -newly created modules as well. - -## Turn on experimental flags -During at least phase 1 of this development, please add these to your `kibana.dev.yml` file to turn on the feature: - -```ts -xpack.metricsEntities.enabled: true -xpack.securitySolution.enableExperimental: ['metricsEntitiesEnabled'] -``` - -## Quick start on using scripts to call the API - -The scripts rely on CURL and jq: - -- [CURL](https://curl.haxx.se) -- [jq](https://stedolan.github.io/jq/) - -Install curl and jq - -```sh -brew update -brew install curl -brew install jq -``` - -Open `$HOME/.zshrc` or `${HOME}.bashrc` depending on your SHELL output from `echo $SHELL` -and add these environment variables: - -```sh -export ELASTICSEARCH_USERNAME=${user} -export ELASTICSEARCH_PASSWORD=${password} -export ELASTICSEARCH_URL=https://${ip}:9200 -export KIBANA_URL=http://localhost:5601 -``` - -source `$HOME/.zshrc` or `${HOME}.bashrc` to ensure variables are set: - -```sh -source ~/.zshrc -``` - -Restart Kibana and ensure that you are using `--no-base-path` as changing the base path is a feature but will -get in the way of the CURL scripts written as is. - -Go to the scripts folder `cd kibana/x-pack/plugins/metrics_entities/server/scripts` and can run some of the scripts -such as: - -```sh -./post_transforms.sh ./post_examples/all.json -``` - -which will post transforms from the `all.json` - -You can also delete them by running: - -```sh -./delete_transforms.sh ./delete_examples/all.json -``` - -See the folder for other curl scripts that exercise parts of the REST API and feel free to add your own examples -in the folder as well. - -## Quick start on how to add a transform - -You will want to figure out how you want your transform from within Kibana roughly using -the UI and then copy the JSON. The JSON you will want to change and paste within a folder -which represents a module. - -For example, for the `host_entities` and a `host_entities_mapping` we created a folder called host_entities -here: - -```sh -sever/modules/host_entities -``` - -Then we add two files, a subset of the transform JSON and a mapping like so: - -```sh -server/modules/host_entities/host_entities_mapping.json <--- this is the mappings -server/modules/host_entities/host_entities.json <--- This is a subset of the transform JSON -index.ts <--- Import/export your json here -``` - -The mappings can be normal mapping like so with `host_entities_mapping.json`: -```json -{ - "mappings": { - "_meta": { - "index": "host_ent" - }, - "dynamic": "strict", - "properties": { - "@timestamp": { - "type": "date" - }, - "metrics": { - "properties": { - "host": { - "properties": { - "name": { - "properties": { - "value_count": { - "type": "long" - } - } - } - } - } - } - }, - "host": { - "properties": { - "name": { - "type": "keyword" - }, - "os": { - "properties": { - "name": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - } - } - } - } - } -} -``` - -One caveat is that you need to add this to the meta section to tell it what the name will be: -```json - "_meta": { - "index": "host_ent" - }, -``` - -Keep the name short as there is only 65 characters for a transform job and we prepend extra information to the mapping such as: -* prefix -* name of estc - -Although not required, a `"dynamic": "strict"` is strongly encouraged to prevent mapping guesses from elastic and it will be better for us -to spot errors quicker in the mappings such as type-o's if this is set to strict. - -Next, for the transform, you should add a subset that doesn't have any additional settings or meta associated like so for `host_entities.json`: - -```json -{ - "id": "host_ent", - "description": "[host.name entities] grouped by @timestamp, host.name, os.name, and os.version, and aggregated on host.name", - "pivot": { - "group_by": { - "@timestamp": { - "date_histogram": { - "field": "@timestamp", - "calendar_interval": "1h" - } - }, - "host.name": { - "terms": { - "field": "host.name" - } - }, - "host.os.name": { - "terms": { - "field": "host.os.name", - "missing_bucket": true - } - }, - "host.os.version": { - "terms": { - "field": "host.os.version", - "missing_bucket": true - } - } - }, - "aggregations": { - "metrics.host.name.value_count": { - "value_count": { - "field": "host.name" - } - } - } - } -} -``` - -Look in the `server/modules` for other examples, but it should be that clear cut. The final part is to wire everything up in the code by touching a few files -to either add this to an existing module or create your own module. In `server/module/host_entities` we add an `index.ts` like so that does an import/export -of the JSON: - -```sh -import hostEntities from './host_entities.json'; -import hostEntitiesMapping from './host_entities_mapping.json'; -export { hostEntities, hostEntitiesMapping }; -``` - -Then in `modules/index.ts` we add a new module name if we are creating a new module to the `export enum ModuleNames {` like so: - -```ts -// Import your host entities you just made -import { hostEntities, hostEntitiesMapping } from './host_entities'; - -/** - * These module names will map 1 to 1 to the REST interface. - */ -export enum ModuleNames { - hostSummaryMetrics = 'host_metrics', - hostSummaryEntities = 'host_entities', // <-- Add the entities/transform and give it a enum name and a module name - networkSummaryEntities = 'network_entities', - networkSummaryMetrics = 'network_metrics', - userSummaryEntities = 'user_entities', - userSummaryMetrics = 'user_metrics', -} -``` - -If you're not creating a new module but rather you are adding to an existing module, you can skip the above step. Next, you -just need to add your installable transform and installable mapping to the two data structures of `installableTransforms` and -`installableMappings` like so: - -```ts -/** - * Add any new folders as modules with their names below and grouped with - * key values. - */ -export const installableTransforms: Record = { - [ModuleNames.hostSummaryMetrics]: [hostMetrics], - [ModuleNames.hostSummaryEntities]: [hostEntities], // <-- Adds my new module name and transform to a new array. - [ModuleNames.networkSummaryEntities]: [ - destinationIpEntities, // <-- If instead I am adding to an existing module, I just add it to the array like these show - sourceIpEntities, - destinationCountryIsoCodeEntities, - sourceCountryIsoCodeEntities, - ], - [ModuleNames.networkSummaryMetrics]: [ipMetrics], - [ModuleNames.userSummaryEntities]: [userEntities], - [ModuleNames.userSummaryMetrics]: [userMetrics], -}; - -/** - * For all the mapping types, add each with their names below and grouped with - * key values. - */ -export const installableMappings: Record = { - [ModuleNames.hostSummaryMetrics]: [hostMetricsMapping], - [ModuleNames.hostSummaryEntities]: [hostEntitiesMapping], // <-- Adds my new module name and mapping to a new array. - [ModuleNames.networkSummaryEntities]: [ // <-- If instead I am adding to an existing module, I just add it to the array like these show - sourceIpEntitiesMapping, - destinationIpEntitiesMapping, - destinationCountryIsoCodeEntitiesMapping, - sourceCountryIsoCodeEntitiesMapping, - ], - [ModuleNames.networkSummaryMetrics]: [ipMetricsMapping], - [ModuleNames.userSummaryEntities]: [userEntitiesMapping], - [ModuleNames.userSummaryMetrics]: [userMetricsMapping], -}; -``` - -And after that, you should check out if there are any existing e2e tests or unit tests to update here to ensure that your mapping and transform will -pass ci. Create a pull request and your mapping and transform are completed. - -To call into the code to activate your module and create your transforms and mappings would be the following where you substitute your -${KIBANA_URL} with your kibana URL and the ${SPACE_URL} with any space id you have. If you're using the default space then you would use -an empty string: -```json -POST ${KIBANA_URL}${SPACE_URL}/api/metrics_entities/transforms -{ - "prefix": "all", - "modules": [ - "host_entities", - ], - "indices": [ - "auditbeat-*", - "endgame-*", - "filebeat-*", - "logs-*", - "packetbeat-*", - "winlogbeat-*", - "-*elastic-cloud-logs-*" - ], - "auto_start": true, - "settings": { - "max_page_search_size": 5000 - }, - "query": { - "range": { - "@timestamp": { - "gte": "now-1d/d", - "format": "strict_date_optional_time" - } - } - } -} -``` - -Very similar to the regular transform REST API, with the caveats that you define which modules you want to install, the prefix name you want to use, and -if you want to `auto_start` it or not. The rest such as `settings`, `query` will be the same as the transforms API. They will also push those same setting into -each of your transforms within your module(s) as the same setting for each individual ones. - -## TODO List -During the phase 1, phase 2, phase N, this TODO will exist as a reminder and notes for what still needs to be developed. These are not in a priority order, but -are notes during the phased approach. As we approach production and the feature flags are removed these TODO's should be removed in favor of Kibana issues or regular -left over TODO's in the code base. - -- Add these properties to the route which are: - - disable_transforms/exclude flag to exclude 1 or more transforms within a module - - pipeline flag - - Change the REST routes on post to change the indexes for whichever indexes you want -- Unit tests to ensure the data of the mapping.json includes the correct fields such as _meta, at least one alias, a mapping section, etc... -- Add text/keyword and other things to the mappings (not just keyword maybe?) ... At least review the mappings one more time -- Add a sort of @timestamp to the output destination indexes? -- Add the REST Kibana security based tags if needed and push those to any plugins using this plugin. Something like: tags: ['access:metricsEntities-read'] and ['access:metricsEntities-all'], -- Add schema validation choosing some schema library (io-ts or Kibana Schema or ... ) -- Add unit tests -- Add e2e tests -- Any UI code should not end up here. There is none right now, but all UI code should be within a kbn package or security_solutions diff --git a/x-pack/plugins/metrics_entities/common/constants.ts b/x-pack/plugins/metrics_entities/common/constants.ts deleted file mode 100644 index 8efa0327f5f41..0000000000000 --- a/x-pack/plugins/metrics_entities/common/constants.ts +++ /dev/null @@ -1,21 +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. - */ - -/** - * Base route - */ -export const METRICS_ENTITIES_URL = '/api/metrics_entities'; - -/** - * Transforms route - */ -export const METRICS_ENTITIES_TRANSFORMS = `${METRICS_ENTITIES_URL}/transforms`; - -/** - * Global prefix for all the transform jobs - */ -export const ELASTIC_NAME = 'estc'; diff --git a/x-pack/plugins/metrics_entities/common/index.ts b/x-pack/plugins/metrics_entities/common/index.ts deleted file mode 100644 index f100308ef2e9b..0000000000000 --- a/x-pack/plugins/metrics_entities/common/index.ts +++ /dev/null @@ -1,13 +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. - */ - -// Careful of exporting anything from this file as any file(s) you export here will cause your functions to be exposed as public. -// If you're using functions/types/etc... internally or within integration tests it's best to import directly from their paths -// than expose the functions/types/etc... here. You should _only_ expose functions/types/etc... that need to be shared with other plugins here. -// When you do have to add things here you might want to consider creating a package such to share with other plugins instead as packages -// are easier to break down. -// See: https://docs.elastic.dev/kibana-dev-docs/key-concepts/platform-intro#public-plugin-api diff --git a/x-pack/plugins/metrics_entities/kibana.json b/x-pack/plugins/metrics_entities/kibana.json deleted file mode 100644 index 9d3a4f7f66a8d..0000000000000 --- a/x-pack/plugins/metrics_entities/kibana.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "metricsEntities", - "owner": { - "name": "Security solution", - "githubTeam": "security-solution" - }, - "version": "8.0.0", - "kibanaVersion": "kibana", - "configPath": ["xpack", "metricsEntities"], - "server": true, - "ui": false, - "requiredPlugins": ["data", "dataEnhanced"], - "optionalPlugins": [] -} diff --git a/x-pack/plugins/metrics_entities/server/error_with_status_code.ts b/x-pack/plugins/metrics_entities/server/error_with_status_code.ts deleted file mode 100644 index 15f7797fa424f..0000000000000 --- a/x-pack/plugins/metrics_entities/server/error_with_status_code.ts +++ /dev/null @@ -1,17 +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. - */ - -export class ErrorWithStatusCode extends Error { - private readonly statusCode: number; - - constructor(message: string, statusCode: number) { - super(message); - this.statusCode = statusCode; - } - - public getStatusCode = (): number => this.statusCode; -} diff --git a/x-pack/plugins/metrics_entities/server/index.ts b/x-pack/plugins/metrics_entities/server/index.ts deleted file mode 100644 index 15b0d110dd178..0000000000000 --- a/x-pack/plugins/metrics_entities/server/index.ts +++ /dev/null @@ -1,28 +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 { schema } from '@kbn/config-schema'; - -import { PluginInitializerContext } from '../../../../src/core/server'; - -import { MetricsEntitiesPlugin } from './plugin'; - -// This exports static code and TypeScript types, -// as well as, Kibana Platform `plugin()` initializer. - -export const plugin = (initializerContext: PluginInitializerContext): MetricsEntitiesPlugin => { - return new MetricsEntitiesPlugin(initializerContext); -}; - -export type { MetricsEntitiesPluginSetup, MetricsEntitiesPluginStart } from './types'; - -export const config = { - schema: schema.object({ - // This plugin is experimental and should be disabled by default. - enabled: schema.boolean({ defaultValue: false }), - }), -}; diff --git a/x-pack/plugins/metrics_entities/server/modules/README.md b/x-pack/plugins/metrics_entities/server/modules/README.md deleted file mode 100644 index d4e28a2f83ed0..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Modules - -This is where all the module types exist so you can load different bundled modules -with a REST endpoint. \ No newline at end of file diff --git a/x-pack/plugins/metrics_entities/server/modules/host_entities/host_entities.json b/x-pack/plugins/metrics_entities/server/modules/host_entities/host_entities.json deleted file mode 100644 index ef6bcfc452860..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/host_entities/host_entities.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "id": "host_ent", - "description": "[host.name entities] grouped by @timestamp, host.name, os.name, and os.version, and aggregated on host.name", - "pivot": { - "group_by": { - "@timestamp": { - "date_histogram": { - "field": "@timestamp", - "calendar_interval": "1h" - } - }, - "host.name": { - "terms": { - "field": "host.name" - } - }, - "host.os.name": { - "terms": { - "field": "host.os.name", - "missing_bucket": true - } - }, - "host.os.version": { - "terms": { - "field": "host.os.version", - "missing_bucket": true - } - } - }, - "aggregations": { - "metrics.host.name.value_count": { - "value_count": { - "field": "host.name" - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/host_entities/host_entities_mapping.json b/x-pack/plugins/metrics_entities/server/modules/host_entities/host_entities_mapping.json deleted file mode 100644 index 1f1e93dabfb5f..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/host_entities/host_entities_mapping.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "mappings": { - "_meta": { - "index": "host_ent" - }, - "dynamic": "strict", - "properties": { - "@timestamp": { - "type": "date" - }, - "metrics": { - "properties": { - "host": { - "properties": { - "name": { - "properties": { - "value_count": { - "type": "long" - } - } - } - } - } - } - }, - "host": { - "properties": { - "name": { - "type": "keyword" - }, - "os": { - "properties": { - "name": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - } - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/host_entities/index.ts b/x-pack/plugins/metrics_entities/server/modules/host_entities/index.ts deleted file mode 100644 index c3f34cd0f535c..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/host_entities/index.ts +++ /dev/null @@ -1,10 +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 hostEntities from './host_entities.json'; -import hostEntitiesMapping from './host_entities_mapping.json'; -export { hostEntities, hostEntitiesMapping }; diff --git a/x-pack/plugins/metrics_entities/server/modules/host_metrics/host_metrics.json b/x-pack/plugins/metrics_entities/server/modules/host_metrics/host_metrics.json deleted file mode 100644 index 8388721f98926..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/host_metrics/host_metrics.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "id": "host_met", - "description": "[host.name metrics] grouped by @timestamp and aggregated on host.name", - "pivot": { - "group_by": { - "@timestamp": { - "date_histogram": { - "field": "@timestamp", - "calendar_interval": "1h" - } - } - }, - "aggregations": { - "metrics.host.name.cardinality": { - "cardinality": { - "field": "host.name" - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/host_metrics/host_metrics_mapping.json b/x-pack/plugins/metrics_entities/server/modules/host_metrics/host_metrics_mapping.json deleted file mode 100644 index 7975fe3c6ed0a..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/host_metrics/host_metrics_mapping.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "mappings": { - "_meta": { - "index": "host_met" - }, - "properties": { - "metrics": { - "properties": { - "source": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - } - } - }, - "destination": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - } - } - }, - "network": { - "properties": { - "community_id": { - "properties": { - "cardinality": { - "type": "long" - } - } - } - } - }, - "host": { - "properties": { - "name": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - } - } - } - } - }, - "@timestamp": { - "type": "date" - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/host_metrics/index.ts b/x-pack/plugins/metrics_entities/server/modules/host_metrics/index.ts deleted file mode 100644 index e11c5321ede85..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/host_metrics/index.ts +++ /dev/null @@ -1,11 +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 hostMetrics from './host_metrics.json'; -import hostMetricsMapping from './host_metrics_mapping.json'; - -export { hostMetrics, hostMetricsMapping }; diff --git a/x-pack/plugins/metrics_entities/server/modules/index.ts b/x-pack/plugins/metrics_entities/server/modules/index.ts deleted file mode 100644 index 61aca783a6c03..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/index.ts +++ /dev/null @@ -1,71 +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 { hostMetrics, hostMetricsMapping } from './host_metrics'; -import { userMetrics, userMetricsMapping } from './user_metrics'; -import { ipMetrics, ipMetricsMapping } from './network_metrics'; -import { hostEntities, hostEntitiesMapping } from './host_entities'; -import { - destinationCountryIsoCodeEntities, - destinationCountryIsoCodeEntitiesMapping, - destinationIpEntities, - destinationIpEntitiesMapping, - sourceCountryIsoCodeEntities, - sourceCountryIsoCodeEntitiesMapping, - sourceIpEntities, - sourceIpEntitiesMapping, -} from './network_entities'; -import { Mappings, Transforms } from './types'; -import { userEntities, userEntitiesMapping } from './user_entities'; - -/** - * These module names will map 1 to 1 to the REST interface. - */ -export enum ModuleNames { - hostSummaryMetrics = 'host_metrics', - hostSummaryEntities = 'host_entities', - networkSummaryEntities = 'network_entities', - networkSummaryMetrics = 'network_metrics', - userSummaryEntities = 'user_entities', - userSummaryMetrics = 'user_metrics', -} - -/** - * Add any new folders as modules with their names below and grouped with - * key values. - */ -export const installableTransforms: Record = { - [ModuleNames.hostSummaryMetrics]: [hostMetrics], - [ModuleNames.hostSummaryEntities]: [hostEntities], - [ModuleNames.networkSummaryEntities]: [ - destinationIpEntities, - sourceIpEntities, - destinationCountryIsoCodeEntities, - sourceCountryIsoCodeEntities, - ], - [ModuleNames.networkSummaryMetrics]: [ipMetrics], - [ModuleNames.userSummaryEntities]: [userEntities], - [ModuleNames.userSummaryMetrics]: [userMetrics], -}; - -/** - * For all the mapping types, add each with their names below and grouped with - * key values. - */ -export const installableMappings: Record = { - [ModuleNames.hostSummaryMetrics]: [hostMetricsMapping], - [ModuleNames.hostSummaryEntities]: [hostEntitiesMapping], - [ModuleNames.networkSummaryEntities]: [ - sourceIpEntitiesMapping, - destinationIpEntitiesMapping, - destinationCountryIsoCodeEntitiesMapping, - sourceCountryIsoCodeEntitiesMapping, - ], - [ModuleNames.networkSummaryMetrics]: [ipMetricsMapping], - [ModuleNames.userSummaryEntities]: [userEntitiesMapping], - [ModuleNames.userSummaryMetrics]: [userMetricsMapping], -}; diff --git a/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_country_iso_code_entities.json b/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_country_iso_code_entities.json deleted file mode 100644 index 1f39c6c9552bd..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_country_iso_code_entities.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "id": "dest_iso_ent", - "description": "[destination.geo.country_iso_code entities] grouped by @timestamp and aggregated on source.bytes, destination.bytes, network.community_id, destination.ip, and source.ip", - "pivot": { - "group_by": { - "@timestamp": { - "date_histogram": { - "field": "@timestamp", - "calendar_interval": "1h" - } - }, - "destination.geo.country_iso_code": { - "terms": { - "field": "destination.geo.country_iso_code" - } - } - }, - "aggregations": { - "metrics.destination.geo.country_iso_code.value_count": { - "value_count": { - "field": "destination.geo.country_iso_code" - } - }, - "metrics.source.bytes.sum": { - "sum": { - "field": "source.bytes" - } - }, - "metrics.destination.bytes.sum": { - "sum": { - "field": "destination.bytes" - } - }, - "metrics.network.community_id.cardinality": { - "cardinality": { - "field": "network.community_id" - } - }, - "metrics.source.ip.cardinality": { - "cardinality": { - "field": "source.ip" - } - }, - "metrics.destination.ip.cardinality": { - "cardinality": { - "field": "destination.ip" - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_country_iso_code_entities_mapping.json b/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_country_iso_code_entities_mapping.json deleted file mode 100644 index e56ed7157afdc..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_country_iso_code_entities_mapping.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "mappings": { - "_meta": { - "index": "dest_iso_ent" - }, - "dynamic": "strict", - "properties": { - "@timestamp": { - "type": "date" - }, - "metrics": { - "properties": { - "source": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - }, - "geo": { - "properties": { - "country_iso_code": { - "properties": { - "value_count": { - "type": "long" - } - } - } - } - } - } - }, - "destination": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - }, - "geo": { - "properties": { - "country_iso_code": { - "properties": { - "value_count": { - "type": "long" - } - } - } - } - } - } - }, - "network": { - "properties": { - "community_id": { - "properties": { - "cardinality": { - "type": "long" - } - } - } - } - } - } - }, - "source": { - "properties": { - "ip": { - "type": "ip" - }, - "geo": { - "properties": { - "country_iso_code": { - "type": "keyword" - } - } - } - } - }, - "destination": { - "properties": { - "ip": { - "type": "ip" - }, - "geo": { - "properties": { - "country_iso_code": { - "type": "keyword" - } - } - } - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_ip_entities.json b/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_ip_entities.json deleted file mode 100644 index 7ecced9a11ebc..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_ip_entities.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "id": "dest_ip_ent", - "description": "[destination.ip entities] grouped by @timestamp and aggregated on destination.ip, source.bytes, destination.bytes, network.community_id, and source.ip", - "pivot": { - "group_by": { - "@timestamp": { - "date_histogram": { - "field": "@timestamp", - "calendar_interval": "1h" - } - }, - "destination.ip": { - "terms": { - "field": "destination.ip" - } - } - }, - "aggregations": { - "metrics.destination.ip.value_count": { - "value_count": { - "field": "destination.ip" - } - }, - "metrics.source.bytes.sum": { - "sum": { - "field": "source.bytes" - } - }, - "metrics.destination.bytes.sum": { - "sum": { - "field": "destination.bytes" - } - }, - "metrics.network.community_id.cardinality": { - "cardinality": { - "field": "network.community_id" - } - }, - "metrics.source.ip.cardinality": { - "cardinality": { - "field": "source.ip" - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_ip_entities_mapping.json b/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_ip_entities_mapping.json deleted file mode 100644 index ef7e1050c9c5d..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_entities/destination_ip_entities_mapping.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "mappings": { - "_meta": { - "index": "dest_ip_ent" - }, - "dynamic": "strict", - "properties": { - "@timestamp": { - "type": "date" - }, - "metrics": { - "properties": { - "source": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - } - } - }, - "destination": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - } - } - }, - "network": { - "properties": { - "community_id": { - "properties": { - "cardinality": { - "type": "long" - } - } - } - } - } - } - }, - "source": { - "properties": { - "ip": { - "type": "ip" - } - } - }, - "destination": { - "properties": { - "ip": { - "type": "ip" - } - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/network_entities/index.ts b/x-pack/plugins/metrics_entities/server/modules/network_entities/index.ts deleted file mode 100644 index b54425763effb..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_entities/index.ts +++ /dev/null @@ -1,26 +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 sourceIpEntities from './source_ip_entities.json'; -import destinationIpEntities from './destination_ip_entities.json'; -import sourceIpEntitiesMapping from './source_ip_entities_mapping.json'; -import destinationIpEntitiesMapping from './destination_ip_entities_mapping.json'; -import destinationCountryIsoCodeEntities from './destination_country_iso_code_entities.json'; -import destinationCountryIsoCodeEntitiesMapping from './destination_country_iso_code_entities_mapping.json'; -import sourceCountryIsoCodeEntities from './source_country_iso_code_entities.json'; -import sourceCountryIsoCodeEntitiesMapping from './source_country_iso_code_entities_mapping.json'; - -export { - sourceIpEntities, - destinationIpEntities, - sourceCountryIsoCodeEntities, - sourceCountryIsoCodeEntitiesMapping, - destinationCountryIsoCodeEntities, - destinationCountryIsoCodeEntitiesMapping, - sourceIpEntitiesMapping, - destinationIpEntitiesMapping, -}; diff --git a/x-pack/plugins/metrics_entities/server/modules/network_entities/source_country_iso_code_entities.json b/x-pack/plugins/metrics_entities/server/modules/network_entities/source_country_iso_code_entities.json deleted file mode 100644 index 60021b975b21d..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_entities/source_country_iso_code_entities.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "id": "src_iso_ent", - "description": "[source.geo.country_iso_code entities] grouped by @timestamp and aggregated on source.geo.country_iso_code, source.bytes, destination.bytes, network.community_id, source.ip, and destination.ip", - "pivot": { - "group_by": { - "@timestamp": { - "date_histogram": { - "field": "@timestamp", - "calendar_interval": "1h" - } - }, - "source.geo.country_iso_code": { - "terms": { - "field": "source.geo.country_iso_code" - } - } - }, - "aggregations": { - "metrics.source.geo.country_iso_code.value_count": { - "value_count": { - "field": "source.geo.country_iso_code" - } - }, - "metrics.source.bytes.sum": { - "sum": { - "field": "source.bytes" - } - }, - "metrics.destination.bytes.sum": { - "sum": { - "field": "destination.bytes" - } - }, - "metrics.network.community_id.cardinality": { - "cardinality": { - "field": "network.community_id" - } - }, - "metrics.source.ip.cardinality": { - "cardinality": { - "field": "source.ip" - } - }, - "metrics.destination.ip.cardinality": { - "cardinality": { - "field": "destination.ip" - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/network_entities/source_country_iso_code_entities_mapping.json b/x-pack/plugins/metrics_entities/server/modules/network_entities/source_country_iso_code_entities_mapping.json deleted file mode 100644 index 0a44016be6a2c..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_entities/source_country_iso_code_entities_mapping.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "mappings": { - "_meta": { - "index": "src_iso_ent" - }, - "dynamic": "strict", - "properties": { - "@timestamp": { - "type": "date" - }, - "metrics": { - "properties": { - "source": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - }, - "geo": { - "properties": { - "country_iso_code": { - "properties": { - "value_count": { - "type": "long" - } - } - } - } - } - } - }, - "destination": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - }, - "geo": { - "properties": { - "country_iso_code": { - "properties": { - "value_count": { - "type": "long" - } - } - } - } - } - } - }, - "network": { - "properties": { - "community_id": { - "properties": { - "cardinality": { - "type": "long" - } - } - } - } - } - } - }, - "source": { - "properties": { - "ip": { - "type": "ip" - }, - "geo": { - "properties": { - "country_iso_code": { - "type": "keyword" - } - } - } - } - }, - "destination": { - "properties": { - "ip": { - "type": "ip" - }, - "geo": { - "properties": { - "country_iso_code": { - "type": "keyword" - } - } - } - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/network_entities/source_ip_entities.json b/x-pack/plugins/metrics_entities/server/modules/network_entities/source_ip_entities.json deleted file mode 100644 index 3de6669c7bedb..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_entities/source_ip_entities.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "id": "src_ip_ent", - "description": "[source.ip entities] grouped by @timestamp and aggregated on destination.ip, source.bytes, destination.bytes, network.community_id, and destination.ip", - "pivot": { - "group_by": { - "@timestamp": { - "date_histogram": { - "field": "@timestamp", - "calendar_interval": "1h" - } - }, - "source.ip": { - "terms": { - "field": "source.ip" - } - } - }, - "aggregations": { - "metrics.source.ip.value_count": { - "value_count": { - "field": "source.ip" - } - }, - "metrics.source.bytes.sum": { - "sum": { - "field": "source.bytes" - } - }, - "metrics.destination.bytes.sum": { - "sum": { - "field": "destination.bytes" - } - }, - "metrics.network.community_id.cardinality": { - "cardinality": { - "field": "network.community_id" - } - }, - "metrics.destination.ip.cardinality": { - "cardinality": { - "field": "destination.ip" - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/network_entities/source_ip_entities_mapping.json b/x-pack/plugins/metrics_entities/server/modules/network_entities/source_ip_entities_mapping.json deleted file mode 100644 index 64d9e48afcee9..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_entities/source_ip_entities_mapping.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "mappings": { - "_meta": { - "index": "src_ip_ent" - }, - "dynamic": "strict", - "properties": { - "@timestamp": { - "type": "date" - }, - "metrics": { - "properties": { - "source": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - } - } - }, - "destination": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - } - } - }, - "network": { - "properties": { - "community_id": { - "properties": { - "cardinality": { - "type": "long" - } - } - } - } - } - } - }, - "source": { - "properties": { - "ip": { - "type": "ip" - } - } - }, - "destination": { - "properties": { - "ip": { - "type": "ip" - } - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/network_metrics/index.ts b/x-pack/plugins/metrics_entities/server/modules/network_metrics/index.ts deleted file mode 100644 index 216b85234dda4..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_metrics/index.ts +++ /dev/null @@ -1,11 +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 ipMetrics from './ip_metrics.json'; -import ipMetricsMapping from './ip_metrics_mapping.json'; - -export { ipMetrics, ipMetricsMapping }; diff --git a/x-pack/plugins/metrics_entities/server/modules/network_metrics/ip_metrics.json b/x-pack/plugins/metrics_entities/server/modules/network_metrics/ip_metrics.json deleted file mode 100644 index ed953be84f3da..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_metrics/ip_metrics.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "id": "ip_met", - "description": "[source.ip metrics] grouped by @timestamp, source.ip, destination.ip and aggregated on tls.version, suricata.eve.tls.version, zeek.ssl.version, dns.question.name, and zeek.dns.query", - "pivot": { - "group_by": { - "@timestamp": { - "date_histogram": { - "field": "@timestamp", - "calendar_interval": "1h" - } - } - }, - "aggregations": { - "metrics.source.ip.cardinality": { - "cardinality": { - "field": "source.ip" - } - }, - "metrics.destination.ip.cardinality": { - "cardinality": { - "field": "destination.ip" - } - }, - "metrics.network": { - "filter": { - "bool": { - "should": [ - { - "exists": { - "field": "source.ip" - } - }, - { - "exists": { - "field": "destination.ip" - } - } - ], - "minimum_should_match": 1 - } - }, - "aggs": { - "events.value_count": { - "value_count": { - "field": "@timestamp" - } - }, - "tls": { - "filter": { - "bool": { - "should": [ - { - "exists": { - "field": "tls.version" - } - }, - { - "exists": { - "field": "suricata.eve.tls.version" - } - }, - { - "exists": { - "field": "zeek.ssl.version" - } - } - ], - "minimum_should_match": 1 - } - }, - "aggs": { - "version.value_count": { - "value_count": { - "field": "@timestamp" - } - } - } - } - } - }, - "metrics.dns": { - "filter": { - "bool": { - "should": [ - { - "exists": { - "field": "dns.question.name" - } - }, - { - "term": { - "suricata.eve.dns.type": { - "value": "query" - } - } - }, - { - "exists": { - "field": "zeek.dns.query" - } - } - ], - "minimum_should_match": 1 - } - }, - "aggs": { - "queries.value_count": { - "value_count": { - "field": "@timestamp" - } - } - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/network_metrics/ip_metrics_mapping.json b/x-pack/plugins/metrics_entities/server/modules/network_metrics/ip_metrics_mapping.json deleted file mode 100644 index a855b6091f29c..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/network_metrics/ip_metrics_mapping.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "mappings": { - "_meta": { - "index": "ip_met" - }, - "dynamic": "strict", - "properties": { - "@timestamp": { - "type": "date" - }, - "metrics": { - "properties": { - "source": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - } - } - }, - "destination": { - "properties": { - "ip": { - "properties": { - "value_count": { - "type": "long" - }, - "cardinality": { - "type": "long" - } - } - }, - "bytes": { - "properties": { - "sum": { - "type": "long" - } - } - } - } - }, - "network": { - "properties": { - "events": { - "properties": { - "value_count": { - "type": "long" - } - } - }, - "tls": { - "properties": { - "version": { - "properties": { - "value_count": { - "type": "long" - } - } - } - } - } - } - }, - "dns": { - "properties": { - "queries": { - "properties": { - "value_count": { - "type": "long" - } - } - } - } - } - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/types.ts b/x-pack/plugins/metrics_entities/server/modules/types.ts deleted file mode 100644 index 22b11ed89f5c4..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/types.ts +++ /dev/null @@ -1,38 +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. - */ - -/** - * Loose type for the mappings - */ -export interface Mappings { - [key: string]: unknown; - mappings: { - [key: string]: unknown; - _meta: { - index: string; - }; - }; -} - -/** - * Loose type for the transforms. id is marked optional so we can delete it before - * pushing it through elastic client. - * TODO: Can we use stricter pre-defined typings for the transforms here or is this ours because we define it slightly different? - */ -export interface Transforms { - [key: string]: unknown; - id: string; - dest?: Partial<{ - index: string; - pipeline: string; - }>; - source?: Partial<{}>; - settings?: Partial<{ - max_page_search_size: number; - docs_per_second: number | null; - }>; -} diff --git a/x-pack/plugins/metrics_entities/server/modules/user_entities/index.ts b/x-pack/plugins/metrics_entities/server/modules/user_entities/index.ts deleted file mode 100644 index 9cc17c8f180f0..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/user_entities/index.ts +++ /dev/null @@ -1,10 +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 userEntities from './user_entities.json'; -import userEntitiesMapping from './user_entities_mapping.json'; -export { userEntities, userEntitiesMapping }; diff --git a/x-pack/plugins/metrics_entities/server/modules/user_entities/user_entities.json b/x-pack/plugins/metrics_entities/server/modules/user_entities/user_entities.json deleted file mode 100644 index aa41edcf40d41..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/user_entities/user_entities.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "id": "user_ent", - "description": "[user.name entities] grouped by @timestamp and aggregated on user.name, and event.categories of success, failure, and unknown", - "pivot": { - "group_by": { - "@timestamp": { - "date_histogram": { - "field": "@timestamp", - "calendar_interval": "1h" - } - }, - "user.name": { - "terms": { - "field": "user.name" - } - } - }, - "aggregations": { - "metrics.event.authentication": { - "filter": { - "term": { - "event.category": "authentication" - } - }, - "aggs": { - "success.value_count": { - "filter": { - "term": { - "event.outcome": "success" - } - } - }, - "failure.value_count": { - "filter": { - "term": { - "event.outcome": "failure" - } - } - }, - "unknown.value_count": { - "filter": { - "term": { - "event.outcome": "unknown" - } - } - } - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/user_entities/user_entities_mapping.json b/x-pack/plugins/metrics_entities/server/modules/user_entities/user_entities_mapping.json deleted file mode 100644 index 2532afa3040c6..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/user_entities/user_entities_mapping.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "mappings": { - "_meta": { - "index": "user_ent" - }, - "dynamic": "strict", - "properties": { - "@timestamp": { - "type": "date" - }, - "metrics": { - "properties": { - "event": { - "properties": { - "authentication": { - "properties": { - "failure": { - "properties": { - "value_count": { - "type": "long" - } - } - }, - "success": { - "properties": { - "value_count": { - "type": "long" - } - } - }, - "unknown": { - "properties": { - "value_count": { - "type": "long" - } - } - } - } - } - } - } - } - }, - "user": { - "properties": { - "name": { - "type": "keyword" - } - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/user_metrics/index.ts b/x-pack/plugins/metrics_entities/server/modules/user_metrics/index.ts deleted file mode 100644 index b7c6e65155ed2..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/user_metrics/index.ts +++ /dev/null @@ -1,11 +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 userMetrics from './user_metrics.json'; -import userMetricsMapping from './user_metrics_mapping.json'; - -export { userMetrics, userMetricsMapping }; diff --git a/x-pack/plugins/metrics_entities/server/modules/user_metrics/user_metrics.json b/x-pack/plugins/metrics_entities/server/modules/user_metrics/user_metrics.json deleted file mode 100644 index 86154bd8c68ec..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/user_metrics/user_metrics.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "id": "user_met", - "description": "[event.category authentication metrics] grouped by @timestamp and aggregated on success, failure, and unknown", - "source": { - "query": { - "bool": { - "filter": [ - { - "bool": { - "filter": [ - { - "term": { - "event.category": "authentication" - } - } - ] - } - } - ] - } - } - }, - "pivot": { - "group_by": { - "@timestamp": { - "date_histogram": { - "field": "@timestamp", - "calendar_interval": "1h" - } - } - }, - "aggregations": { - "metrics.event.authentication.success.value_count": { - "filter": { - "term": { - "event.outcome": "success" - } - } - }, - "metrics.event.authentication.failure.value_count": { - "filter": { - "term": { - "event.outcome": "failure" - } - } - }, - "metrics.event.authentication.unknown.value_count": { - "filter": { - "term": { - "event.outcome": "unknown" - } - } - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/modules/user_metrics/user_metrics_mapping.json b/x-pack/plugins/metrics_entities/server/modules/user_metrics/user_metrics_mapping.json deleted file mode 100644 index c63dcd2b4a429..0000000000000 --- a/x-pack/plugins/metrics_entities/server/modules/user_metrics/user_metrics_mapping.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "mappings": { - "_meta": { - "index": "user_met" - }, - "dynamic": "strict", - "properties": { - "metrics": { - "properties": { - "event": { - "properties": { - "authentication": { - "properties": { - "failure": { - "properties": { - "value_count": { - "type": "long" - } - } - }, - "success": { - "properties": { - "value_count": { - "type": "long" - } - } - }, - "unknown": { - "properties": { - "value_count": { - "type": "long" - } - } - } - } - } - } - } - } - }, - "@timestamp": { - "type": "date" - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/plugin.ts b/x-pack/plugins/metrics_entities/server/plugin.ts deleted file mode 100644 index c2eb16a1f616e..0000000000000 --- a/x-pack/plugins/metrics_entities/server/plugin.ts +++ /dev/null @@ -1,90 +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, - CoreStart, - Logger, - Plugin, - PluginInitializerContext, -} from '../../../../src/core/server'; - -import { - ContextProvider, - ContextProviderReturn, - MetricsEntitiesPluginSetup, - MetricsEntitiesPluginStart, - MetricsEntitiesRequestHandlerContext, -} from './types'; -import { getTransforms, postTransforms } from './routes'; -import { MetricsEntitiesClient } from './services/metrics_entities_client'; -import { deleteTransforms } from './routes/delete_transforms'; - -export class MetricsEntitiesPlugin - implements Plugin -{ - private readonly logger: Logger; - private kibanaVersion: string; - - constructor(initializerContext: PluginInitializerContext) { - this.logger = initializerContext.logger.get(); - this.kibanaVersion = initializerContext.env.packageInfo.version; - } - - public setup(core: CoreSetup): MetricsEntitiesPluginSetup { - const router = core.http.createRouter(); - - core.http.registerRouteHandlerContext( - 'metricsEntities', - this.createRouteHandlerContext() - ); - - // Register server side APIs - // TODO: Add all of these into a separate file and call that file called init_routes.ts - getTransforms(router); - postTransforms(router); - deleteTransforms(router); - - return { - getMetricsEntitiesClient: (esClient): MetricsEntitiesClient => - new MetricsEntitiesClient({ - esClient, - kibanaVersion: this.kibanaVersion, - logger: this.logger, - }), - }; - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public start(core: CoreStart): void { - this.logger.debug('Starting plugin'); - } - - public stop(): void { - this.logger.debug('Stopping plugin'); - } - - private createRouteHandlerContext = (): ContextProvider => { - return async (context): ContextProviderReturn => { - const { - core: { - elasticsearch: { - client: { asCurrentUser: esClient }, - }, - }, - } = context; - return { - getMetricsEntitiesClient: (): MetricsEntitiesClient => - new MetricsEntitiesClient({ - esClient, - kibanaVersion: this.kibanaVersion, - logger: this.logger, - }), - }; - }; - }; -} diff --git a/x-pack/plugins/metrics_entities/server/routes/delete_transforms.ts b/x-pack/plugins/metrics_entities/server/routes/delete_transforms.ts deleted file mode 100644 index 531e90963add4..0000000000000 --- a/x-pack/plugins/metrics_entities/server/routes/delete_transforms.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { schema } from '@kbn/config-schema'; - -import { IRouter } from '../../../../../src/core/server'; -import { METRICS_ENTITIES_TRANSFORMS } from '../../common/constants'; -import { ModuleNames } from '../modules'; - -import { getMetricsEntitiesClient } from './utils/get_metrics_entities_client'; - -/** - * Deletes transforms. - * NOTE: We use a POST rather than a DELETE on purpose here to ensure that there - * are not problems with the body being sent. - * @param router The router to delete the collection of transforms - */ -export const deleteTransforms = (router: IRouter): void => { - router.post( - { - path: `${METRICS_ENTITIES_TRANSFORMS}/_delete`, - validate: { - // TODO: Add the validation instead of allowing handler to have access to raw non-validated in runtime - body: schema.object({}, { unknowns: 'allow' }), - query: schema.object({}, { unknowns: 'allow' }), - }, - }, - async (context, request, response) => { - // TODO: Type this through validation above and remove the weird casting of: "as { modules: ModuleNames };" - // TODO: Validate for runtime that the module exists or not and throw before pushing the module name lower - // TODO: Change modules to be part of the body and become an array of values - // TODO: Wrap this in a try catch block and report errors - const { - modules, - prefix = '', - suffix = '', - } = request.body as { - modules: ModuleNames[]; - prefix: string; - suffix: string; - }; - const metrics = getMetricsEntitiesClient(context); - await metrics.deleteTransforms({ modules, prefix, suffix }); - - return response.custom({ - statusCode: 204, - }); - } - ); -}; diff --git a/x-pack/plugins/metrics_entities/server/routes/get_transforms.ts b/x-pack/plugins/metrics_entities/server/routes/get_transforms.ts deleted file mode 100644 index cda61512ce293..0000000000000 --- a/x-pack/plugins/metrics_entities/server/routes/get_transforms.ts +++ /dev/null @@ -1,36 +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 { IRouter } from '../../../../../src/core/server'; -import { METRICS_ENTITIES_TRANSFORMS } from '../../common/constants'; - -import { getMetricsEntitiesClient } from './utils/get_metrics_entities_client'; - -/** - * Returns all transforms from all modules - * TODO: Add support for specific modules and prefix - * @param router The router to get the collection of transforms - */ -export const getTransforms = (router: IRouter): void => { - router.get( - { - path: METRICS_ENTITIES_TRANSFORMS, - // TODO: Add the validation instead of false - // TODO: Add the prefix and module support - validate: false, - }, - async (context, _, response) => { - const metrics = getMetricsEntitiesClient(context); - const summaries = await metrics.getTransforms(); - return response.ok({ - body: { - summaries, - }, - }); - } - ); -}; diff --git a/x-pack/plugins/metrics_entities/server/routes/index.ts b/x-pack/plugins/metrics_entities/server/routes/index.ts deleted file mode 100644 index 9470772f46d70..0000000000000 --- a/x-pack/plugins/metrics_entities/server/routes/index.ts +++ /dev/null @@ -1,10 +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. - */ - -export * from './delete_transforms'; -export * from './get_transforms'; -export * from './post_transforms'; diff --git a/x-pack/plugins/metrics_entities/server/routes/post_transforms.ts b/x-pack/plugins/metrics_entities/server/routes/post_transforms.ts deleted file mode 100644 index f5a46ec04611d..0000000000000 --- a/x-pack/plugins/metrics_entities/server/routes/post_transforms.ts +++ /dev/null @@ -1,96 +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 { schema } from '@kbn/config-schema'; - -import { IRouter } from '../../../../../src/core/server'; -import { METRICS_ENTITIES_TRANSFORMS } from '../../common/constants'; -import { ModuleNames } from '../modules'; - -import { getMetricsEntitiesClient } from './utils/get_metrics_entities_client'; - -/** - * Creates transforms. - * @param router The router to get the collection of transforms - */ -export const postTransforms = (router: IRouter): void => { - router.post( - { - path: METRICS_ENTITIES_TRANSFORMS, - validate: { - // TODO: Add the validation instead of allowing handler to have access to raw non-validated in runtime - body: schema.object({}, { unknowns: 'allow' }), - query: schema.object({}, { unknowns: 'allow' }), - }, - }, - async (context, request, response) => { - // TODO: Type this through validation above and remove the weird casting of: "as { modules: ModuleNames };" - // TODO: Validate for runtime that the module exists or not and throw before pushing the module name lower - // TODO: Change modules to be part of the body and become an array of values - // TODO: Wrap this in a try catch block and report errors - const { - modules, - auto_start: autoStart = false, - settings: { - max_page_search_size: maxPageSearchSize = 500, - docs_per_second: docsPerSecond = undefined, - } = { - docsPerSecond: undefined, - maxPageSearchSize: 500, - }, - frequency = '1m', - indices, - query = { match_all: {} }, - prefix = '', - suffix = '', - sync = { - time: { - delay: '60s', - field: '@timestamp', - }, - }, - } = request.body as { - modules: ModuleNames[]; - auto_start: boolean; - indices: string[]; - // We can blow up at 65 character+ for transform id. We need to validate the prefix + transform jobs and return an error - prefix: string; - query: object; - suffix: string; - frequency: string; - settings: { - max_page_search_size: number; - docs_per_second: number; - }; - sync: { - time: { - delay: string; - field: string; - }; - }; - }; - const metrics = getMetricsEntitiesClient(context); - await metrics.postTransforms({ - autoStart, - docsPerSecond, - frequency, - indices, - maxPageSearchSize, - modules, - prefix, - query, - suffix, - sync, - }); - - return response.custom({ - body: { acknowledged: true }, - statusCode: 201, - }); - } - ); -}; diff --git a/x-pack/plugins/metrics_entities/server/routes/utils/get_metrics_entities_client.ts b/x-pack/plugins/metrics_entities/server/routes/utils/get_metrics_entities_client.ts deleted file mode 100644 index fdbbd98128741..0000000000000 --- a/x-pack/plugins/metrics_entities/server/routes/utils/get_metrics_entities_client.ts +++ /dev/null @@ -1,21 +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 { ErrorWithStatusCode } from '../../error_with_status_code'; -import { MetricsEntitiesClient } from '../../services/metrics_entities_client'; -import type { MetricsEntitiesRequestHandlerContext } from '../../types'; - -export const getMetricsEntitiesClient = ( - context: MetricsEntitiesRequestHandlerContext -): MetricsEntitiesClient => { - const metricsEntities = context.metricsEntities?.getMetricsEntitiesClient(); - if (metricsEntities == null) { - throw new ErrorWithStatusCode('Metrics Entities is not found as a plugin', 404); - } else { - return metricsEntities; - } -}; diff --git a/x-pack/plugins/metrics_entities/server/routes/utils/index.ts b/x-pack/plugins/metrics_entities/server/routes/utils/index.ts deleted file mode 100644 index eee678d64b30d..0000000000000 --- a/x-pack/plugins/metrics_entities/server/routes/utils/index.ts +++ /dev/null @@ -1,8 +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. - */ - -export * from './get_metrics_entities_client'; diff --git a/x-pack/plugins/metrics_entities/server/scripts/check_env_variables.sh b/x-pack/plugins/metrics_entities/server/scripts/check_env_variables.sh deleted file mode 100755 index df2354ed8398a..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/check_env_variables.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -# -# 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. -# - -# Add this to the start of any scripts to detect if env variables are set - -set -e - -if [ -z "${ELASTICSEARCH_USERNAME}" ]; then - echo "Set ELASTICSEARCH_USERNAME in your environment" - exit 1 -fi - -if [ -z "${ELASTICSEARCH_PASSWORD}" ]; then - echo "Set ELASTICSEARCH_PASSWORD in your environment" - exit 1 -fi - -if [ -z "${ELASTICSEARCH_URL}" ]; then - echo "Set ELASTICSEARCH_URL in your environment" - exit 1 -fi - -if [ -z "${KIBANA_URL}" ]; then - echo "Set KIBANA_URL in your environment" - exit 1 -fi diff --git a/x-pack/plugins/metrics_entities/server/scripts/delete_examples/all.json b/x-pack/plugins/metrics_entities/server/scripts/delete_examples/all.json deleted file mode 100644 index b07028d0cab89..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/delete_examples/all.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "prefix": "all", - "modules": [ - "host_metrics", - "host_entities", - "network_metrics", - "network_entities", - "user_entities", - "user_metrics" - ] -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/delete_examples/all_prefix_auditbeat.json b/x-pack/plugins/metrics_entities/server/scripts/delete_examples/all_prefix_auditbeat.json deleted file mode 100644 index 5b20203075924..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/delete_examples/all_prefix_auditbeat.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "prefix": "auditbeat", - "modules": [ - "host_metrics", - "host_entities", - "network_metrics", - "network_entities", - "user_entities", - "user_metrics" - ] -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/delete_examples/network_entities_auditbeat.json b/x-pack/plugins/metrics_entities/server/scripts/delete_examples/network_entities_auditbeat.json deleted file mode 100644 index b1e21ebbc9bd6..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/delete_examples/network_entities_auditbeat.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "modules": ["network_entities"] -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/delete_examples/one_module.json b/x-pack/plugins/metrics_entities/server/scripts/delete_examples/one_module.json deleted file mode 100644 index 2e9a62b9fbe82..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/delete_examples/one_module.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "modules": ["user_entities"] -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/delete_examples/two_modules.json b/x-pack/plugins/metrics_entities/server/scripts/delete_examples/two_modules.json deleted file mode 100644 index e3292834f3d08..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/delete_examples/two_modules.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "modules": ["host_metrics", "host_entities"] -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/delete_transforms.sh b/x-pack/plugins/metrics_entities/server/scripts/delete_transforms.sh deleted file mode 100755 index d4c03411cbcca..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/delete_transforms.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -# -# 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. -# - -set -e -./check_env_variables.sh - -# Uses a default if no argument is specified -FILE=${1:-./post_examples/one_module.json} - -# Example: ./delete_transforms.sh ./delete_examples/one_module.json -curl -s -k \ - -H 'Content-Type: application/json' \ - -H 'kbn-xsrf: 123' \ - -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ - -X POST ${KIBANA_URL}${SPACE_URL}/api/metrics_entities/transforms/_delete \ - -d @${FILE} \ - | jq . diff --git a/x-pack/plugins/metrics_entities/server/scripts/get_transforms.sh b/x-pack/plugins/metrics_entities/server/scripts/get_transforms.sh deleted file mode 100755 index 34f7e4b83cc39..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/get_transforms.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -# -# 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. -# - -set -e -./check_env_variables.sh - -# Example: ./get_transforms.sh -curl -s -k \ - -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ - -X GET ${KIBANA_URL}${SPACE_URL}/api/metrics_entities/transforms | jq . diff --git a/x-pack/plugins/metrics_entities/server/scripts/hard_reset.sh b/x-pack/plugins/metrics_entities/server/scripts/hard_reset.sh deleted file mode 100755 index 69acf10764936..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/hard_reset.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -# -# 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. -# - -# TODO Make this work - -set -e -./check_env_variables.sh - -# remove all templates -# add all templates again and start them - diff --git a/x-pack/plugins/metrics_entities/server/scripts/post_examples/all.json b/x-pack/plugins/metrics_entities/server/scripts/post_examples/all.json deleted file mode 100644 index dac53a63dad55..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/post_examples/all.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "prefix": "all", - "modules": [ - "host_metrics", - "host_entities", - "network_metrics", - "network_entities", - "user_entities", - "user_metrics" - ], - "indices": [ - "auditbeat-*", - "endgame-*", - "filebeat-*", - "logs-*", - "packetbeat-*", - "winlogbeat-*", - "-*elastic-cloud-logs-*" - ], - "auto_start": true, - "settings": { - "max_page_search_size": 5000 - }, - "query": { - "range": { - "@timestamp": { - "gte": "now-1d/d", - "format": "strict_date_optional_time" - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/post_examples/all_auditbeat.json b/x-pack/plugins/metrics_entities/server/scripts/post_examples/all_auditbeat.json deleted file mode 100644 index 5a2f6b5024689..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/post_examples/all_auditbeat.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "modules": [ - "host_metrics", - "host_entities", - "network_metrics", - "network_entities", - "user_entities", - "user_metrics" - ], - "indices": ["auditbeat-*"], - "auto_start": true, - "settings": { - "max_page_search_size": 5000 - }, - "query": { - "range": { - "@timestamp": { - "gte": "now-1d/d", - "format": "strict_date_optional_time" - } - } - } -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/post_examples/network_entities_auditbeat.json b/x-pack/plugins/metrics_entities/server/scripts/post_examples/network_entities_auditbeat.json deleted file mode 100644 index 379a5733a91f9..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/post_examples/network_entities_auditbeat.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "modules": ["network_entities"], - "indices": ["auditbeat-*"] -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_allindices_autostart.json b/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_allindices_autostart.json deleted file mode 100644 index 9872706ff1ac2..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_allindices_autostart.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "modules": ["network_metrics"], - "indices": [ - "auditbeat-*", - "endgame-*", - "filebeat-*", - "logs-*", - "packetbeat-*", - "winlogbeat-*", - "-*elastic-cloud-logs-*" - ], - "auto_start": true, - "query": { - "range": { - "@timestamp": { - "gte": "now-1d/d", - "format": "strict_date_optional_time" - } - } - }, - "settings": { - "max_page_search_size": 5000 - } -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_auditbeat.json b/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_auditbeat.json deleted file mode 100644 index 4ce4db5da9f23..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_auditbeat.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "modules": ["network_metrics"], - "indices": ["auditbeat-*"], - "auto_start": true, - "query": { - "range": { - "@timestamp": { - "gte": "now-1d/d", - "format": "strict_date_optional_time" - } - } - }, - "settings": { - "max_page_search_size": 5000 - } -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_auto_start.json b/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_auto_start.json deleted file mode 100644 index d5a87c80a44a0..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_auto_start.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "modules": ["host_metrics"], - "indices": ["auditbeat-*"], - "auto_start": true, - "settings": { - "max_page_search_size": 5000 - } -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_prefix_auditbeat.json b/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_prefix_auditbeat.json deleted file mode 100644 index f20875f28ffa3..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/post_examples/one_module_prefix_auditbeat.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "modules": ["host_metrics"], - "indices": ["auditbeat-*"], - "prefix": ["default_"] -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/post_examples/two_modules_all.json b/x-pack/plugins/metrics_entities/server/scripts/post_examples/two_modules_all.json deleted file mode 100644 index 8ec9401b94433..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/post_examples/two_modules_all.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "modules": ["network_metrics", "network_entities"], - "indices": [ - "auditbeat-*", - "endgame-*", - "filebeat-*", - "logs-*", - "packetbeat-*", - "winlogbeat-*", - "-*elastic-cloud-logs-*" - ], - "auto_start": true, - "query": { - "range": { - "@timestamp": { - "gte": "now-1d/d", - "format": "strict_date_optional_time" - } - } - }, - "settings": { - "max_page_search_size": 5000 - } -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/post_examples/two_modules_auditbeat.json b/x-pack/plugins/metrics_entities/server/scripts/post_examples/two_modules_auditbeat.json deleted file mode 100644 index 5229cd88fc433..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/post_examples/two_modules_auditbeat.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "modules": ["host_metrics", "host_entities"], - "indices": ["auditbeat-*"] -} diff --git a/x-pack/plugins/metrics_entities/server/scripts/post_transforms.sh b/x-pack/plugins/metrics_entities/server/scripts/post_transforms.sh deleted file mode 100755 index 9dd4169cc01d6..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/post_transforms.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -# -# 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. -# - -set -e -./check_env_variables.sh - -# Uses a default if no argument is specified -FILE=${1:-./post_examples/one_module_auditbeat.json} - -# Example: ./post_transforms.sh ./post_examples/one_module_auditbeat.json -# Example: ./post_transforms.sh ./post_examples/one_module_namespace_auditbeat.json -curl -s -k \ - -H 'Content-Type: application/json' \ - -H 'kbn-xsrf: 123' \ - -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ - -X POST ${KIBANA_URL}${SPACE_URL}/api/metrics_entities/transforms \ - -d @${FILE} \ - | jq . diff --git a/x-pack/plugins/metrics_entities/server/scripts/update_transforms.sh b/x-pack/plugins/metrics_entities/server/scripts/update_transforms.sh deleted file mode 100755 index bccf49e2d1b0d..0000000000000 --- a/x-pack/plugins/metrics_entities/server/scripts/update_transforms.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -# -# 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. -# - -set -e -./check_env_variables.sh - -# TODO Make this work diff --git a/x-pack/plugins/metrics_entities/server/services/delete_transforms.ts b/x-pack/plugins/metrics_entities/server/services/delete_transforms.ts deleted file mode 100644 index ef172bcbf7c02..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/delete_transforms.ts +++ /dev/null @@ -1,38 +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 { ElasticsearchClient } from 'kibana/server'; - -import { ModuleNames, installableMappings, installableTransforms } from '../modules'; -import type { Logger } from '../../../../../src/core/server'; - -import { uninstallMappings } from './uninstall_mappings'; -import { uninstallTransforms } from './uninstall_transforms'; - -interface DeleteTransformsOptions { - esClient: ElasticsearchClient; - logger: Logger; - modules: ModuleNames[]; - prefix: string; - suffix: string; -} - -export const deleteTransforms = async ({ - esClient, - logger, - modules, - prefix, - suffix, -}: DeleteTransformsOptions): Promise => { - for (const moduleName of modules) { - const mappings = installableMappings[moduleName]; - const transforms = installableTransforms[moduleName]; - - await uninstallTransforms({ esClient, logger, prefix, suffix, transforms }); - await uninstallMappings({ esClient, logger, mappings, prefix, suffix }); - } -}; diff --git a/x-pack/plugins/metrics_entities/server/services/get_transforms.ts b/x-pack/plugins/metrics_entities/server/services/get_transforms.ts deleted file mode 100644 index 07c3d95b0943a..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/get_transforms.ts +++ /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 { ElasticsearchClient } from 'kibana/server'; - -import type { Logger } from '../../../../../src/core/server'; - -interface GetTransformsOptions { - esClient: ElasticsearchClient; - logger: Logger; -} - -// TODO: Type the Promise to a stronger type -export const getTransforms = async ({ esClient }: GetTransformsOptions): Promise => { - const body = await esClient.transform.getTransform({ - size: 1000, - transform_id: '*', - }); - return body; -}; diff --git a/x-pack/plugins/metrics_entities/server/services/index.ts b/x-pack/plugins/metrics_entities/server/services/index.ts deleted file mode 100644 index 71611d2a5eae0..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './delete_transforms'; -export * from './get_transforms'; -export * from './install_mappings'; -export * from './install_transforms'; -export * from './metrics_entities_client'; -export * from './post_transforms'; -export * from './uninstall_mappings'; -export * from './uninstall_transforms'; diff --git a/x-pack/plugins/metrics_entities/server/services/install_mappings.ts b/x-pack/plugins/metrics_entities/server/services/install_mappings.ts deleted file mode 100644 index da42f9916ff9b..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/install_mappings.ts +++ /dev/null @@ -1,82 +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 { ElasticsearchClient } from 'kibana/server'; - -import { Mappings } from '../modules/types'; -import type { Logger } from '../../../../../src/core/server'; - -import { - computeMappingId, - getIndexExists, - logMappingDebug, - logMappingError, - logMappingInfo, -} from './utils'; - -interface CreateMappingOptions { - esClient: ElasticsearchClient; - mappings: Mappings[]; - prefix: string; - suffix: string; - logger: Logger; - kibanaVersion: string; -} - -export const installMappings = async ({ - esClient, - kibanaVersion, - mappings, - prefix, - suffix, - logger, -}: CreateMappingOptions): Promise => { - for (const mapping of mappings) { - const { index } = mapping.mappings._meta; - const mappingId = computeMappingId({ id: index, prefix, suffix }); - const exists = await getIndexExists(esClient, mappingId); - const computedBody = { - ...mapping, - ...{ - mappings: { - ...mapping.mappings, - _meta: { - ...mapping.mappings._meta, - ...{ - created_by: 'metrics_entities', - index: mappingId, - version: kibanaVersion, - }, - }, - }, - }, - }; - if (!exists) { - try { - logMappingInfo({ id: mappingId, logger, message: 'does not exist, creating the mapping' }); - await esClient.indices.create({ - body: computedBody, - index: mappingId, - }); - } catch (error) { - logMappingError({ - error, - id: mappingId, - logger, - message: 'cannot install mapping', - postBody: computedBody, - }); - } - } else { - logMappingDebug({ - id: mappingId, - logger, - message: 'mapping already exists. It will not be recreated', - }); - } - } -}; diff --git a/x-pack/plugins/metrics_entities/server/services/install_transforms.ts b/x-pack/plugins/metrics_entities/server/services/install_transforms.ts deleted file mode 100644 index eec4f8d555356..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/install_transforms.ts +++ /dev/null @@ -1,122 +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 { ElasticsearchClient } from 'kibana/server'; - -import { Transforms } from '../modules/types'; -import type { Logger } from '../../../../../src/core/server'; - -import { - computeMappingId, - computeTransformId, - getTransformExists, - logTransformDebug, - logTransformError, - logTransformInfo, -} from './utils'; - -interface CreateTransformOptions { - esClient: ElasticsearchClient; - transforms: Transforms[]; - autoStart: boolean; - indices: string[]; - frequency: string; - logger: Logger; - query: object; - docsPerSecond: number | undefined; - maxPageSearchSize: number; - sync: { - time: { - delay: string; - field: string; - }; - }; - prefix: string; - suffix: string; -} - -export const installTransforms = async ({ - autoStart, - esClient, - frequency, - indices, - docsPerSecond, - logger, - maxPageSearchSize, - prefix, - suffix, - transforms, - query, - sync, -}: CreateTransformOptions): Promise => { - for (const transform of transforms) { - const destIndex = transform?.dest?.index ?? transform.id; - const computedMappingIndex = computeMappingId({ id: destIndex, prefix, suffix }); - const { id, ...transformNoId } = { - ...transform, - ...{ source: { ...transform.source, index: indices, query } }, - ...{ dest: { ...transform.dest, index: computedMappingIndex } }, - ...{ - settings: { - ...transform.settings, - docs_per_second: docsPerSecond, - max_page_search_size: maxPageSearchSize, - }, - }, - frequency, - sync, - }; - - const computedName = computeTransformId({ id, prefix, suffix }); - const exists = await getTransformExists(esClient, computedName); - if (!exists) { - try { - logTransformInfo({ - id: computedName, - logger, - message: 'does not exist, creating the transform', - }); - await esClient.transform.putTransform({ - body: transformNoId, - defer_validation: true, - transform_id: computedName, - }); - - if (autoStart) { - logTransformInfo({ - id: computedName, - logger, - message: 'is being auto started', - }); - await esClient.transform.startTransform({ - transform_id: computedName, - }); - } else { - logTransformInfo({ - id: computedName, - logger, - message: 'is not being auto started', - }); - } - } catch (error) { - logTransformError({ - error, - id: computedName, - logger, - message: 'Could not create and/or start', - postBody: transformNoId, - }); - } - } else { - logTransformDebug({ - id: computedName, - logger, - message: 'already exists. It will not be recreated', - }); - } - } -}; diff --git a/x-pack/plugins/metrics_entities/server/services/metrics_entities_client.ts b/x-pack/plugins/metrics_entities/server/services/metrics_entities_client.ts deleted file mode 100644 index 3905503df876d..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/metrics_entities_client.ts +++ /dev/null @@ -1,76 +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 { ElasticsearchClient } from 'kibana/server'; - -import type { Logger } from '../../../../../src/core/server'; - -import { getTransforms } from './get_transforms'; -import { - ConstructorOptions, - DeleteTransformsOptions, - PostTransformsOptions, -} from './metrics_entities_client_types'; -import { postTransforms } from './post_transforms'; -import { deleteTransforms } from './delete_transforms'; - -export class MetricsEntitiesClient { - private readonly esClient: ElasticsearchClient; - private readonly logger: Logger; - private readonly kibanaVersion: string; - - constructor({ esClient, logger, kibanaVersion }: ConstructorOptions) { - this.esClient = esClient; - this.logger = logger; - this.kibanaVersion = kibanaVersion; - } - - // TODO: Type the unknown to be stronger - public getTransforms = async (): Promise => { - const { esClient, logger } = this; - return getTransforms({ esClient, logger }); - }; - - public postTransforms = async ({ - autoStart, - frequency, - docsPerSecond, - maxPageSearchSize, - modules, - indices, - prefix, - suffix, - query, - sync, - }: PostTransformsOptions): Promise => { - const { esClient, logger, kibanaVersion } = this; - return postTransforms({ - autoStart, - docsPerSecond, - esClient, - frequency, - indices, - kibanaVersion, - logger, - maxPageSearchSize, - modules, - prefix, - query, - suffix, - sync, - }); - }; - - public deleteTransforms = async ({ - modules, - prefix, - suffix, - }: DeleteTransformsOptions): Promise => { - const { esClient, logger } = this; - return deleteTransforms({ esClient, logger, modules, prefix, suffix }); - }; -} diff --git a/x-pack/plugins/metrics_entities/server/services/metrics_entities_client_types.ts b/x-pack/plugins/metrics_entities/server/services/metrics_entities_client_types.ts deleted file mode 100644 index def26c5342ef9..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/metrics_entities_client_types.ts +++ /dev/null @@ -1,41 +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 { ElasticsearchClient } from 'kibana/server'; - -import type { Logger } from '../../../../../src/core/server'; -import { ModuleNames } from '../modules'; - -export interface ConstructorOptions { - esClient: ElasticsearchClient; - logger: Logger; - kibanaVersion: string; -} - -export interface PostTransformsOptions { - modules: ModuleNames[]; - autoStart: boolean; - frequency: string; - indices: string[]; - docsPerSecond: number | undefined; - maxPageSearchSize: number; - prefix: string; - query: object; - suffix: string; - sync: { - time: { - delay: string; - field: string; - }; - }; -} - -export interface DeleteTransformsOptions { - modules: ModuleNames[]; - prefix: string; - suffix: string; -} diff --git a/x-pack/plugins/metrics_entities/server/services/post_transforms.ts b/x-pack/plugins/metrics_entities/server/services/post_transforms.ts deleted file mode 100644 index f14f53d78f10e..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/post_transforms.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ElasticsearchClient } from 'kibana/server'; - -import { ModuleNames, installableMappings, installableTransforms } from '../modules'; -import type { Logger } from '../../../../../src/core/server'; - -import { installMappings } from './install_mappings'; -import { installTransforms } from './install_transforms'; - -interface PostTransformsOptions { - logger: Logger; - esClient: ElasticsearchClient; - modules: ModuleNames[]; - autoStart: boolean; - frequency: string; - indices: string[]; - docsPerSecond: number | undefined; - kibanaVersion: string; - maxPageSearchSize: number; - query: object; - prefix: string; - suffix: string; - sync: { - time: { - delay: string; - field: string; - }; - }; -} - -export const postTransforms = async ({ - autoStart, - logger, - esClient, - frequency, - indices, - docsPerSecond, - kibanaVersion, - maxPageSearchSize, - modules, - prefix, - suffix, - query, - sync, -}: PostTransformsOptions): Promise => { - for (const moduleName of modules) { - const mappings = installableMappings[moduleName]; - const transforms = installableTransforms[moduleName]; - - await installMappings({ esClient, kibanaVersion, logger, mappings, prefix, suffix }); - await installTransforms({ - autoStart, - docsPerSecond, - esClient, - frequency, - indices, - logger, - maxPageSearchSize, - prefix, - query, - suffix, - sync, - transforms, - }); - } -}; diff --git a/x-pack/plugins/metrics_entities/server/services/stop_transforms.ts b/x-pack/plugins/metrics_entities/server/services/stop_transforms.ts deleted file mode 100644 index 18476d8345cf2..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/stop_transforms.ts +++ /dev/null @@ -1,8 +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. - */ - -// TODO: Write this diff --git a/x-pack/plugins/metrics_entities/server/services/uninstall_mappings.ts b/x-pack/plugins/metrics_entities/server/services/uninstall_mappings.ts deleted file mode 100644 index b2ea9d96cda13..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/uninstall_mappings.ts +++ /dev/null @@ -1,55 +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 { ElasticsearchClient } from 'kibana/server'; - -import { Mappings } from '../modules/types'; -import type { Logger } from '../../../../../src/core/server'; - -import { computeMappingId, logMappingInfo } from './utils'; -import { logMappingError } from './utils/log_mapping_error'; - -interface UninstallMappingOptions { - esClient: ElasticsearchClient; - mappings: Mappings[]; - prefix: string; - suffix: string; - logger: Logger; -} - -export const uninstallMappings = async ({ - esClient, - logger, - mappings, - prefix, - suffix, -}: UninstallMappingOptions): Promise => { - const indices = mappings.map((mapping) => { - const { index } = mapping.mappings._meta; - return computeMappingId({ id: index, prefix, suffix }); - }); - logMappingInfo({ - id: indices.join(), - logger, - message: 'deleting indices', - }); - try { - await esClient.indices.delete({ - allow_no_indices: true, - ignore_unavailable: true, - index: indices, - }); - } catch (error) { - logMappingError({ - error, - id: indices.join(), - logger, - message: 'could not delete index', - postBody: undefined, - }); - } -}; diff --git a/x-pack/plugins/metrics_entities/server/services/uninstall_transforms.ts b/x-pack/plugins/metrics_entities/server/services/uninstall_transforms.ts deleted file mode 100644 index fbf59fc28af2f..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/uninstall_transforms.ts +++ /dev/null @@ -1,93 +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 { ElasticsearchClient } from 'kibana/server'; -import { asyncForEach } from '@kbn/std'; - -import { Transforms } from '../modules/types'; -import type { Logger } from '../../../../../src/core/server'; - -import { - computeTransformId, - getTransformExists, - logTransformError, - logTransformInfo, -} from './utils'; - -interface UninstallTransformsOptions { - esClient: ElasticsearchClient; - transforms: Transforms[]; - prefix: string; - suffix: string; - logger: Logger; -} - -/** - * Uninstalls all the transforms underneath a given module - */ -export const uninstallTransforms = async ({ - esClient, - logger, - prefix, - suffix, - transforms, -}: UninstallTransformsOptions): Promise => { - await asyncForEach(transforms, async (transform) => { - const { id } = transform; - const computedId = computeTransformId({ id, prefix, suffix }); - const exists = await getTransformExists(esClient, computedId); - if (exists) { - logTransformInfo({ - id: computedId, - logger, - message: 'stopping transform', - }); - try { - await esClient.transform.stopTransform({ - allow_no_match: true, - force: true, - timeout: '5s', - transform_id: computedId, - wait_for_completion: true, - }); - } catch (error) { - logTransformError({ - error, - id: computedId, - logger, - message: 'Could not stop transform, still attempting to delete it', - postBody: undefined, - }); - } - logTransformInfo({ - id: computedId, - logger, - message: 'deleting transform', - }); - try { - await esClient.transform.deleteTransform({ - force: true, - transform_id: computedId, - }); - } catch (error) { - logTransformError({ - error, - id: computedId, - logger, - message: 'Could not create and/or start', - postBody: undefined, - }); - } - } else { - logTransformInfo({ - id: computedId, - logger, - message: 'transform does not exist to delete', - }); - } - }); -}; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/compute_mapping_index.ts b/x-pack/plugins/metrics_entities/server/services/utils/compute_mapping_index.ts deleted file mode 100644 index bb1a7720fc575..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/compute_mapping_index.ts +++ /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 { computeTransformId } from './compute_transform_id'; - -export const computeMappingId = ({ - prefix, - id, - suffix, -}: { - prefix: string; - id: string; - suffix: string; -}): string => { - // TODO: This causes issues if above 65 character limit. We should limit the prefix - // and anything else on the incoming routes to avoid this causing an issue. We should still - // throw here in case I change the prefix or other names and cause issues. - const computedId = computeTransformId({ id, prefix, suffix }); - return `.${computedId}`; -}; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/compute_transform_id.ts b/x-pack/plugins/metrics_entities/server/services/utils/compute_transform_id.ts deleted file mode 100644 index dde4d98220549..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/compute_transform_id.ts +++ /dev/null @@ -1,33 +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 { ELASTIC_NAME } from '../../../common/constants'; - -export const computeTransformId = ({ - prefix, - id, - suffix, -}: { - prefix: string; - id: string; - suffix: string; -}): string => { - const prefixExists = prefix.trim() !== ''; - const suffixExists = suffix.trim() !== ''; - - // TODO: Check for invalid characters on the main route for prefixExists and suffixExists and do an invalidation - // if either have invalid characters for a job name. Might want to add that same check within the API too at a top level? - if (prefixExists && suffixExists) { - return `${ELASTIC_NAME}_${prefix}_${id}_${suffix}`; - } else if (prefixExists) { - return `${ELASTIC_NAME}_${prefix}_${id}`; - } else if (suffixExists) { - return `${ELASTIC_NAME}_${id}_${suffix}`; - } else { - return `${ELASTIC_NAME}_${id}`; - } -}; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/get_index_exists.ts b/x-pack/plugins/metrics_entities/server/services/utils/get_index_exists.ts deleted file mode 100644 index 7bac15d516221..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/get_index_exists.ts +++ /dev/null @@ -1,38 +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 { ElasticsearchClient } from 'kibana/server'; - -/** - * Tried and true, copied forever again and again, the way we check if an index exists - * with the least amount of privileges. - * @param esClient The client to check if the index already exists - * @param index The index to check for - * @returns true if it exists, otherwise false - */ -export const getIndexExists = async ( - esClient: ElasticsearchClient, - index: string -): Promise => { - try { - const response = await esClient.search({ - allow_no_indices: true, - body: { - terminate_after: 1, - }, - index, - size: 0, - }); - return response._shards.total > 0; - } catch (err) { - if (err.body?.status === 404) { - return false; - } else { - throw err.body ? err.body : err; - } - } -}; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/get_json.ts b/x-pack/plugins/metrics_entities/server/services/utils/get_json.ts deleted file mode 100644 index 71853f2a4ee66..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/get_json.ts +++ /dev/null @@ -1,10 +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. - */ - -// TODO: Move indent to configuration part or flip to default false -export const getJSON = (body: unknown, indent: boolean = true): string => - indent ? JSON.stringify(body, null, 2) : JSON.stringify(body); diff --git a/x-pack/plugins/metrics_entities/server/services/utils/get_transform_exists.ts b/x-pack/plugins/metrics_entities/server/services/utils/get_transform_exists.ts deleted file mode 100644 index f6b9266baca91..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/get_transform_exists.ts +++ /dev/null @@ -1,27 +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 { ElasticsearchClient } from 'kibana/server'; - -export const getTransformExists = async ( - esClient: ElasticsearchClient, - id: string -): Promise => { - try { - const { count } = await esClient.transform.getTransform({ - size: 1000, - transform_id: id, - }); - return count > 0; - } catch (err) { - if (err.body?.status === 404) { - return false; - } else { - throw err.body ? err.body : err; - } - } -}; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/index.ts b/x-pack/plugins/metrics_entities/server/services/utils/index.ts deleted file mode 100644 index 0871c1bf3f7b4..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/index.ts +++ /dev/null @@ -1,17 +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. - */ - -export * from './compute_mapping_index'; -export * from './compute_transform_id'; -export * from './get_index_exists'; -export * from './get_transform_exists'; -export * from './log_mapping_debug'; -export * from './log_mapping_error'; -export * from './log_mapping_info'; -export * from './log_transform_debug'; -export * from './log_transform_error'; -export * from './log_transform_info'; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/log_mapping_debug.ts b/x-pack/plugins/metrics_entities/server/services/utils/log_mapping_debug.ts deleted file mode 100644 index f3c56aac900f1..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/log_mapping_debug.ts +++ /dev/null @@ -1,20 +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 type { Logger } from '../../../../../../src/core/server'; - -export const logMappingDebug = ({ - logger, - id, - message, -}: { - logger: Logger; - id: string; - message: string; -}): void => { - logger.debug(`mapping id: "${id}", ${message}`); -}; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/log_mapping_error.ts b/x-pack/plugins/metrics_entities/server/services/utils/log_mapping_error.ts deleted file mode 100644 index 43ae07619318c..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/log_mapping_error.ts +++ /dev/null @@ -1,27 +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 type { Logger } from '../../../../../../src/core/server'; - -import { getJSON } from './get_json'; - -export const logMappingError = ({ - logger, - id, - message, - error, - postBody, -}: { - logger: Logger; - id: string; - error: unknown; - message: string; - postBody: {} | undefined; -}): void => { - const postString = postBody != null ? `, post body: "${getJSON(postBody)}"` : ''; - logger.error(`${message}, mapping id: "${id}"${postString}, error: ${getJSON(error)}`); -}; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/log_mapping_info.ts b/x-pack/plugins/metrics_entities/server/services/utils/log_mapping_info.ts deleted file mode 100644 index e75c380aad38a..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/log_mapping_info.ts +++ /dev/null @@ -1,20 +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 type { Logger } from '../../../../../../src/core/server'; - -export const logMappingInfo = ({ - logger, - id, - message, -}: { - logger: Logger; - id: string; - message: string; -}): void => { - logger.info(`mapping id: "${id}", ${message}`); -}; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/log_transform_debug.ts b/x-pack/plugins/metrics_entities/server/services/utils/log_transform_debug.ts deleted file mode 100644 index 61c5dd0b37947..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/log_transform_debug.ts +++ /dev/null @@ -1,20 +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 type { Logger } from '../../../../../../src/core/server'; - -export const logTransformDebug = ({ - logger, - id, - message, -}: { - logger: Logger; - id: string; - message: string; -}): void => { - logger.debug(`transform id: "${id}", ${message}`); -}; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/log_transform_error.ts b/x-pack/plugins/metrics_entities/server/services/utils/log_transform_error.ts deleted file mode 100644 index 2d883ca68be75..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/log_transform_error.ts +++ /dev/null @@ -1,27 +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 type { Logger } from '../../../../../../src/core/server'; - -import { getJSON } from './get_json'; - -export const logTransformError = ({ - id, - logger, - error, - postBody, - message, -}: { - logger: Logger; - id: string; - error: unknown; - message: string; - postBody: {} | undefined; -}): void => { - const postString = postBody != null ? `, post body: "${getJSON(postBody)}"` : ''; - logger.error(`${message}, transform id: ${id}${postString}, response error: ${getJSON(error)}`); -}; diff --git a/x-pack/plugins/metrics_entities/server/services/utils/log_transform_info.ts b/x-pack/plugins/metrics_entities/server/services/utils/log_transform_info.ts deleted file mode 100644 index 1bfb918664007..0000000000000 --- a/x-pack/plugins/metrics_entities/server/services/utils/log_transform_info.ts +++ /dev/null @@ -1,20 +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 type { Logger } from '../../../../../../src/core/server'; - -export const logTransformInfo = ({ - logger, - id, - message, -}: { - logger: Logger; - id: string; - message: string; -}): void => { - logger.info(`transform id: "${id}", ${message}`); -}; diff --git a/x-pack/plugins/metrics_entities/server/types.ts b/x-pack/plugins/metrics_entities/server/types.ts deleted file mode 100644 index 41df562234c0d..0000000000000 --- a/x-pack/plugins/metrics_entities/server/types.ts +++ /dev/null @@ -1,36 +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 { ElasticsearchClient, IContextProvider, RequestHandlerContext } from 'kibana/server'; - -import { MetricsEntitiesClient } from './services/metrics_entities_client'; - -export type GetMetricsEntitiesClientType = (esClient: ElasticsearchClient) => MetricsEntitiesClient; - -export interface MetricsEntitiesPluginSetup { - getMetricsEntitiesClient: GetMetricsEntitiesClientType; -} - -export type MetricsEntitiesPluginStart = void; - -export type ContextProvider = IContextProvider< - MetricsEntitiesRequestHandlerContext, - 'metricsEntities' ->; - -export interface MetricsEntitiesApiRequestHandlerContext { - getMetricsEntitiesClient: () => MetricsEntitiesClient; -} - -export interface MetricsEntitiesRequestHandlerContext extends RequestHandlerContext { - metricsEntities?: MetricsEntitiesApiRequestHandlerContext; -} - -/** - * @internal - */ -export type ContextProviderReturn = Promise; diff --git a/x-pack/plugins/metrics_entities/tsconfig.json b/x-pack/plugins/metrics_entities/tsconfig.json deleted file mode 100644 index 402b327a2dbf2..0000000000000 --- a/x-pack/plugins/metrics_entities/tsconfig.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "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", - "../../../typings/**/*" - ], - "references": [ - { "path": "../../../src/core/tsconfig.json" }, - { "path": "../spaces/tsconfig.json" }, - { "path": "../security/tsconfig.json" }, - { "path": "../licensing/tsconfig.json" }, - { "path": "../features/tsconfig.json" }, - { "path": "../../../src/plugins/usage_collection/tsconfig.json" }, - { "path": "../../../src/plugins/kibana_utils/tsconfig.json" } - ] -} diff --git a/x-pack/plugins/screenshotting/server/formats/pdf/index.ts b/x-pack/plugins/screenshotting/server/formats/pdf/index.ts index 7364ec210313a..b7718155c5424 100644 --- a/x-pack/plugins/screenshotting/server/formats/pdf/index.ts +++ b/x-pack/plugins/screenshotting/server/formats/pdf/index.ts @@ -7,7 +7,7 @@ import { groupBy } from 'lodash'; import type { Values } from '@kbn/utility-types'; -import type { Logger } from 'src/core/server'; +import type { Logger, PackageInfo } from 'src/core/server'; import type { LayoutParams } from '../../../common'; import { LayoutTypes } from '../../../common'; import type { Layout } from '../../layouts'; @@ -93,6 +93,7 @@ function getTimeRange(results: CaptureResult['results']) { export async function toPdf( logger: Logger, + packageInfo: PackageInfo, layout: Layout, { logo, title }: PdfScreenshotOptions, { metrics, results }: CaptureResult @@ -104,6 +105,7 @@ export async function toPdf( results, layout, logo, + packageInfo, logger, }); diff --git a/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/index.ts b/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/index.ts index ce5ea3cab813c..2c5439267ffc4 100644 --- a/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/index.ts +++ b/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { Logger } from 'src/core/server'; +import type { Logger, PackageInfo } from 'src/core/server'; import { PdfMaker } from './pdfmaker'; import type { Layout } from '../../../layouts'; import { getTracker } from './tracker'; @@ -14,6 +14,7 @@ import type { CaptureResult } from '../../../screenshots'; interface PngsToPdfArgs { results: CaptureResult['results']; layout: Layout; + packageInfo: PackageInfo; logger: Logger; logo?: string; title?: string; @@ -24,9 +25,10 @@ export async function pngsToPdf({ layout, logo, title, + packageInfo, logger, }: PngsToPdfArgs): Promise<{ buffer: Buffer; pages: number }> { - const pdfMaker = new PdfMaker(layout, logo, logger); + const pdfMaker = new PdfMaker(layout, logo, packageInfo, logger); const tracker = getTracker(); if (title) { pdfMaker.setTitle(title); diff --git a/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/integration_tests/pdfmaker.test.ts b/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/integration_tests/pdfmaker.test.ts index d3c9f2003dd4e..e08cf808abbc5 100644 --- a/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/integration_tests/pdfmaker.test.ts +++ b/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/integration_tests/pdfmaker.test.ts @@ -7,11 +7,12 @@ /* eslint-disable max-classes-per-file */ +import { PackageInfo } from 'kibana/server'; import path from 'path'; import { loggingSystemMock } from 'src/core/server/mocks'; import { isUint8Array } from 'util/types'; -import { createMockLayout } from '../../../../layouts/mock'; import { errors } from '../../../../../common'; +import { createMockLayout } from '../../../../layouts/mock'; import { PdfMaker } from '../pdfmaker'; const imageBase64 = Buffer.from( @@ -23,11 +24,19 @@ describe('PdfMaker', () => { let layout: ReturnType; let pdf: PdfMaker; let logger: ReturnType; + let packageInfo: Readonly; beforeEach(() => { layout = createMockLayout(); logger = loggingSystemMock.createLogger(); - pdf = new PdfMaker(layout, undefined, logger); + packageInfo = { + branch: 'screenshot-test', + buildNum: 567891011, + buildSha: 'screenshot-dfdfed0a', + dist: false, + version: '1000.0.0', + }; + pdf = new PdfMaker(layout, undefined, packageInfo, logger); }); describe('generate', () => { @@ -56,14 +65,14 @@ describe('PdfMaker', () => { protected workerMaxOldHeapSizeMb = 2; protected workerMaxYoungHeapSizeMb = 2; protected workerModulePath = path.resolve(__dirname, './memory_leak_worker.js'); - })(layout, undefined, logger); + })(layout, undefined, packageInfo, logger); await expect(leakyMaker.generate()).rejects.toBeInstanceOf(errors.PdfWorkerOutOfMemoryError); }); it('restarts the PDF worker if it crashes', async () => { const buggyMaker = new (class BuggyPdfMaker extends PdfMaker { protected workerModulePath = path.resolve(__dirname, './buggy_worker.js'); - })(layout, undefined, logger); + })(layout, undefined, packageInfo, logger); await expect(buggyMaker.generate()).rejects.toThrowError(new Error('This is a bug')); await expect(buggyMaker.generate()).rejects.toThrowError(new Error('This is a bug')); diff --git a/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/pdfmaker.ts b/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/pdfmaker.ts index f32bec1e3ed38..a10f259e5c9e5 100644 --- a/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/pdfmaker.ts +++ b/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/pdfmaker.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { Logger } from 'src/core/server'; +import type { Logger, PackageInfo } from 'src/core/server'; import { SerializableRecord } from '@kbn/utility-types'; import path from 'path'; import { Content, ContentImage, ContentText } from 'pdfmake/interfaces'; @@ -34,7 +34,7 @@ export class PdfMaker { private worker?: Worker; private pageCount: number = 0; - protected workerModulePath = path.resolve(__dirname, './worker.js'); + protected workerModulePath: string; /** * The maximum heap size for old memory region of the worker thread. @@ -65,10 +65,18 @@ export class PdfMaker { constructor( private readonly layout: Layout, private readonly logo: string | undefined, + { dist }: PackageInfo, private readonly logger: Logger ) { this.title = ''; this.content = []; + + // running in dist: `worker.ts` becomes `worker.js` + // running in source: `worker_src_harness.ts` needs to be wrapped in JS and have a ts-node environment initialized. + this.workerModulePath = path.resolve( + __dirname, + dist ? './worker.js' : './worker_src_harness.js' + ); } _addContents(contents: Content[]) { diff --git a/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/worker.js b/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/worker_src_harness.js similarity index 64% rename from x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/worker.js rename to x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/worker_src_harness.js index d3dfa3e9accf8..e180c130bc4af 100644 --- a/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/worker.js +++ b/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/worker_src_harness.js @@ -5,5 +5,10 @@ * 2.0. */ +/** + * This file is the harness for importing worker.ts with Kibana running in dev mode. + * The TS file needs to be compiled on the fly, unlike when Kibana is running as a dist. + */ + require('../../../../../../../src/setup_node_env'); require('./worker.ts'); diff --git a/x-pack/plugins/screenshotting/server/plugin.ts b/x-pack/plugins/screenshotting/server/plugin.ts index 3f97de22d5e4b..2f675335d4393 100755 --- a/x-pack/plugins/screenshotting/server/plugin.ts +++ b/x-pack/plugins/screenshotting/server/plugin.ts @@ -11,6 +11,7 @@ import type { CoreSetup, CoreStart, Logger, + PackageInfo, Plugin, PluginInitializerContext, } from 'src/core/server'; @@ -45,6 +46,7 @@ export interface ScreenshottingStart { export class ScreenshottingPlugin implements Plugin { private config: ConfigType; private logger: Logger; + private packageInfo: PackageInfo; private screenshotMode!: ScreenshotModePluginSetup; private browserDriverFactory!: Promise; private screenshots!: Promise; @@ -52,6 +54,7 @@ export class ScreenshottingPlugin implements Plugin) { this.logger = context.logger.get(); this.config = context.config.get(); + this.packageInfo = context.env.packageInfo; } setup({ http }: CoreSetup, { screenshotMode }: SetupDeps) { @@ -82,7 +85,7 @@ export class ScreenshottingPlugin implements Plugin {}); diff --git a/x-pack/plugins/screenshotting/server/screenshots/index.test.ts b/x-pack/plugins/screenshotting/server/screenshots/index.test.ts index 3799ac359f151..666e59e0617c5 100644 --- a/x-pack/plugins/screenshotting/server/screenshots/index.test.ts +++ b/x-pack/plugins/screenshotting/server/screenshots/index.test.ts @@ -6,7 +6,7 @@ */ import { lastValueFrom, of, throwError } from 'rxjs'; -import type { Logger } from 'src/core/server'; +import type { Logger, PackageInfo } from 'src/core/server'; import { httpServiceMock } from 'src/core/server/mocks'; import { SCREENSHOTTING_APP_ID, @@ -31,6 +31,7 @@ describe('Screenshot Observable Pipeline', () => { let http: ReturnType; let layout: ReturnType; let logger: jest.Mocked; + let packageInfo: Readonly; let options: ScreenshotOptions; let screenshots: Screenshots; @@ -44,6 +45,13 @@ describe('Screenshot Observable Pipeline', () => { error: jest.fn(), info: jest.fn(), } as unknown as jest.Mocked; + packageInfo = { + branch: 'screenshot-test', + buildNum: 567891011, + buildSha: 'screenshot-dfdfed0a', + dist: false, + version: '5000.0.0', + }; options = { browserTimezone: 'UTC', headers: {}, @@ -56,7 +64,9 @@ describe('Screenshot Observable Pipeline', () => { }, urls: ['/welcome/home/start/index.htm'], } as unknown as typeof options; - screenshots = new Screenshots(driverFactory, logger, http, { poolSize: 1 } as ConfigType); + screenshots = new Screenshots(driverFactory, logger, packageInfo, http, { + poolSize: 1, + } as ConfigType); jest.spyOn(Layouts, 'createLayout').mockReturnValue(layout); diff --git a/x-pack/plugins/screenshotting/server/screenshots/index.ts b/x-pack/plugins/screenshotting/server/screenshots/index.ts index 8672babe8b514..cfd5c76093d3b 100644 --- a/x-pack/plugins/screenshotting/server/screenshots/index.ts +++ b/x-pack/plugins/screenshotting/server/screenshots/index.ts @@ -22,7 +22,7 @@ import { tap, toArray, } from 'rxjs/operators'; -import type { HttpServiceSetup, KibanaRequest, Logger } from 'src/core/server'; +import type { HttpServiceSetup, KibanaRequest, Logger, PackageInfo } from 'src/core/server'; import type { ExpressionAstExpression } from 'src/plugins/expressions/common'; import { LayoutParams, @@ -99,6 +99,7 @@ export class Screenshots { constructor( private readonly browserDriverFactory: HeadlessChromiumDriverFactory, private readonly logger: Logger, + private readonly packageInfo: PackageInfo, private readonly http: HttpServiceSetup, { poolSize }: ConfigType ) { @@ -214,7 +215,7 @@ export class Screenshots { mergeMap((result) => { switch (options.format) { case 'pdf': - return toPdf(this.logger, layout, options, result); + return toPdf(this.logger, this.packageInfo, layout, options, result); default: return toPng(result); } diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index f7bdc889f9c33..3b820b16ef8a4 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -5,8 +5,6 @@ * 2.0. */ -import type { TransformConfigSchema } from './transforms/types'; - /** * as const * @@ -54,7 +52,6 @@ export const DEFAULT_INTERVAL_PAUSE = true as const; export const DEFAULT_INTERVAL_TYPE = 'manual' as const; export const DEFAULT_INTERVAL_VALUE = 300000 as const; // ms export const DEFAULT_TIMEPICKER_QUICK_RANGES = 'timepicker:quickRanges' as const; -export const DEFAULT_TRANSFORMS = 'securitySolution:transforms' as const; export const SCROLLING_DISABLED_CLASS_NAME = 'scrolling-disabled' as const; export const GLOBAL_HEADER_HEIGHT = 96 as const; // px export const FILTERS_GLOBAL_HEIGHT = 109 as const; // px @@ -203,38 +200,6 @@ export const IP_REPUTATION_LINKS_SETTING_DEFAULT = `[ { "name": "talosIntelligence.com", "url_template": "https://talosintelligence.com/reputation_center/lookup?search={{ip}}" } ]`; -/** The default settings for the transforms */ -export const defaultTransformsSetting: TransformConfigSchema = { - enabled: false, - auto_start: true, - auto_create: true, - query: { - range: { - '@timestamp': { - gte: 'now-1d/d', - format: 'strict_date_optional_time', - }, - }, - }, - retention_policy: { - time: { - field: '@timestamp', - max_age: '1w', - }, - }, - max_page_search_size: 5000, - settings: [ - { - prefix: 'all', - indices: ['auditbeat-*', 'endgame-*', 'filebeat-*', 'logs-*', 'packetbeat-*', 'winlogbeat-*'], - data_sources: [ - ['auditbeat-*', 'endgame-*', 'filebeat-*', 'logs-*', 'packetbeat-*', 'winlogbeat-*'], - ], - }, - ], -}; -export const DEFAULT_TRANSFORMS_SETTING = JSON.stringify(defaultTransformsSetting, null, 2); - /** * Id for the notifications alerting type * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function @@ -371,13 +336,6 @@ export const showAllOthersBucket: string[] = [ 'user.name', ]; -/** - * Used for transforms for metrics_entities. If the security_solutions pulls in - * the metrics_entities plugin, then it should pull this constant from there rather - * than use it from here. - */ -export const ELASTIC_NAME = 'estc' as const; - export const RISKY_HOSTS_INDEX_PREFIX = 'ml_host_risk_score_' as const; export const RISKY_USERS_INDEX_PREFIX = 'ml_user_risk_score_' as const; diff --git a/x-pack/plugins/security_solution/common/detection_engine/constants.ts b/x-pack/plugins/security_solution/common/detection_engine/constants.ts index b61cd34dc4790..6a6bf9df6d27a 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/constants.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/constants.ts @@ -6,7 +6,7 @@ */ export enum RULE_PREVIEW_INVOCATION_COUNT { - HOUR = 20, + HOUR = 12, DAY = 24, WEEK = 168, MONTH = 30, diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index a9cf3e4a8132e..374901358650e 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -12,7 +12,6 @@ export type ExperimentalFeatures = typeof allowedExperimentalValues; * This object is then used to validate and parse the value entered. */ export const allowedExperimentalValues = Object.freeze({ - metricsEntitiesEnabled: false, ruleRegistryEnabled: true, tGridEnabled: true, tGridEventRenderedViewEnabled: true, diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/index.ts index 245abdd49a62d..5473349bf144b 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/index.ts @@ -17,7 +17,6 @@ export enum HostsQueries { details = 'hostDetails', firstOrLastSeen = 'firstOrLastSeen', hosts = 'hosts', - hostsEntities = 'hostsEntities', overview = 'overviewHost', uncommonProcesses = 'uncommonProcesses', } diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/kpi/authentications/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/kpi/authentications/index.ts index 73729b613c38c..b120161210745 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/kpi/authentications/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/kpi/authentications/index.ts @@ -12,8 +12,6 @@ import { HostsKpiHistogramData } from '../common'; export interface HostsKpiAuthenticationsHistogramCount { doc_count: number; - // TODO: Should I keep this or split this interface into two for entities and non-entities? - value?: number; } export type HostsKpiAuthenticationsRequestOptions = RequestBasicOptions; diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/kpi/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/kpi/index.ts index d48172bebee4c..79054fc736a80 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/kpi/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts/kpi/index.ts @@ -16,11 +16,8 @@ import { HostsKpiUniqueIpsStrategyResponse } from './unique_ips'; export enum HostsKpiQueries { kpiAuthentications = 'hostsKpiAuthentications', - kpiAuthenticationsEntities = 'hostsKpiAuthenticationsEntities', kpiHosts = 'hostsKpiHosts', - kpiHostsEntities = 'hostsKpiHostsEntities', kpiUniqueIps = 'hostsKpiUniqueIps', - kpiUniqueIpsEntities = 'hostsKpiUniqueIpsEntities', } export type HostsKpiStrategyResponse = diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/index.ts index e59aec9e000d9..f2d9e0e36bd0e 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/index.ts @@ -59,7 +59,6 @@ import { } from './network'; import { MatrixHistogramQuery, - MatrixHistogramQueryEntities, MatrixHistogramRequestOptions, MatrixHistogramStrategyResponse, } from './matrix_histogram'; @@ -106,8 +105,7 @@ export type FactoryQueryTypes = | NetworkKpiQueries | RiskQueries | CtiQueries - | typeof MatrixHistogramQuery - | typeof MatrixHistogramQueryEntities; + | typeof MatrixHistogramQuery; export interface RequestBasicOptions extends IEsSearchRequest { timerange: TimerangeInput; diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/matrix_histogram/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/matrix_histogram/index.ts index ef637031dd899..d1d9a8f5d9d3e 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/matrix_histogram/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/matrix_histogram/index.ts @@ -25,11 +25,9 @@ export * from './events'; export * from './preview'; export const MatrixHistogramQuery = 'matrixHistogram'; -export const MatrixHistogramQueryEntities = 'matrixHistogramEntities'; export enum MatrixHistogramType { authentications = 'authentications', - authenticationsEntities = 'authenticationsEntities', anomalies = 'anomalies', events = 'events', alerts = 'alerts', @@ -41,7 +39,6 @@ export const MatrixHistogramTypeToAggName = { [MatrixHistogramType.alerts]: 'aggregations.alertsGroup.buckets', [MatrixHistogramType.anomalies]: 'aggregations.anomalyActionGroup.buckets', [MatrixHistogramType.authentications]: 'aggregations.eventActionGroup.buckets', - [MatrixHistogramType.authenticationsEntities]: 'aggregations.events.buckets', [MatrixHistogramType.dns]: 'aggregations.dns_name_query_count.buckets', [MatrixHistogramType.events]: 'aggregations.eventActionGroup.buckets', [MatrixHistogramType.preview]: 'aggregations.preview.buckets', diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/index.ts index 2e0a5d7d2f0f1..24c6484f94e71 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/index.ts @@ -23,8 +23,6 @@ export enum NetworkQueries { overview = 'overviewNetwork', tls = 'tls', topCountries = 'topCountries', - topCountriesEntities = 'topCountriesEntities', topNFlow = 'topNFlow', - topNFlowEntities = 'topNFlowEntities', users = 'users', } diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/kpi/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/kpi/index.ts index cb18a3edb4937..fa9e55096f7a6 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/kpi/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/network/kpi/index.ts @@ -19,14 +19,10 @@ import { NetworkKpiUniquePrivateIpsStrategyResponse } from './unique_private_ips export enum NetworkKpiQueries { dns = 'networkKpiDns', - dnsEntities = 'networkKpiDnsEntities', networkEvents = 'networkKpiNetworkEvents', - networkEventsEntities = 'networkKpiNetworkEventsEntities', tlsHandshakes = 'networkKpiTlsHandshakes', - tlsHandshakesEntities = 'networkKpiTlsHandshakesEntities', uniqueFlows = 'networkKpiUniqueFlows', uniquePrivateIps = 'networkKpiUniquePrivateIps', - uniquePrivateIpsEntities = 'networkKpiUniquePrivateIpsEntities', } export type NetworkKpiStrategyResponse = diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/users/authentications/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/users/authentications/index.ts index 205169c8e6b0e..f4b6cdcbe6e55 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/users/authentications/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/users/authentications/index.ts @@ -76,13 +76,9 @@ export interface AuthenticationBucket { doc_count: number; failures: { doc_count: number; - // TODO: Keep this or make a new structure? - value?: number; }; successes: { doc_count: number; - // TODO: Keep this or make a new structure? - value?: number; }; authentication: { hits: { diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/users/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/users/index.ts index 7b3937de2913e..4223b9b2fa7ab 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/users/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/users/index.ts @@ -18,7 +18,6 @@ export enum UsersQueries { kpiTotalUsers = 'usersKpiTotalUsers', users = 'allUsers', authentications = 'authentications', - authenticationsEntities = 'authenticationsEntities', } export type UserskKpiStrategyResponse = Omit; diff --git a/x-pack/plugins/security_solution/common/transforms/types.ts b/x-pack/plugins/security_solution/common/transforms/types.ts deleted file mode 100644 index ac4e3cae92e22..0000000000000 --- a/x-pack/plugins/security_solution/common/transforms/types.ts +++ /dev/null @@ -1,39 +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 { schema, TypeOf } from '@kbn/config-schema'; - -/** - * Kibana configuration schema - */ -export const transformConfigSchema = schema.object({ - auto_start: schema.boolean(), - auto_create: schema.boolean(), - enabled: schema.boolean(), - query: schema.maybe(schema.object({}, { unknowns: 'allow' })), - retention_policy: schema.maybe( - schema.object({ - time: schema.object({ - field: schema.string(), - max_age: schema.string(), - }), - }) - ), - docs_per_second: schema.maybe(schema.number({ min: 1 })), - max_page_search_size: schema.maybe(schema.number({ min: 1, max: 10000 })), - settings: schema.arrayOf( - schema.object({ - prefix: schema.string(), - indices: schema.arrayOf(schema.string()), - data_sources: schema.arrayOf(schema.arrayOf(schema.string())), - disable_widgets: schema.maybe(schema.arrayOf(schema.string())), - disable_transforms: schema.maybe(schema.arrayOf(schema.string())), - }) - ), -}); - -export type TransformConfigSchema = TypeOf; 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 d2e9c2a6715fe..caeeaa0c17bee 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/index.ts @@ -326,6 +326,7 @@ export enum TimelineId { casePage = 'timeline-case', test = 'test', // Reserved for testing purposes alternateTest = 'alternateTest', + rulePreview = 'rule-preview', } export const TimelineIdLiteralRt = runtimeTypes.union([ @@ -339,6 +340,7 @@ export const TimelineIdLiteralRt = runtimeTypes.union([ runtimeTypes.literal(TimelineId.networkPageExternalAlerts), runtimeTypes.literal(TimelineId.active), runtimeTypes.literal(TimelineId.test), + runtimeTypes.literal(TimelineId.rulePreview), ]); export type TimelineIdLiteral = runtimeTypes.TypeOf; diff --git a/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts index 17f545c25c39c..ed69f1d18d5e6 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts @@ -327,9 +327,9 @@ export const fillDefineEqlRuleAndContinue = (rule: CustomRule) => { cy.get(PREVIEW_HISTOGRAM) .invoke('text') .then((text) => { - if (text !== 'Hits') { + if (text !== 'Rule Preview') { cy.get(RULES_CREATION_PREVIEW).find(QUERY_PREVIEW_BUTTON).click({ force: true }); - cy.get(PREVIEW_HISTOGRAM).should('contain.text', 'Hits'); + cy.get(PREVIEW_HISTOGRAM).should('contain.text', 'Rule Preview'); } }); cy.get(TOAST_ERROR).should('not.exist'); 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 650b915f50214..fe8a3d00a6364 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 @@ -82,6 +82,15 @@ describe('AlertSummaryView', () => { expect(queryAllByTestId('hover-actions-filter-for').length).toEqual(0); }); + test('it does NOT render the action cell when readOnly is passed', () => { + const { queryAllByTestId } = render( + + + + ); + expect(queryAllByTestId('hover-actions-filter-for').length).toEqual(0); + }); + test("render no investigation guide if it doesn't exist", async () => { (useRuleWithFallback as jest.Mock).mockReturnValue({ rule: { diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/columns.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/columns.test.tsx index a37157905bef9..be197499a700b 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/columns.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/columns.test.tsx @@ -136,5 +136,18 @@ describe('getColumns', () => { ).toEqual('hover-actions-copy-button'); }); }); + + describe('does not render hover actions when readOnly prop is passed', () => { + test('it renders a filter for (+) button', () => { + actionsColumn = getColumns({ ...defaultProps, isReadOnly: true })[0] as Column; + const wrapper = mount( + {actionsColumn.render(testValue, testData)} + ) as ReactWrapper; + + expect(wrapper.find('[data-test-subj="hover-actions-filter-for"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="hover-actions-filter-out"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="more-actions-agent.id"]').exists()).toBeFalsy(); + }); + }); }); }); 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 14910c77d198c..f7df157ed4602 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 @@ -140,5 +140,20 @@ describe('EventDetails', () => { alertsWrapper.find('[data-test-subj="threatIntelTab"]').first().simulate('click'); expect(alertsWrapper.find('[data-test-subj="no-enrichments-found"]').exists()).toEqual(true); }); + it('does not render if readOnly prop is passed', async () => { + const newProps = { ...defaultProps, isReadOnly: true }; + wrapper = mount( + + + + ) as ReactWrapper; + alertsWrapper = mount( + + + + ) as ReactWrapper; + await waitFor(() => wrapper.update()); + expect(alertsWrapper.find('[data-test-subj="threatIntelTab"]').exists()).toBeFalsy(); + }); }); }); 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 a05a9e36a24e9..dcb28eafb6ef8 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 @@ -132,6 +132,25 @@ describe('EventFieldsBrowser', () => { expect(wrapper.find('[data-test-subj="more-actions-@timestamp"]').exists()).toBeTruthy(); }); + test('it does not render hover actions when readOnly prop is passed', () => { + const wrapper = mount( + + + + ); + + expect(wrapper.find('[data-test-subj="hover-actions-filter-for"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="hover-actions-filter-out"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="more-actions-@timestamp"]').exists()).toBeFalsy(); + }); + test('it renders a column toggle button', () => { const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.test.tsx index 0f241bace7663..52e038fa07c56 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/overview/index.test.tsx @@ -29,6 +29,20 @@ describe('Event Details Overview Cards', () => { getByText('Rule'); }); + it('renders only readOnly cards', () => { + const { getByText, queryByText } = render( + + + + ); + + getByText('Severity'); + getByText('Risk Score'); + + expect(queryByText('Status')).not.toBeInTheDocument(); + expect(queryByText('Rule')).not.toBeInTheDocument(); + }); + it('renders all cards it has data for', () => { const { getByText, queryByText } = render( @@ -194,3 +208,8 @@ const propsWithoutSeverity = { browserFields: { kibana: { fields: fieldsWithoutSeverity } }, data: dataWithoutSeverity, }; + +const propsWithReadOnly = { + ...props, + isReadOnly: true, +}; diff --git a/x-pack/plugins/security_solution/public/common/containers/authentications/index.tsx b/x-pack/plugins/security_solution/public/common/containers/authentications/index.tsx index 593d5e4186e29..543ebc3e15e9a 100644 --- a/x-pack/plugins/security_solution/public/common/containers/authentications/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/authentications/index.tsx @@ -29,7 +29,6 @@ import { getInspectResponse } from '../../../helpers'; import { InspectResponse } from '../../../types'; import * as i18n from './translations'; -import { useTransforms } from '../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; export interface AuthenticationArgs { @@ -73,7 +72,6 @@ export const useAuthentications = ({ const [loading, setLoading] = useState(false); const [authenticationsRequest, setAuthenticationsRequest] = useState(null); - const { getTransformChangesIfTheyExist } = useTransforms(); const { addError, addWarning } = useAppToasts(); const wrappedLoadMore = useCallback( @@ -162,26 +160,19 @@ export const useAuthentications = ({ useEffect(() => { setAuthenticationsRequest((prevRequest) => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ - factoryQueryType: UsersQueries.authentications, - indices: indexNames, - filterQuery, - timerange: { - interval: '12h', - from: startDate, - to: endDate, - }, - }); - const myRequest = { ...(prevRequest ?? {}), - defaultIndex: indices, + defaultIndex: indexNames, docValueFields: docValueFields ?? [], - factoryQueryType, + factoryQueryType: UsersQueries.authentications, filterQuery: createFilter(filterQuery), stackByField, pagination: generateTablePaginationOptions(activePage, limit), - timerange, + timerange: { + interval: '12h', + from: startDate, + to: endDate, + }, sort: {} as SortField, }; if (!deepEqual(prevRequest, myRequest)) { @@ -198,7 +189,6 @@ export const useAuthentications = ({ stackByField, limit, startDate, - getTransformChangesIfTheyExist, ]); useEffect(() => { diff --git a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts index f6670c98fc0ee..e22960e833b9a 100644 --- a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts +++ b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.ts @@ -25,7 +25,6 @@ import { isErrorResponse, isCompleteResponse } from '../../../../../../../src/pl import { getInspectResponse } from '../../../helpers'; import { InspectResponse } from '../../../types'; import * as i18n from './translations'; -import { useTransforms } from '../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../hooks/use_app_toasts'; export type Buckets = Array<{ @@ -71,32 +70,18 @@ export const useMatrixHistogram = ({ const abortCtrl = useRef(new AbortController()); const searchSubscription$ = useRef(new Subscription()); const [loading, setLoading] = useState(false); - const { getTransformChangesIfTheyExist } = useTransforms(); - - const { - indices: initialIndexName, - factoryQueryType: initialFactoryQueryType, - histogramType: initialHistogramType, - timerange: initialTimerange, - } = getTransformChangesIfTheyExist({ - histogramType, - factoryQueryType: MatrixHistogramQuery, - indices: indexNames, - filterQuery, - timerange: { - interval: '12h', - from: startDate, - to: endDate, - }, - }); const [matrixHistogramRequest, setMatrixHistogramRequest] = useState({ - defaultIndex: initialIndexName, - factoryQueryType: initialFactoryQueryType, + defaultIndex: indexNames, + factoryQueryType: MatrixHistogramQuery, filterQuery: createFilter(filterQuery), - histogramType: initialHistogramType ?? histogramType, - timerange: initialTimerange, + histogramType: histogramType ?? histogramType, + timerange: { + interval: '12h', + from: startDate, + to: endDate, + }, stackByField, runtimeMappings, threshold, @@ -170,31 +155,17 @@ export const useMatrixHistogram = ({ ); useEffect(() => { - const { - indices, - factoryQueryType, - histogramType: newHistogramType, - timerange, - } = getTransformChangesIfTheyExist({ - histogramType, - factoryQueryType: MatrixHistogramQuery, - indices: indexNames, - filterQuery, - timerange: { - interval: '12h', - from: startDate, - to: endDate, - }, - }); - setMatrixHistogramRequest((prevRequest) => { const myRequest = { ...prevRequest, - defaultIndex: indices, - factoryQueryType, + defaultIndex: indexNames, filterQuery: createFilter(filterQuery), - histogramType: newHistogramType ?? histogramType, - timerange, + histogramType, + timerange: { + interval: '12h', + from: startDate, + to: endDate, + }, stackByField, threshold, ...(isPtrIncluded != null ? { isPtrIncluded } : {}), @@ -215,7 +186,6 @@ export const useMatrixHistogram = ({ threshold, isPtrIncluded, docValueFields, - getTransformChangesIfTheyExist, ]); useEffect(() => { diff --git a/x-pack/plugins/security_solution/public/common/containers/use_search_strategy/index.test.ts b/x-pack/plugins/security_solution/public/common/containers/use_search_strategy/index.test.ts index 131242513e583..ecbf7058fded2 100644 --- a/x-pack/plugins/security_solution/public/common/containers/use_search_strategy/index.test.ts +++ b/x-pack/plugins/security_solution/public/common/containers/use_search_strategy/index.test.ts @@ -11,12 +11,6 @@ import { act, renderHook } from '@testing-library/react-hooks'; import { useObservable } from '@kbn/securitysolution-hook-utils'; import { FactoryQueryTypes } from '../../../../common/search_strategy'; -jest.mock('../../../transforms/containers/use_transforms', () => ({ - useTransforms: jest.fn(() => ({ - getTransformChangesIfTheyExist: null, - })), -})); - const mockAddToastError = jest.fn(); jest.mock('../../hooks/use_app_toasts', () => ({ diff --git a/x-pack/plugins/security_solution/public/common/containers/use_search_strategy/index.tsx b/x-pack/plugins/security_solution/public/common/containers/use_search_strategy/index.tsx index 8e284c7c29413..916ed4aad3e47 100644 --- a/x-pack/plugins/security_solution/public/common/containers/use_search_strategy/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/use_search_strategy/index.tsx @@ -25,10 +25,6 @@ import { isCompleteResponse, isErrorResponse, } from '../../../../../../../src/plugins/data/public'; -import { - TransformChangesIfTheyExist, - useTransforms, -} from '../../../transforms/containers/use_transforms'; import { getInspectResponse } from '../../../helpers'; import { inputsModel } from '../../store'; import { useKibana } from '../../lib/kibana'; @@ -39,7 +35,6 @@ type UseSearchStrategyRequestArgs = RequestBasicOptions & { data: DataPublicPluginStart; signal: AbortSignal; factoryQueryType: FactoryQueryTypes; - getTransformChangesIfTheyExist: TransformChangesIfTheyExist; }; const search = ({ @@ -49,26 +44,14 @@ const search = ({ defaultIndex, filterQuery, timerange, - getTransformChangesIfTheyExist, ...requestProps }: UseSearchStrategyRequestArgs): Observable => { - const { - indices: transformIndices, - factoryQueryType: transformFactoryQueryType, - timerange: transformTimerange, - } = getTransformChangesIfTheyExist({ - factoryQueryType, - indices: defaultIndex, - filterQuery, - timerange, - }); - return data.search.search( { ...requestProps, - factoryQueryType: transformFactoryQueryType, - defaultIndex: transformIndices, - timerange: transformTimerange, + factoryQueryType, + defaultIndex, + timerange, filterQuery, }, { @@ -114,7 +97,6 @@ export const useSearchStrategy = ({ abort?: boolean; }) => { const abortCtrl = useRef(new AbortController()); - const { getTransformChangesIfTheyExist } = useTransforms(); const refetch = useRef(noop); const { data } = useKibana().services; @@ -141,7 +123,6 @@ export const useSearchStrategy = ({ ...props, data, factoryQueryType, - getTransformChangesIfTheyExist, signal: abortCtrl.current.signal, } as never); // This typescast is required because every StrategyRequestType instance has different fields. }; @@ -151,7 +132,7 @@ export const useSearchStrategy = ({ refetch.current = asyncSearch; }, - [data, start, factoryQueryType, getTransformChangesIfTheyExist] + [data, start, factoryQueryType] ); useEffect(() => { diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts index b683f4bd1375a..a0053bba304cc 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts @@ -32,7 +32,6 @@ import { DEFAULT_RULES_TABLE_REFRESH_SETTING, DEFAULT_RULE_REFRESH_INTERVAL_ON, DEFAULT_RULE_REFRESH_INTERVAL_VALUE, - DEFAULT_TRANSFORMS, } from '../../../../common/constants'; import { StartServices } from '../../../types'; import { createSecuritySolutionStorageMock } from '../../mock/mock_local_storage'; @@ -61,9 +60,6 @@ const mockUiSettings: Record = { on: DEFAULT_RULE_REFRESH_INTERVAL_ON, value: DEFAULT_RULE_REFRESH_INTERVAL_VALUE, }, - [DEFAULT_TRANSFORMS]: { - enabled: false, - }, }; export const createUseUiSettingMock = diff --git a/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.tsx b/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.tsx index f3ee9cbd81c52..e24a4d0025aee 100644 --- a/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.tsx +++ b/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.tsx @@ -8,7 +8,7 @@ import { useState, useEffect } from 'react'; import { useRouteSpy } from '../route/use_route_spy'; -const hideTimelineForRoutes = [`/cases/configure`, '/administration']; +const hideTimelineForRoutes = [`/cases/configure`, '/administration', 'rules/create']; export const useShowTimeline = () => { const [{ pageName, pathName }] = useRouteSpy(); 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 7dc3561628193..8ae7e358f280d 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 @@ -16,7 +16,10 @@ import { RowRendererId } from '../../../../common/types/timeline'; import { Status } from '../../../../common/detection_engine/schemas/common/schemas'; import { SubsetTimelineModel } from '../../../timelines/store/timeline/model'; import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; -import { columns } from '../../configurations/security_solution_detections/columns'; +import { + columns, + rulePreviewColumns, +} from '../../configurations/security_solution_detections/columns'; export const buildAlertStatusFilter = (status: Status): Filter[] => { const combinedQuery = @@ -156,6 +159,19 @@ export const alertsDefaultModel: SubsetTimelineModel = { excludedRowRendererIds: Object.values(RowRendererId), }; +export const alertsPreviewDefaultModel: SubsetTimelineModel = { + ...alertsDefaultModel, + columns: rulePreviewColumns, + defaultColumns: rulePreviewColumns, + sort: [ + { + columnId: 'kibana.alert.original_time', + columnType: 'number', + sortDirection: 'desc', + }, + ], +}; + export const requiredFieldsForActions = [ '@timestamp', 'kibana.alert.workflow_status', diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/helpers.ts b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/helpers.ts index f4e58c0d34c74..a2c4d2b14cdc9 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/helpers.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/helpers.ts @@ -234,7 +234,7 @@ export const getIsRulePreviewDisabled = ({ if (ruleType === 'machine_learning') { return machineLearningJobId.length === 0; } - if (ruleType === 'eql') { + if (ruleType === 'eql' || ruleType === 'query' || ruleType === 'threshold') { return queryBar.query.query.length === 0; } return false; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx index a870b837a7d33..1286f6d5758c7 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/index.tsx @@ -29,6 +29,13 @@ import { LoadingHistogram } from './loading_histogram'; import { FieldValueThreshold } from '../threshold_input'; import { isJobStarted } from '../../../../../common/machine_learning/helpers'; +const HelpTextComponent = ( + + {i18n.QUERY_PREVIEW_HELP_TEXT} + {i18n.QUERY_PREVIEW_DISCLAIMER} + +); + export interface RulePreviewProps { index: string[]; isDisabled: boolean; @@ -116,7 +123,7 @@ const RulePreviewComponent: React.FC = ({ <> = ({ previewId={previewId} addNoiseWarning={addNoiseWarning} spaceId={spaceId} - threshold={threshold} index={index} /> )} diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_histogram.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_histogram.test.tsx index bf174984a3492..1f16ddf3f845e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_histogram.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_histogram.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { mount } from 'enzyme'; +import { render } from '@testing-library/react'; import * as i18n from '../rule_preview/translations'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; @@ -14,10 +14,12 @@ import { TestProviders } from '../../../../common/mock'; import { usePreviewHistogram } from './use_preview_histogram'; import { PreviewHistogram } from './preview_histogram'; +import { ALL_VALUES_ZEROS_TITLE } from '../../../../common/components/charts/translation'; +jest.mock('../../../../common/lib/kibana'); jest.mock('../../../../common/containers/use_global_time'); jest.mock('./use_preview_histogram'); -jest.mock('../../../../common/lib/kibana'); +jest.mock('../../../../common/components/url_state/normalize_time_range.ts'); describe('PreviewHistogram', () => { const mockSetQuery = jest.fn(); @@ -35,9 +37,9 @@ describe('PreviewHistogram', () => { jest.clearAllMocks(); }); - test('it renders loader when isLoading is true', () => { + describe('when there is no data', () => { (usePreviewHistogram as jest.Mock).mockReturnValue([ - true, + false, { inspect: { dsl: [], response: [] }, totalCount: 1, @@ -47,42 +49,38 @@ describe('PreviewHistogram', () => { }, ]); - const wrapper = mount( - - - - ); + test('it renders an empty histogram and table', () => { + const wrapper = render( + + + + ); - expect(wrapper.find('[data-test-subj="preview-histogram-loading"]').exists()).toBeTruthy(); - expect(wrapper.find('[data-test-subj="header-section-subtitle"]').text()).toEqual( - i18n.QUERY_PREVIEW_SUBTITLE_LOADING - ); + expect(wrapper.findByText('hello grid')).toBeTruthy(); + expect(wrapper.findByText(ALL_VALUES_ZEROS_TITLE)).toBeTruthy(); + }); }); - test('it configures data and subtitle', () => { + test('it renders loader when isLoading is true', () => { (usePreviewHistogram as jest.Mock).mockReturnValue([ - false, + true, { inspect: { dsl: [], response: [] }, - totalCount: 9154, + totalCount: 1, refetch: jest.fn(), - data: [ - { x: 1602247050000, y: 2314, g: 'All others' }, - { x: 1602247162500, y: 3471, g: 'All others' }, - { x: 1602247275000, y: 3369, g: 'All others' }, - ], + data: [], buckets: [], }, ]); - const wrapper = mount( + const wrapper = render( { ); - expect(wrapper.find('[data-test-subj="preview-histogram-loading"]').exists()).toBeFalsy(); - expect(wrapper.find('[data-test-subj="header-section-subtitle"]').text()).toEqual( - i18n.QUERY_PREVIEW_TITLE(9154) - ); - expect( - ( - wrapper.find('[data-test-subj="preview-histogram-bar-chart"]').props() as { - barChart: unknown; - } - ).barChart - ).toEqual([ - { - key: 'hits', - value: [ - { - g: 'All others', - x: 1602247050000, - y: 2314, - }, - { - g: 'All others', - x: 1602247162500, - y: 3471, - }, - { - g: 'All others', - x: 1602247275000, - y: 3369, - }, - ], - }, - ]); + expect(wrapper.findByTestId('preview-histogram-loading')).toBeTruthy(); + expect(wrapper.findByText(i18n.QUERY_PREVIEW_SUBTITLE_LOADING)).toBeTruthy(); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_histogram.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_histogram.tsx index 326811783fc4a..2119ab75ee67b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_histogram.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_histogram.tsx @@ -11,19 +11,20 @@ import { Unit } from '@kbn/datemath'; import { EuiFlexGroup, EuiFlexItem, EuiText, EuiSpacer, EuiLoadingChart } from '@elastic/eui'; import styled from 'styled-components'; import { Type } from '@kbn/securitysolution-io-ts-alerting-types'; +import { useDispatch, useSelector } from 'react-redux'; +import { eventsViewerSelector } from '../../../../common/components/events_viewer/selectors'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { useKibana } from '../../../../common/lib/kibana'; import * as i18n from './translations'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; -import { getHistogramConfig, getThresholdHistogramConfig, isNoisy } from './helpers'; +import { getHistogramConfig, isNoisy } from './helpers'; import { ChartSeriesConfigs, ChartSeriesData } from '../../../../common/components/charts/common'; import { Panel } from '../../../../common/components/panel'; import { HeaderSection } from '../../../../common/components/header_section'; import { BarChart } from '../../../../common/components/charts/barchart'; import { usePreviewHistogram } from './use_preview_histogram'; import { formatDate } from '../../../../common/components/super_date_picker'; -import { FieldValueThreshold } from '../threshold_input'; -import { alertsDefaultModel } from '../../alerts_table/default_config'; +import { alertsPreviewDefaultModel } from '../../alerts_table/default_config'; import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; import { defaultRowRenderers } from '../../../../timelines/components/timeline/body/renderers'; import { TimelineId } from '../../../../../common/types'; @@ -35,6 +36,8 @@ import { PreviewRenderCellValue } from './preview_table_cell_renderer'; import { getPreviewTableControlColumn } from './preview_table_control_columns'; import { useGlobalFullScreen } from '../../../../common/containers/use_full_screen'; import { InspectButtonContainer } from '../../../../common/components/inspect'; +import { timelineActions } from '../../../../timelines/store/timeline'; +import { State } from '../../../../common/store'; const LoadingChart = styled(EuiLoadingChart)` display: block; @@ -55,7 +58,6 @@ interface PreviewHistogramProps { previewId: string; addNoiseWarning: () => void; spaceId: string; - threshold?: FieldValueThreshold; ruleType: Type; index: string[]; } @@ -67,10 +69,10 @@ export const PreviewHistogram = ({ previewId, addNoiseWarning, spaceId, - threshold, ruleType, index, }: PreviewHistogramProps) => { + const dispatch = useDispatch(); const { setQuery, isInitializing } = useGlobalTime(); const { timelines: timelinesUi, cases } = useKibana().services; const from = useMemo(() => `now-1${timeFrame}`, [timeFrame]); @@ -78,34 +80,36 @@ export const PreviewHistogram = ({ const startDate = useMemo(() => formatDate(from), [from]); const endDate = useMemo(() => formatDate(to), [to]); const isEqlRule = useMemo(() => ruleType === 'eql', [ruleType]); - const isThresholdRule = useMemo(() => ruleType === 'threshold', [ruleType]); + const isMlRule = useMemo(() => ruleType === 'machine_learning', [ruleType]); - const [isLoading, { data, inspect, totalCount, refetch, buckets }] = usePreviewHistogram({ + const [isLoading, { data, inspect, totalCount, refetch }] = usePreviewHistogram({ previewId, startDate, endDate, spaceId, - threshold: isThresholdRule ? threshold : undefined, index, ruleType, }); const { - columns, - dataProviders, - deletedEventIds, - kqlMode, - itemsPerPage, - itemsPerPageOptions, - graphEventId, - sort, - } = alertsDefaultModel; + timeline: { + columns, + dataProviders, + defaultColumns, + deletedEventIds, + itemsPerPage, + itemsPerPageOptions, + kqlMode, + sort, + } = alertsPreviewDefaultModel, + } = useSelector((state: State) => eventsViewerSelector(state, TimelineId.rulePreview)); const { browserFields, docValueFields, indexPattern, runtimeMappings, + dataViewId: selectedDataViewId, loading: isLoadingIndexPattern, } = useSourcererDataView(SourcererScopeName.detections); @@ -129,42 +133,28 @@ export const PreviewHistogram = ({ } }, [setQuery, inspect, isLoading, isInitializing, refetch, previewId]); + useEffect(() => { + dispatch( + timelineActions.createTimeline({ + columns, + dataViewId: selectedDataViewId, + defaultColumns, + id: TimelineId.rulePreview, + indexNames: [`${DEFAULT_PREVIEW_INDEX}-${spaceId}`], + itemsPerPage, + sort, + }) + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const barConfig = useMemo( (): ChartSeriesConfigs => getHistogramConfig(endDate, startDate, !isEqlRule), [endDate, startDate, isEqlRule] ); - const thresholdBarConfig = useMemo((): ChartSeriesConfigs => getThresholdHistogramConfig(), []); - const chartData = useMemo((): ChartSeriesData[] => [{ key: 'hits', value: data }], [data]); - const { thresholdChartData, thresholdTotalCount } = useMemo((): { - thresholdChartData: ChartSeriesData[]; - thresholdTotalCount: number; - } => { - const total = buckets.length; - const dataBuckets = buckets.map<{ x: string; y: number; g: string }>( - ({ key, doc_count: docCount }) => ({ - x: key, - y: docCount, - g: key, - }) - ); - return { - thresholdChartData: [{ key: 'hits', value: dataBuckets }], - thresholdTotalCount: total, - }; - }, [buckets]); - - const subtitle = useMemo( - (): string => - isLoading - ? i18n.QUERY_PREVIEW_SUBTITLE_LOADING - : isThresholdRule - ? i18n.QUERY_PREVIEW_THRESHOLD_WITH_FIELD_TITLE(thresholdTotalCount) - : i18n.QUERY_PREVIEW_TITLE(totalCount), - [isLoading, totalCount, thresholdTotalCount, isThresholdRule] - ); const CasesContext = cases.ui.getCasesContext(); return ( @@ -176,7 +166,6 @@ export const PreviewHistogram = ({ id={`${ID}-${previewId}`} title={i18n.QUERY_GRAPH_HITS_TITLE} titleSize="xs" - subtitle={subtitle} /> @@ -184,8 +173,8 @@ export const PreviewHistogram = ({ ) : ( )} @@ -194,7 +183,11 @@ export const PreviewHistogram = ({ <> -

{i18n.QUERY_PREVIEW_DISCLAIMER_MAX_SIGNALS}

+

+ {isMlRule + ? i18n.ML_PREVIEW_HISTOGRAM_DISCLAIMER + : i18n.PREVIEW_HISTOGRAM_DISCLAIMER} +

@@ -213,13 +206,12 @@ export const PreviewHistogram = ({ deletedEventIds, disabledCellActions: FIELDS_WITHOUT_CELL_ACTIONS, docValueFields, - end: to, - entityType: 'alerts', + end: endDate, + entityType: 'events', filters: [], globalFullScreen, - graphEventId, hasAlertsCrud: false, - id: TimelineId.detectionsPage, + id: TimelineId.rulePreview, indexNames: [`${DEFAULT_PREVIEW_INDEX}-${spaceId}`], indexPattern, isLive: false, @@ -233,7 +225,7 @@ export const PreviewHistogram = ({ runtimeMappings, setQuery: () => {}, sort, - start: from, + start: startDate, tGridEventRenderedViewEnabled, type: 'embedded', leadingControlColumns: getPreviewTableControlColumn(1.5), @@ -242,11 +234,11 @@ export const PreviewHistogram = ({ diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_table_cell_renderer.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_table_cell_renderer.test.tsx new file mode 100644 index 0000000000000..37b03dbc3fd88 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_table_cell_renderer.test.tsx @@ -0,0 +1,167 @@ +/* + * 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 { mount } from 'enzyme'; +import { cloneDeep } from 'lodash/fp'; +import React from 'react'; + +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 { PreviewTableCellRenderer } from './preview_table_cell_renderer'; +import { getColumnRenderer } from '../../../../timelines/components/timeline/body/renderers/get_column_renderer'; +import { DroppableWrapper } from '../../../../common/components/drag_and_drop/droppable_wrapper'; +import { BrowserFields } from '../../../../../../timelines/common/search_strategy'; +import { Ecs } from '../../../../../common/ecs'; +import { columnRenderers } from '../../../../timelines/components/timeline/body/renderers'; + +jest.mock('../../../../common/lib/kibana'); +jest.mock('../../../../timelines/components/timeline/body/renderers/get_column_renderer'); + +const getColumnRendererMock = getColumnRenderer as jest.Mock; +const mockImplementation = { + renderColumn: jest.fn(), +}; + +describe('PreviewTableCellRenderer', () => { + const columnId = '@timestamp'; + const eventId = '_id-123'; + const isExpandable = true; + const isExpanded = true; + const linkValues = ['foo', 'bar', '@baz']; + const rowIndex = 3; + const colIndex = 0; + const setCellProps = jest.fn(); + const timelineId = 'test'; + const ecsData = {} as Ecs; + const browserFields = {} as BrowserFields; + + beforeEach(() => { + jest.clearAllMocks(); + getColumnRendererMock.mockImplementation(() => mockImplementation); + }); + + test('it invokes `getColumnRenderer` with the expected arguments', () => { + const data = cloneDeep(mockTimelineData[0].data); + const header = cloneDeep(defaultHeaders[0]); + const isDetails = true; + + mount( + + + + + + + + ); + + expect(getColumnRenderer).toBeCalledWith(header.id, columnRenderers, data); + }); + + test('if in tgrid expanded value, it invokes `renderColumn` with the expected arguments', () => { + const data = cloneDeep(mockTimelineData[0].data); + const header = cloneDeep(defaultHeaders[0]); + const isDetails = true; + const truncate = isDetails ? false : true; + + mount( + + + + + + + + ); + + expect(mockImplementation.renderColumn).toBeCalledWith({ + asPlainText: false, + browserFields, + columnName: header.id, + ecsData, + eventId, + field: header, + isDetails, + isDraggable: true, + linkValues, + rowRenderers: undefined, + timelineId, + truncate, + values: ['2018-11-05T19:03:25.937Z'], + }); + }); + + test('if in tgrid expanded value, it does not render any actions', () => { + const data = cloneDeep(mockTimelineData[0].data); + const header = cloneDeep(defaultHeaders[1]); + const isDetails = true; + const id = 'event.severity'; + const wrapper = mount( + + + + + + + + ); + + expect( + wrapper.find('[data-test-subj="data-grid-expanded-cell-value-actions"]').exists() + ).toBeFalsy(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_table_cell_renderer.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_table_cell_renderer.tsx index ab56bd3fbfe0d..0e9df27827e47 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_table_cell_renderer.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_table_cell_renderer.tsx @@ -89,6 +89,7 @@ export const PreviewTableCellRenderer: React.FC = ({ const styledContentClassName = isDetails ? 'eui-textBreakWord' : 'eui-displayInlineBlock eui-textTruncate'; + return ( <> diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/translations.ts b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/translations.ts index 3acb533913cfd..81ff4b8cfc440 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/translations.ts @@ -54,7 +54,7 @@ export const QUERY_PREVIEW_LABEL = i18n.translate( export const QUERY_PREVIEW_HELP_TEXT = i18n.translate( 'xpack.securitySolution.detectionEngine.queryPreview.queryPreviewHelpText', { - defaultMessage: 'Select a timeframe of data to preview query results', + defaultMessage: 'Select a timeframe of data to preview query results.', } ); @@ -73,9 +73,9 @@ export const THRESHOLD_QUERY_GRAPH_COUNT = i18n.translate( ); export const QUERY_GRAPH_HITS_TITLE = i18n.translate( - 'xpack.securitySolution.detectionEngine.queryPreview.queryGraphHitsTitle', + 'xpack.securitySolution.detectionEngine.queryPreview.queryPreviewTitle', { - defaultMessage: 'Hits', + defaultMessage: 'Rule Preview', } ); @@ -124,18 +124,25 @@ export const QUERY_PREVIEW_ERROR = i18n.translate( ); export const QUERY_PREVIEW_DISCLAIMER = i18n.translate( - 'xpack.securitySolution.detectionEngine.queryPreview.queryGraphDisclaimer', + 'xpack.securitySolution.detectionEngine.queryPreview.queryPreviewDisclaimer', { defaultMessage: 'Note: This preview excludes effects of rule exceptions and timestamp overrides.', } ); -export const QUERY_PREVIEW_DISCLAIMER_MAX_SIGNALS = i18n.translate( - 'xpack.securitySolution.detectionEngine.queryPreview.queryGraphDisclaimerEql', +export const PREVIEW_HISTOGRAM_DISCLAIMER = i18n.translate( + 'xpack.securitySolution.detectionEngine.queryPreview.histogramDisclaimer', { defaultMessage: - 'Note: This preview excludes effects of rule exceptions and timestamp overrides, and is limited to 100 results.', + 'Note: Alerts with multiple event.category values will be counted more than once.', + } +); + +export const ML_PREVIEW_HISTOGRAM_DISCLAIMER = i18n.translate( + 'xpack.securitySolution.detectionEngine.queryPreview.mlHistogramDisclaimer', + { + defaultMessage: 'Note: Alerts with multiple host.name values will be counted more than once.', } ); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_histogram.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_histogram.tsx index 0d63092ee4eef..d336c75bb5f49 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_histogram.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_histogram.tsx @@ -13,14 +13,12 @@ import { getEsQueryConfig } from '../../../../../../../../src/plugins/data/commo import { useKibana } from '../../../../common/lib/kibana'; import { QUERY_PREVIEW_ERROR } from './translations'; import { DEFAULT_PREVIEW_INDEX } from '../../../../../common/constants'; -import { FieldValueThreshold } from '../threshold_input'; interface PreviewHistogramParams { previewId: string | undefined; endDate: string; startDate: string; spaceId: string; - threshold?: FieldValueThreshold; index: string[]; ruleType: Type; } @@ -30,7 +28,6 @@ export const usePreviewHistogram = ({ startDate, endDate, spaceId, - threshold, index, ruleType, }: PreviewHistogramParams) => { @@ -47,9 +44,8 @@ export const usePreviewHistogram = ({ }); const stackByField = useMemo(() => { - const stackByDefault = ruleType === 'machine_learning' ? 'host.name' : 'event.category'; - return threshold?.field[0] ?? stackByDefault; - }, [threshold, ruleType]); + return ruleType === 'machine_learning' ? 'host.name' : 'event.category'; + }, [ruleType]); const matrixHistogramRequest = useMemo(() => { return { @@ -60,11 +56,10 @@ export const usePreviewHistogram = ({ indexNames: [`${DEFAULT_PREVIEW_INDEX}-${spaceId}`], stackByField, startDate, - threshold, includeMissingData: false, skip: error != null, }; - }, [startDate, endDate, filterQuery, spaceId, error, threshold, stackByField]); + }, [startDate, endDate, filterQuery, spaceId, error, stackByField]); return useMatrixHistogramCombined(matrixHistogramRequest); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/user_info/index.tsx b/x-pack/plugins/security_solution/public/detections/components/user_info/index.tsx index 9c81b51445f60..1699d452be1f4 100644 --- a/x-pack/plugins/security_solution/public/detections/components/user_info/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/user_info/index.tsx @@ -10,7 +10,6 @@ import React, { useEffect, useReducer, Dispatch, createContext, useContext } fro import { useAlertsPrivileges } from '../../containers/detection_engine/alerts/use_alerts_privileges'; import { useSignalIndex } from '../../containers/detection_engine/alerts/use_signal_index'; -import { useCreateTransforms } from '../../../transforms/containers/use_create_transforms'; export interface State { canUserCRUD: boolean | null; @@ -233,8 +232,6 @@ export const useUserInfo = (): State => { createDeSignalIndex: createSignalIndex, } = useSignalIndex(); - const { createTransforms } = useCreateTransforms(); - useEffect(() => { if (!loading && canUserCRUD !== hasKibanaCRUD) { dispatch({ type: 'updateCanUserCRUD', canUserCRUD: hasKibanaCRUD }); @@ -335,13 +332,6 @@ export const useUserInfo = (): State => { } }, [dispatch, loading, signalIndexMappingOutdated, apiSignalIndexMappingOutdated]); - // TODO: Get the permissions model and if the user has the correct permissions for transforms - // then activate the transforms similar to the createSignalIndex. - // TODO: This should move out of detections/components and into its own transform area - useEffect(() => { - createTransforms(); - }, [createTransforms]); - useEffect(() => { if ( isAuthenticated && 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 a7942642b830f..b542fa7d40c4a 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 @@ -16,25 +16,9 @@ import { import * as i18n from '../../components/alerts_table/translations'; -/** - * columns implements a subset of `EuiDataGrid`'s `EuiDataGridColumn` interface, - * plus additional TGrid column properties - */ -export const columns: Array< +const baseColumns: Array< Pick & ColumnHeaderOptions > = [ - { - columnHeaderType: defaultColumnHeaderType, - id: '@timestamp', - initialWidth: DEFAULT_DATE_COLUMN_MIN_WIDTH + 10, - }, - { - columnHeaderType: defaultColumnHeaderType, - displayAsText: i18n.ALERTS_HEADERS_RULE, - id: 'kibana.alert.rule.name', - initialWidth: DEFAULT_COLUMN_MIN_WIDTH, - linkField: 'kibana.alert.rule.uuid', - }, { columnHeaderType: defaultColumnHeaderType, displayAsText: i18n.ALERTS_HEADERS_SEVERITY, @@ -78,3 +62,36 @@ export const columns: Array< id: 'destination.ip', }, ]; + +/** + * columns implements a subset of `EuiDataGrid`'s `EuiDataGridColumn` interface, + * plus additional TGrid column properties + */ +export const columns: Array< + Pick & ColumnHeaderOptions +> = [ + { + columnHeaderType: defaultColumnHeaderType, + id: '@timestamp', + initialWidth: DEFAULT_DATE_COLUMN_MIN_WIDTH + 10, + }, + { + columnHeaderType: defaultColumnHeaderType, + displayAsText: i18n.ALERTS_HEADERS_RULE, + id: 'kibana.alert.rule.name', + initialWidth: DEFAULT_COLUMN_MIN_WIDTH, + linkField: 'kibana.alert.rule.uuid', + }, + ...baseColumns, +]; + +export const rulePreviewColumns: Array< + Pick & ColumnHeaderOptions +> = [ + { + columnHeaderType: defaultColumnHeaderType, + id: 'kibana.alert.original_time', + initialWidth: DEFAULT_DATE_COLUMN_MIN_WIDTH + 10, + }, + ...baseColumns, +]; diff --git a/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx b/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx index c4259e8a5a737..a951712f97022 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx @@ -30,7 +30,6 @@ import * as i18n from './translations'; import { isCompleteResponse, isErrorResponse } from '../../../../../../../src/plugins/data/common'; import { getInspectResponse } from '../../../helpers'; import { InspectResponse } from '../../../types'; -import { useTransforms } from '../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; export const ID = 'hostsAllQuery'; @@ -78,7 +77,6 @@ export const useAllHost = ({ const searchSubscription = useRef(new Subscription()); const [loading, setLoading] = useState(false); const [hostsRequest, setHostRequest] = useState(null); - const { getTransformChangesIfTheyExist } = useTransforms(); const { addError, addWarning } = useAppToasts(); const wrappedLoadMore = useCallback( @@ -168,24 +166,18 @@ export const useAllHost = ({ useEffect(() => { setHostRequest((prevRequest) => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ + const myRequest = { + ...(prevRequest ?? {}), + defaultIndex: indexNames, + docValueFields: docValueFields ?? [], factoryQueryType: HostsQueries.hosts, - indices: indexNames, - filterQuery, + filterQuery: createFilter(filterQuery), + pagination: generateTablePaginationOptions(activePage, limit), timerange: { interval: '12h', from: startDate, to: endDate, }, - }); - const myRequest = { - ...(prevRequest ?? {}), - defaultIndex: indices, - docValueFields: docValueFields ?? [], - factoryQueryType, - filterQuery: createFilter(filterQuery), - pagination: generateTablePaginationOptions(activePage, limit), - timerange, sort: { direction, field: sortField, @@ -206,7 +198,6 @@ export const useAllHost = ({ limit, startDate, sortField, - getTransformChangesIfTheyExist, ]); useEffect(() => { diff --git a/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/authentications/index.tsx b/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/authentications/index.tsx index 9fa38c14e2ea4..bf67c00c03cd9 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/authentications/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/authentications/index.tsx @@ -10,7 +10,6 @@ import { noop } from 'lodash/fp'; import { useCallback, useEffect, useRef, useState } from 'react'; import { Subscription } from 'rxjs'; -import { useTransforms } from '../../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { inputsModel } from '../../../../common/store'; import { createFilter } from '../../../../common/containers/helpers'; @@ -58,7 +57,6 @@ export const useHostsKpiAuthentications = ({ const [loading, setLoading] = useState(false); const [hostsKpiAuthenticationsRequest, setHostsKpiAuthenticationsRequest] = useState(null); - const { getTransformChangesIfTheyExist } = useTransforms(); const [hostsKpiAuthenticationsResponse, setHostsKpiAuthenticationsResponse] = useState({ @@ -132,30 +130,24 @@ export const useHostsKpiAuthentications = ({ ); useEffect(() => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ - factoryQueryType: HostsKpiQueries.kpiAuthentications, - indices: indexNames, - filterQuery, - timerange: { - interval: '12h', - from: startDate, - to: endDate, - }, - }); setHostsKpiAuthenticationsRequest((prevRequest) => { const myRequest = { ...(prevRequest ?? {}), - defaultIndex: indices, - factoryQueryType, + defaultIndex: indexNames, + factoryQueryType: HostsKpiQueries.kpiAuthentications, filterQuery: createFilter(filterQuery), - timerange, + timerange: { + interval: '12h', + from: startDate, + to: endDate, + }, }; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } return prevRequest; }); - }, [indexNames, endDate, filterQuery, startDate, getTransformChangesIfTheyExist]); + }, [indexNames, endDate, filterQuery, startDate]); useEffect(() => { hostsKpiAuthenticationsSearch(hostsKpiAuthenticationsRequest); diff --git a/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/hosts/index.tsx b/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/hosts/index.tsx index 63f0476c2b631..a2644277246de 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/hosts/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/hosts/index.tsx @@ -10,7 +10,6 @@ import { noop } from 'lodash/fp'; import { useCallback, useEffect, useRef, useState } from 'react'; import { Subscription } from 'rxjs'; -import { useTransforms } from '../../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { inputsModel } from '../../../../common/store'; import { createFilter } from '../../../../common/containers/helpers'; @@ -57,7 +56,6 @@ export const useHostsKpiHosts = ({ const [loading, setLoading] = useState(false); const [hostsKpiHostsRequest, setHostsKpiHostsRequest] = useState(null); - const { getTransformChangesIfTheyExist } = useTransforms(); const [hostsKpiHostsResponse, setHostsKpiHostsResponse] = useState({ hosts: 0, @@ -123,29 +121,23 @@ export const useHostsKpiHosts = ({ useEffect(() => { setHostsKpiHostsRequest((prevRequest) => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ + const myRequest = { + ...(prevRequest ?? {}), + defaultIndex: indexNames, factoryQueryType: HostsKpiQueries.kpiHosts, - indices: indexNames, - filterQuery, + filterQuery: createFilter(filterQuery), timerange: { interval: '12h', from: startDate, to: endDate, }, - }); - const myRequest = { - ...(prevRequest ?? {}), - defaultIndex: indices, - factoryQueryType, - filterQuery: createFilter(filterQuery), - timerange, }; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } return prevRequest; }); - }, [indexNames, endDate, filterQuery, startDate, getTransformChangesIfTheyExist]); + }, [indexNames, endDate, filterQuery, startDate]); useEffect(() => { hostsKpiHostsSearch(hostsKpiHostsRequest); diff --git a/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/unique_ips/index.tsx b/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/unique_ips/index.tsx index 25a9f76daf40f..24ef95a324b2f 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/unique_ips/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/containers/kpi_hosts/unique_ips/index.tsx @@ -10,7 +10,6 @@ import { noop } from 'lodash/fp'; import { useCallback, useEffect, useRef, useState } from 'react'; import { Subscription } from 'rxjs'; -import { useTransforms } from '../../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { inputsModel } from '../../../../common/store'; import { createFilter } from '../../../../common/containers/helpers'; @@ -56,7 +55,6 @@ export const useHostsKpiUniqueIps = ({ const abortCtrl = useRef(new AbortController()); const searchSubscription$ = useRef(new Subscription()); const [loading, setLoading] = useState(false); - const { getTransformChangesIfTheyExist } = useTransforms(); const [hostsKpiUniqueIpsRequest, setHostsKpiUniqueIpsRequest] = useState(null); @@ -130,30 +128,24 @@ export const useHostsKpiUniqueIps = ({ ); useEffect(() => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ - factoryQueryType: HostsKpiQueries.kpiUniqueIps, - indices: indexNames, - filterQuery, - timerange: { - interval: '12h', - from: startDate, - to: endDate, - }, - }); setHostsKpiUniqueIpsRequest((prevRequest) => { const myRequest = { ...(prevRequest ?? {}), - defaultIndex: indices, - factoryQueryType, + defaultIndex: indexNames, + factoryQueryType: HostsKpiQueries.kpiUniqueIps, filterQuery: createFilter(filterQuery), - timerange, + timerange: { + interval: '12h', + from: startDate, + to: endDate, + }, }; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } return prevRequest; }); - }, [indexNames, endDate, filterQuery, skip, startDate, getTransformChangesIfTheyExist]); + }, [indexNames, endDate, filterQuery, skip, startDate]); useEffect(() => { hostsKpiUniqueIpsSearch(hostsKpiUniqueIpsRequest); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/models/advanced_policy_schema.ts b/x-pack/plugins/security_solution/public/management/pages/policy/models/advanced_policy_schema.ts index d5147f58d4f0b..7f86540e36426 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/models/advanced_policy_schema.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/models/advanced_policy_schema.ts @@ -880,7 +880,7 @@ export const AdvancedPolicySchema: AdvancedPolicySchemaType[] = [ 'xpack.securitySolution.endpoint.policy.advanced.linux.advanced.kernel.capture_mode', { defaultMessage: - 'Allows users to control whether kprobes or ebpf are used to gather data. Possible options are kprobes, ebpf, or auto. Default: auto', + 'Allows users to control whether kprobes or ebpf are used to gather data. Possible options are kprobes, ebpf, or auto. Default: kprobes', } ), }, diff --git a/x-pack/plugins/security_solution/public/network/containers/kpi_network/dns/index.tsx b/x-pack/plugins/security_solution/public/network/containers/kpi_network/dns/index.tsx index 89f58f547bd75..9e6cf9f620287 100644 --- a/x-pack/plugins/security_solution/public/network/containers/kpi_network/dns/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/kpi_network/dns/index.tsx @@ -10,7 +10,6 @@ import { noop } from 'lodash/fp'; import { useCallback, useEffect, useRef, useState } from 'react'; import { Subscription } from 'rxjs'; -import { useTransforms } from '../../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { inputsModel } from '../../../../common/store'; import { createFilter } from '../../../../common/containers/helpers'; @@ -62,7 +61,6 @@ export const useNetworkKpiDns = ({ const [loading, setLoading] = useState(false); const [networkKpiDnsRequest, setNetworkKpiDnsRequest] = useState(null); - const { getTransformChangesIfTheyExist } = useTransforms(); const [networkKpiDnsResponse, setNetworkKpiDnsResponse] = useState({ dnsQueries: 0, @@ -127,30 +125,23 @@ export const useNetworkKpiDns = ({ useEffect(() => { setNetworkKpiDnsRequest((prevRequest) => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ + const myRequest = { + ...(prevRequest ?? {}), + defaultIndex: indexNames, factoryQueryType: NetworkKpiQueries.dns, - indices: indexNames, - filterQuery, + filterQuery: createFilter(filterQuery), timerange: { interval: '12h', from: startDate, to: endDate, }, - }); - - const myRequest = { - ...(prevRequest ?? {}), - defaultIndex: indices, - factoryQueryType, - filterQuery: createFilter(filterQuery), - timerange, }; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } return prevRequest; }); - }, [indexNames, endDate, filterQuery, startDate, getTransformChangesIfTheyExist]); + }, [indexNames, endDate, filterQuery, startDate]); useEffect(() => { networkKpiDnsSearch(networkKpiDnsRequest); diff --git a/x-pack/plugins/security_solution/public/network/containers/kpi_network/network_events/index.tsx b/x-pack/plugins/security_solution/public/network/containers/kpi_network/network_events/index.tsx index 51a5367446b6e..b5c8058f5035c 100644 --- a/x-pack/plugins/security_solution/public/network/containers/kpi_network/network_events/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/kpi_network/network_events/index.tsx @@ -10,7 +10,6 @@ import { noop } from 'lodash/fp'; import { useCallback, useEffect, useRef, useState } from 'react'; import { Subscription } from 'rxjs'; -import { useTransforms } from '../../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { inputsModel } from '../../../../common/store'; import { createFilter } from '../../../../common/containers/helpers'; @@ -62,7 +61,6 @@ export const useNetworkKpiNetworkEvents = ({ const [loading, setLoading] = useState(false); const [networkKpiNetworkEventsRequest, setNetworkKpiNetworkEventsRequest] = useState(null); - const { getTransformChangesIfTheyExist } = useTransforms(); const [networkKpiNetworkEventsResponse, setNetworkKpiNetworkEventsResponse] = useState({ @@ -131,29 +129,23 @@ export const useNetworkKpiNetworkEvents = ({ useEffect(() => { setNetworkKpiNetworkEventsRequest((prevRequest) => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ + const myRequest = { + ...(prevRequest ?? {}), + defaultIndex: indexNames, factoryQueryType: NetworkKpiQueries.networkEvents, - indices: indexNames, - filterQuery, + filterQuery: createFilter(filterQuery), timerange: { interval: '12h', from: startDate, to: endDate, }, - }); - const myRequest = { - ...(prevRequest ?? {}), - defaultIndex: indices, - factoryQueryType, - filterQuery: createFilter(filterQuery), - timerange, }; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } return prevRequest; }); - }, [indexNames, endDate, filterQuery, startDate, getTransformChangesIfTheyExist]); + }, [indexNames, endDate, filterQuery, startDate]); useEffect(() => { networkKpiNetworkEventsSearch(networkKpiNetworkEventsRequest); diff --git a/x-pack/plugins/security_solution/public/network/containers/kpi_network/tls_handshakes/index.tsx b/x-pack/plugins/security_solution/public/network/containers/kpi_network/tls_handshakes/index.tsx index ba42d79ad0eed..b5e1eaa401a46 100644 --- a/x-pack/plugins/security_solution/public/network/containers/kpi_network/tls_handshakes/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/kpi_network/tls_handshakes/index.tsx @@ -10,7 +10,6 @@ import { noop } from 'lodash/fp'; import { useCallback, useEffect, useRef, useState } from 'react'; import { Subscription } from 'rxjs'; -import { useTransforms } from '../../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { inputsModel } from '../../../../common/store'; import { createFilter } from '../../../../common/containers/helpers'; @@ -62,7 +61,6 @@ export const useNetworkKpiTlsHandshakes = ({ const [loading, setLoading] = useState(false); const [networkKpiTlsHandshakesRequest, setNetworkKpiTlsHandshakesRequest] = useState(null); - const { getTransformChangesIfTheyExist } = useTransforms(); const [networkKpiTlsHandshakesResponse, setNetworkKpiTlsHandshakesResponse] = useState({ @@ -130,30 +128,23 @@ export const useNetworkKpiTlsHandshakes = ({ useEffect(() => { setNetworkKpiTlsHandshakesRequest((prevRequest) => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ + const myRequest = { + ...(prevRequest ?? {}), + defaultIndex: indexNames, factoryQueryType: NetworkKpiQueries.tlsHandshakes, - indices: indexNames, - filterQuery, + filterQuery: createFilter(filterQuery), timerange: { interval: '12h', from: startDate, to: endDate, }, - }); - - const myRequest = { - ...(prevRequest ?? {}), - defaultIndex: indices, - factoryQueryType, - filterQuery: createFilter(filterQuery), - timerange, }; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } return prevRequest; }); - }, [indexNames, endDate, filterQuery, startDate, getTransformChangesIfTheyExist]); + }, [indexNames, endDate, filterQuery, startDate]); useEffect(() => { networkKpiTlsHandshakesSearch(networkKpiTlsHandshakesRequest); diff --git a/x-pack/plugins/security_solution/public/network/containers/kpi_network/unique_private_ips/index.tsx b/x-pack/plugins/security_solution/public/network/containers/kpi_network/unique_private_ips/index.tsx index b68c4fcb698c0..fafd38cf15f73 100644 --- a/x-pack/plugins/security_solution/public/network/containers/kpi_network/unique_private_ips/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/kpi_network/unique_private_ips/index.tsx @@ -10,7 +10,6 @@ import { noop } from 'lodash/fp'; import { useCallback, useEffect, useRef, useState } from 'react'; import { Subscription } from 'rxjs'; -import { useTransforms } from '../../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { inputsModel } from '../../../../common/store'; import { createFilter } from '../../../../common/containers/helpers'; @@ -66,7 +65,6 @@ export const useNetworkKpiUniquePrivateIps = ({ const [loading, setLoading] = useState(false); const [networkKpiUniquePrivateIpsRequest, setNetworkKpiUniquePrivateIpsRequest] = useState(null); - const { getTransformChangesIfTheyExist } = useTransforms(); const [networkKpiUniquePrivateIpsResponse, setNetworkKpiUniquePrivateIpsResponse] = useState({ @@ -142,30 +140,23 @@ export const useNetworkKpiUniquePrivateIps = ({ useEffect(() => { setNetworkKpiUniquePrivateIpsRequest((prevRequest) => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ + const myRequest = { + ...(prevRequest ?? {}), + defaultIndex: indexNames, factoryQueryType: NetworkKpiQueries.uniquePrivateIps, - indices: indexNames, - filterQuery, + filterQuery: createFilter(filterQuery), timerange: { interval: '12h', from: startDate, to: endDate, }, - }); - - const myRequest = { - ...(prevRequest ?? {}), - defaultIndex: indices, - factoryQueryType, - filterQuery: createFilter(filterQuery), - timerange, }; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } return prevRequest; }); - }, [indexNames, endDate, filterQuery, startDate, getTransformChangesIfTheyExist]); + }, [indexNames, endDate, filterQuery, startDate]); useEffect(() => { networkKpiUniquePrivateIpsSearch(networkKpiUniquePrivateIpsRequest); diff --git a/x-pack/plugins/security_solution/public/network/containers/network_top_countries/index.tsx b/x-pack/plugins/security_solution/public/network/containers/network_top_countries/index.tsx index 6110e84804fe3..4bb8f62b10a87 100644 --- a/x-pack/plugins/security_solution/public/network/containers/network_top_countries/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/network_top_countries/index.tsx @@ -29,7 +29,6 @@ import { isCompleteResponse, isErrorResponse } from '../../../../../../../src/pl import { getInspectResponse } from '../../../helpers'; import { InspectResponse } from '../../../types'; import * as i18n from './translations'; -import { useTransforms } from '../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; export const ID = 'networkTopCountriesQuery'; @@ -76,7 +75,6 @@ export const useNetworkTopCountries = ({ const searchSubscription$ = useRef(new Subscription()); const [loading, setLoading] = useState(false); const queryId = useMemo(() => `${ID}-${flowTarget}`, [flowTarget]); - const { getTransformChangesIfTheyExist } = useTransforms(); const [networkTopCountriesRequest, setHostRequest] = useState(null); @@ -170,45 +168,27 @@ export const useNetworkTopCountries = ({ useEffect(() => { setHostRequest((prevRequest) => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ - factoryQueryType: NetworkQueries.topCountries, - indices: indexNames, - filterQuery, - timerange: { - interval: '12h', - from: startDate, - to: endDate, - }, - }); - const myRequest = { ...(prevRequest ?? {}), - defaultIndex: indices, - factoryQueryType, + defaultIndex: indexNames, + factoryQueryType: NetworkQueries.topCountries, filterQuery: createFilter(filterQuery), flowTarget, ip, pagination: generateTablePaginationOptions(activePage, limit), sort, - timerange, + timerange: { + interval: '12h', + from: startDate, + to: endDate, + }, }; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } return prevRequest; }); - }, [ - activePage, - indexNames, - endDate, - filterQuery, - ip, - limit, - startDate, - sort, - flowTarget, - getTransformChangesIfTheyExist, - ]); + }, [activePage, indexNames, endDate, filterQuery, ip, limit, startDate, sort, flowTarget]); useEffect(() => { networkTopCountriesSearch(networkTopCountriesRequest); diff --git a/x-pack/plugins/security_solution/public/network/containers/network_top_n_flow/index.tsx b/x-pack/plugins/security_solution/public/network/containers/network_top_n_flow/index.tsx index 022b76c315c17..26d2f7a9d1df5 100644 --- a/x-pack/plugins/security_solution/public/network/containers/network_top_n_flow/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/network_top_n_flow/index.tsx @@ -29,7 +29,6 @@ import { isCompleteResponse, isErrorResponse } from '../../../../../../../src/pl import { getInspectResponse } from '../../../helpers'; import { InspectResponse } from '../../../types'; import * as i18n from './translations'; -import { useTransforms } from '../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; export const ID = 'networkTopNFlowQuery'; @@ -75,7 +74,6 @@ export const useNetworkTopNFlow = ({ const abortCtrl = useRef(new AbortController()); const searchSubscription$ = useRef(new Subscription()); const [loading, setLoading] = useState(false); - const { getTransformChangesIfTheyExist } = useTransforms(); const [networkTopNFlowRequest, setTopNFlowRequest] = useState(null); @@ -168,25 +166,19 @@ export const useNetworkTopNFlow = ({ useEffect(() => { setTopNFlowRequest((prevRequest) => { - const { indices, factoryQueryType, timerange } = getTransformChangesIfTheyExist({ - factoryQueryType: NetworkQueries.topNFlow, - indices: indexNames, - filterQuery, - timerange: { - interval: '12h', - from: startDate, - to: endDate, - }, - }); const myRequest = { ...(prevRequest ?? {}), - defaultIndex: indices, - factoryQueryType, + defaultIndex: indexNames, + factoryQueryType: NetworkQueries.topNFlow, filterQuery: createFilter(filterQuery), flowTarget, ip, pagination: generateTablePaginationOptions(activePage, limit), - timerange, + timerange: { + interval: '12h', + from: startDate, + to: endDate, + }, sort, }; if (!deepEqual(prevRequest, myRequest)) { @@ -194,18 +186,7 @@ export const useNetworkTopNFlow = ({ } return prevRequest; }); - }, [ - activePage, - endDate, - filterQuery, - indexNames, - ip, - limit, - startDate, - sort, - flowTarget, - getTransformChangesIfTheyExist, - ]); + }, [activePage, endDate, filterQuery, indexNames, ip, limit, startDate, sort, flowTarget]); useEffect(() => { networkTopNFlowSearch(networkTopNFlowRequest); diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx b/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx index 8c95a081b3e86..fe91c2fc1af9e 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx +++ b/x-pack/plugins/security_solution/public/risk_score/containers/all/index.tsx @@ -28,7 +28,6 @@ import * as i18n from './translations'; import { isCompleteResponse, isErrorResponse } from '../../../../../../../src/plugins/data/common'; import { getInspectResponse } from '../../../helpers'; import { InspectResponse } from '../../../types'; -import { useTransforms } from '../../../transforms/containers/use_transforms'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import { isIndexNotFoundError } from '../../../common/utils/exceptions'; import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; @@ -135,7 +134,6 @@ export const useRiskScore = (featureEnabled); const [riskScoreRequest, setRiskScoreRequest] = useState(null); - const { getTransformChangesIfTheyExist } = useTransforms(); const { addError, addWarning } = useAppToasts(); const [riskScoreResponse, setRiskScoreResponse] = useState>({ @@ -247,16 +245,7 @@ export const useRiskScore = { riskScoreSearch(riskScoreRequest); diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx index bdb896e31cfa3..5147301b4ea5d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/index.test.tsx @@ -167,4 +167,13 @@ describe('event details footer component', () => { ); expect(wrapper.getByTestId('side-panel-flyout-footer')).toBeTruthy(); }); + test("it doesn't render the take action dropdown when readOnly prop is passed", () => { + const wrapper = render( + + + + ); + const element = wrapper.queryByTestId('side-panel-flyout-footer'); + expect(element).toBeNull(); + }); }); diff --git a/x-pack/plugins/security_solution/public/transforms/containers/api.ts b/x-pack/plugins/security_solution/public/transforms/containers/api.ts deleted file mode 100644 index 0a796286de1aa..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/containers/api.ts +++ /dev/null @@ -1,49 +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 { KibanaServices } from '../../common/lib/kibana'; - -export interface CreateTransforms { - signal: AbortSignal; - // TODO: Stronger types from the metrics_entities project - bodies: unknown[]; -} - -export interface CreateTransform { - signal: AbortSignal; - // TODO: Stronger types from the metrics_entities project - body: unknown; -} - -/** - * Creates transforms given a configuration - * @param signal AbortSignal for cancelling request - * @param bodies The bodies for the REST interface that is going to create them one at a time. - * - * TODO: Once there is a _bulk API, then we can do these all at once - * @throws An error if response is not OK - */ -export const createTransforms = async ({ bodies, signal }: CreateTransforms): Promise => { - for (const body of bodies) { - await createTransform({ body, signal }); - } -}; - -/** - * Creates a single transform given a configuration - * @param signal AbortSignal for cancelling request - * @param bodies The body for the REST interface that is going to it. - * @throws An error if response is not OK - */ -export const createTransform = async ({ body, signal }: CreateTransform): Promise => { - // TODO: Use constants for the url here or from the metrics package. - return KibanaServices.get().http.fetch('/api/metrics_entities/transforms', { - method: 'POST', - body: JSON.stringify(body), - signal, - }); -}; diff --git a/x-pack/plugins/security_solution/public/transforms/containers/translations.ts b/x-pack/plugins/security_solution/public/transforms/containers/translations.ts deleted file mode 100644 index 2fdd285dddd85..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/containers/translations.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const TRANSFORM_CREATE_FAILURE = i18n.translate( - 'xpack.securitySolution.containers.transforms.errorCreatingTransformsLabel', - { - defaultMessage: 'Failed to create transforms', - } -); diff --git a/x-pack/plugins/security_solution/public/transforms/containers/use_create_transforms.ts b/x-pack/plugins/security_solution/public/transforms/containers/use_create_transforms.ts deleted file mode 100644 index 789a35939cba8..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/containers/use_create_transforms.ts +++ /dev/null @@ -1,112 +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 { useEffect, useState } from 'react'; -import { defaultTransformsSetting, DEFAULT_TRANSFORMS } from '../../../common/constants'; -import { TransformConfigSchema } from '../../../common/transforms/types'; -import { errorToToaster, useStateToaster } from '../../common/components/toasters'; -import * as i18n from './translations'; -import { createTransforms } from './api'; -import { useUiSetting$ } from '../../common/lib/kibana'; -import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; - -type Func = () => Promise; - -export interface ReturnTransform { - loading: boolean; - createTransforms: Func; -} - -export const noop: Func = () => Promise.resolve(); - -export const useCreateTransforms = (): ReturnTransform => { - const [loading, setLoading] = useState(true); - const [, dispatchToaster] = useStateToaster(); - const [transformSettings] = useUiSetting$( - DEFAULT_TRANSFORMS, - JSON.stringify(defaultTransformsSetting) as unknown as TransformConfigSchema // TODO: The types are not 100% correct within uiSettings$, so I have to cast here. Once that is fixed, this cast can be removed - ); - const [transforms, setTransforms] = useState>({ - createTransforms: noop, - }); - // TODO: Once we are past experimental phase this code should be removed - const metricsEntitiesEnabled = useIsExperimentalFeatureEnabled('metricsEntitiesEnabled'); - - useEffect(() => { - let isSubscribed = true; - const abortCtrl = new AbortController(); - - const createTheTransforms = async () => { - // TODO: Once we are past experimental phase this code should be removed - if (!metricsEntitiesEnabled) { - return; - } - - // double check one more time and not create the transform if the settings are not enabled. - if (!transformSettings.enabled || !transformSettings.auto_create) { - return; - } - let isFetchingData = false; - setLoading(true); - const bodies = getTransformBodies(transformSettings); - try { - await createTransforms({ bodies, signal: abortCtrl.signal }); - if (isSubscribed) { - isFetchingData = true; - } - } catch (error) { - if (isSubscribed) { - if (error.body.statusCode !== 404 && error.body.status_code !== 404) { - errorToToaster({ title: i18n.TRANSFORM_CREATE_FAILURE, error, dispatchToaster }); - } else { - // This means that the plugin is disabled and/or the user does not have permissions - // so we do not show an error toaster for this condition since this is a 404 error message - } - } - } - if (isSubscribed && !isFetchingData) { - setLoading(false); - } - }; - - if (transformSettings.enabled) { - setTransforms({ createTransforms: createTheTransforms }); - } else { - setTransforms({ createTransforms: noop }); - } - return () => { - isSubscribed = false; - abortCtrl.abort(); - }; - }, [dispatchToaster, transformSettings, metricsEntitiesEnabled]); - - return { loading, ...transforms }; -}; - -export const getTransformBodies = (transformSettings: TransformConfigSchema) => { - // eslint-disable-next-line @typescript-eslint/naming-convention - const { query, auto_start, max_page_search_size, docs_per_second } = transformSettings; - return transformSettings.settings.map(({ prefix, indices }) => { - return { - query, - prefix, - modules: [ - 'host_metrics', - 'host_entities', - 'network_entities', - 'network_metrics', - 'user_entities', - 'user_metrics', - ], - indices, - auto_start, - settings: { - max_page_search_size, - docs_per_second, - }, - }; - }); -}; diff --git a/x-pack/plugins/security_solution/public/transforms/containers/use_transforms.ts b/x-pack/plugins/security_solution/public/transforms/containers/use_transforms.ts deleted file mode 100644 index 9a98fb0815a3e..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/containers/use_transforms.ts +++ /dev/null @@ -1,111 +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 { useMemo, useState } from 'react'; -import { ESQuery } from '../../../common/typed_json'; -import { - FactoryQueryTypes, - MatrixHistogramType, - TimerangeInput, -} from '../../../common/search_strategy'; -import { TransformConfigSchema } from '../../../common/transforms/types'; -import { defaultTransformsSetting, DEFAULT_TRANSFORMS } from '../../../common/constants'; -import { useUiSetting$ } from '../../common/lib/kibana'; -import { getTransformChangesIfTheyExist } from '../utils'; -import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; - -export type TransformChangesIfTheyExist = ({ - factoryQueryType, - indices, - filterQuery, - histogramType, - timerange, -}: { - factoryQueryType: FactoryQueryTypes; - indices: string[]; - filterQuery: ESQuery | string | undefined; - histogramType?: MatrixHistogramType; - timerange: TimerangeInput; -}) => { - indices: string[]; - factoryQueryType: FactoryQueryTypes; - histogramType?: MatrixHistogramType; - timerange: TimerangeInput; -}; - -export interface ReturnTransform { - getTransformChangesIfTheyExist: TransformChangesIfTheyExist; -} - -export const useTransforms = (): ReturnTransform => { - const [transformSettings] = useUiSetting$( - DEFAULT_TRANSFORMS, - JSON.stringify(defaultTransformsSetting) as unknown as TransformConfigSchema // TODO: The types are not 100% correct within uiSettings$, so I have to cast here. Once that is fixed, this cast can be removed - ); - // TODO: Once we are past experimental phase this code should be removed - const metricsEntitiesEnabled = useIsExperimentalFeatureEnabled('metricsEntitiesEnabled'); - const [transforms, setTransforms] = useState({ - getTransformChangesIfTheyExist: ({ - factoryQueryType, - indices, - filterQuery, - histogramType, - timerange, - }) => { - if (metricsEntitiesEnabled) { - return getTransformChangesIfTheyExist({ - factoryQueryType, - indices, - filterQuery, - transformSettings, - histogramType, - timerange, - }); - } else { - // TODO: Once the experimental flag is removed, then remove this return statement - return { - indices, - filterQuery, - timerange, - factoryQueryType, - }; - } - }, - }); - - useMemo(() => { - setTransforms({ - getTransformChangesIfTheyExist: ({ - factoryQueryType, - indices, - filterQuery, - histogramType, - timerange, - }) => { - if (metricsEntitiesEnabled) { - return getTransformChangesIfTheyExist({ - factoryQueryType, - indices, - transformSettings, - filterQuery, - histogramType, - timerange, - }); - } else { - // TODO: Once the experimental flag is removed, then remove this return statement - return { - indices, - filterQuery, - timerange, - factoryQueryType, - }; - } - }, - }); - }, [transformSettings, metricsEntitiesEnabled]); - - return { ...transforms }; -}; diff --git a/x-pack/plugins/security_solution/public/transforms/jest.config.js b/x-pack/plugins/security_solution/public/transforms/jest.config.js deleted file mode 100644 index 095a70933abc1..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/jest.config.js +++ /dev/null @@ -1,26 +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. - */ - -module.exports = { - preset: '@kbn/test', - rootDir: '../../../../..', - roots: ['/x-pack/plugins/security_solution/public/transforms'], - coverageDirectory: - '/target/kibana-coverage/jest/x-pack/plugins/security_solution/public/transforms', - coverageReporters: ['text', 'html'], - collectCoverageFrom: [ - '/x-pack/plugins/security_solution/public/transforms/**/*.{ts,tsx}', - ], - // See: https://github.com/elastic/kibana/issues/117255, the moduleNameMapper creates mocks to avoid memory leaks from kibana core. - moduleNameMapper: { - 'core/server$': '/x-pack/plugins/security_solution/server/__mocks__/core.mock.ts', - 'task_manager/server$': - '/x-pack/plugins/security_solution/server/__mocks__/task_manager.mock.ts', - 'alerting/server$': '/x-pack/plugins/security_solution/server/__mocks__/alert.mock.ts', - 'actions/server$': '/x-pack/plugins/security_solution/server/__mocks__/action.mock.ts', - }, -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/adjust_timerange.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/adjust_timerange.test.ts deleted file mode 100644 index daf3ab5365bef..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/adjust_timerange.test.ts +++ /dev/null @@ -1,71 +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 { adjustTimeRange } from './adjust_timerange'; -import moment from 'moment'; - -/** Get the return type of adjustTimeRange for TypeScript checks against expected */ -type ReturnTypeAdjustTimeRange = ReturnType; - -describe('adjust_timerange', () => { - beforeEach(() => { - // Adds extra switch to suppress deprecation warnings that moment does not expose in TypeScript - ( - moment as typeof moment & { - suppressDeprecationWarnings: boolean; - } - ).suppressDeprecationWarnings = true; - }); - - afterEach(() => { - // Adds extra switch to suppress deprecation warnings that moment does not expose in TypeScript - ( - moment as typeof moment & { - suppressDeprecationWarnings: boolean; - } - ).suppressDeprecationWarnings = false; - }); - - test('it will adjust the time range from by rounding down by an hour within "from"', () => { - expect( - adjustTimeRange({ - interval: '5m', - to: '2021-07-06T22:07:56.972Z', - from: '2021-07-06T22:07:56.972Z', - }) - ).toMatchObject>({ - timeRangeAdjusted: { - interval: '5m', - to: '2021-07-06T22:07:56.972Z', - from: '2021-07-06T22:00:00.000Z', // <-- Rounded down by an hour - }, - }); - }); - - test('it will compute the duration between to and and from', () => { - expect( - adjustTimeRange({ - interval: '5m', - to: '2021-07-06T22:08:56.972Z', - from: '2021-07-06T22:07:56.972Z', - }).duration?.asMinutes() - ).toEqual(1); - }); - - test('it will return "undefined" if the to and from are invalid dateMath parsable', () => { - expect( - adjustTimeRange({ - interval: '5m', - to: 'now-invalid', - from: 'now-invalid2', - }) - ).toMatchObject>({ - timeRangeAdjusted: undefined, - duration: undefined, - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/adjust_timerange.ts b/x-pack/plugins/security_solution/public/transforms/utils/adjust_timerange.ts deleted file mode 100644 index 464ccd8692512..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/adjust_timerange.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import dateMath from '@kbn/datemath'; -import moment, { Duration } from 'moment'; -import type { TimerangeInput } from '../../../common/search_strategy'; - -export interface TimeRangeAdjusted { - timeRangeAdjusted: TimerangeInput | undefined; - duration: Duration | undefined; -} - -/** - * Adjusts a given timerange by rounding the "from" down by an hour and returning - * the duration between "to" and "from". The duration is typically analyzed to determine - * if the adjustment should be made or not. Although we check "to" and use "to" for duration - * we are careful to still return "to: timerange.to", which is the original input to be careful - * about accidental bugs from trying to over parse or change relative date time ranges. - * @param timerange The timeRange to determine if we adjust or not - * @returns The time input adjustment and a duration - */ -export const adjustTimeRange = (timerange: TimerangeInput): TimeRangeAdjusted => { - const from = dateMath.parse(timerange.from); - const to = dateMath.parse(timerange.to); - if (from == null || to == null) { - return { timeRangeAdjusted: undefined, duration: undefined }; - } else { - const newTimerange: TimerangeInput = { - from: moment(from).startOf('hour').toISOString(), - to: timerange.to, - interval: timerange.interval, - }; - const duration = moment.duration(to.diff(from)); - return { timeRangeAdjusted: newTimerange, duration }; - } -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/create_indices_from_prefix.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/create_indices_from_prefix.test.ts deleted file mode 100644 index 2cdb1c4ebc2cd..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/create_indices_from_prefix.test.ts +++ /dev/null @@ -1,31 +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 { createIndicesFromPrefix } from './create_indices_from_prefix'; - -/** Get the return type of createIndicesFromPrefix for TypeScript checks against expected */ -type ReturnTypeCreateIndicesFromPrefix = ReturnType; - -describe('create_indices_from_prefix', () => { - test('returns empty array given an empty array', () => { - expect( - createIndicesFromPrefix({ - transformIndices: [], - prefix: 'prefix', - }) - ).toEqual([]); - }); - - test('returns expected prefix given a set of indices', () => { - expect( - createIndicesFromPrefix({ - transformIndices: ['index_1', 'index_2'], - prefix: 'prefix', - }) - ).toEqual(['.estc_prefix_index_1', '.estc_prefix_index_2']); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/create_indices_from_prefix.ts b/x-pack/plugins/security_solution/public/transforms/utils/create_indices_from_prefix.ts deleted file mode 100644 index de63933ba4475..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/create_indices_from_prefix.ts +++ /dev/null @@ -1,25 +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 { ELASTIC_NAME } from '../../../common/constants'; - -/** - * Given a set of input indices and a prefix this will return the elastic name - * concatenated with the prefix. - * @param transformIndices The indices to add the prefix to - * @param prefix The prefix to add along with the elastic name - * @returns The indices with the prefix string - */ -export const createIndicesFromPrefix = ({ - transformIndices, - prefix, -}: { - transformIndices: string[]; - prefix: string; -}): string[] => { - return transformIndices.map((index) => `.${ELASTIC_NAME}_${prefix}_${index}`); -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_settings_match.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_settings_match.test.ts deleted file mode 100644 index a58757c261624..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_settings_match.test.ts +++ /dev/null @@ -1,82 +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 { getSettingsMatch } from './get_settings_match'; -import { getTransformConfigSchemaMock } from './transform_config_schema.mock'; - -/** Get the return type of createIndicesFromPrefix for TypeScript checks against expected */ -type ReturnTypeCreateIndicesFromPrefix = ReturnType; - -describe('get_settings_match', () => { - test('it returns undefined given an empty array of indices', () => { - expect( - getSettingsMatch({ - indices: [], - transformSettings: getTransformConfigSchemaMock(), - }) - ).toEqual(undefined); - }); - - test('it returns a setting given an index pattern that matches', () => { - expect( - getSettingsMatch({ - indices: [ - 'auditbeat-*', - 'endgame-*', - 'filebeat-*', - 'logs-*', - 'packetbeat-*', - 'winlogbeat-*', - ], - transformSettings: getTransformConfigSchemaMock(), - }) - ).toEqual(getTransformConfigSchemaMock().settings[0]); - }); - - test('it returns a setting given an index pattern that matches even if the indices are different order', () => { - expect( - getSettingsMatch({ - indices: [ - 'endgame-*', - 'filebeat-*', - 'logs-*', - 'auditbeat-*', - 'packetbeat-*', - 'winlogbeat-*', - ], - transformSettings: getTransformConfigSchemaMock(), - }) - ).toEqual(getTransformConfigSchemaMock().settings[0]); - }); - - test('it returns a setting given an index pattern that matches and removes any that have a dash in them meaning to subtract them', () => { - expect( - getSettingsMatch({ - indices: [ - 'endgame-*', - 'filebeat-*', - 'logs-*', - 'auditbeat-*', - 'packetbeat-*', - 'winlogbeat-*', - '-subtract-1', // extra dashed one that should still allow a match - '-subtract-2', // extra dashed one that should still allow a match - ], - transformSettings: getTransformConfigSchemaMock(), - }) - ).toEqual(getTransformConfigSchemaMock().settings[0]); - }); - - test('it returns "undefined" given a set of indices that do not match a setting', () => { - expect( - getSettingsMatch({ - indices: ['endgame-*', 'filebeat-*', 'logs-*', 'auditbeat-*', 'packetbeat-*'], - transformSettings: getTransformConfigSchemaMock(), - }) - ).toEqual(undefined); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_settings_match.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_settings_match.ts deleted file mode 100644 index ed7be4a530dcf..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_settings_match.ts +++ /dev/null @@ -1,34 +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 { TransformConfigSchema } from '../../../common/transforms/types'; - -/** - * Given a transform setting and indices this will return either the particular setting - * that matches the index or it will return undefined if it is not found - * @param indices The indices to check against the transform - * @returns Either the setting if it matches or an undefined if it cannot find one - */ -export const getSettingsMatch = ({ - indices, - transformSettings, -}: { - indices: string[]; - transformSettings: TransformConfigSchema; -}): TransformConfigSchema['settings'][0] | undefined => { - const removeAllSubtractedIndices = indices.filter((index) => !index.startsWith('-')).sort(); - return transformSettings.settings.find((setting) => { - const match = setting.data_sources.some((dataSource) => { - return dataSource.sort().join() === removeAllSubtractedIndices.join(); - }); - if (match) { - return setting; - } else { - return undefined; - } - }); -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes.test.ts deleted file mode 100644 index 702d259f98615..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes.test.ts +++ /dev/null @@ -1,177 +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 { getTransformChanges } from './get_transform_changes'; -import { getTransformConfigSchemaMock } from './transform_config_schema.mock'; -import { - HostsKpiQueries, - HostsQueries, - MatrixHistogramQuery, - MatrixHistogramQueryEntities, - MatrixHistogramType, - NetworkKpiQueries, - NetworkQueries, - UsersQueries, -} from '../../../common/search_strategy'; - -/** Get the return type of createIndicesFromPrefix for TypeScript checks against expected */ -type ReturnTypeGetTransformChanges = ReturnType; - -describe('get_transform_changes', () => { - describe('kpi transforms', () => { - test('it gets a transform change for kpiHosts', () => { - expect( - getTransformChanges({ - factoryQueryType: HostsKpiQueries.kpiHosts, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: HostsKpiQueries.kpiHostsEntities, - indices: ['.estc_all_host_ent*'], - }); - }); - - test('it gets a transform change for kpiAuthentications', () => { - expect( - getTransformChanges({ - factoryQueryType: HostsKpiQueries.kpiAuthentications, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: HostsKpiQueries.kpiAuthenticationsEntities, - indices: ['.estc_all_user_ent*'], - }); - }); - - test('it gets a transform change for kpiUniqueIps', () => { - expect( - getTransformChanges({ - factoryQueryType: HostsKpiQueries.kpiUniqueIps, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: HostsKpiQueries.kpiUniqueIpsEntities, - indices: ['.estc_all_src_ip_ent*', '.estc_all_dest_ip_ent*'], - }); - }); - }); - - describe('host transforms', () => { - test('it gets a transform change for hosts', () => { - expect( - getTransformChanges({ - factoryQueryType: HostsQueries.hosts, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: HostsQueries.hostsEntities, - indices: ['.estc_all_host_ent*'], - }); - }); - - test('it gets a transform change for authentications', () => { - expect( - getTransformChanges({ - factoryQueryType: UsersQueries.authentications, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: UsersQueries.authenticationsEntities, - indices: ['.estc_all_user_ent*'], - }); - }); - }); - - describe('network transforms', () => { - test('it gets a transform change for topCountries', () => { - expect( - getTransformChanges({ - factoryQueryType: NetworkQueries.topCountries, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkQueries.topCountriesEntities, - indices: ['.estc_all_src_iso_ent*', '.estc_all_dest_iso_ent*'], - }); - }); - - test('it gets a transform change for topNFlow', () => { - expect( - getTransformChanges({ - factoryQueryType: NetworkQueries.topNFlow, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkQueries.topNFlowEntities, - indices: ['.estc_all_src_ip_ent*', '.estc_all_dest_ip_ent*'], - }); - }); - - test('it gets a transform change for dns', () => { - expect( - getTransformChanges({ - factoryQueryType: NetworkKpiQueries.dns, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkKpiQueries.dnsEntities, - indices: ['.estc_all_ip_met*'], - }); - }); - - test('it gets a transform change for networkEvents', () => { - expect( - getTransformChanges({ - factoryQueryType: NetworkKpiQueries.networkEvents, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkKpiQueries.networkEventsEntities, - indices: ['.estc_all_ip_met*'], - }); - }); - - test('it gets a transform change for tlsHandshakes', () => { - expect( - getTransformChanges({ - factoryQueryType: NetworkKpiQueries.tlsHandshakes, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkKpiQueries.tlsHandshakesEntities, - indices: ['.estc_all_ip_met*'], - }); - }); - }); - - describe('matrix transforms', () => { - test('it gets a transform change for authentications', () => { - expect( - getTransformChanges({ - factoryQueryType: MatrixHistogramQuery, - histogramType: MatrixHistogramType.authentications, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - histogramType: MatrixHistogramType.authenticationsEntities, - factoryQueryType: MatrixHistogramQueryEntities, - indices: ['.estc_all_user_met*'], - }); - }); - }); - - describe('unsupported/undefined transforms', () => { - test('it returned unsupported/undefined for firstOrLastSeen since there are not transforms for it', () => { - expect( - getTransformChanges({ - factoryQueryType: HostsQueries.firstOrLastSeen, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual(undefined); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes.ts deleted file mode 100644 index 1a72c556490a5..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { getTransformChangesForHosts } from './get_transform_changes_for_hosts'; -import { getTransformChangesForKpi } from './get_transform_changes_for_kpi'; -import { getTransformChangesForMatrixHistogram } from './get_transform_changes_for_matrix_histogram'; -import { getTransformChangesForNetwork } from './get_transform_changes_for_network'; -import { getTransformChangesForUsers } from './get_transform_changes_for_users'; -import { GetTransformChanges } from './types'; - -export const getTransformChanges: GetTransformChanges = ({ - factoryQueryType, - settings, - histogramType, -}) => { - const kpiTransform = getTransformChangesForKpi({ factoryQueryType, settings }); - if (kpiTransform != null) { - return kpiTransform; - } - - const hostTransform = getTransformChangesForHosts({ factoryQueryType, settings }); - if (hostTransform != null) { - return hostTransform; - } - - const userTransform = getTransformChangesForUsers({ factoryQueryType, settings }); - if (userTransform != null) { - return userTransform; - } - - const networkTransform = getTransformChangesForNetwork({ - factoryQueryType, - settings, - }); - if (networkTransform != null) { - return networkTransform; - } - - const matrixHistogram = getTransformChangesForMatrixHistogram({ - factoryQueryType, - settings, - histogramType, - }); - if (matrixHistogram != null) { - return matrixHistogram; - } - - // nothing matches - return undefined; -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_hosts.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_hosts.test.ts deleted file mode 100644 index 8223e3a9cd6e6..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_hosts.test.ts +++ /dev/null @@ -1,36 +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 { getTransformChangesForHosts } from './get_transform_changes_for_hosts'; -import { HostsQueries } from '../../../common/search_strategy/security_solution/hosts'; -import { getTransformConfigSchemaMock } from './transform_config_schema.mock'; - -/** Get the return type of getTransformChangesForHosts for TypeScript checks against expected */ -type ReturnTypeGetTransformChangesForHosts = ReturnType; - -describe('get_transform_changes_for_host', () => { - test('it gets a transform change for hosts', () => { - expect( - getTransformChangesForHosts({ - factoryQueryType: HostsQueries.hosts, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: HostsQueries.hostsEntities, - indices: ['.estc_all_host_ent*'], - }); - }); - - test('it returns an "undefined" for another value', () => { - expect( - getTransformChangesForHosts({ - factoryQueryType: HostsQueries.firstOrLastSeen, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual(undefined); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_hosts.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_hosts.ts deleted file mode 100644 index 265b2857d5397..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_hosts.ts +++ /dev/null @@ -1,37 +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 { HostsQueries } from '../../../common/search_strategy'; -import { createIndicesFromPrefix } from './create_indices_from_prefix'; -import { GetTransformChanges } from './types'; - -/** - * Given a factory query type this will return the transform changes such as the transform indices if it matches - * the correct type, otherwise it will return "undefined" - * @param factoryQueryType The query type to check if we have a transform for it and are capable of rendering one or not - * @param settings The settings configuration to get the prefix from - * @returns The transform type if we have one, otherwise undefined - */ -export const getTransformChangesForHosts: GetTransformChanges = ({ - factoryQueryType, - settings, -}) => { - switch (factoryQueryType) { - case HostsQueries.hosts: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['host_ent*'], - }), - factoryQueryType: HostsQueries.hostsEntities, - }; - } - default: { - return undefined; - } - } -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_kpi.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_kpi.test.ts deleted file mode 100644 index 561874930feae..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_kpi.test.ts +++ /dev/null @@ -1,61 +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 { getTransformChangesForKpi } from './get_transform_changes_for_kpi'; -import { HostsKpiQueries } from '../../../common/search_strategy'; -import { HostsQueries } from '../../../common/search_strategy/security_solution/hosts'; -import { getTransformConfigSchemaMock } from './transform_config_schema.mock'; - -/** Get the return type of getTransformChangesForKpi for TypeScript checks against expected */ -type ReturnTypeGetTransformChangesForKpi = ReturnType; - -describe('get_transform_changes_for_kpi', () => { - test('it gets a transform change for kpiHosts', () => { - expect( - getTransformChangesForKpi({ - factoryQueryType: HostsKpiQueries.kpiHosts, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: HostsKpiQueries.kpiHostsEntities, - indices: ['.estc_all_host_ent*'], - }); - }); - - test('it gets a transform change for kpiAuthentications', () => { - expect( - getTransformChangesForKpi({ - factoryQueryType: HostsKpiQueries.kpiAuthentications, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: HostsKpiQueries.kpiAuthenticationsEntities, - indices: ['.estc_all_user_ent*'], - }); - }); - - test('it gets a transform change for kpiUniqueIps', () => { - expect( - getTransformChangesForKpi({ - factoryQueryType: HostsKpiQueries.kpiUniqueIps, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: HostsKpiQueries.kpiUniqueIpsEntities, - indices: ['.estc_all_src_ip_ent*', '.estc_all_dest_ip_ent*'], - }); - }); - - test('it returns an "undefined" for another value', () => { - expect( - getTransformChangesForKpi({ - factoryQueryType: HostsQueries.firstOrLastSeen, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual(undefined); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_kpi.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_kpi.ts deleted file mode 100644 index 800d3189e0c7a..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_kpi.ts +++ /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 { HostsKpiQueries } from '../../../common/search_strategy'; -import { createIndicesFromPrefix } from './create_indices_from_prefix'; -import { GetTransformChanges } from './types'; - -/** - * Given a factory query type this will return the transform changes such as the transform indices if it matches - * the correct type, otherwise it will return "undefined" - * @param factoryQueryType The query type to check if we have a transform for it and are capable of rendering one or not - * @param settings The settings configuration to get the prefix from - * @returns The transform type if we have one, otherwise undefined - */ -export const getTransformChangesForKpi: GetTransformChanges = ({ factoryQueryType, settings }) => { - switch (factoryQueryType) { - case HostsKpiQueries.kpiHosts: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['host_ent*'], - }), - factoryQueryType: HostsKpiQueries.kpiHostsEntities, - }; - } - case HostsKpiQueries.kpiAuthentications: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['user_ent*'], - }), - factoryQueryType: HostsKpiQueries.kpiAuthenticationsEntities, - }; - } - case HostsKpiQueries.kpiUniqueIps: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['src_ip_ent*', 'dest_ip_ent*'], - }), - factoryQueryType: HostsKpiQueries.kpiUniqueIpsEntities, - }; - } - default: { - return undefined; - } - } -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_matrix_histogram.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_matrix_histogram.test.ts deleted file mode 100644 index 539fb960e4411..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_matrix_histogram.test.ts +++ /dev/null @@ -1,45 +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 { - MatrixHistogramType, - MatrixHistogramQuery, - MatrixHistogramQueryEntities, -} from '../../../common/search_strategy'; -import { getTransformChangesForMatrixHistogram } from './get_transform_changes_for_matrix_histogram'; -import { HostsQueries } from '../../../common/search_strategy/security_solution/hosts'; -import { getTransformConfigSchemaMock } from './transform_config_schema.mock'; - -/** Get the return type of getTransformChangesForMatrixHistogram for TypeScript checks against expected */ -type ReturnTypeGetTransformChangesForMatrixHistogram = ReturnType< - typeof getTransformChangesForMatrixHistogram ->; - -describe('get_transform_changes_for_matrix_histogram', () => { - test('it gets a transform change for authentications', () => { - expect( - getTransformChangesForMatrixHistogram({ - factoryQueryType: MatrixHistogramQuery, - histogramType: MatrixHistogramType.authentications, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - histogramType: MatrixHistogramType.authenticationsEntities, - factoryQueryType: MatrixHistogramQueryEntities, - indices: ['.estc_all_user_met*'], - }); - }); - - test('it returns an "undefined" for another value', () => { - expect( - getTransformChangesForMatrixHistogram({ - factoryQueryType: HostsQueries.firstOrLastSeen, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual(undefined); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_matrix_histogram.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_matrix_histogram.ts deleted file mode 100644 index 36e8c2203200b..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_matrix_histogram.ts +++ /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 { - MatrixHistogramQuery, - MatrixHistogramQueryEntities, - MatrixHistogramType, -} from '../../../common/search_strategy'; -import { createIndicesFromPrefix } from './create_indices_from_prefix'; -import { GetTransformChanges } from './types'; - -/** - * Given a factory query type this will return the transform changes such as the transform indices if it matches - * the correct type, otherwise it will return "undefined" - * @param factoryQueryType The query type to check if we have a transform for it and are capable of rendering one or not - * @param histogramType The histogram type to check if we have a transform for it and are capable fo rendering one or not - * @param settings The settings configuration to get the prefix from - * @returns The transform type if we have one, otherwise undefined - */ -export const getTransformChangesForMatrixHistogram: GetTransformChanges = ({ - factoryQueryType, - settings, - histogramType, -}) => { - switch (factoryQueryType) { - case MatrixHistogramQuery: { - switch (histogramType) { - case MatrixHistogramType.authentications: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['user_met*'], - }), - factoryQueryType: MatrixHistogramQueryEntities, - histogramType: MatrixHistogramType.authenticationsEntities, - }; - } - default: { - return undefined; - } - } - } - default: { - return undefined; - } - } -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_network.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_network.test.ts deleted file mode 100644 index ffac8853f6e67..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_network.test.ts +++ /dev/null @@ -1,97 +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 { getTransformChangesForNetwork } from './get_transform_changes_for_network'; -import { NetworkKpiQueries, NetworkQueries } from '../../../common/search_strategy'; -import { HostsQueries } from '../../../common/search_strategy/security_solution/hosts'; -import { getTransformConfigSchemaMock } from './transform_config_schema.mock'; - -/** Get the return type of getTransformChangesForNetwork for TypeScript checks against expected */ -type ReturnTypeGetTransformChangesForNetwork = ReturnType; - -describe('get_transform_changes_for_network', () => { - test('it gets a transform change for topCountries', () => { - expect( - getTransformChangesForNetwork({ - factoryQueryType: NetworkQueries.topCountries, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkQueries.topCountriesEntities, - indices: ['.estc_all_src_iso_ent*', '.estc_all_dest_iso_ent*'], - }); - }); - - test('it gets a transform change for topNFlow', () => { - expect( - getTransformChangesForNetwork({ - factoryQueryType: NetworkQueries.topNFlow, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkQueries.topNFlowEntities, - indices: ['.estc_all_src_ip_ent*', '.estc_all_dest_ip_ent*'], - }); - }); - - test('it gets a transform change for dns', () => { - expect( - getTransformChangesForNetwork({ - factoryQueryType: NetworkKpiQueries.dns, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkKpiQueries.dnsEntities, - indices: ['.estc_all_ip_met*'], - }); - }); - - test('it gets a transform change for networkEvents', () => { - expect( - getTransformChangesForNetwork({ - factoryQueryType: NetworkKpiQueries.networkEvents, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkKpiQueries.networkEventsEntities, - indices: ['.estc_all_ip_met*'], - }); - }); - - test('it gets a transform change for tlsHandshakes', () => { - expect( - getTransformChangesForNetwork({ - factoryQueryType: NetworkKpiQueries.tlsHandshakes, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkKpiQueries.tlsHandshakesEntities, - indices: ['.estc_all_ip_met*'], - }); - }); - - test('it gets a transform change for uniquePrivateIps', () => { - expect( - getTransformChangesForNetwork({ - factoryQueryType: NetworkKpiQueries.uniquePrivateIps, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: NetworkKpiQueries.uniquePrivateIpsEntities, - indices: ['.estc_all_src_ip_ent*', '.estc_all_dest_ip_ent*'], - }); - }); - - test('it returns an "undefined" for another value', () => { - expect( - getTransformChangesForNetwork({ - factoryQueryType: HostsQueries.firstOrLastSeen, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual(undefined); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_network.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_network.ts deleted file mode 100644 index a1ec0783235f8..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_network.ts +++ /dev/null @@ -1,82 +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 { NetworkKpiQueries, NetworkQueries } from '../../../common/search_strategy'; -import { createIndicesFromPrefix } from './create_indices_from_prefix'; -import { GetTransformChanges } from './types'; - -/** - * Given a factory query type this will return the transform changes such as the transform indices if it matches - * the correct type, otherwise it will return "undefined" - * @param factoryQueryType The query type to check if we have a transform for it and are capable of rendering one or not - * @param settings The settings configuration to get the prefix from - * @returns The transform type if we have one, otherwise undefined - */ -export const getTransformChangesForNetwork: GetTransformChanges = ({ - factoryQueryType, - settings, -}) => { - switch (factoryQueryType) { - case NetworkQueries.topCountries: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['src_iso_ent*', 'dest_iso_ent*'], - }), - factoryQueryType: NetworkQueries.topCountriesEntities, - }; - } - case NetworkQueries.topNFlow: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['src_ip_ent*', 'dest_ip_ent*'], - }), - factoryQueryType: NetworkQueries.topNFlowEntities, - }; - } - case NetworkKpiQueries.dns: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['ip_met*'], - }), - factoryQueryType: NetworkKpiQueries.dnsEntities, - }; - } - case NetworkKpiQueries.networkEvents: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['ip_met*'], - }), - factoryQueryType: NetworkKpiQueries.networkEventsEntities, - }; - } - case NetworkKpiQueries.tlsHandshakes: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['ip_met*'], - }), - factoryQueryType: NetworkKpiQueries.tlsHandshakesEntities, - }; - } - case NetworkKpiQueries.uniquePrivateIps: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['src_ip_ent*', 'dest_ip_ent*'], - }), - factoryQueryType: NetworkKpiQueries.uniquePrivateIpsEntities, - }; - } - default: { - return undefined; - } - } -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_users.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_users.test.ts deleted file mode 100644 index ae3690d72baba..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_users.test.ts +++ /dev/null @@ -1,36 +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 { UsersQueries } from '../../../common/search_strategy'; -import { getTransformChangesForUsers } from './get_transform_changes_for_users'; -import { getTransformConfigSchemaMock } from './transform_config_schema.mock'; - -/** Get the return type of getTransformChangesForUsers for TypeScript checks against expected */ -type ReturnTypeGetTransformChangesForUsers = ReturnType; - -describe('get_transform_changes_for_user', () => { - test('it gets a transform change for authentications', () => { - expect( - getTransformChangesForUsers({ - factoryQueryType: UsersQueries.authentications, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual({ - factoryQueryType: UsersQueries.authenticationsEntities, - indices: ['.estc_all_user_ent*'], - }); - }); - - test('it returns an "undefined" for another value', () => { - expect( - getTransformChangesForUsers({ - factoryQueryType: UsersQueries.details, - settings: getTransformConfigSchemaMock().settings[0], - }) - ).toEqual(undefined); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_users.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_users.ts deleted file mode 100644 index a91bc05bb7383..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_for_users.ts +++ /dev/null @@ -1,37 +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 { UsersQueries } from '../../../common/search_strategy'; -import { createIndicesFromPrefix } from './create_indices_from_prefix'; -import { GetTransformChanges } from './types'; - -/** - * Given a factory query type this will return the transform changes such as the transform indices if it matches - * the correct type, otherwise it will return "undefined" - * @param factoryQueryType The query type to check if we have a transform for it and are capable of rendering one or not - * @param settings The settings configuration to get the prefix from - * @returns The transform type if we have one, otherwise undefined - */ -export const getTransformChangesForUsers: GetTransformChanges = ({ - factoryQueryType, - settings, -}) => { - switch (factoryQueryType) { - case UsersQueries.authentications: { - return { - indices: createIndicesFromPrefix({ - prefix: settings.prefix, - transformIndices: ['user_ent*'], - }), - factoryQueryType: UsersQueries.authenticationsEntities, - }; - } - default: { - return undefined; - } - } -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_if_they_exist.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_if_they_exist.test.ts deleted file mode 100644 index 19c9ba5596027..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_if_they_exist.test.ts +++ /dev/null @@ -1,305 +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 { getTransformChangesIfTheyExist } from './get_transform_changes_if_they_exist'; -import { HostsKpiQueries, HostsQueries } from '../../../common/search_strategy'; -import moment from 'moment'; -import { getTransformConfigSchemaMock } from './transform_config_schema.mock'; - -/** Get the return type of createIndicesFromPrefix for TypeScript checks against expected */ -type ReturnTypeGetTransformChangesIfTheyExist = ReturnType; - -describe('get_transform_changes_if_they_exist', () => { - beforeEach(() => { - // Adds extra switch to suppress deprecation warnings that moment does not expose in TypeScript - ( - moment as typeof moment & { - suppressDeprecationWarnings: boolean; - } - ).suppressDeprecationWarnings = true; - }); - - afterEach(() => { - // Adds extra switch to suppress deprecation warnings that moment does not expose in TypeScript - ( - moment as typeof moment & { - suppressDeprecationWarnings: boolean; - } - ).suppressDeprecationWarnings = false; - }); - - describe('transformSettings enabled conditional logic', () => { - test('returns transformed settings if our settings is enabled', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.hosts, - indices: ['auditbeat-*'], - transformSettings: { ...getTransformConfigSchemaMock(), enabled: true }, // sets enabled to true - filterQuery: undefined, - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', - from: '2021-07-06T20:49:38.643Z', - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['.estc_all_host_ent*'], - factoryQueryType: HostsQueries.hostsEntities, - }); - }); - - test('returns regular settings if our settings is disabled', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.hosts, - indices: ['auditbeat-*'], - transformSettings: { ...getTransformConfigSchemaMock(), enabled: false }, // sets enabled to false - filterQuery: undefined, - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', - from: '2021-07-06T20:49:38.643Z', - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['auditbeat-*'], - factoryQueryType: HostsQueries.hosts, - }); - }); - }); - - describe('filter query compatibility conditional logic', () => { - test('returns regular settings if filter is set to something other than match_all', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.hosts, - indices: ['auditbeat-*'], - transformSettings: getTransformConfigSchemaMock(), - filterQuery: { - bool: { - must: [], - filter: [{ match_none: {} }], // match_none shouldn't return transform - should: [], - must_not: [], - }, - }, - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', - from: '2021-07-06T20:49:38.643Z', - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['auditbeat-*'], - factoryQueryType: HostsQueries.hosts, - }); - }); - - test('returns transformed settings if filter is set to something such as match_all', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.hosts, - indices: ['auditbeat-*'], - transformSettings: getTransformConfigSchemaMock(), - filterQuery: { - bool: { - must: [], - filter: [{ match_all: {} }], // match_all should return transform - should: [], - must_not: [], - }, - }, - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', - from: '2021-07-06T20:49:38.643Z', - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['.estc_all_host_ent*'], - factoryQueryType: HostsQueries.hostsEntities, - }); - }); - - test('returns transformed settings if filter is set to undefined', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.hosts, - indices: ['auditbeat-*'], - transformSettings: getTransformConfigSchemaMock(), - filterQuery: undefined, // undefined should return transform - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', - from: '2021-07-06T20:49:38.643Z', - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['.estc_all_host_ent*'], - factoryQueryType: HostsQueries.hostsEntities, - }); - }); - }); - - describe('timerange adjustments conditional logic', () => { - test('returns regular settings if timerange is less than an hour', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.hosts, - indices: ['auditbeat-*'], - transformSettings: getTransformConfigSchemaMock(), - filterQuery: undefined, - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', // Less than hour - from: '2021-07-06T23:39:38.643Z', // Less than hour - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['auditbeat-*'], - factoryQueryType: HostsQueries.hosts, - }); - }); - - test('returns regular settings if timerange is invalid', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.hosts, - indices: ['auditbeat-*'], - transformSettings: getTransformConfigSchemaMock(), - filterQuery: undefined, - histogramType: undefined, - timerange: { - to: 'now-invalid', // invalid to - from: 'now-invalid2', // invalid from - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['auditbeat-*'], - factoryQueryType: HostsQueries.hosts, - }); - }); - - test('returns transformed settings if timerange is greater than an hour', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.hosts, - indices: ['auditbeat-*'], - transformSettings: getTransformConfigSchemaMock(), - filterQuery: undefined, - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', // Greater than an hour - from: '2021-07-06T20:49:38.643Z', // Greater than an hour - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['.estc_all_host_ent*'], - factoryQueryType: HostsQueries.hostsEntities, - }); - }); - }); - - describe('settings match conditional logic', () => { - test('it returns regular settings if settings do not match', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.hosts, - indices: ['should-not-match-*'], // index doesn't match anything - transformSettings: getTransformConfigSchemaMock(), - filterQuery: undefined, - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', - from: '2021-07-06T20:49:38.643Z', - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['should-not-match-*'], - factoryQueryType: HostsQueries.hosts, - }); - }); - - test('it returns transformed settings if settings do match', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.hosts, - indices: [ - 'auditbeat-*', - 'endgame-*', - 'filebeat-*', - 'logs-*', - 'packetbeat-*', - 'winlogbeat-*', - '-subtract-something', - ], - transformSettings: getTransformConfigSchemaMock(), - filterQuery: undefined, - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', - from: '2021-07-06T20:49:38.643Z', - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['.estc_all_host_ent*'], - factoryQueryType: HostsQueries.hostsEntities, - }); - }); - }); - - describe('transform changes conditional logic', () => { - test('it returns regular settings if it does not match a transform factory type', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsQueries.firstOrLastSeen, // query type not used for any transforms yet - indices: ['auditbeat-*'], - transformSettings: getTransformConfigSchemaMock(), - filterQuery: undefined, - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', - from: '2021-07-06T20:49:38.643Z', - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['auditbeat-*'], - factoryQueryType: HostsQueries.firstOrLastSeen, - }); - }); - - test('it returns transformed settings if it does match a transform factory type', () => { - expect( - getTransformChangesIfTheyExist({ - factoryQueryType: HostsKpiQueries.kpiHosts, // valid kpiHosts for a transform - indices: ['auditbeat-*'], - transformSettings: getTransformConfigSchemaMock(), - filterQuery: undefined, - histogramType: undefined, - timerange: { - to: '2021-07-06T23:49:38.643Z', - from: '2021-07-06T20:49:38.643Z', - interval: '5m', - }, - }) - ).toMatchObject>({ - indices: ['.estc_all_host_ent*'], - factoryQueryType: HostsKpiQueries.kpiHostsEntities, - }); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_if_they_exist.ts b/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_if_they_exist.ts deleted file mode 100644 index 20e0b6a31d2c3..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/get_transform_changes_if_they_exist.ts +++ /dev/null @@ -1,55 +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 { adjustTimeRange } from './adjust_timerange'; -import { getSettingsMatch } from './get_settings_match'; -import { getTransformChanges } from './get_transform_changes'; -import { isFilterQueryCompatible } from './is_filter_query_compatible'; -import { GetTransformChangesIfTheyExist } from './types'; - -// TODO: Add the other switches here such as the disabling of a widget/factory type -// or if a transform is disabled, then this cannot use the query -export const getTransformChangesIfTheyExist: GetTransformChangesIfTheyExist = ({ - factoryQueryType, - indices, - transformSettings, - filterQuery, - histogramType, - timerange, -}) => { - if (!transformSettings.enabled) { - // Early return if we are not enabled - return { factoryQueryType, indices, timerange }; - } - - if (!isFilterQueryCompatible(filterQuery)) { - // Early return if the filter query is not compatible - return { factoryQueryType, indices, timerange }; - } - - const { timeRangeAdjusted, duration } = adjustTimeRange(timerange); - - if (timeRangeAdjusted == null || duration == null || duration.asHours() < 1) { - // Early return if we are less than hour of time or from is something not as we expect - // and as we should just use raw events instead of summaries - return { factoryQueryType, indices, timerange }; - } - - const settings = getSettingsMatch({ indices, transformSettings }); - if (settings == null) { - // early return if none of the settings match - return { factoryQueryType, indices, timerange }; - } - - const transform = getTransformChanges({ factoryQueryType, settings, histogramType }); - if (transform) { - return { ...transform, timerange: timeRangeAdjusted }; - } - - // nothing matched, return what was sent in unchanged - return { factoryQueryType, indices, timerange }; -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/index.ts b/x-pack/plugins/security_solution/public/transforms/utils/index.ts deleted file mode 100644 index 8cacb0035204a..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/index.ts +++ /dev/null @@ -1,17 +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. - */ -export * from './adjust_timerange'; -export * from './create_indices_from_prefix'; -export * from './get_settings_match'; -export * from './get_transform_changes_for_hosts'; -export * from './get_transform_changes_for_kpi'; -export * from './get_transform_changes_for_matrix_histogram'; -export * from './get_transform_changes_for_network'; -export * from './get_transform_changes_if_they_exist'; -export * from './get_transform_changes'; -export * from './is_filter_query_compatible'; -export * from './types'; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/is_filter_query_compatible.test.ts b/x-pack/plugins/security_solution/public/transforms/utils/is_filter_query_compatible.test.ts deleted file mode 100644 index 74dd1373a4d39..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/is_filter_query_compatible.test.ts +++ /dev/null @@ -1,87 +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 { isFilterQueryCompatible } from './is_filter_query_compatible'; - -describe('is_filter_query_compatible', () => { - test('returns true if given an undefined', () => { - expect(isFilterQueryCompatible(undefined)).toEqual(true); - }); - - test('returns "true" if given a match all object', () => { - expect( - isFilterQueryCompatible({ - bool: { - must: [], - filter: [{ match_all: {} }], - should: [], - must_not: [], - }, - }) - ).toEqual(true); - }); - - test('returns "false" if given a match all object with something inside of it such as match_none', () => { - expect( - isFilterQueryCompatible({ - bool: { - must: [], - filter: [{ match_none: {} }], - should: [], - must_not: [], - }, - }) - ).toEqual(false); - }); - - test('returns "true" if given empty array for a filter', () => { - expect( - isFilterQueryCompatible({ - bool: { - must: [], - filter: [], - should: [], - must_not: [], - }, - }) - ).toEqual(true); - }); - - test('returns "true" if given match all object as a string', () => { - expect( - isFilterQueryCompatible( - JSON.stringify({ - bool: { - must: [], - filter: [], - should: [], - must_not: [], - }, - }) - ) - ).toEqual(true); - }); - - test('returns "true" if given empty array for a filter as a string', () => { - expect( - isFilterQueryCompatible( - JSON.stringify({ - bool: { - must: [], - filter: [], - should: [], - must_not: [], - }, - }) - ) - ).toEqual(true); - }); - - test('returns "false" if given an invalid string', () => { - expect(isFilterQueryCompatible('invalid string')).toEqual(false); - }); -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/is_filter_query_compatible.ts b/x-pack/plugins/security_solution/public/transforms/utils/is_filter_query_compatible.ts deleted file mode 100644 index 2f2c9ee7f2deb..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/is_filter_query_compatible.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { isEqual } from 'lodash/fp'; -import { ESQuery } from '../../../common/typed_json'; - -/** - * Array of query compatible objects which are at the moment all - * simple empty or match all based objects - */ -const queryCompatibleStrings: ESQuery[] = [ - { - bool: { - must: [], - filter: [{ match_all: {} }], - should: [], - must_not: [], - }, - }, - { - bool: { - must: [], - filter: [], - should: [], - must_not: [], - }, - }, -]; - -/** - * Returns true if the filter query matches against one of the compatible strings, otherwise - * false. Right now we only check if the filter query is empty, or a match all in order to activate - * the transform. - * @param filterQuery The filterQuery to check against and return true if it matches, otherwise false. - * @returns true if the filter is compatible, otherwise false. - */ -export const isFilterQueryCompatible = (filterQuery: ESQuery | string | undefined): boolean => { - if (filterQuery === undefined) { - return true; - } else if (typeof filterQuery === 'string') { - try { - const filterQueryObject = JSON.parse(filterQuery); - return queryCompatibleStrings.some((entry) => isEqual(entry, filterQueryObject)); - } catch (error) { - return false; - } - } else { - return queryCompatibleStrings.some((entry) => isEqual(entry, filterQuery)); - } -}; diff --git a/x-pack/plugins/security_solution/public/transforms/utils/transform_config_schema.mock.ts b/x-pack/plugins/security_solution/public/transforms/utils/transform_config_schema.mock.ts deleted file mode 100644 index ef3d4bfe6f007..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/transform_config_schema.mock.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { TransformConfigSchema } from '../../../common/transforms/types'; - -/** - * Mock for the TransformConfigSchema. - * @returns A transform config schema mock - */ -export const getTransformConfigSchemaMock = (): TransformConfigSchema => ({ - enabled: true, - auto_start: true, - auto_create: true, - query: { - range: { - '@timestamp': { - gte: 'now-1d/d', - format: 'strict_date_optional_time', - }, - }, - }, - retention_policy: { - time: { - field: '@timestamp', - max_age: '1w', - }, - }, - max_page_search_size: 5000, - settings: [ - { - prefix: 'all', - indices: ['auditbeat-*', 'endgame-*', 'filebeat-*', 'logs-*', 'packetbeat-*', 'winlogbeat-*'], - data_sources: [ - ['auditbeat-*', 'endgame-*', 'filebeat-*', 'logs-*', 'packetbeat-*', 'winlogbeat-*'], - ['auditbeat-*', 'filebeat-*', 'logs-*', 'winlogbeat-*'], - ['auditbeat-*'], - ], - }, - ], -}); diff --git a/x-pack/plugins/security_solution/public/transforms/utils/types.ts b/x-pack/plugins/security_solution/public/transforms/utils/types.ts deleted file mode 100644 index 96dc1ee228bd0..0000000000000 --- a/x-pack/plugins/security_solution/public/transforms/utils/types.ts +++ /dev/null @@ -1,50 +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 { TimerangeInput } from '../../../common/search_strategy/common'; -import { ESQuery } from '../../../common/typed_json'; -import { TransformConfigSchema } from '../../../common/transforms/types'; -import { - FactoryQueryTypes, - MatrixHistogramType, -} from '../../../common/search_strategy/security_solution'; - -export type GetTransformChanges = ({ - factoryQueryType, - settings, - histogramType, -}: { - factoryQueryType: FactoryQueryTypes; - settings: TransformConfigSchema['settings'][0]; - histogramType?: MatrixHistogramType; -}) => - | { - indices: string[]; - factoryQueryType: FactoryQueryTypes; - histogramType?: MatrixHistogramType; - } - | undefined; - -export type GetTransformChangesIfTheyExist = ({ - factoryQueryType, - indices, - filterQuery, - histogramType, - timerange, -}: { - factoryQueryType: FactoryQueryTypes; - indices: string[]; - transformSettings: TransformConfigSchema; - filterQuery: ESQuery | string | undefined; - histogramType?: MatrixHistogramType; - timerange: TimerangeInput; -}) => { - indices: string[]; - factoryQueryType: FactoryQueryTypes; - histogramType?: MatrixHistogramType; - timerange: TimerangeInput; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts index d936ffdefb6c2..d05b9e1f8fb1a 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts @@ -29,7 +29,6 @@ import { buildHostsQuery } from './query.all_hosts.dsl'; import { formatHostEdgesData, HOSTS_FIELDS } from './helpers'; import { IScopedClusterClient } from '../../../../../../../../../src/core/server'; -import { buildHostsQueryEntities } from './query.all_hosts_entities.dsl'; import { EndpointAppContext } from '../../../../../endpoint/types'; import { buildRiskScoreQuery } from '../../risk_score/all/query.risk_score.dsl'; @@ -132,43 +131,3 @@ async function getHostRiskData( return undefined; } } - -export const allHostsEntities: SecuritySolutionFactory = { - buildDsl: (options: HostsRequestOptions) => { - if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) { - throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`); - } - return buildHostsQueryEntities(options); - }, - parse: async ( - options: HostsRequestOptions, - response: IEsSearchResponse - ): Promise => { - const { activePage, cursorStart, fakePossibleCount, querySize } = options.pagination; - const totalCount = getOr(0, 'aggregations.host_count.value', response.rawResponse); - const buckets: HostAggEsItem[] = getOr( - [], - 'aggregations.host_data.buckets', - response.rawResponse - ); - const hostsEdges = buckets.map((bucket) => formatHostEdgesData(HOSTS_FIELDS, bucket)); - const fakeTotalCount = fakePossibleCount <= totalCount ? fakePossibleCount : totalCount; - const edges = hostsEdges.splice(cursorStart, querySize - cursorStart); - const inspect = { - dsl: [inspectStringifyObject(buildHostsQueryEntities(options))], - }; - const showMorePagesIndicator = totalCount > fakeTotalCount; - - return { - ...response, - inspect, - edges, - totalCount, - pageInfo: { - activePage: activePage ?? 0, - fakeTotalCount, - showMorePagesIndicator, - }, - }; - }, -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/query.all_hosts_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/query.all_hosts_entities.dsl.ts deleted file mode 100644 index 73f35091ae093..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/query.all_hosts_entities.dsl.ts +++ /dev/null @@ -1,92 +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 { isEmpty } from 'lodash/fp'; -import type { ISearchRequestParams } from '../../../../../../../../../src/plugins/data/common'; -import { - Direction, - HostsRequestOptions, - SortField, - HostsFields, -} from '../../../../../../common/search_strategy'; -import { createQueryFilterClauses } from '../../../../../utils/build_query'; -import { assertUnreachable } from '../../../../../../common/utility_types'; - -export const buildHostsQueryEntities = ({ - defaultIndex, - docValueFields, - filterQuery, - pagination: { querySize }, - sort, - timerange: { from, to }, -}: HostsRequestOptions): ISearchRequestParams => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const agg = { host_count: { cardinality: { field: 'host.name' } } }; - - const dslQuery = { - allow_no_indices: true, - index: defaultIndex, - ignore_unavailable: true, - track_total_hits: false, - body: { - ...(!isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), - aggregations: { - ...agg, - host_data: { - terms: { size: querySize, field: 'host.name', order: getQueryOrder(sort) }, - aggs: { - lastSeen: { max: { field: '@timestamp' } }, - os: { - top_hits: { - size: 1, - sort: [ - { - '@timestamp': { - order: 'desc' as const, - }, - }, - ], - _source: { - includes: ['host.os.*'], - }, - }, - }, - }, - }, - }, - query: { bool: { filter } }, - size: 0, - }, - }; - - return dslQuery; -}; - -type QueryOrder = { lastSeen: Direction } | { _key: Direction }; - -const getQueryOrder = (sort: SortField): QueryOrder => { - switch (sort.field) { - case HostsFields.lastSeen: - return { lastSeen: sort.direction }; - case HostsFields.hostName: - return { _key: sort.direction }; - default: - return assertUnreachable(sort.field); - } -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/index.test.ts index 901d577fdbf5a..3cac14fb56f80 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/index.test.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/index.test.ts @@ -13,9 +13,9 @@ import { hostOverview } from './overview'; import { firstOrLastSeenHost } from './last_first_seen'; import { uncommonProcesses } from './uncommon_processes'; -import { hostsKpiAuthentications, hostsKpiAuthenticationsEntities } from './kpi/authentications'; -import { hostsKpiHosts, hostsKpiHostsEntities } from './kpi/hosts'; -import { hostsKpiUniqueIps, hostsKpiUniqueIpsEntities } from './kpi/unique_ips'; +import { hostsKpiAuthentications } from './kpi/authentications'; +import { hostsKpiHosts } from './kpi/hosts'; +import { hostsKpiUniqueIps } from './kpi/unique_ips'; jest.mock('./all'); jest.mock('./details'); @@ -35,10 +35,7 @@ describe('hostsFactory', () => { [HostsQueries.firstOrLastSeen]: firstOrLastSeenHost, [HostsQueries.uncommonProcesses]: uncommonProcesses, [HostsKpiQueries.kpiAuthentications]: hostsKpiAuthentications, - [HostsKpiQueries.kpiAuthenticationsEntities]: hostsKpiAuthenticationsEntities, [HostsKpiQueries.kpiHosts]: hostsKpiHosts, - [HostsKpiQueries.kpiHostsEntities]: hostsKpiHostsEntities, - [HostsKpiQueries.kpiUniqueIpsEntities]: hostsKpiUniqueIpsEntities, [HostsKpiQueries.kpiUniqueIps]: hostsKpiUniqueIps, }; expect(hostsFactory).toEqual(expectedHostsFactory); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/index.ts index 5d40e5e153599..d7a37f871e252 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/index.ts @@ -12,14 +12,14 @@ import { } from '../../../../../common/search_strategy/security_solution'; import { SecuritySolutionFactory } from '../types'; -import { allHosts, allHostsEntities } from './all'; +import { allHosts } from './all'; import { hostDetails } from './details'; import { hostOverview } from './overview'; import { firstOrLastSeenHost } from './last_first_seen'; import { uncommonProcesses } from './uncommon_processes'; -import { hostsKpiAuthentications, hostsKpiAuthenticationsEntities } from './kpi/authentications'; -import { hostsKpiHosts, hostsKpiHostsEntities } from './kpi/hosts'; -import { hostsKpiUniqueIps, hostsKpiUniqueIpsEntities } from './kpi/unique_ips'; +import { hostsKpiAuthentications } from './kpi/authentications'; +import { hostsKpiHosts } from './kpi/hosts'; +import { hostsKpiUniqueIps } from './kpi/unique_ips'; export const hostsFactory: Record< HostsQueries | HostsKpiQueries, @@ -27,14 +27,10 @@ export const hostsFactory: Record< > = { [HostsQueries.details]: hostDetails, [HostsQueries.hosts]: allHosts, - [HostsQueries.hostsEntities]: allHostsEntities, [HostsQueries.overview]: hostOverview, [HostsQueries.firstOrLastSeen]: firstOrLastSeenHost, [HostsQueries.uncommonProcesses]: uncommonProcesses, [HostsKpiQueries.kpiAuthentications]: hostsKpiAuthentications, - [HostsKpiQueries.kpiAuthenticationsEntities]: hostsKpiAuthenticationsEntities, [HostsKpiQueries.kpiHosts]: hostsKpiHosts, - [HostsKpiQueries.kpiHostsEntities]: hostsKpiHostsEntities, [HostsKpiQueries.kpiUniqueIps]: hostsKpiUniqueIps, - [HostsKpiQueries.kpiUniqueIpsEntities]: hostsKpiUniqueIpsEntities, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/helpers.ts index 6b81dd177bbf6..34b4a682d42de 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/helpers.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/helpers.ts @@ -20,13 +20,3 @@ export const formatAuthenticationsHistogramData = ( y: count.doc_count, })) : null; - -export const formatAuthenticationsHistogramDataEntities = ( - data: Array> -): HostsKpiHistogramData[] | null => - data && data.length > 0 - ? data.map(({ key, count }) => ({ - x: key, - y: count.value, - })) - : null; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/index.ts index 1512dc1b7da61..d6a1e1a8ac7ec 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/index.ts @@ -16,11 +16,7 @@ import { import { inspectStringifyObject } from '../../../../../../utils/build_query'; import { SecuritySolutionFactory } from '../../../types'; import { buildHostsKpiAuthenticationsQuery } from './query.hosts_kpi_authentications.dsl'; -import { - formatAuthenticationsHistogramData, - formatAuthenticationsHistogramDataEntities, -} from './helpers'; -import { buildHostsKpiAuthenticationsQueryEntities } from './query.hosts_kpi_authentications_entities.dsl'; +import { formatAuthenticationsHistogramData } from './helpers'; export const hostsKpiAuthentications: SecuritySolutionFactory = { @@ -67,49 +63,3 @@ export const hostsKpiAuthentications: SecuritySolutionFactory = - { - buildDsl: (options: HostsKpiAuthenticationsRequestOptions) => - buildHostsKpiAuthenticationsQueryEntities(options), - parse: async ( - options: HostsKpiAuthenticationsRequestOptions, - response: IEsSearchResponse - ): Promise => { - const inspect = { - dsl: [inspectStringifyObject(buildHostsKpiAuthenticationsQueryEntities(options))], - }; - - const authenticationsSuccessHistogram = getOr( - null, - 'aggregations.authentication_success_histogram.buckets', - response.rawResponse - ); - const authenticationsFailureHistogram = getOr( - null, - 'aggregations.authentication_failure_histogram.buckets', - response.rawResponse - ); - - return { - ...response, - inspect, - authenticationsSuccess: getOr( - null, - 'aggregations.authentication_success.value', - response.rawResponse - ), - authenticationsSuccessHistogram: formatAuthenticationsHistogramDataEntities( - authenticationsSuccessHistogram - ), - authenticationsFailure: getOr( - null, - 'aggregations.authentication_failure.value', - response.rawResponse - ), - authenticationsFailureHistogram: formatAuthenticationsHistogramDataEntities( - authenticationsFailureHistogram - ), - }; - }, - }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/query.hosts_kpi_authentications_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/query.hosts_kpi_authentications_entities.dsl.ts deleted file mode 100644 index fd1104345babc..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/authentications/query.hosts_kpi_authentications_entities.dsl.ts +++ /dev/null @@ -1,83 +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 { HostsKpiAuthenticationsRequestOptions } from '../../../../../../../common/search_strategy/security_solution/hosts'; -import { createQueryFilterClauses } from '../../../../../../utils/build_query'; - -export const buildHostsKpiAuthenticationsQueryEntities = ({ - filterQuery, - timerange: { from, to }, - defaultIndex, -}: HostsKpiAuthenticationsRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const dslQuery = { - index: defaultIndex, - allow_no_indices: true, - ignore_unavailable: true, - track_total_hits: false, - body: { - aggs: { - authentication_success: { - sum: { - field: 'metrics.event.authentication.success.value_count', - }, - }, - authentication_success_histogram: { - auto_date_histogram: { - field: '@timestamp', - buckets: 6, - }, - aggs: { - count: { - sum: { - field: 'metrics.event.authentication.success.value_count', - }, - }, - }, - }, - authentication_failure: { - sum: { - field: 'metrics.event.authentication.failure.value_count', - }, - }, - authentication_failure_histogram: { - auto_date_histogram: { - field: '@timestamp', - buckets: 6, - }, - aggs: { - count: { - sum: { - field: 'metrics.event.authentication.failure.value_count', - }, - }, - }, - }, - }, - query: { - bool: { - filter, - }, - }, - size: 0, - }, - }; - - return dslQuery; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/hosts/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/hosts/index.ts index a8082822b2775..c4714e81c6ec4 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/hosts/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/hosts/index.ts @@ -17,7 +17,6 @@ import { inspectStringifyObject } from '../../../../../../utils/build_query'; import { SecuritySolutionFactory } from '../../../types'; import { buildHostsKpiHostsQuery } from './query.hosts_kpi_hosts.dsl'; import { formatGeneralHistogramData } from '../common'; -import { buildHostsKpiHostsQueryEntities } from './query.hosts_kpi_hosts_entities.dsl'; export const hostsKpiHosts: SecuritySolutionFactory = { buildDsl: (options: HostsKpiHostsRequestOptions) => buildHostsKpiHostsQuery(options), @@ -42,27 +41,3 @@ export const hostsKpiHosts: SecuritySolutionFactory = }; }, }; - -export const hostsKpiHostsEntities: SecuritySolutionFactory = { - buildDsl: (options: HostsKpiHostsRequestOptions) => buildHostsKpiHostsQueryEntities(options), - parse: async ( - options: HostsKpiHostsRequestOptions, - response: IEsSearchResponse - ): Promise => { - const inspect = { - dsl: [inspectStringifyObject(buildHostsKpiHostsQueryEntities(options))], - }; - - const hostsHistogram = getOr( - null, - 'aggregations.hosts_histogram.buckets', - response.rawResponse - ); - return { - ...response, - inspect, - hosts: getOr(null, 'aggregations.hosts.value', response.rawResponse), - hostsHistogram: formatGeneralHistogramData(hostsHistogram), - }; - }, -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/hosts/query.hosts_kpi_hosts_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/hosts/query.hosts_kpi_hosts_entities.dsl.ts deleted file mode 100644 index 785f6aa5b6980..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/hosts/query.hosts_kpi_hosts_entities.dsl.ts +++ /dev/null @@ -1,65 +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 { HostsKpiHostsRequestOptions } from '../../../../../../../common/search_strategy/security_solution/hosts'; -import { createQueryFilterClauses } from '../../../../../../utils/build_query'; - -export const buildHostsKpiHostsQueryEntities = ({ - filterQuery, - timerange: { from, to }, - defaultIndex, -}: HostsKpiHostsRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const dslQuery = { - index: defaultIndex, - allow_no_indices: true, - ignore_unavailable: true, - track_total_hits: false, - body: { - aggregations: { - hosts: { - cardinality: { - field: 'host.name', - }, - }, - hosts_histogram: { - auto_date_histogram: { - field: '@timestamp', - buckets: 6, - }, - aggs: { - count: { - cardinality: { - field: 'host.name', - }, - }, - }, - }, - }, - query: { - bool: { - filter, - }, - }, - size: 0, - }, - }; - - return dslQuery; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/unique_ips/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/unique_ips/index.ts index b81d9a4d2322b..17eceea840029 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/unique_ips/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/unique_ips/index.ts @@ -17,7 +17,6 @@ import { inspectStringifyObject } from '../../../../../../utils/build_query'; import { SecuritySolutionFactory } from '../../../types'; import { buildHostsKpiUniqueIpsQuery } from './query.hosts_kpi_unique_ips.dsl'; import { formatGeneralHistogramData } from '../common'; -import { buildHostsKpiUniqueIpsQueryEntities } from './query.hosts_kpi_unique_ips_entities.dsl'; export const hostsKpiUniqueIps: SecuritySolutionFactory = { buildDsl: (options: HostsKpiUniqueIpsRequestOptions) => buildHostsKpiUniqueIpsQuery(options), @@ -55,41 +54,3 @@ export const hostsKpiUniqueIps: SecuritySolutionFactory = { - buildDsl: (options: HostsKpiUniqueIpsRequestOptions) => - buildHostsKpiUniqueIpsQueryEntities(options), - parse: async ( - options: HostsKpiUniqueIpsRequestOptions, - response: IEsSearchResponse - ): Promise => { - const inspect = { - dsl: [inspectStringifyObject(buildHostsKpiUniqueIpsQueryEntities(options))], - }; - - const uniqueSourceIpsHistogram = getOr( - null, - 'aggregations.unique_source_ips_histogram.buckets', - response.rawResponse - ); - - const uniqueDestinationIpsHistogram = getOr( - null, - 'aggregations.unique_destination_ips_histogram.buckets', - response.rawResponse - ); - - return { - ...response, - inspect, - uniqueSourceIps: getOr(null, 'aggregations.unique_source_ips.value', response.rawResponse), - uniqueSourceIpsHistogram: formatGeneralHistogramData(uniqueSourceIpsHistogram), - uniqueDestinationIps: getOr( - null, - 'aggregations.unique_destination_ips.value', - response.rawResponse - ), - uniqueDestinationIpsHistogram: formatGeneralHistogramData(uniqueDestinationIpsHistogram), - }; - }, -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/unique_ips/query.hosts_kpi_unique_ips_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/unique_ips/query.hosts_kpi_unique_ips_entities.dsl.ts deleted file mode 100644 index e323de78a0459..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/kpi/unique_ips/query.hosts_kpi_unique_ips_entities.dsl.ts +++ /dev/null @@ -1,83 +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 { HostsKpiUniqueIpsRequestOptions } from '../../../../../../../common/search_strategy/security_solution/hosts'; -import { createQueryFilterClauses } from '../../../../../../utils/build_query'; - -export const buildHostsKpiUniqueIpsQueryEntities = ({ - filterQuery, - timerange: { from, to }, - defaultIndex, -}: HostsKpiUniqueIpsRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const dslQuery = { - index: defaultIndex, - allow_no_indices: true, - ignore_unavailable: true, - track_total_hits: false, - body: { - aggregations: { - unique_source_ips: { - cardinality: { - field: 'source.ip', - }, - }, - unique_source_ips_histogram: { - auto_date_histogram: { - field: '@timestamp', - buckets: 6, - }, - aggs: { - count: { - cardinality: { - field: 'source.ip', - }, - }, - }, - }, - unique_destination_ips: { - cardinality: { - field: 'destination.ip', - }, - }, - unique_destination_ips_histogram: { - auto_date_histogram: { - field: '@timestamp', - buckets: 6, - }, - aggs: { - count: { - cardinality: { - field: 'destination.ip', - }, - }, - }, - }, - }, - query: { - bool: { - filter, - }, - }, - size: 0, - }, - }; - - return dslQuery; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/authentications/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/authentications/index.ts index bde058942f2bb..377cd0a019d3f 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/authentications/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/authentications/index.ts @@ -6,19 +6,10 @@ */ import { MatrixHistogramTypeToAggName } from '../../../../../../common/search_strategy'; -import { getEntitiesParser } from '../helpers'; import { buildAuthenticationsHistogramQuery } from './query.authentications_histogram.dsl'; -import { buildAuthenticationsHistogramQueryEntities } from './query.authentications_histogram_entities.dsl'; export const authenticationsMatrixHistogramConfig = { buildDsl: buildAuthenticationsHistogramQuery, aggName: MatrixHistogramTypeToAggName.authentications, parseKey: 'events.buckets', }; - -export const authenticationsMatrixHistogramEntitiesConfig = { - buildDsl: buildAuthenticationsHistogramQueryEntities, - aggName: MatrixHistogramTypeToAggName.authenticationsEntities, - parseKey: 'events.buckets', - parser: getEntitiesParser, -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/authentications/query.authentications_histogram_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/authentications/query.authentications_histogram_entities.dsl.ts deleted file mode 100644 index 886dcf11123bd..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/authentications/query.authentications_histogram_entities.dsl.ts +++ /dev/null @@ -1,77 +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 moment from 'moment'; - -import { createQueryFilterClauses } from '../../../../../utils/build_query'; -import { MatrixHistogramRequestOptions } from '../../../../../../common/search_strategy/security_solution/matrix_histogram'; - -export const buildAuthenticationsHistogramQueryEntities = ({ - filterQuery, - timerange: { from, to }, - defaultIndex, - stackByField = 'event.outcome', // TODO: Remove this field if not used -}: MatrixHistogramRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const getHistogramAggregation = () => { - const histogramTimestampField = '@timestamp'; - const dateHistogram = { - date_histogram: { - field: histogramTimestampField, - calendar_interval: '1h', - min_doc_count: 0, - extended_bounds: { - min: moment(from).valueOf(), - max: moment(to).valueOf(), - }, - }, - aggs: { - failure: { - sum: { - field: 'metrics.event.authentication.failure.value_count', - }, - }, - success: { - sum: { - field: 'metrics.event.authentication.success.value_count', - }, - }, - }, - }; - return { events: dateHistogram }; - }; - - const dslQuery = { - index: defaultIndex, - allow_no_indices: true, - ignore_unavailable: true, - track_total_hits: true, - body: { - aggregations: getHistogramAggregation(), - query: { - bool: { - filter, - }, - }, - size: 0, - }, - }; - - return dslQuery; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/helpers.ts index c8ede95d166c7..aa6b85d795443 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/helpers.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/helpers.ts @@ -32,19 +32,3 @@ export const getGenericData = ( return result; }; - -export const getEntitiesParser = ( - data: MatrixHistogramParseData, - keyBucket: string // TODO: Remove this keyBucket if it is not being used. -): MatrixHistogramData[] => { - let result: MatrixHistogramData[] = []; - data.forEach((bucketData: unknown) => { - const successValue = get('success.value', bucketData); - const failureValue = get('failure.value', bucketData); - const key = get('key', bucketData); - const histDataSuccess = { x: key, y: successValue, g: 'success' }; - const histDataFailure = { x: key, y: failureValue, g: 'failure' }; - result = [...result, histDataFailure, histDataSuccess]; - }); - return result; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/index.ts index db9fcc6067a74..06405fb74bc0f 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/matrix_histogram/index.ts @@ -15,17 +15,13 @@ import { MatrixHistogramQuery, MatrixHistogramType, MatrixHistogramDataConfig, - MatrixHistogramQueryEntities, } from '../../../../../common/search_strategy/security_solution'; import { inspectStringifyObject } from '../../../../utils/build_query'; import { SecuritySolutionFactory } from '../types'; import { getGenericData } from './helpers'; import { alertsMatrixHistogramConfig } from './alerts'; import { anomaliesMatrixHistogramConfig } from './anomalies'; -import { - authenticationsMatrixHistogramConfig, - authenticationsMatrixHistogramEntitiesConfig, -} from './authentications'; +import { authenticationsMatrixHistogramConfig } from './authentications'; import { dnsMatrixHistogramConfig } from './dns'; import { eventsMatrixHistogramConfig } from './events'; import { previewMatrixHistogramConfig } from './preview'; @@ -34,7 +30,6 @@ const matrixHistogramConfig: MatrixHistogramDataConfig = { [MatrixHistogramType.alerts]: alertsMatrixHistogramConfig, [MatrixHistogramType.anomalies]: anomaliesMatrixHistogramConfig, [MatrixHistogramType.authentications]: authenticationsMatrixHistogramConfig, - [MatrixHistogramType.authenticationsEntities]: authenticationsMatrixHistogramEntitiesConfig, [MatrixHistogramType.dns]: dnsMatrixHistogramConfig, [MatrixHistogramType.events]: eventsMatrixHistogramConfig, [MatrixHistogramType.preview]: previewMatrixHistogramConfig, @@ -113,9 +108,8 @@ export const matrixHistogramEntities: SecuritySolutionFactory > = { [MatrixHistogramQuery]: matrixHistogram, - [MatrixHistogramQueryEntities]: matrixHistogramEntities, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.test.ts index 3e770cbedaed6..d3621ef22bf2a 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.test.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.test.ts @@ -19,14 +19,11 @@ import { networkTls } from './tls'; import { networkTopCountries } from './top_countries'; import { networkTopNFlow } from './top_n_flow'; import { networkUsers } from './users'; -import { networkKpiDns, networkKpiDnsEntities } from './kpi/dns'; -import { networkKpiNetworkEvents, networkKpiNetworkEventsEntities } from './kpi/network_events'; -import { networkKpiTlsHandshakes, networkKpiTlsHandshakesEntities } from './kpi/tls_handshakes'; +import { networkKpiDns } from './kpi/dns'; +import { networkKpiNetworkEvents } from './kpi/network_events'; +import { networkKpiTlsHandshakes } from './kpi/tls_handshakes'; import { networkKpiUniqueFlows } from './kpi/unique_flows'; -import { - networkKpiUniquePrivateIps, - networkKpiUniquePrivateIpsEntities, -} from './kpi/unique_private_ips'; +import { networkKpiUniquePrivateIps } from './kpi/unique_private_ips'; jest.mock('./details'); jest.mock('./dns'); @@ -54,14 +51,10 @@ describe('networkFactory', () => { [NetworkQueries.topNFlow]: networkTopNFlow, [NetworkQueries.users]: networkUsers, [NetworkKpiQueries.dns]: networkKpiDns, - [NetworkKpiQueries.dnsEntities]: networkKpiDnsEntities, [NetworkKpiQueries.networkEvents]: networkKpiNetworkEvents, - [NetworkKpiQueries.networkEventsEntities]: networkKpiNetworkEventsEntities, - [NetworkKpiQueries.tlsHandshakesEntities]: networkKpiTlsHandshakesEntities, [NetworkKpiQueries.tlsHandshakes]: networkKpiTlsHandshakes, [NetworkKpiQueries.uniqueFlows]: networkKpiUniqueFlows, [NetworkKpiQueries.uniquePrivateIps]: networkKpiUniquePrivateIps, - [NetworkKpiQueries.uniquePrivateIpsEntities]: networkKpiUniquePrivateIpsEntities, }; expect(networkFactory).toEqual(expectedNetworkFactory); }); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.ts index 3a7c4951ea878..9d9940247eb30 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/index.ts @@ -11,22 +11,19 @@ import { NetworkKpiQueries, } from '../../../../../common/search_strategy/security_solution'; -import { networkKpiDns, networkKpiDnsEntities } from './kpi/dns'; -import { networkKpiNetworkEvents, networkKpiNetworkEventsEntities } from './kpi/network_events'; -import { networkKpiTlsHandshakes, networkKpiTlsHandshakesEntities } from './kpi/tls_handshakes'; +import { networkKpiDns } from './kpi/dns'; +import { networkKpiNetworkEvents } from './kpi/network_events'; +import { networkKpiTlsHandshakes } from './kpi/tls_handshakes'; import { networkKpiUniqueFlows } from './kpi/unique_flows'; -import { - networkKpiUniquePrivateIps, - networkKpiUniquePrivateIpsEntities, -} from './kpi/unique_private_ips'; +import { networkKpiUniquePrivateIps } from './kpi/unique_private_ips'; import { SecuritySolutionFactory } from '../types'; import { networkDetails } from './details'; import { networkDns } from './dns'; import { networkHttp } from './http'; import { networkOverview } from './overview'; import { networkTls } from './tls'; -import { networkTopCountries, networkTopCountriesEntities } from './top_countries'; -import { networkTopNFlow, networkTopNFlowEntities } from './top_n_flow'; +import { networkTopCountries } from './top_countries'; +import { networkTopNFlow } from './top_n_flow'; import { networkUsers } from './users'; export const networkFactory: Record< @@ -39,17 +36,11 @@ export const networkFactory: Record< [NetworkQueries.overview]: networkOverview, [NetworkQueries.tls]: networkTls, [NetworkQueries.topCountries]: networkTopCountries, - [NetworkQueries.topCountriesEntities]: networkTopCountriesEntities, [NetworkQueries.topNFlow]: networkTopNFlow, - [NetworkQueries.topNFlowEntities]: networkTopNFlowEntities, [NetworkQueries.users]: networkUsers, [NetworkKpiQueries.dns]: networkKpiDns, - [NetworkKpiQueries.dnsEntities]: networkKpiDnsEntities, [NetworkKpiQueries.networkEvents]: networkKpiNetworkEvents, - [NetworkKpiQueries.networkEventsEntities]: networkKpiNetworkEventsEntities, [NetworkKpiQueries.tlsHandshakes]: networkKpiTlsHandshakes, - [NetworkKpiQueries.tlsHandshakesEntities]: networkKpiTlsHandshakesEntities, [NetworkKpiQueries.uniqueFlows]: networkKpiUniqueFlows, [NetworkKpiQueries.uniquePrivateIps]: networkKpiUniquePrivateIps, - [NetworkKpiQueries.uniquePrivateIpsEntities]: networkKpiUniquePrivateIpsEntities, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/dns/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/dns/index.ts index b8a21d4791c57..25dd078955203 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/dns/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/dns/index.ts @@ -13,7 +13,6 @@ import { } from '../../../../../../../common/search_strategy/security_solution/network'; import { inspectStringifyObject } from '../../../../../../utils/build_query'; import { SecuritySolutionFactory } from '../../../types'; -import { buildDnsQueryEntities } from './query.network_kip_dns_entities.dsl'; import { buildDnsQuery } from './query.network_kpi_dns.dsl'; export const networkKpiDns: SecuritySolutionFactory = { @@ -34,21 +33,3 @@ export const networkKpiDns: SecuritySolutionFactory = { }; }, }; - -export const networkKpiDnsEntities: SecuritySolutionFactory = { - buildDsl: (options: NetworkKpiDnsRequestOptions) => buildDnsQueryEntities(options), - parse: async ( - options: NetworkKpiDnsRequestOptions, - response: IEsSearchResponse - ): Promise => { - const inspect = { - dsl: [inspectStringifyObject(buildDnsQueryEntities(options))], - }; - return { - ...response, - inspect, - // @ts-expect-error code doesn't handle TotalHits - dnsQueries: response.rawResponse.aggregations?.dns?.value ?? null, - }; - }, -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/dns/query.network_kip_dns_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/dns/query.network_kip_dns_entities.dsl.ts deleted file mode 100644 index c0317772e5fa9..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/dns/query.network_kip_dns_entities.dsl.ts +++ /dev/null @@ -1,52 +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 { NetworkKpiDnsRequestOptions } from '../../../../../../../common/search_strategy/security_solution/network'; -import { createQueryFilterClauses } from '../../../../../../utils/build_query'; - -export const buildDnsQueryEntities = ({ - filterQuery, - timerange: { from, to }, - defaultIndex, -}: NetworkKpiDnsRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const dslQuery = { - index: defaultIndex, - allow_no_indices: true, - ignore_unavailable: true, - track_total_hits: false, - body: { - aggs: { - dns: { - sum: { - field: 'metrics.dns.queries.value_count', - }, - }, - }, - query: { - bool: { - filter, - }, - }, - size: 0, - }, - }; - - return dslQuery; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/index.ts index 326d4f33e7a93..2a18bf3b5de86 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/index.ts @@ -11,26 +11,19 @@ import { } from '../../../../../../common/search_strategy/security_solution'; import { SecuritySolutionFactory } from '../../types'; -import { networkKpiDns, networkKpiDnsEntities } from './dns'; -import { networkKpiNetworkEvents, networkKpiNetworkEventsEntities } from './network_events'; -import { networkKpiTlsHandshakes, networkKpiTlsHandshakesEntities } from './tls_handshakes'; +import { networkKpiDns } from './dns'; +import { networkKpiNetworkEvents } from './network_events'; +import { networkKpiTlsHandshakes } from './tls_handshakes'; import { networkKpiUniqueFlows } from './unique_flows'; -import { - networkKpiUniquePrivateIps, - networkKpiUniquePrivateIpsEntities, -} from './unique_private_ips'; +import { networkKpiUniquePrivateIps } from './unique_private_ips'; export const networkKpiFactory: Record< NetworkKpiQueries, SecuritySolutionFactory > = { [NetworkKpiQueries.dns]: networkKpiDns, - [NetworkKpiQueries.dnsEntities]: networkKpiDnsEntities, [NetworkKpiQueries.networkEvents]: networkKpiNetworkEvents, - [NetworkKpiQueries.networkEventsEntities]: networkKpiNetworkEventsEntities, [NetworkKpiQueries.tlsHandshakes]: networkKpiTlsHandshakes, - [NetworkKpiQueries.tlsHandshakesEntities]: networkKpiTlsHandshakesEntities, [NetworkKpiQueries.uniqueFlows]: networkKpiUniqueFlows, [NetworkKpiQueries.uniquePrivateIps]: networkKpiUniquePrivateIps, - [NetworkKpiQueries.uniquePrivateIpsEntities]: networkKpiUniquePrivateIpsEntities, }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/network_events/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/network_events/index.ts index ac3d01512428a..89773581f6515 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/network_events/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/network_events/index.ts @@ -14,7 +14,6 @@ import { import { inspectStringifyObject } from '../../../../../../utils/build_query'; import { SecuritySolutionFactory } from '../../../types'; import { buildNetworkEventsQuery } from './query.network_kpi_network_events.dsl'; -import { buildNetworkEventsQueryEntities } from './query.network_kpi_network_events_entities.dsl'; export const networkKpiNetworkEvents: SecuritySolutionFactory = { buildDsl: (options: NetworkKpiNetworkEventsRequestOptions) => buildNetworkEventsQuery(options), @@ -34,24 +33,3 @@ export const networkKpiNetworkEvents: SecuritySolutionFactory = - { - buildDsl: (options: NetworkKpiNetworkEventsRequestOptions) => - buildNetworkEventsQueryEntities(options), - parse: async ( - options: NetworkKpiNetworkEventsRequestOptions, - response: IEsSearchResponse - ): Promise => { - const inspect = { - dsl: [inspectStringifyObject(buildNetworkEventsQueryEntities(options))], - }; - - return { - ...response, - inspect, - // @ts-expect-error code doesn't handle TotalHits - networkEvents: response.rawResponse.aggregations?.events?.value ?? null, - }; - }, - }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/network_events/query.network_kpi_network_events_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/network_events/query.network_kpi_network_events_entities.dsl.ts deleted file mode 100644 index bb40da0a064fb..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/network_events/query.network_kpi_network_events_entities.dsl.ts +++ /dev/null @@ -1,52 +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 { NetworkKpiNetworkEventsRequestOptions } from '../../../../../../../common/search_strategy/security_solution/network'; -import { createQueryFilterClauses } from '../../../../../../utils/build_query'; - -export const buildNetworkEventsQueryEntities = ({ - filterQuery, - timerange: { from, to }, - defaultIndex, -}: NetworkKpiNetworkEventsRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const dslQuery = { - index: defaultIndex, - allow_no_indices: true, - ignore_unavailable: true, - track_total_hits: false, - body: { - aggs: { - events: { - sum: { - field: 'metrics.network.events.value_count', - }, - }, - }, - query: { - bool: { - filter, - }, - }, - size: 0, - }, - }; - - return dslQuery; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/tls_handshakes/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/tls_handshakes/index.ts index cb57d63f4f3a6..1f3c7280cd7c1 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/tls_handshakes/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/tls_handshakes/index.ts @@ -14,7 +14,6 @@ import { import { inspectStringifyObject } from '../../../../../../utils/build_query'; import { SecuritySolutionFactory } from '../../../types'; import { buildTlsHandshakeQuery } from './query.network_kpi_tls_handshakes.dsl'; -import { buildTlsHandshakeQueryEntities } from './query.network_kpi_tls_handshakes_entities.dsl'; export const networkKpiTlsHandshakes: SecuritySolutionFactory = { buildDsl: (options: NetworkKpiTlsHandshakesRequestOptions) => buildTlsHandshakeQuery(options), @@ -34,24 +33,3 @@ export const networkKpiTlsHandshakes: SecuritySolutionFactory = - { - buildDsl: (options: NetworkKpiTlsHandshakesRequestOptions) => - buildTlsHandshakeQueryEntities(options), - parse: async ( - options: NetworkKpiTlsHandshakesRequestOptions, - response: IEsSearchResponse - ): Promise => { - const inspect = { - dsl: [inspectStringifyObject(buildTlsHandshakeQueryEntities(options))], - }; - - return { - ...response, - inspect, - // @ts-expect-error code doesn't handle TotalHits - tlsHandshakes: response.rawResponse.aggregations?.tls?.value ?? null, - }; - }, - }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/tls_handshakes/query.network_kpi_tls_handshakes_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/tls_handshakes/query.network_kpi_tls_handshakes_entities.dsl.ts deleted file mode 100644 index bd7a464e1a090..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/tls_handshakes/query.network_kpi_tls_handshakes_entities.dsl.ts +++ /dev/null @@ -1,52 +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 { NetworkKpiTlsHandshakesRequestOptions } from '../../../../../../../common/search_strategy/security_solution/network'; -import { createQueryFilterClauses } from '../../../../../../utils/build_query'; - -export const buildTlsHandshakeQueryEntities = ({ - filterQuery, - timerange: { from, to }, - defaultIndex, -}: NetworkKpiTlsHandshakesRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const dslQuery = { - index: defaultIndex, - allow_no_indices: true, - ignore_unavailable: true, - track_total_hits: false, - body: { - aggs: { - tls: { - sum: { - field: 'metrics.network.tls.version.value_count', - }, - }, - }, - query: { - bool: { - filter, - }, - }, - size: 0, - }, - }; - - return dslQuery; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/unique_private_ips/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/unique_private_ips/index.ts index 927e2a2fb5aee..9fa63eb939977 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/unique_private_ips/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/unique_private_ips/index.ts @@ -17,7 +17,6 @@ import { inspectStringifyObject } from '../../../../../../utils/build_query'; import { SecuritySolutionFactory } from '../../../types'; import { formatHistogramData } from '../common'; import { buildUniquePrivateIpsQuery } from './query.network_kpi_unique_private_ips.dsl'; -import { buildUniquePrivateIpsQueryEntities } from './query.network_kpi_unique_private_ips_entities.dsl'; export const networkKpiUniquePrivateIps: SecuritySolutionFactory = { @@ -63,48 +62,3 @@ export const networkKpiUniquePrivateIps: SecuritySolutionFactory = - { - // @ts-expect-error auto_date_histogram.buckets is incompatible - buildDsl: (options: NetworkKpiUniquePrivateIpsRequestOptions) => - buildUniquePrivateIpsQueryEntities(options), - parse: async ( - options: NetworkKpiUniquePrivateIpsRequestOptions, - response: IEsSearchResponse - ): Promise => { - const inspect = { - dsl: [inspectStringifyObject(buildUniquePrivateIpsQueryEntities(options))], - }; - - const uniqueSourcePrivateIpsHistogram = getOr( - null, - 'aggregations.source.histogram.buckets', - response.rawResponse - ); - const uniqueDestinationPrivateIpsHistogram = getOr( - null, - 'aggregations.destination.histogram.buckets', - response.rawResponse - ); - - return { - ...response, - inspect, - uniqueSourcePrivateIps: getOr( - null, - 'aggregations.source.unique_private_ips.value', - response.rawResponse - ), - uniqueDestinationPrivateIps: getOr( - null, - 'aggregations.destination.unique_private_ips.value', - response.rawResponse - ), - uniqueSourcePrivateIpsHistogram: formatHistogramData(uniqueSourcePrivateIpsHistogram), - uniqueDestinationPrivateIpsHistogram: formatHistogramData( - uniqueDestinationPrivateIpsHistogram - ), - }; - }, - }; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/unique_private_ips/query.network_kpi_unique_private_ips_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/unique_private_ips/query.network_kpi_unique_private_ips_entities.dsl.ts deleted file mode 100644 index 922a082439807..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/kpi/unique_private_ips/query.network_kpi_unique_private_ips_entities.dsl.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - NetworkKpiUniquePrivateIpsRequestOptions, - UniquePrivateAttributeQuery, -} from '../../../../../../../common/search_strategy/security_solution/network'; -import { createQueryFilterClauses } from '../../../../../../utils/build_query'; - -const getUniquePrivateIpsFilter = (attrQuery: UniquePrivateAttributeQuery) => ({ - bool: { - should: [ - { - term: { - [`${attrQuery}.ip`]: '10.0.0.0/8', - }, - }, - { - term: { - [`${attrQuery}.ip`]: '192.168.0.0/16', - }, - }, - { - term: { - [`${attrQuery}.ip`]: '172.16.0.0/12', - }, - }, - { - term: { - [`${attrQuery}.ip`]: 'fd00::/8', - }, - }, - ], - minimum_should_match: 1, - }, -}); - -const getAggs = (attrQuery: 'source' | 'destination') => ({ - [attrQuery]: { - filter: getUniquePrivateIpsFilter(attrQuery), - aggs: { - unique_private_ips: { - cardinality: { - field: `${attrQuery}.ip`, - }, - }, - histogram: { - auto_date_histogram: { - field: '@timestamp', - buckets: '6', - }, - aggs: { - count: { - cardinality: { - field: `${attrQuery}.ip`, - }, - }, - }, - }, - }, - }, -}); - -export const buildUniquePrivateIpsQueryEntities = ({ - filterQuery, - timerange: { from, to }, - defaultIndex, -}: NetworkKpiUniquePrivateIpsRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const dslQuery = { - allow_no_indices: true, - index: defaultIndex, - ignore_unavailable: true, - track_total_hits: false, - body: { - aggregations: { - ...getAggs('source'), - ...getAggs('destination'), - }, - query: { - bool: { - filter, - }, - }, - size: 0, - }, - }; - - return dslQuery; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.ts index e65ff6e4d1ad7..ef114dcb6167d 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/index.ts @@ -22,7 +22,6 @@ import { SecuritySolutionFactory } from '../../types'; import { getTopCountriesEdges } from './helpers'; import { buildTopCountriesQuery } from './query.top_countries_network.dsl'; -import { buildTopCountriesQueryEntities } from './query.top_countries_network_entities.dsl'; export const networkTopCountries: SecuritySolutionFactory = { buildDsl: (options: NetworkTopCountriesRequestOptions) => { @@ -61,41 +60,3 @@ export const networkTopCountries: SecuritySolutionFactory = { - buildDsl: (options: NetworkTopCountriesRequestOptions) => { - if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) { - throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`); - } - return buildTopCountriesQueryEntities(options); - }, - parse: async ( - options: NetworkTopCountriesRequestOptions, - response: IEsSearchResponse - ): Promise => { - const { activePage, cursorStart, fakePossibleCount, querySize } = options.pagination; - const totalCount = getOr(0, 'aggregations.top_countries_count.value', response.rawResponse); - const networkTopCountriesEdges: NetworkTopCountriesEdges[] = getTopCountriesEdges( - response, - options - ); - const fakeTotalCount = fakePossibleCount <= totalCount ? fakePossibleCount : totalCount; - const edges = networkTopCountriesEdges.splice(cursorStart, querySize - cursorStart); - const inspect = { - dsl: [inspectStringifyObject(buildTopCountriesQueryEntities(options))], - }; - const showMorePagesIndicator = totalCount > fakeTotalCount; - - return { - ...response, - edges, - inspect, - pageInfo: { - activePage: activePage ?? 0, - fakeTotalCount, - showMorePagesIndicator, - }, - totalCount, - }; - }, -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/query.top_countries_network_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/query.top_countries_network_entities.dsl.ts deleted file mode 100644 index 7f1d27db45d2d..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_countries/query.top_countries_network_entities.dsl.ts +++ /dev/null @@ -1,162 +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 { createQueryFilterClauses } from '../../../../../utils/build_query'; -import { assertUnreachable } from '../../../../../../common/utility_types'; -import { - Direction, - FlowTargetSourceDest, - NetworkTopTablesFields, - NetworkTopCountriesRequestOptions, - SortField, -} from '../../../../../../common/search_strategy'; - -// TODO: This is the same as the other one, so move this into helpers. -const getCountAgg = (flowTarget: FlowTargetSourceDest) => ({ - top_countries_count: { - cardinality: { - field: `${flowTarget}.geo.country_iso_code`, - }, - }, -}); - -export const buildTopCountriesQueryEntities = ({ - defaultIndex, - filterQuery, - flowTarget, - sort, - pagination: { querySize }, - timerange: { from, to }, - ip, -}: NetworkTopCountriesRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const dslQuery = { - allow_no_indices: true, - index: defaultIndex, - ignore_unavailable: true, - body: { - aggregations: { - ...getCountAgg(flowTarget), - ...getFlowTargetAggs(sort, flowTarget, querySize), - }, - query: { - bool: ip - ? { - filter, - should: [ - { - term: { - [`${getOppositeField(flowTarget)}.ip`]: ip, - }, - }, - ], - minimum_should_match: 1, - } - : { - filter, - }, - }, - }, - size: 0, - track_total_hits: false, - }; - return dslQuery; -}; - -const getFlowTargetAggs = ( - sort: SortField, - flowTarget: FlowTargetSourceDest, - querySize: number -) => ({ - [flowTarget]: { - terms: { - field: `${flowTarget}.geo.country_iso_code`, - size: querySize, - order: { - ...getQueryOrder(sort), - }, - }, - aggs: { - bytes_in: { - sum: { - field: `metrics.${getOppositeField(flowTarget)}.bytes.sum`, - }, - }, - bytes_out: { - sum: { - field: `metrics.${flowTarget}.bytes.sum`, - }, - }, - flows: { - // TODO: Should we use max here and/or do a hybrid with a max here for performance? - avg: { - field: 'metrics.network.community_id.cardinality', - }, - }, - source_ips: { - avg: { - field: 'metrics.source.ip.cardinality', - }, - }, - destination_ips: { - avg: { - field: 'metrics.destination.ip.cardinality', - }, - }, - }, - }, -}); - -// TODO: This is the same as the other one, so move this to helpers and use it from there. -export const getOppositeField = (flowTarget: FlowTargetSourceDest): FlowTargetSourceDest => { - switch (flowTarget) { - case FlowTargetSourceDest.source: - return FlowTargetSourceDest.destination; - case FlowTargetSourceDest.destination: - return FlowTargetSourceDest.source; - } - assertUnreachable(flowTarget); -}; - -// TODO: This is the same as the other one, so move this to helpers and use it from there. -type QueryOrder = - | { bytes_in: Direction } - | { bytes_out: Direction } - | { flows: Direction } - | { destination_ips: Direction } - | { source_ips: Direction }; - -// TODO: This is the same as the other one, so move this to helpers and use it from there. -const getQueryOrder = ( - networkTopCountriesSortField: SortField -): QueryOrder => { - switch (networkTopCountriesSortField.field) { - case NetworkTopTablesFields.bytes_in: - return { bytes_in: networkTopCountriesSortField.direction }; - case NetworkTopTablesFields.bytes_out: - return { bytes_out: networkTopCountriesSortField.direction }; - case NetworkTopTablesFields.flows: - return { flows: networkTopCountriesSortField.direction }; - case NetworkTopTablesFields.destination_ips: - return { destination_ips: networkTopCountriesSortField.direction }; - case NetworkTopTablesFields.source_ips: - return { source_ips: networkTopCountriesSortField.direction }; - } - assertUnreachable(networkTopCountriesSortField.field); -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/index.ts index 06fac027685bd..218c9361517ce 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/index.ts @@ -22,7 +22,6 @@ import { SecuritySolutionFactory } from '../../types'; import { getTopNFlowEdges } from './helpers'; import { buildTopNFlowQuery } from './query.top_n_flow_network.dsl'; -import { buildTopNFlowQueryEntities } from './query.top_n_flow_network_entities.dsl'; export const networkTopNFlow: SecuritySolutionFactory = { buildDsl: (options: NetworkTopNFlowRequestOptions) => { @@ -58,38 +57,3 @@ export const networkTopNFlow: SecuritySolutionFactory = }; }, }; - -export const networkTopNFlowEntities: SecuritySolutionFactory = { - buildDsl: (options: NetworkTopNFlowRequestOptions) => { - if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) { - throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`); - } - return buildTopNFlowQueryEntities(options); - }, - parse: async ( - options: NetworkTopNFlowRequestOptions, - response: IEsSearchResponse - ): Promise => { - const { activePage, cursorStart, fakePossibleCount, querySize } = options.pagination; - const totalCount = getOr(0, 'aggregations.top_n_flow_count.value', response.rawResponse); - const networkTopNFlowEdges: NetworkTopNFlowEdges[] = getTopNFlowEdges(response, options); - const fakeTotalCount = fakePossibleCount <= totalCount ? fakePossibleCount : totalCount; - const edges = networkTopNFlowEdges.splice(cursorStart, querySize - cursorStart); - const inspect = { - dsl: [inspectStringifyObject(buildTopNFlowQueryEntities(options))], - }; - const showMorePagesIndicator = totalCount > fakeTotalCount; - - return { - ...response, - edges, - inspect, - pageInfo: { - activePage: activePage ?? 0, - fakeTotalCount, - showMorePagesIndicator, - }, - totalCount, - }; - }, -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/query.top_n_flow_network_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/query.top_n_flow_network_entities.dsl.ts deleted file mode 100644 index d11a2debf3cff..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/network/top_n_flow/query.top_n_flow_network_entities.dsl.ts +++ /dev/null @@ -1,165 +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 { - SortField, - FlowTargetSourceDest, - NetworkTopTablesFields, - NetworkTopNFlowRequestOptions, -} from '../../../../../../common/search_strategy'; -import { createQueryFilterClauses } from '../../../../../utils/build_query'; -import { getOppositeField } from '../helpers'; -import { getQueryOrder } from './helpers'; - -// TODO: This is the same as the other one, so move this into helpers. -const getCountAgg = (flowTarget: FlowTargetSourceDest) => ({ - top_n_flow_count: { - cardinality: { - field: `${flowTarget}.ip`, - }, - }, -}); - -export const buildTopNFlowQueryEntities = ({ - defaultIndex, - filterQuery, - flowTarget, - sort, - pagination: { querySize }, - timerange: { from, to }, - ip, -}: NetworkTopNFlowRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const dslQuery = { - allow_no_indices: true, - index: defaultIndex, - ignore_unavailable: true, - body: { - aggregations: { - ...getCountAgg(flowTarget), - ...getFlowTargetAggs(sort, flowTarget, querySize), - }, - query: { - bool: ip - ? { - filter, - should: [ - { - term: { - [`${getOppositeField(flowTarget)}.ip`]: ip, - }, - }, - ], - minimum_should_match: 1, - } - : { - filter, - }, - }, - }, - size: 0, - track_total_hits: false, - }; - return dslQuery; -}; - -const getFlowTargetAggs = ( - sort: SortField, - flowTarget: FlowTargetSourceDest, - querySize: number -) => ({ - [flowTarget]: { - terms: { - field: `${flowTarget}.ip`, - size: querySize, - order: { - ...getQueryOrder(sort), - }, - }, - aggs: { - bytes_in: { - sum: { - field: `metrics.${getOppositeField(flowTarget)}.bytes.sum`, - }, - }, - bytes_out: { - sum: { - field: `metrics.${flowTarget}.bytes.sum`, - }, - }, - domain: { - terms: { - field: `${flowTarget}.domain`, - order: { - timestamp: 'desc', - }, - }, - aggs: { - timestamp: { - max: { - field: '@timestamp', - }, - }, - }, - }, - location: { - filter: { - exists: { - field: `${flowTarget}.geo`, - }, - }, - aggs: { - top_geo: { - top_hits: { - _source: `${flowTarget}.geo.*`, - size: 1, - }, - }, - }, - }, - autonomous_system: { - filter: { - exists: { - field: `${flowTarget}.as`, - }, - }, - aggs: { - top_as: { - top_hits: { - _source: `${flowTarget}.as.*`, - size: 1, - }, - }, - }, - }, - flows: { - avg: { - // TODO: Should we use a max here along with a hybrid query? - field: 'metrics.network.community_id.cardinality', - }, - }, - [`${getOppositeField(flowTarget)}_ips`]: { - avg: { - // TODO: Should we use a max here along with a hybrid query? - field: `metrics.${getOppositeField(flowTarget)}.ip.cardinality`, - }, - }, - }, - }, -}); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/dsl/query_entities.dsl.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/dsl/query_entities.dsl.ts deleted file mode 100644 index 7c9c29a1efdc4..0000000000000 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/dsl/query_entities.dsl.ts +++ /dev/null @@ -1,81 +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 { isEmpty } from 'lodash/fp'; -import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; - -import { createQueryFilterClauses } from '../../../../../../utils/build_query'; -import { UserAuthenticationsRequestOptions } from '../../../../../../../common/search_strategy'; - -export const buildQueryEntities = ({ - filterQuery, - timerange: { from, to }, - pagination: { querySize }, - defaultIndex, - docValueFields, - stackByField, -}: UserAuthenticationsRequestOptions) => { - const filter = [ - ...createQueryFilterClauses(filterQuery), - { - range: { - '@timestamp': { - gte: from, - lte: to, - format: 'strict_date_optional_time', - }, - }, - }, - ]; - - const dslQuery = { - allow_no_indices: true, - index: defaultIndex, - ignore_unavailable: true, - body: { - ...(!isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), - aggregations: { - stack_by_count: { - cardinality: { - field: stackByField, - }, - }, - stack_by: { - terms: { - size: querySize, - field: stackByField, - order: [ - { successes: 'desc' }, - { failures: 'desc' }, - ] as estypes.AggregationsTermsAggregationOrder, - }, - aggs: { - failures: { - sum: { - field: 'metrics.event.authentication.failure.value_count', - }, - }, - successes: { - sum: { - field: 'metrics.event.authentication.success.value_count', - }, - }, - }, - }, - }, - query: { - bool: { - filter, - }, - }, - size: 0, - }, - track_total_hits: false, - }; - - return dslQuery; -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts index 02a89dd08a222..43baa4aadea14 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/helpers.ts @@ -95,68 +95,3 @@ export const getHits = (response: StrategyResponseT successes: bucket.successes.doc_count, }) ); - -export const getHitsEntities = (response: StrategyResponseType) => - getOr([], 'aggregations.stack_by.buckets', response.rawResponse).map( - (bucket: AuthenticationBucket) => ({ - _id: getOr( - `${bucket.key}+${bucket.doc_count}`, - 'failures.lastFailure.hits.hits[0].id', - bucket - ), - _source: { - lastSuccess: getOr(null, 'successes.lastSuccess.hits.hits[0]._source', bucket), - lastFailure: getOr(null, 'failures.lastFailure.hits.hits[0]._source', bucket), - }, - stackedValue: bucket.key, - failures: bucket.failures.value, - successes: bucket.successes.value, - }) - ); - -export const formatAuthenticationEntitiesData = ( - fields: readonly string[] = authenticationsFields, - hit: AuthenticationHit, - fieldMap: Readonly> -): AuthenticationsEdges => { - return fields.reduce( - (flattenedFields, fieldName) => { - if (hit.cursor) { - flattenedFields.cursor.value = hit.cursor; - } - flattenedFields.node = { - ...flattenedFields.node, - ...{ - _id: hit._id, - stackedValue: [hit.stackedValue], - failures: hit.failures, - successes: hit.successes, - }, - }; - const mergedResult = mergeFieldsWithHit(fieldName, flattenedFields, fieldMap, hit); - const fieldPath = `node.${fieldName}`; - const fieldValue = get(fieldPath, mergedResult); - if (!isEmpty(fieldValue)) { - return set( - fieldPath, - toObjectArrayOfStrings(fieldValue).map(({ str }) => str), - mergedResult - ); - } else { - return mergedResult; - } - }, - { - node: { - failures: 0, - successes: 0, - _id: '', - stackedValue: [''], - }, - cursor: { - value: '', - tiebreaker: null, - }, - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/index.tsx b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/index.tsx index 11400166e3344..e748023bfe76c 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/index.tsx +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/authentications/index.tsx @@ -22,15 +22,7 @@ import { inspectStringifyObject } from '../../../../../utils/build_query'; import { SecuritySolutionFactory } from '../../types'; import { auditdFieldsMap, buildQuery as buildAuthenticationQuery } from './dsl/query.dsl'; -import { buildQueryEntities as buildAuthenticationQueryEntities } from './dsl/query_entities.dsl'; - -import { - authenticationsFields, - formatAuthenticationData, - formatAuthenticationEntitiesData, - getHits, - getHitsEntities, -} from './helpers'; +import { authenticationsFields, formatAuthenticationData, getHits } from './helpers'; export const authentications: SecuritySolutionFactory = { buildDsl: (options: UserAuthenticationsRequestOptions) => { @@ -71,44 +63,3 @@ export const authentications: SecuritySolutionFactory = { - buildDsl: (options: UserAuthenticationsRequestOptions) => { - if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) { - throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`); - } - - return buildAuthenticationQueryEntities(options); - }, - parse: async ( - options: UserAuthenticationsRequestOptions, - response: IEsSearchResponse - ): Promise => { - const { activePage, cursorStart, fakePossibleCount, querySize } = options.pagination; - const totalCount = getOr(0, 'aggregations.stack_by_count.value', response.rawResponse); - - const fakeTotalCount = fakePossibleCount <= totalCount ? fakePossibleCount : totalCount; - const hits: AuthenticationHit[] = getHitsEntities(response); - const authenticationEdges: AuthenticationsEdges[] = hits.map((hit) => - formatAuthenticationEntitiesData(authenticationsFields, hit, auditdFieldsMap) - ); - - const edges = authenticationEdges.splice(cursorStart, querySize - cursorStart); - const inspect = { - dsl: [inspectStringifyObject(buildAuthenticationQueryEntities(options))], - }; - const showMorePagesIndicator = totalCount > fakeTotalCount; - - return { - ...response, - inspect, - edges, - totalCount, - pageInfo: { - activePage: activePage ?? 0, - fakeTotalCount, - showMorePagesIndicator, - }, - }; - }, -}; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/index.ts index 0b13319cc11c7..0720244a73ff3 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/index.ts @@ -10,7 +10,7 @@ import { UsersQueries } from '../../../../../common/search_strategy/security_sol import { SecuritySolutionFactory } from '../types'; import { allUsers } from './all'; -import { authentications, authenticationsEntities } from './authentications'; +import { authentications } from './authentications'; import { userDetails } from './details'; import { totalUsersKpi } from './kpi/total_users'; @@ -19,5 +19,4 @@ export const usersFactory: Record>; @@ -232,26 +229,6 @@ export const initUiSettings = ( requiresPageReload: false, schema: schema.boolean(), }, - // TODO: Remove this check once the experimental flag is removed - ...(experimentalFeatures.metricsEntitiesEnabled - ? { - [DEFAULT_TRANSFORMS]: { - name: i18n.translate('xpack.securitySolution.uiSettings.transforms', { - defaultMessage: 'Default transforms to use', - }), - value: DEFAULT_TRANSFORMS_SETTING, - type: 'json', - description: i18n.translate('xpack.securitySolution.uiSettings.transformDescription', { - // TODO: Add a hyperlink to documentation about this feature - defaultMessage: 'Experimental: Enable an application cache through transforms', - }), - sensitive: true, - category: [APP_ID], - requiresPageReload: false, - schema: transformConfigSchema, - }, - } - : {}), }; uiSettings.register(orderSettings(securityUiSettings)); diff --git a/x-pack/plugins/timelines/common/types/timeline/index.ts b/x-pack/plugins/timelines/common/types/timeline/index.ts index cac24f65d0fd2..867264fa81546 100644 --- a/x-pack/plugins/timelines/common/types/timeline/index.ts +++ b/x-pack/plugins/timelines/common/types/timeline/index.ts @@ -322,6 +322,7 @@ export enum TimelineId { casePage = 'timeline-case', test = 'test', // Reserved for testing purposes alternateTest = 'alternateTest', + rulePreview = 'rule-preview', } export const TimelineIdLiteralRt = runtimeTypes.union([ @@ -333,6 +334,7 @@ export const TimelineIdLiteralRt = runtimeTypes.union([ runtimeTypes.literal(TimelineId.networkPageExternalAlerts), runtimeTypes.literal(TimelineId.active), runtimeTypes.literal(TimelineId.test), + runtimeTypes.literal(TimelineId.rulePreview), ]); export type TimelineIdLiteral = runtimeTypes.TypeOf; diff --git a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx index 6f74fd1d2cb37..2991d80c7af0a 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx @@ -113,7 +113,7 @@ export interface TGridIntegratedProps { filterStatus?: AlertStatus; globalFullScreen: boolean; // If truthy, the graph viewer (Resolver) is showing - graphEventId: string | undefined; + graphEventId?: string; graphOverlay?: React.ReactNode; hasAlertsCrud: boolean; height?: number; diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 687339109cbb0..a1abc744c3336 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -19873,7 +19873,6 @@ "xpack.securitySolution.containers.detectionEngine.rulesAndTimelines": "Impossible de récupérer les règles et les chronologies", "xpack.securitySolution.containers.detectionEngine.tagFetchFailDescription": "Impossible de récupérer les balises", "xpack.securitySolution.containers.errors.stopJobFailureTitle": "Échec d'arrêt de la tâche", - "xpack.securitySolution.containers.transforms.errorCreatingTransformsLabel": "Impossible de créer des transformations", "xpack.securitySolution.customizeEventRenderers.customizeEventRenderersDescription": "Les outils de rendu d'événement transmettent automatiquement les détails les plus pertinents d'un événement pour révéler son histoire", "xpack.securitySolution.customizeEventRenderers.customizeEventRenderersTitle": "Personnaliser les outils de rendu d'événement", "xpack.securitySolution.customizeEventRenderers.disableAllRenderersButtonLabel": "Tout désactiver", @@ -20726,9 +20725,6 @@ "xpack.securitySolution.detectionEngine.pageTitle": "Moteur de détection", "xpack.securitySolution.detectionEngine.panelSubtitleShowing": "Affichant", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphCountLabel": "Compte", - "xpack.securitySolution.detectionEngine.queryPreview.queryGraphDisclaimer": "Remarque : cet aperçu exclut les effets d'exceptions aux règles et les remplacements d'horodatages.", - "xpack.securitySolution.detectionEngine.queryPreview.queryGraphDisclaimerEql": "Remarque : cet aperçu exclut les effets d'exceptions aux règles et les remplacements d'horodatages, et est limité à 100 résultats.", - "xpack.securitySolution.detectionEngine.queryPreview.queryGraphHitsTitle": "Résultats", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphPreviewError": "Erreur de récupération de l'aperçu", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphPreviewInspectTitle": "aperçu de la recherche", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphPreviewNoiseWarning": "Avertissement de bruit : cette règle peut générer beaucoup de bruit. Envisagez d'affiner votre recherche. La base est une progression linéaire comportant 1 alerte par heure.", @@ -22310,8 +22306,6 @@ "xpack.securitySolution.uiSettings.newsFeedUrlDescription": "

Le contenu du fil d'actualités sera récupéré à partir de cette URL

", "xpack.securitySolution.uiSettings.rulesTableRefresh": "Actualisation automatique des règles", "xpack.securitySolution.uiSettings.rulesTableRefreshDescription": "

Active l'actualisation automatique sur tous les tableaux de règles et de monitorings, en millisecondes

", - "xpack.securitySolution.uiSettings.transformDescription": "Expérimental : active un cache d'application via les transformations", - "xpack.securitySolution.uiSettings.transforms": "Transformations par défaut à utiliser", "xpack.securitySolution.uncommonProcesses.errorSearchDescription": "Une erreur s'est produite sur une recherche de processus inhabituels", "xpack.securitySolution.uncommonProcesses.failSearchDescription": "Impossible de lancer la recherche sur les processus inhabituels", "xpack.securitySolution.uncommonProcessTable.hostsTitle": "Noms d'hôtes", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1527acb993bb4..d58da0f2ed657 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -22697,7 +22697,6 @@ "xpack.securitySolution.containers.detectionEngine.rulesAndTimelines": "ルールとタイムラインを取得できませんでした", "xpack.securitySolution.containers.detectionEngine.tagFetchFailDescription": "タグを取得できませんでした", "xpack.securitySolution.containers.errors.stopJobFailureTitle": "ジョブ停止エラー", - "xpack.securitySolution.containers.transforms.errorCreatingTransformsLabel": "変換を作成できませんでした", "xpack.securitySolution.contextMenuItemByRouter.viewDetails": "詳細を表示", "xpack.securitySolution.customizeEventRenderers.customizeEventRenderersDescription": "イベントレンダラーは、イベントで最も関連性が高い詳細情報を自動的に表示し、ストーリーを明らかにします", "xpack.securitySolution.customizeEventRenderers.customizeEventRenderersTitle": "イベントレンダラーのカスタマイズ", @@ -23586,9 +23585,6 @@ "xpack.securitySolution.detectionEngine.pageTitle": "検出エンジン", "xpack.securitySolution.detectionEngine.panelSubtitleShowing": "表示中", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphCountLabel": "カウント", - "xpack.securitySolution.detectionEngine.queryPreview.queryGraphDisclaimer": "注:このプレビューは、ルール例外とタイムスタンプオーバーライドの効果を除外します。", - "xpack.securitySolution.detectionEngine.queryPreview.queryGraphDisclaimerEql": "注:このプレビューは、ルール例外とタイムスタンプオーバーライドの効果を除外します。結果は100件に制限されます。", - "xpack.securitySolution.detectionEngine.queryPreview.queryGraphHitsTitle": "ヒット数", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphPreviewError": "プレビュー取得エラー", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphPreviewInspectTitle": "クエリプレビュー", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphPreviewNoiseWarning": "ノイズ警告:このルールではノイズが多く生じる可能性があります。クエリを絞り込むことを検討してください。これは1時間ごとに1アラートという線形進行に基づいています。", @@ -25500,8 +25496,6 @@ "xpack.securitySolution.uiSettings.newsFeedUrlDescription": "

ニュースフィードコンテンツはこの URL から取得されます

", "xpack.securitySolution.uiSettings.rulesTableRefresh": "ルール自動更新", "xpack.securitySolution.uiSettings.rulesTableRefreshDescription": "

すべてのルールと監視テーブルの自動更新を有効にします(ミリ秒)

", - "xpack.securitySolution.uiSettings.transformDescription": "実験:変換を通してアプリケーションキャッシュを有効にする", - "xpack.securitySolution.uiSettings.transforms": "使用するデフォルトの変換", "xpack.securitySolution.uncommonProcesses.errorSearchDescription": "一般的ではないプロセス検索でエラーが発生しました", "xpack.securitySolution.uncommonProcesses.failSearchDescription": "一般的ではないプロセスで検索を実行できませんでした", "xpack.securitySolution.uncommonProcessTable.hostsTitle": "ホスト名", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 70d58abb23a95..1f8bcf7b4fb74 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -22724,7 +22724,6 @@ "xpack.securitySolution.containers.detectionEngine.rulesAndTimelines": "无法提取规则和时间线", "xpack.securitySolution.containers.detectionEngine.tagFetchFailDescription": "无法提取标签", "xpack.securitySolution.containers.errors.stopJobFailureTitle": "停止作业失败", - "xpack.securitySolution.containers.transforms.errorCreatingTransformsLabel": "无法创建转换", "xpack.securitySolution.contextMenuItemByRouter.viewDetails": "查看详情", "xpack.securitySolution.customizeEventRenderers.customizeEventRenderersDescription": "事件呈现器自动在事件中传送最相关的详情,以揭示其故事", "xpack.securitySolution.customizeEventRenderers.customizeEventRenderersTitle": "定制事件呈现器", @@ -23613,9 +23612,6 @@ "xpack.securitySolution.detectionEngine.pageTitle": "检测引擎", "xpack.securitySolution.detectionEngine.panelSubtitleShowing": "正在显示", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphCountLabel": "计数", - "xpack.securitySolution.detectionEngine.queryPreview.queryGraphDisclaimer": "注意:此预览不包括规则例外和时间戳覆盖的影响。", - "xpack.securitySolution.detectionEngine.queryPreview.queryGraphDisclaimerEql": "注意:此预览不包括规则例外和时间戳覆盖的影响,且仅显示 100 个结果。", - "xpack.securitySolution.detectionEngine.queryPreview.queryGraphHitsTitle": "命中数", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphPreviewError": "提取预览时出错", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphPreviewInspectTitle": "查询预览", "xpack.securitySolution.detectionEngine.queryPreview.queryGraphPreviewNoiseWarning": "噪音警告:此规则可能会导致大量噪音。考虑缩小您的查询范围。这基于每小时 1 条告警的线性级数。", @@ -25529,8 +25525,6 @@ "xpack.securitySolution.uiSettings.newsFeedUrlDescription": "

将从此 URL 检索新闻源内容

", "xpack.securitySolution.uiSettings.rulesTableRefresh": "规则自动刷新", "xpack.securitySolution.uiSettings.rulesTableRefreshDescription": "

对所有规则和监测表启用自动刷新(毫秒)

", - "xpack.securitySolution.uiSettings.transformDescription": "实验性:通过转换启用应用程序缓存", - "xpack.securitySolution.uiSettings.transforms": "要使用的默认转换", "xpack.securitySolution.uncommonProcesses.errorSearchDescription": "搜索不常见进程时发生错误", "xpack.securitySolution.uncommonProcesses.failSearchDescription": "无法对不常见进程执行搜索", "xpack.securitySolution.uncommonProcessTable.hostsTitle": "主机名", diff --git a/x-pack/test/detection_engine_api_integration/utils.ts b/x-pack/test/detection_engine_api_integration/utils.ts index ebf3a7008cd57..de66002343212 100644 --- a/x-pack/test/detection_engine_api_integration/utils.ts +++ b/x-pack/test/detection_engine_api_integration/utils.ts @@ -116,12 +116,12 @@ export const getSimpleRule = (ruleId = 'rule-1', enabled = false): QueryCreateSc /** * This is a typical simple preview rule for testing that is easy for most basic testing * @param ruleId - * @param enabled The number of times the rule will be run through the executors. Defaulted to 20, + * @param enabled The number of times the rule will be run through the executors. Defaulted to 12, * the execution time for the default interval time of 5m. */ export const getSimplePreviewRule = ( ruleId = 'preview-rule-1', - invocationCount = 20 + invocationCount = 12 ): PreviewRulesSchema => ({ name: 'Simple Rule Query', description: 'Simple Rule Query', diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json index 752bf09d96df0..91b82bc785ae9 100644 --- a/x-pack/test/tsconfig.json +++ b/x-pack/test/tsconfig.json @@ -77,7 +77,6 @@ { "path": "../plugins/licensing/tsconfig.json" }, { "path": "../plugins/lists/tsconfig.json" }, { "path": "../plugins/logstash/tsconfig.json" }, - { "path": "../plugins/metrics_entities/tsconfig.json" }, { "path": "../plugins/ml/tsconfig.json" }, { "path": "../plugins/monitoring/tsconfig.json" }, { "path": "../plugins/observability/tsconfig.json" },