diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5c54fb6ef1ce4..000943bf62d8e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -5,6 +5,10 @@ # The #CC# prefix delineates Code Coverage, # used for the 'team' designator within Kibana Stats +# Tech leads +/dev_docs @elastic/kibana-tech-leads +/packages/kbn-docs-utils/ @elastic/kibana-tech-leads @elastic/kibana-operations + # App /x-pack/plugins/discover_enhanced/ @elastic/kibana-app /x-pack/plugins/lens/ @elastic/kibana-app @@ -201,6 +205,7 @@ /test/functional/services/remote @elastic/kibana-qa # Core +/examples/hello_world/ @elastic/kibana-core /src/core/ @elastic/kibana-core /src/plugins/saved_objects_tagging_oss @elastic/kibana-core /config/kibana.yml @elastic/kibana-core diff --git a/STYLEGUIDE.mdx b/STYLEGUIDE.mdx index afe00476640b3..95f29c674da9b 100644 --- a/STYLEGUIDE.mdx +++ b/STYLEGUIDE.mdx @@ -35,7 +35,7 @@ remove it, don't simply comment it out. We are gradually moving the Kibana code base over to Prettier. All TypeScript code and some JavaScript code (check `.eslintrc.js`) is using Prettier to format code. You -can run `node script/eslint --fix` to fix linting issues and apply Prettier formatting. +can run `node scripts/eslint --fix` to fix linting issues and apply Prettier formatting. We recommend you to enable running ESLint via your IDE. Whenever possible we are trying to use Prettier and linting over written style guide rules. diff --git a/api_docs/charts.json b/api_docs/charts.json index 177a63556d59b..7081f410ee8af 100644 --- a/api_docs/charts.json +++ b/api_docs/charts.json @@ -2539,7 +2539,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/charts/common/palette.ts", @@ -2597,7 +2597,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/charts/common/palette.ts", diff --git a/api_docs/dashboard.json b/api_docs/dashboard.json index 656364b835af5..cf504e4452a1a 100644 --- a/api_docs/dashboard.json +++ b/api_docs/dashboard.json @@ -1137,8 +1137,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" } ], "path": "src/plugins/dashboard/public/locator.ts", @@ -1204,8 +1204,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ") | undefined" ], @@ -1334,8 +1334,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ") | undefined" ], diff --git a/api_docs/data.json b/api_docs/data.json index e4f94168f50be..0456a1ed04414 100644 --- a/api_docs/data.json +++ b/api_docs/data.json @@ -241,7 +241,7 @@ "description": [], "signature": [ "Pick & Pick<{ type: ", { "pluginId": "data", @@ -608,7 +608,7 @@ "description": [], "signature": [ "() => { type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; }" ], "path": "src/plugins/data/common/search/aggs/agg_config.ts", @@ -629,7 +629,7 @@ "description": [], "signature": [ "() => { type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; }" ], "path": "src/plugins/data/common/search/aggs/agg_config.ts", @@ -1273,7 +1273,7 @@ "description": [], "signature": [ "Pick & Pick<{ type: string | ", { "pluginId": "data", @@ -1512,7 +1512,7 @@ "text": "AggConfig" }, ">(params: Pick & Pick<{ type: string | ", { "pluginId": "data", @@ -1543,7 +1543,7 @@ "description": [], "signature": [ "Pick & Pick<{ type: string | ", { "pluginId": "data", @@ -2274,7 +2274,7 @@ "description": [], "signature": [ "(agg: TAggConfig, state?: { type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined) => TAggConfig" ], "path": "src/plugins/data/common/search/aggs/param_types/agg.ts", @@ -2303,7 +2303,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/param_types/agg.ts", @@ -8188,7 +8188,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -8270,7 +8270,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -8320,7 +8320,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -8434,7 +8434,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -8516,7 +8516,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -8598,7 +8598,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -8648,7 +8648,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -8762,7 +8762,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -8844,7 +8844,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -8958,7 +8958,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9012,7 +9012,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9062,7 +9062,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9120,7 +9120,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9178,7 +9178,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9236,7 +9236,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9294,7 +9294,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9352,7 +9352,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9402,7 +9402,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9452,7 +9452,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9506,7 +9506,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9560,7 +9560,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9610,7 +9610,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9660,7 +9660,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9710,7 +9710,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9760,7 +9760,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9810,7 +9810,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9860,7 +9860,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9914,7 +9914,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -9964,7 +9964,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -10014,7 +10014,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -10068,7 +10068,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -10118,7 +10118,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -10168,7 +10168,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -10218,7 +10218,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -14889,7 +14889,7 @@ "text": "IAggType" }, "; enabled?: boolean | undefined; id?: string | undefined; schema?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; }" ], "path": "src/plugins/data/common/search/aggs/agg_config.ts", @@ -15020,7 +15020,7 @@ "text": "IndexPattern" }, ", configStates?: Pick & Pick<{ type: string | ", { "pluginId": "data", @@ -15131,7 +15131,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts", @@ -15170,7 +15170,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/esdsl.ts", @@ -17656,7 +17656,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/index_patterns/expressions/load_index_pattern.ts", @@ -24304,7 +24304,7 @@ "description": [], "signature": [ "(agg: TAggConfig, state?: { type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined) => TAggConfig" ], "path": "src/plugins/data/common/search/aggs/param_types/agg.ts", @@ -24333,7 +24333,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/param_types/agg.ts", @@ -28751,7 +28751,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -28833,7 +28833,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -28883,7 +28883,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -28997,7 +28997,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29079,7 +29079,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29161,7 +29161,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29211,7 +29211,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29325,7 +29325,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29407,7 +29407,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29521,7 +29521,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29575,7 +29575,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29625,7 +29625,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29683,7 +29683,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29741,7 +29741,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29799,7 +29799,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29857,7 +29857,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29915,7 +29915,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -29965,7 +29965,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30015,7 +30015,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30069,7 +30069,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30123,7 +30123,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30173,7 +30173,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30223,7 +30223,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30273,7 +30273,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30323,7 +30323,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30373,7 +30373,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30423,7 +30423,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30477,7 +30477,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30527,7 +30527,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30577,7 +30577,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30631,7 +30631,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30681,7 +30681,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30731,7 +30731,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -30781,7 +30781,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -32535,7 +32535,7 @@ "text": "IAggType" }, "; enabled?: boolean | undefined; id?: string | undefined; schema?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; }" ], "path": "src/plugins/data/common/search/aggs/agg_config.ts", @@ -32631,7 +32631,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts", @@ -34951,7 +34951,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/index_patterns/expressions/load_index_pattern.ts", diff --git a/api_docs/data_index_patterns.json b/api_docs/data_index_patterns.json index 3badbb04ce527..3ca81e7ff4b82 100644 --- a/api_docs/data_index_patterns.json +++ b/api_docs/data_index_patterns.json @@ -8503,7 +8503,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/index_patterns/expressions/load_index_pattern.ts", diff --git a/api_docs/data_query.json b/api_docs/data_query.json index 3ed8cc6ab9f02..af30ed33b0303 100644 --- a/api_docs/data_query.json +++ b/api_docs/data_query.json @@ -30,8 +30,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -492,8 +492,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ", collector: unknown) => {}" ], diff --git a/api_docs/data_search.json b/api_docs/data_search.json index d6006dc315db1..e035cee56c6e0 100644 --- a/api_docs/data_search.json +++ b/api_docs/data_search.json @@ -918,7 +918,7 @@ "text": "IndexPattern" }, ", configStates?: Pick & Pick<{ type: string | ", { "pluginId": "data", @@ -4174,7 +4174,7 @@ "description": [], "signature": [ "Pick & Pick<{ type: ", { "pluginId": "data", @@ -4541,7 +4541,7 @@ "description": [], "signature": [ "() => { type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; }" ], "path": "src/plugins/data/common/search/aggs/agg_config.ts", @@ -4562,7 +4562,7 @@ "description": [], "signature": [ "() => { type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; }" ], "path": "src/plugins/data/common/search/aggs/agg_config.ts", @@ -5206,7 +5206,7 @@ "description": [], "signature": [ "Pick & Pick<{ type: string | ", { "pluginId": "data", @@ -5445,7 +5445,7 @@ "text": "AggConfig" }, ">(params: Pick & Pick<{ type: string | ", { "pluginId": "data", @@ -5476,7 +5476,7 @@ "description": [], "signature": [ "Pick & Pick<{ type: string | ", { "pluginId": "data", @@ -6207,7 +6207,7 @@ "description": [], "signature": [ "(agg: TAggConfig, state?: { type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined) => TAggConfig" ], "path": "src/plugins/data/common/search/aggs/param_types/agg.ts", @@ -6236,7 +6236,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/param_types/agg.ts", @@ -11247,7 +11247,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">) => any" ], "path": "src/plugins/data/common/search/expressions/utils/function_wrapper.ts", @@ -14922,7 +14922,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15004,7 +15004,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15054,7 +15054,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15168,7 +15168,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15250,7 +15250,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15332,7 +15332,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15382,7 +15382,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15496,7 +15496,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15578,7 +15578,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15692,7 +15692,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15746,7 +15746,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15796,7 +15796,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15854,7 +15854,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15912,7 +15912,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -15970,7 +15970,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16028,7 +16028,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16086,7 +16086,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16136,7 +16136,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16186,7 +16186,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16240,7 +16240,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16294,7 +16294,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16344,7 +16344,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16394,7 +16394,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16444,7 +16444,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16494,7 +16494,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16544,7 +16544,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16594,7 +16594,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16648,7 +16648,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16698,7 +16698,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16748,7 +16748,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16802,7 +16802,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16852,7 +16852,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16902,7 +16902,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -16952,7 +16952,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/aggs/types.ts", @@ -17102,7 +17102,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/bucket_avg.ts", @@ -17117,7 +17117,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/bucket_avg.ts", @@ -17156,7 +17156,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", @@ -17171,7 +17171,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/bucket_max.ts", @@ -17210,7 +17210,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", @@ -17225,7 +17225,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/bucket_min.ts", @@ -17264,7 +17264,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", @@ -17279,7 +17279,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/bucket_sum.ts", @@ -17365,7 +17365,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/cumulative_sum.ts", @@ -17702,7 +17702,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/derivative.ts", @@ -17843,7 +17843,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", @@ -17858,7 +17858,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/filtered_metric.ts", @@ -18557,7 +18557,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/moving_avg.ts", @@ -18770,7 +18770,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/metrics/serial_diff.ts", @@ -19027,7 +19027,7 @@ "description": [], "signature": [ "{ type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined" ], "path": "src/plugins/data/common/search/aggs/buckets/terms.ts", @@ -23574,7 +23574,7 @@ "text": "IAggType" }, "; enabled?: boolean | undefined; id?: string | undefined; schema?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; }" ], "path": "src/plugins/data/common/search/aggs/agg_config.ts", @@ -24027,7 +24027,7 @@ "text": "IndexPattern" }, ", configStates?: Pick & Pick<{ type: string | ", { "pluginId": "data", @@ -24216,7 +24216,7 @@ "text": "IAggType" }, "; enabled?: boolean | undefined; id?: string | undefined; schema?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; }" ], "path": "src/plugins/data/common/search/aggs/agg_configs.ts", @@ -24356,7 +24356,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts", @@ -24395,7 +24395,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/esdsl.ts", @@ -24575,7 +24575,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/cidr.ts", @@ -24638,7 +24638,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/date_range.ts", @@ -24687,7 +24687,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/exists_filter.ts", @@ -24750,7 +24750,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/extended_bounds.ts", @@ -24805,7 +24805,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/field.ts", @@ -24860,7 +24860,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/geo_bounding_box.ts", @@ -24915,7 +24915,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/geo_point.ts", @@ -24978,7 +24978,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/ip_range.ts", @@ -25149,7 +25149,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/kibana_filter.ts", @@ -25212,7 +25212,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/timerange.ts", @@ -25261,7 +25261,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/kql.ts", @@ -25310,7 +25310,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/lucene.ts", @@ -25373,7 +25373,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/numerical_range.ts", @@ -25422,7 +25422,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/phrase_filter.ts", @@ -25477,7 +25477,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/query_filter.ts", @@ -25524,7 +25524,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/range.ts", @@ -25573,7 +25573,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/data/common/search/expressions/range_filter.ts", @@ -30132,7 +30132,7 @@ "text": "IBucketAggConfig" }, ", state?: { type: string; enabled?: boolean | undefined; id?: string | undefined; params?: {} | ", - "SerializableState", + "Serializable", " | undefined; schema?: string | undefined; } | undefined) => ", { "pluginId": "data", diff --git a/api_docs/discover.json b/api_docs/discover.json index ec94f42df2a0e..61d2f39d0c87f 100644 --- a/api_docs/discover.json +++ b/api_docs/discover.json @@ -81,8 +81,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" } ], "path": "src/plugins/discover/public/locator.ts", @@ -163,8 +163,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ") | undefined" ], @@ -278,8 +278,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ") | undefined" ], diff --git a/api_docs/embeddable.json b/api_docs/embeddable.json index 44c5ecbe0c063..7e5ef7bbdcc1b 100644 --- a/api_docs/embeddable.json +++ b/api_docs/embeddable.json @@ -8095,8 +8095,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; disabledActions?: string[] | undefined; disableTriggers?: boolean | undefined; searchSessionId?: string | undefined; syncColors?: boolean | undefined; }" ], @@ -8511,8 +8511,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">) => void" ], @@ -8539,8 +8539,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -9194,8 +9194,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">) => void" ], @@ -9222,8 +9222,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -9965,8 +9965,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; disabledActions?: string[] | undefined; disableTriggers?: boolean | undefined; searchSessionId?: string | undefined; syncColors?: boolean | undefined; }" ], @@ -10037,16 +10037,16 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ", version: string) => ", { "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" } ], "path": "src/plugins/embeddable/common/lib/migrate.ts", diff --git a/api_docs/expression_repeat_image.json b/api_docs/expression_repeat_image.json index 4917dc1f62205..e2039e6e2ac45 100644 --- a/api_docs/expression_repeat_image.json +++ b/api_docs/expression_repeat_image.json @@ -350,7 +350,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expression_repeat_image/common/types/expression_functions.ts", diff --git a/api_docs/expression_shape.json b/api_docs/expression_shape.json index 607c10fb38240..94a969388a61c 100644 --- a/api_docs/expression_shape.json +++ b/api_docs/expression_shape.json @@ -891,7 +891,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expression_shape/common/types/expression_functions.ts", @@ -1405,7 +1405,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expression_shape/common/types/expression_functions.ts", diff --git a/api_docs/expressions.json b/api_docs/expressions.json index 6185466a02cc8..0abef59f1deef 100644 --- a/api_docs/expressions.json +++ b/api_docs/expressions.json @@ -76,8 +76,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>, ", { @@ -116,8 +116,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>, {}>" ], @@ -157,7 +157,7 @@ "text": "ExecutionContext" }, "" ], "path": "src/plugins/expressions/common/execution/execution.ts", @@ -203,8 +203,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>" ], @@ -350,8 +350,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>" ], @@ -840,8 +840,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>" ], @@ -1469,8 +1469,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>" ], @@ -1851,8 +1851,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">) => ", { @@ -1886,8 +1886,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -2301,16 +2301,16 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ") => ", { "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, "; }" ], @@ -4000,8 +4000,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>" ], @@ -4616,8 +4616,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">) => ", { @@ -4651,8 +4651,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -7709,7 +7709,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -7755,7 +7755,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -7793,7 +7793,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -7831,7 +7831,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -7869,7 +7869,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -7931,7 +7931,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -7993,7 +7993,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -8055,7 +8055,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -8117,7 +8117,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -8614,8 +8614,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>" ], @@ -9105,7 +9105,7 @@ "label": "searchContext", "description": [], "signature": [ - "SerializableState", + "Serializable", " | undefined" ], "path": "src/plugins/expressions/public/types/index.ts", @@ -10235,7 +10235,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -10638,8 +10638,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }" ], @@ -10786,8 +10786,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }" ], @@ -11195,8 +11195,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>; readonly fork: () => ", { @@ -11550,8 +11550,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>, ", { @@ -11590,8 +11590,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>, {}>" ], @@ -11631,7 +11631,7 @@ "text": "ExecutionContext" }, "" ], "path": "src/plugins/expressions/common/execution/execution.ts", @@ -11677,8 +11677,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>" ], @@ -11824,8 +11824,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>" ], @@ -12745,8 +12745,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>" ], @@ -13127,8 +13127,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">) => ", { @@ -13162,8 +13162,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -13577,16 +13577,16 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ") => ", { "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, "; }" ], @@ -17443,7 +17443,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -17489,7 +17489,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -17527,7 +17527,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -17565,7 +17565,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -17603,7 +17603,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -17665,7 +17665,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -17727,7 +17727,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -17789,7 +17789,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -17851,7 +17851,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -18962,7 +18962,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -19314,8 +19314,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }" ], @@ -19462,8 +19462,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }" ], @@ -19839,8 +19839,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>; readonly fork: () => ", { @@ -19955,8 +19955,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>, ", { @@ -19995,8 +19995,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>, {}>" ], @@ -20036,7 +20036,7 @@ "text": "ExecutionContext" }, "" ], "path": "src/plugins/expressions/common/execution/execution.ts", @@ -20082,8 +20082,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>" ], @@ -20229,8 +20229,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>>>" ], @@ -20719,8 +20719,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>" ], @@ -21348,8 +21348,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>" ], @@ -21730,8 +21730,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">) => ", { @@ -21765,8 +21765,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -22180,16 +22180,16 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ") => ", { "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, "; }" ], @@ -23248,8 +23248,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>" ], @@ -23864,8 +23864,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">) => ", { @@ -23899,8 +23899,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -25367,8 +25367,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>" ], @@ -25533,7 +25533,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">" ], "path": "src/plugins/expressions/common/util/test_utils.ts", @@ -25923,8 +25923,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>" ], @@ -26796,7 +26796,7 @@ "\nany extra parameters for the source that produced this column" ], "signature": [ - "SerializableState", + "Serializable", " | undefined" ], "path": "src/plugins/expressions/common/expression_types/specs/datatable.ts", @@ -28555,8 +28555,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined" ], @@ -29009,7 +29009,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -29055,7 +29055,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -29093,7 +29093,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -29131,7 +29131,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -29169,7 +29169,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -29231,7 +29231,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -29293,7 +29293,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -29355,7 +29355,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -29417,7 +29417,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -29882,8 +29882,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>" ], @@ -31260,7 +31260,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/types.ts", @@ -31570,8 +31570,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | undefined; rawError?: any; duration: number | undefined; }" ], @@ -31640,7 +31640,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/specs/clog.ts", @@ -31703,7 +31703,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/specs/cumulative_sum.ts", @@ -31766,7 +31766,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/specs/derivative.ts", @@ -31813,7 +31813,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/specs/font.ts", @@ -31876,7 +31876,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/specs/moving_average.ts", @@ -31939,7 +31939,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/specs/overall_metric.ts", @@ -31978,7 +31978,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/specs/theme.ts", @@ -32033,7 +32033,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/specs/ui_setting.ts", @@ -32072,7 +32072,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/specs/var.ts", @@ -32111,7 +32111,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/expressions/common/expression_functions/specs/var_set.ts", @@ -32271,8 +32271,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>; readonly fork: () => ", { @@ -32380,8 +32380,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }" ], @@ -32550,8 +32550,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }" ], @@ -34894,8 +34894,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>) => ", { @@ -34926,8 +34926,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>, \"error\" | \"info\">; }>" ], @@ -34962,8 +34962,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }>" ], @@ -36961,7 +36961,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">) => ", { "pluginId": "expressions", @@ -37038,7 +37038,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">" ], "path": "src/plugins/expressions/common/expression_functions/specs/math_column.ts", @@ -39686,7 +39686,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">) => any" ], "path": "src/plugins/expressions/common/expression_functions/specs/theme.ts", @@ -39744,7 +39744,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">" ], "path": "src/plugins/expressions/common/expression_functions/specs/theme.ts", @@ -40166,7 +40166,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">) => any" ], "path": "src/plugins/expressions/common/expression_functions/specs/var.ts", @@ -40224,7 +40224,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">" ], "path": "src/plugins/expressions/common/expression_functions/specs/var.ts", @@ -40429,7 +40429,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">) => unknown" ], "path": "src/plugins/expressions/common/expression_functions/specs/var_set.ts", @@ -40487,7 +40487,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">" ], "path": "src/plugins/expressions/common/expression_functions/specs/var_set.ts", diff --git a/api_docs/index_lifecycle_management.json b/api_docs/index_lifecycle_management.json index 744bc3f12f3c8..d1d99aa17cff5 100644 --- a/api_docs/index_lifecycle_management.json +++ b/api_docs/index_lifecycle_management.json @@ -24,8 +24,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" } ], "path": "x-pack/plugins/index_lifecycle_management/public/locator.ts", diff --git a/api_docs/kibana_utils.json b/api_docs/kibana_utils.json index fa59e31712129..2bd4e7f310b68 100644 --- a/api_docs/kibana_utils.json +++ b/api_docs/kibana_utils.json @@ -9150,8 +9150,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">) => S" ], @@ -9198,8 +9198,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -10007,8 +10007,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">) => P) | undefined" ], @@ -10037,8 +10037,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -10964,16 +10964,16 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ", version: string) => ", { "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" } ], "path": "src/plugins/kibana_utils/common/persistable_state/types.ts", @@ -11216,16 +11216,16 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | ", { "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableValue", - "text": "SerializableValue" + "section": "def-common.SerializableRecord", + "text": "SerializableRecord" }, "[] | null | undefined" ], @@ -11235,10 +11235,10 @@ }, { "parentPluginId": "kibanaUtils", - "id": "def-common.SerializableState", + "id": "def-common.Serializable", "type": "Type", "tags": [], - "label": "SerializableState", + "label": "Serializable", "description": [ "\nSerializable state is something is a POJO JavaScript object that can be\nserialized to a JSON string." ], @@ -11259,10 +11259,10 @@ }, { "parentPluginId": "kibanaUtils", - "id": "def-common.SerializableValue", + "id": "def-common.SerializableRecord", "type": "Type", "tags": [], - "label": "SerializableValue", + "label": "SerializableRecord", "description": [], "signature": [ "string | number | boolean | ", @@ -11270,8 +11270,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | null | undefined" ], diff --git a/api_docs/lens.json b/api_docs/lens.json index 34408d962cead..0e4b2aee2ac2b 100644 --- a/api_docs/lens.json +++ b/api_docs/lens.json @@ -2742,8 +2742,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, " | undefined; }> | Output>>; readonly fork: () => ", { diff --git a/api_docs/presentation_util.json b/api_docs/presentation_util.json index d062fa63965e7..e14e04794e022 100644 --- a/api_docs/presentation_util.json +++ b/api_docs/presentation_util.json @@ -598,7 +598,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">) => any" ], "path": "src/plugins/presentation_util/common/lib/test_helpers/function_wrapper.ts", diff --git a/api_docs/share.json b/api_docs/share.json index d9b0ba64d94ce..826348efb8eb8 100644 --- a/api_docs/share.json +++ b/api_docs/share.json @@ -437,8 +437,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">(locator: ", { @@ -1884,8 +1884,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">(locator: ", { diff --git a/api_docs/ui_actions_enhanced.json b/api_docs/ui_actions_enhanced.json index 697231e9f7935..0847694c73025 100644 --- a/api_docs/ui_actions_enhanced.json +++ b/api_docs/ui_actions_enhanced.json @@ -1566,8 +1566,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">, triggers: string[]) => Promise" ], @@ -1596,8 +1596,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -1647,8 +1647,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">, triggers: string[]) => Promise" ], @@ -1693,8 +1693,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">" ], @@ -1880,8 +1880,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">; }[]>" ], @@ -3132,8 +3132,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ", object, ", { @@ -3366,8 +3366,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">; }" ], @@ -3935,8 +3935,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">; }" ], @@ -4124,8 +4124,8 @@ "pluginId": "kibanaUtils", "scope": "common", "docId": "kibKibanaUtilsPluginApi", - "section": "def-common.SerializableState", - "text": "SerializableState" + "section": "def-common.Serializable", + "text": "Serializable" }, ">; }" ], diff --git a/api_docs/visualizations.json b/api_docs/visualizations.json index c779b4695fde5..655890dd601f2 100644 --- a/api_docs/visualizations.json +++ b/api_docs/visualizations.json @@ -1256,7 +1256,7 @@ "text": "SerializedFieldFormat" }, "> | undefined; source?: string | undefined; sourceParams?: ", - "SerializableState", + "Serializable", " | undefined; }; id: string; name: string; }[]; type: \"datatable\"; rows: Record[]; }" ], "path": "src/plugins/visualizations/common/prepare_log_table.ts", @@ -1651,7 +1651,7 @@ "description": [], "signature": [ "Pick & Pick<{ type: ", { "pluginId": "data", @@ -2075,7 +2075,7 @@ "description": [], "signature": [ "Pick & Pick<{ type: ", { "pluginId": "data", @@ -4881,7 +4881,7 @@ "text": "SerializedFieldFormat" }, "> | undefined; source?: string | undefined; sourceParams?: ", - "SerializableState", + "Serializable", " | undefined; }; id: string; name: string; }[]; type: \"datatable\"; rows: Record[]; }" ], "path": "src/plugins/visualizations/common/prepare_log_table.ts", @@ -4981,7 +4981,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/visualizations/common/expression_functions/range.ts", @@ -5047,7 +5047,7 @@ "text": "Adapters" }, ", ", - "SerializableState", + "Serializable", ">>" ], "path": "src/plugins/visualizations/common/expression_functions/vis_dimension.ts", @@ -5120,7 +5120,7 @@ "description": [], "signature": [ "Pick & Pick<{ type: ", { "pluginId": "data", diff --git a/dev_docs/best_practices.mdx b/dev_docs/best_practices.mdx index d87c6eb618993..0bc86da6998dd 100644 --- a/dev_docs/best_practices.mdx +++ b/dev_docs/best_practices.mdx @@ -171,7 +171,7 @@ Kibana is translated into other languages. Use our i18n utilities to ensure your ## Styleguide -We use es-lint rules when possible, but please review our [styleguide](https://github.com/elastic/kibana/blob/master/STYLEGUIDE.md), which includes recommendations that can't be linted on. +We use es-lint rules when possible, but please review our [styleguide](https://github.com/elastic/kibana/blob/master/STYLEGUIDE.mdx), which includes recommendations that can't be linted on. Es-lint overrides on a per-plugin level are discouraged. diff --git a/dev_docs/dev_welcome.mdx b/dev_docs/dev_welcome.mdx deleted file mode 100644 index cc185e689fa43..0000000000000 --- a/dev_docs/dev_welcome.mdx +++ /dev/null @@ -1,17 +0,0 @@ ---- -id: kibDevDocsWelcome -slug: /kibana-dev-docs/welcome -title: Welcome -summary: Build custom solutions and applications on top of Kibana. -date: 2021-01-02 -tags: ['kibana','dev', 'contributor'] ---- - -Welcome to Kibana's plugin developer documentation! - -Did you know that the vast majority of functionality built inside of Kibana is a plugin? A handful of core services hold the system together, -but it's our vast system of plugin developers that provide the amazing, out of the box, functionality you can use when building your own set of -custom utilities and applications. - -Browse the `Services` section to view all the plugins that offer functionality you can take advantage of, or check out the -`API documentation` to dig into the nitty gritty details of every public plugin API. diff --git a/dev_docs/getting_started/dev_welcome.mdx b/dev_docs/getting_started/dev_welcome.mdx new file mode 100644 index 0000000000000..3d645b4e54d66 --- /dev/null +++ b/dev_docs/getting_started/dev_welcome.mdx @@ -0,0 +1,20 @@ +--- +id: kibDevDocsWelcome +slug: /kibana-dev-docs/welcome +title: Welcome +summary: Build custom solutions and applications on top of Kibana. +date: 2021-01-02 +tags: ['kibana', 'dev', 'contributor'] +--- + +[Kibana](https://www.elastic.co/what-is/kibana) is a pluggable platform that allows users to search, visualize and analyze data in Elasticsearch. + +Kibana ships with many out-of-the-box capabilities that can be extended and enhanced by custom javascript plugins. Developers can also write their own custom applications. + +Recommended next reading: + +1. +2. Create a simple . + +Check out our to dig into the nitty gritty details of +every public plugin API. diff --git a/dev_docs/getting_started/hello_world_generated.png b/dev_docs/getting_started/hello_world_generated.png new file mode 100644 index 0000000000000..57f389389b794 Binary files /dev/null and b/dev_docs/getting_started/hello_world_generated.png differ diff --git a/dev_docs/getting_started/hello_world_manual.png b/dev_docs/getting_started/hello_world_manual.png new file mode 100644 index 0000000000000..bb36aab32f392 Binary files /dev/null and b/dev_docs/getting_started/hello_world_manual.png differ diff --git a/dev_docs/getting_started/hello_world_plugin.mdx b/dev_docs/getting_started/hello_world_plugin.mdx new file mode 100644 index 0000000000000..d3b30b240dedc --- /dev/null +++ b/dev_docs/getting_started/hello_world_plugin.mdx @@ -0,0 +1,157 @@ +--- +id: kibHelloWorldApp +slug: /kibana-dev-docs/hello-world-app +title: Hello World +summary: Build a very basic plugin that registers an application that says "Hello World!". +date: 2021-08-03 +tags: ['kibana', 'dev', 'contributor', 'tutorials'] +--- + +This tutorial walks you through two ways to create a plugin that registers an application that says "Hello World!". + +You can view the tested example plugin at [examples/hello_world](https://github.com/elastic/kibana/tree/master/examples/hello_world). + +## 1. Set up your development environment + +Read through to get your development environment set up. + +## 2. Option 1 - Write it manually + +This is a good option if you want to understand the bare minimum needed to register a "Hello world" application. The example plugin is based off of this option. + +1. Create your plugin folder. Start off in the `kibana` folder. + +``` +$ cd examples +$ mkdir hello_world +$ cd hello_world +``` + +2. Create the . + +``` +$ touch kibana.json +``` + +and add the following: + +``` +{ + "id": "helloWorld", + "version": "1.0.0", + "kibanaVersion": "kibana", + "ui": true +} +``` + +3. Create a `tsconfig.json` file. + +``` +$ touch tsconfig.json +``` + +And add the following to it: + +``` +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": [ + "index.ts", + "common/**/*.ts", + "public/**/*.ts", + "public/**/*.tsx", + "server/**/*.ts", + "../../typings/**/*" + ], + "exclude": [] +} +``` + +4. Create a . + +``` +$ mkdir public +$ touch plugin.tsx +``` + +And add the following to it: + +```ts +import React from 'react'; +import ReactDOM from 'react-dom'; +import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '../../../src/core/public'; + +export class HelloWorldPlugin implements Plugin { + public setup(core: CoreSetup) { + // Register an application into the side navigation menu + core.application.register({ + id: 'helloWorld', + title: 'Hello World', + async mount({ element }: AppMountParameters) { + ReactDOM.render(
Hello World!
, element); + return () => ReactDOM.unmountComponentAtNode(element); + }, + }); + } + public start(core: CoreStart) { + return {}; + } + public stop() {} +} +``` + +5. Create a . + +``` +$ touch index.ts +``` + +```ts +import { HelloWorldPlugin } from './plugin'; + +export function plugin() { + return new HelloWorldPlugin(); +} +``` + +## 2. Option 2 - Use the automatic plugin generator + +This is an easy option to get up and running ASAP and includes additional code. + +Use the Automatic plugin generator to get a basic structure for a new plugin. Plugins that are not part of the Kibana repo should be developed inside the plugins folder. If you are building a new plugin to check in to the Kibana repo, you will choose between a few locations: + +`x-pack/plugins` for plugins related to subscription features +`src/plugins` for plugins related to free features +`examples` for developer example plugins (these will not be included in the distributables) + +``` +% node scripts/generate_plugin hello_world +? Plugin name (use camelCase) helloWorld +? Will this plugin be part of the Kibana repository? Yes +? What type of internal plugin would you like to create Kibana Example +? Should an UI plugin be generated? Yes +? Should a server plugin be generated? No + succ 🎉 + + Your plugin has been created in examples/hello_world +``` + +## 3. Build your new application + +Run `yarn kbn bootstrap` + +## 3. Start Kibana with examples and navigate to your new application + +In one terminal window, run `yarn es snapshot --license trial` to boot up Elasticsearch. + +In another terminal window, run `yarn start --run-examples` to boot up Kibana and include the example plugins. Your example plugin should show up in the navigation at the very bottom. + +If you build it manually it will look something like this: +![hello world manual](./hello_world_manual.png) + +If you built it with the generator, it will look something like this: +![hello world generated](./hello_world_generated.png) diff --git a/dev_docs/tutorials/setting_up_a_development_env.mdx b/dev_docs/getting_started/setting_up_a_development_env.mdx similarity index 87% rename from dev_docs/tutorials/setting_up_a_development_env.mdx rename to dev_docs/getting_started/setting_up_a_development_env.mdx index 449e8b886a44d..04e0511e255b1 100644 --- a/dev_docs/tutorials/setting_up_a_development_env.mdx +++ b/dev_docs/getting_started/setting_up_a_development_env.mdx @@ -1,8 +1,8 @@ --- id: kibDevTutorialSetupDevEnv slug: /kibana-dev-docs/tutorial/setup-dev-env -title: Setting up a Development Environment -summary: Learn how to setup a development environemnt for contributing to the Kibana repository +title: Set up a Development Environment +summary: Learn how to setup a development environment for contributing to the Kibana repository date: 2021-04-26 tags: ['kibana', 'onboarding', 'dev', 'architecture', 'setup'] --- @@ -12,11 +12,11 @@ Setting up a development environment is pretty easy. In order to support Windows development we currently require you to use one of the following: - - [Git Bash](https://git-scm.com/download/win) - - [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about) +- [Git Bash](https://git-scm.com/download/win) +- [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about) +Before running the steps below, please make sure you have installed [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145) and that you are running all commands in either Git Bash or WSL. - Before running the steps below, please make sure you have installed [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145) and that you are running all commands in either Git Bash or WSL. ## Get the code diff --git a/dev_docs/tutorials/building_a_plugin.mdx b/dev_docs/key_concepts/anatomy_of_a_plugin.mdx similarity index 67% rename from dev_docs/tutorials/building_a_plugin.mdx rename to dev_docs/key_concepts/anatomy_of_a_plugin.mdx index e751ce7d01b16..4ff5e403ff851 100644 --- a/dev_docs/tutorials/building_a_plugin.mdx +++ b/dev_docs/key_concepts/anatomy_of_a_plugin.mdx @@ -1,13 +1,13 @@ --- id: kibDevTutorialBuildAPlugin -slug: /kibana-dev-docs/tutorials/build-a-plugin -title: Kibana plugin tutorial -summary: Anatomy of a Kibana plugin and how to build one -date: 2021-02-05 -tags: ['kibana', 'onboarding', 'dev', 'tutorials'] +slug: /kibana-dev-docs/tutorials/anatomy-of-a-plugin +title: Anatomy of a plugin +summary: Anatomy of a Kibana plugin. +date: 2021-08-03 +tags: ['kibana', 'onboarding', 'dev'] --- -Prereading material: +Pre-reading material: - @@ -39,27 +39,50 @@ plugins/ ``` { - "id": "demo", - "version": "kibana", + "id": "examplePluginId", + "version": "1.0.0", + "kibanaVersion": "7.14.0", "server": true, "ui": true, - "owner": { [1] + "configPath": "path/to/config", + "type": "standard", + "owner": { "name": "App Services", "githubTeam": "kibana-app-services" }, - "description": "This plugin extends Kibana by doing xyz, and allows other plugins to extend Kibana by offering abc functionality. It also exposes some helper utilities that do efg", [2] - "requiredPlugins": ["data"], [3] - "optionalPlugins": ["alerting"] [4] - "requiredBundles": ["anotherPlugin"] [5] + "description": "A description about this plugin!", + "requiredPlugins": ["data"], + "optionalPlugins": ["alerting"] + "requiredBundles": ["anotherPlugin"] } ``` -[1], [2]: Every internal plugin should fill in the owner and description properties. +`id` - [Required] The id of your plugin can be anything, though it should be fairly unique, as every plugin in an installation needs to be unique. It must be snakeCase. + +`version` - [Required] Note the version of your plugin. For internal plugins that don't specify a `kibanaVersion`, this will have to match the version of Kibana or ci will fail. Because teams won't want to be bumping this number for every release, internal plugins should set `kibanaVersion` to "kibana", and set this to anything. + +`kibanaVersion` - [Optional] If your plugin is only compatible with a specific version of Kibana, put it here. Internal, first-party plugins should set this to "kibana", otherwise they will need to bump this value, or the one in `version`, every time the Kibana version is bumped. When [#61087](https://github.com/elastic/kibana/issues/61087) is fixed, we will stop requiring this field for internal plugins. + +`server` - [Optional] If your plugin contains server-side code, this must be true. + +`ui` - [Optional] If your plugin contains client-side code, this must be true. + +`configPath` - [Optional] Every plugin might allow Kibana users to adjust configuration via kibana.yml file. If your plugin needs to read config from `kibana.yml , you should declare what property name it should have access to. + +`type` - [Optional] Should be either `preboot` or `standard` which specifies the type of plugin. Default value, if unspecified, is `standard`. There are two types of plugins: + +- preboot plugins are bootstrapped to prepare the environment before Kibana starts. +- standard plugins define Kibana functionality while Kibana is running. + +`owner` - [Required] Help users of your plugin know who manages this plugin and how to get in touch. This is required for internal plugins. `Owner.name` should be the name of the team that manages this plugin. This should match the team that owns this code in the [CODEOWNERS](https://github.com/elastic/kibana/blob/master/.github/CODEOWNERS) file (however, this is not currently enforced). Internal teams should also use a [GitHub team alias](https://github.com/orgs/elastic/teams) for `owner.githubTeam`. While many teams can contribute to a plugin, only a single team should be the primary owner. + +`description` - [Required] Give your plugin a description to help other developers understand what it does. This is required for internal plugins. -[3], [4]: Any plugin that you have a dependency on should be listed in `requiredPlugins` or `optionalPlugins`. Doing this will ensure that you have access to that plugin's start and setup contract inside your own plugin's start and setup lifecycle methods. If a plugin you optionally depend on is not installed or disabled, it will be undefined if you try to access it. If a plugin you require is not installed or disabled, kibana will fail to build. +`requiredPlugins` - [Optional] If your plugin requires any other plugins to work, you must list them here by id. If any of the required plugins are disabled or not installed, then your plugin will be disabled. -[5]: Don't worry too much about getting 5 right. The build optimizer will complain if any of these values are incorrect. +`optionalPlugins` - [Optional] If your plugin has an optional dependency on other plugins, you must list them here by id. If any of the optional plugins are disabled or not installed, your plugin will still load, however that plugin's API contract will be undefined in the second parameter of the setup and start functions. +`requiredBundles` - [Required in certain situations] Don't worry about getting this right. The build optimizer will complain if any of these values are incorrect. You don't need to declare a dependency on a plugin if you only wish to access its types. @@ -233,7 +256,7 @@ With that specified in the plugin manifest, the appropriate interfaces are then import type { CoreSetup, CoreStart } from 'kibana/server'; import type { FoobarPluginSetup, FoobarPluginStart } from '../../foobar/server'; -interface DemoSetupPlugins { [1] +interface DemoSetupPlugins { [1]; foobar: FoobarPluginSetup; } @@ -242,13 +265,13 @@ interface DemoStartPlugins { } export class DemoPlugin { - public setup(core: CoreSetup, plugins: DemoSetupPlugins) { [2] + public setup(core: CoreSetup, plugins: DemoSetupPlugins) { [2]; const { foobar } = plugins; foobar.getFoo(); // 'foo' foobar.getBar(); // throws because getBar does not exist } - public start(core: CoreStart, plugins: DemoStartPlugins) { [3] + public start(core: CoreStart, plugins: DemoStartPlugins) { [3]; const { foobar } = plugins; foobar.getFoo(); // throws because getFoo does not exist foobar.getBar(); // 'bar' diff --git a/docs/developer/best-practices/index.asciidoc b/docs/developer/best-practices/index.asciidoc index b048e59e6c98c..04422a613475a 100644 --- a/docs/developer/best-practices/index.asciidoc +++ b/docs/developer/best-practices/index.asciidoc @@ -45,7 +45,7 @@ guidelines] === Conventions * Become familiar with our -{kib-repo}blob/{branch}/STYLEGUIDE.md[styleguide] +{kib-repo}blob/{branch}/STYLEGUIDE.mdx[styleguide] (use Typescript!) * Write all new code on {kib-repo}blob/{branch}/src/core/README.md[the diff --git a/docs/developer/contributing/linting.asciidoc b/docs/developer/contributing/linting.asciidoc index eb7c22c517e4b..144e23c228535 100644 --- a/docs/developer/contributing/linting.asciidoc +++ b/docs/developer/contributing/linting.asciidoc @@ -2,7 +2,7 @@ == Linting A note about linting: We use http://eslint.org[eslint] to check that the -link:STYLEGUIDE.md[styleguide] is being followed. It runs in a +link:STYLEGUIDE.mdx[styleguide] is being followed. It runs in a pre-commit hook and as a part of the tests, but most contributors integrate it with their code editors for real-time feedback. diff --git a/docs/developer/contributing/pr-review.asciidoc b/docs/developer/contributing/pr-review.asciidoc index 885725795b0b9..95f012d569c3a 100644 --- a/docs/developer/contributing/pr-review.asciidoc +++ b/docs/developer/contributing/pr-review.asciidoc @@ -75,7 +75,7 @@ Reviewers are not simply evaluating the code itself, they are also evaluating th Having a relatively consistent codebase is an important part of us building a sustainable project. With dozens of active contributors at any given time, we rely on automation to help ensure consistency - we enforce a comprehensive set of linting rules through CI. We're also rolling out prettier to make this even more automatic. -For things that can't be easily automated, we maintain a link:{kib-repo}tree/{branch}/STYLEGUIDE.md[style guide] that authors should adhere to and reviewers should keep in mind when they review a pull request. +For things that can't be easily automated, we maintain a link:{kib-repo}tree/{branch}/STYLEGUIDE.mdx[style guide] that authors should adhere to and reviewers should keep in mind when they review a pull request. Beyond that, we're into subjective territory. Statements like "this isn't very readable" are hardly helpful since they can't be qualified, but that doesn't mean a reviewer should outright ignore code that is hard to understand due to how it is written. There isn't one definitively "best" way to write any particular code, so pursuing such shouldn't be our goal. Instead, reviewers and authors alike must accept that there are likely many different appropriate ways to accomplish the same thing with code, and so long as the contribution is utilizing one of those ways, then we're in good shape. diff --git a/docs/development/core/public/kibana-plugin-core-public.corestart.executioncontext.md b/docs/development/core/public/kibana-plugin-core-public.corestart.executioncontext.md deleted file mode 100644 index 66c5f3efa2d84..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.corestart.executioncontext.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [CoreStart](./kibana-plugin-core-public.corestart.md) > [executionContext](./kibana-plugin-core-public.corestart.executioncontext.md) - -## CoreStart.executionContext property - -[ExecutionContextServiceStart](./kibana-plugin-core-public.executioncontextservicestart.md) - -Signature: - -```typescript -executionContext: ExecutionContextServiceStart; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.corestart.md b/docs/development/core/public/kibana-plugin-core-public.corestart.md index df1929b1f20ab..6ad9adca53ef5 100644 --- a/docs/development/core/public/kibana-plugin-core-public.corestart.md +++ b/docs/development/core/public/kibana-plugin-core-public.corestart.md @@ -20,7 +20,6 @@ export interface CoreStart | [chrome](./kibana-plugin-core-public.corestart.chrome.md) | ChromeStart | [ChromeStart](./kibana-plugin-core-public.chromestart.md) | | [deprecations](./kibana-plugin-core-public.corestart.deprecations.md) | DeprecationsServiceStart | [DeprecationsServiceStart](./kibana-plugin-core-public.deprecationsservicestart.md) | | [docLinks](./kibana-plugin-core-public.corestart.doclinks.md) | DocLinksStart | [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) | -| [executionContext](./kibana-plugin-core-public.corestart.executioncontext.md) | ExecutionContextServiceStart | [ExecutionContextServiceStart](./kibana-plugin-core-public.executioncontextservicestart.md) | | [fatalErrors](./kibana-plugin-core-public.corestart.fatalerrors.md) | FatalErrorsStart | [FatalErrorsStart](./kibana-plugin-core-public.fatalerrorsstart.md) | | [http](./kibana-plugin-core-public.corestart.http.md) | HttpStart | [HttpStart](./kibana-plugin-core-public.httpstart.md) | | [i18n](./kibana-plugin-core-public.corestart.i18n.md) | I18nStart | [I18nStart](./kibana-plugin-core-public.i18nstart.md) | diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextservicestart.create.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextservicestart.create.md deleted file mode 100644 index b36f8ade848e5..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextservicestart.create.md +++ /dev/null @@ -1,19 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextServiceStart](./kibana-plugin-core-public.executioncontextservicestart.md) > [create](./kibana-plugin-core-public.executioncontextservicestart.create.md) - -## ExecutionContextServiceStart.create property - -Creates a context container carrying the meta-data of a runtime operation. Provided meta-data will be propagated to Kibana and Elasticsearch servers. - -```js -const context = executionContext.create(...); -http.fetch('/endpoint/', { context }); - -``` - -Signature: - -```typescript -create: (context: KibanaExecutionContext) => IExecutionContextContainer; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextservicestart.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextservicestart.md deleted file mode 100644 index d3eecf601ba9c..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextservicestart.md +++ /dev/null @@ -1,25 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextServiceStart](./kibana-plugin-core-public.executioncontextservicestart.md) - -## ExecutionContextServiceStart interface - - -Signature: - -```typescript -export interface ExecutionContextServiceStart -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [create](./kibana-plugin-core-public.executioncontextservicestart.create.md) | (context: KibanaExecutionContext) => IExecutionContextContainer | Creates a context container carrying the meta-data of a runtime operation. Provided meta-data will be propagated to Kibana and Elasticsearch servers. -```js -const context = executionContext.create(...); -http.fetch('/endpoint/', { context }); - -``` - | - diff --git a/docs/development/core/public/kibana-plugin-core-public.httpfetchoptions.context.md b/docs/development/core/public/kibana-plugin-core-public.httpfetchoptions.context.md index 6c6ce3171aaeb..09ab95a5135f6 100644 --- a/docs/development/core/public/kibana-plugin-core-public.httpfetchoptions.context.md +++ b/docs/development/core/public/kibana-plugin-core-public.httpfetchoptions.context.md @@ -7,5 +7,5 @@ Signature: ```typescript -context?: IExecutionContextContainer; +context?: KibanaExecutionContext; ``` diff --git a/docs/development/core/public/kibana-plugin-core-public.httpfetchoptions.md b/docs/development/core/public/kibana-plugin-core-public.httpfetchoptions.md index 020a941189013..45a48372b4512 100644 --- a/docs/development/core/public/kibana-plugin-core-public.httpfetchoptions.md +++ b/docs/development/core/public/kibana-plugin-core-public.httpfetchoptions.md @@ -18,7 +18,7 @@ export interface HttpFetchOptions extends HttpRequestInit | --- | --- | --- | | [asResponse](./kibana-plugin-core-public.httpfetchoptions.asresponse.md) | boolean | When true the return type of [HttpHandler](./kibana-plugin-core-public.httphandler.md) will be an [HttpResponse](./kibana-plugin-core-public.httpresponse.md) with detailed request and response information. When false, the return type will just be the parsed response body. Defaults to false. | | [asSystemRequest](./kibana-plugin-core-public.httpfetchoptions.assystemrequest.md) | boolean | Whether or not the request should include the "system request" header to differentiate an end user request from Kibana internal request. Can be read on the server-side using KibanaRequest\#isSystemRequest. Defaults to false. | -| [context](./kibana-plugin-core-public.httpfetchoptions.context.md) | IExecutionContextContainer | | +| [context](./kibana-plugin-core-public.httpfetchoptions.context.md) | KibanaExecutionContext | | | [headers](./kibana-plugin-core-public.httpfetchoptions.headers.md) | HttpHeadersInit | Headers to send with the request. See [HttpHeadersInit](./kibana-plugin-core-public.httpheadersinit.md). | | [prependBasePath](./kibana-plugin-core-public.httpfetchoptions.prependbasepath.md) | boolean | Whether or not the request should automatically prepend the basePath. Defaults to true. | | [query](./kibana-plugin-core-public.httpfetchoptions.query.md) | HttpFetchQuery | The query string for an HTTP request. See [HttpFetchQuery](./kibana-plugin-core-public.httpfetchquery.md). | diff --git a/docs/development/core/public/kibana-plugin-core-public.iexecutioncontextcontainer.md b/docs/development/core/public/kibana-plugin-core-public.iexecutioncontextcontainer.md deleted file mode 100644 index 96ca86cffbc5f..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.iexecutioncontextcontainer.md +++ /dev/null @@ -1,20 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [IExecutionContextContainer](./kibana-plugin-core-public.iexecutioncontextcontainer.md) - -## IExecutionContextContainer interface - - -Signature: - -```typescript -export interface IExecutionContextContainer -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [toHeader](./kibana-plugin-core-public.iexecutioncontextcontainer.toheader.md) | () => Record<string, string> | | -| [toJSON](./kibana-plugin-core-public.iexecutioncontextcontainer.tojson.md) | () => Readonly<KibanaExecutionContext> | | - diff --git a/docs/development/core/public/kibana-plugin-core-public.iexecutioncontextcontainer.toheader.md b/docs/development/core/public/kibana-plugin-core-public.iexecutioncontextcontainer.toheader.md deleted file mode 100644 index 03132d24bcca5..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.iexecutioncontextcontainer.toheader.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [IExecutionContextContainer](./kibana-plugin-core-public.iexecutioncontextcontainer.md) > [toHeader](./kibana-plugin-core-public.iexecutioncontextcontainer.toheader.md) - -## IExecutionContextContainer.toHeader property - -Signature: - -```typescript -toHeader: () => Record; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.iexecutioncontextcontainer.tojson.md b/docs/development/core/public/kibana-plugin-core-public.iexecutioncontextcontainer.tojson.md deleted file mode 100644 index 916148141c8f3..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.iexecutioncontextcontainer.tojson.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [IExecutionContextContainer](./kibana-plugin-core-public.iexecutioncontextcontainer.md) > [toJSON](./kibana-plugin-core-public.iexecutioncontextcontainer.tojson.md) - -## IExecutionContextContainer.toJSON property - -Signature: - -```typescript -toJSON: () => Readonly; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.description.md b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.description.md deleted file mode 100644 index ea8c543c6789e..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.description.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [KibanaExecutionContext](./kibana-plugin-core-public.kibanaexecutioncontext.md) > [description](./kibana-plugin-core-public.kibanaexecutioncontext.description.md) - -## KibanaExecutionContext.description property - -human readable description. For example, a vis title, action name - -Signature: - -```typescript -readonly description: string; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.id.md b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.id.md deleted file mode 100644 index d17f9cb8a7ff3..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.id.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [KibanaExecutionContext](./kibana-plugin-core-public.kibanaexecutioncontext.md) > [id](./kibana-plugin-core-public.kibanaexecutioncontext.id.md) - -## KibanaExecutionContext.id property - -unique value to identify the source - -Signature: - -```typescript -readonly id: string; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md index 06154c814c4e7..8b758715a1975 100644 --- a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md @@ -2,22 +2,19 @@ [Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [KibanaExecutionContext](./kibana-plugin-core-public.kibanaexecutioncontext.md) -## KibanaExecutionContext interface +## KibanaExecutionContext type +Represents a meta-information about a Kibana entity initiating a search request. Signature: ```typescript -export interface KibanaExecutionContext +export declare type KibanaExecutionContext = { + readonly type: string; + readonly name: string; + readonly id: string; + readonly description: string; + readonly url?: string; + parent?: KibanaExecutionContext; +}; ``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [description](./kibana-plugin-core-public.kibanaexecutioncontext.description.md) | string | human readable description. For example, a vis title, action name | -| [id](./kibana-plugin-core-public.kibanaexecutioncontext.id.md) | string | unique value to identify the source | -| [name](./kibana-plugin-core-public.kibanaexecutioncontext.name.md) | string | public name of a user-facing feature | -| [type](./kibana-plugin-core-public.kibanaexecutioncontext.type.md) | string | Kibana application initated an operation. | -| [url](./kibana-plugin-core-public.kibanaexecutioncontext.url.md) | string | in browser - url to navigate to a current page, on server - endpoint path, for task: task SO url | - diff --git a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.name.md b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.name.md deleted file mode 100644 index 21dde32e21ce7..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.name.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [KibanaExecutionContext](./kibana-plugin-core-public.kibanaexecutioncontext.md) > [name](./kibana-plugin-core-public.kibanaexecutioncontext.name.md) - -## KibanaExecutionContext.name property - -public name of a user-facing feature - -Signature: - -```typescript -readonly name: string; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.type.md b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.type.md deleted file mode 100644 index 48009ebaaeaa5..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.type.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [KibanaExecutionContext](./kibana-plugin-core-public.kibanaexecutioncontext.md) > [type](./kibana-plugin-core-public.kibanaexecutioncontext.type.md) - -## KibanaExecutionContext.type property - -Kibana application initated an operation. - -Signature: - -```typescript -readonly type: string; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.url.md b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.url.md deleted file mode 100644 index 47ad7604b473d..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.url.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [KibanaExecutionContext](./kibana-plugin-core-public.kibanaexecutioncontext.md) > [url](./kibana-plugin-core-public.kibanaexecutioncontext.url.md) - -## KibanaExecutionContext.url property - -in browser - url to navigate to a current page, on server - endpoint path, for task: task SO url - -Signature: - -```typescript -readonly url?: string; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.md b/docs/development/core/public/kibana-plugin-core-public.md index d743508e046ea..e984fbb675e6d 100644 --- a/docs/development/core/public/kibana-plugin-core-public.md +++ b/docs/development/core/public/kibana-plugin-core-public.md @@ -63,7 +63,6 @@ The plugin integrates with the core system via lifecycle events: `setup` | [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) | | | [DomainDeprecationDetails](./kibana-plugin-core-public.domaindeprecationdetails.md) | | | [ErrorToastOptions](./kibana-plugin-core-public.errortoastoptions.md) | Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) error APIs. | -| [ExecutionContextServiceStart](./kibana-plugin-core-public.executioncontextservicestart.md) | | | [FatalErrorInfo](./kibana-plugin-core-public.fatalerrorinfo.md) | Represents the message and stack of a fatal Error | | [FatalErrorsSetup](./kibana-plugin-core-public.fatalerrorssetup.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. | | [HttpFetchOptions](./kibana-plugin-core-public.httpfetchoptions.md) | All options that may be used with a [HttpHandler](./kibana-plugin-core-public.httphandler.md). | @@ -80,14 +79,12 @@ The plugin integrates with the core system via lifecycle events: `setup` | [I18nStart](./kibana-plugin-core-public.i18nstart.md) | I18nStart.Context is required by any localizable React component from @kbn/i18n and @elastic/eui packages and is supposed to be used as the topmost component for any i18n-compatible React tree. | | [IAnonymousPaths](./kibana-plugin-core-public.ianonymouspaths.md) | APIs for denoting paths as not requiring authentication | | [IBasePath](./kibana-plugin-core-public.ibasepath.md) | APIs for manipulating the basePath on URL segments. | -| [IExecutionContextContainer](./kibana-plugin-core-public.iexecutioncontextcontainer.md) | | | [IExternalUrl](./kibana-plugin-core-public.iexternalurl.md) | APIs for working with external URLs. | | [IExternalUrlPolicy](./kibana-plugin-core-public.iexternalurlpolicy.md) | A policy describing whether access to an external destination is allowed. | | [IHttpFetchError](./kibana-plugin-core-public.ihttpfetcherror.md) | | | [IHttpInterceptController](./kibana-plugin-core-public.ihttpinterceptcontroller.md) | Used to halt a request Promise chain in a [HttpInterceptor](./kibana-plugin-core-public.httpinterceptor.md). | | [IHttpResponseInterceptorOverrides](./kibana-plugin-core-public.ihttpresponseinterceptoroverrides.md) | Properties that can be returned by HttpInterceptor.request to override the response. | | [IUiSettingsClient](./kibana-plugin-core-public.iuisettingsclient.md) | Client-side client that provides access to the advanced settings stored in elasticsearch. The settings provide control over the behavior of the Kibana application. For example, a user can specify how to display numeric or date fields. Users can adjust the settings via Management UI. [IUiSettingsClient](./kibana-plugin-core-public.iuisettingsclient.md) | -| [KibanaExecutionContext](./kibana-plugin-core-public.kibanaexecutioncontext.md) | | | [NavigateToAppOptions](./kibana-plugin-core-public.navigatetoappoptions.md) | Options for the [navigateToApp API](./kibana-plugin-core-public.applicationstart.navigatetoapp.md) | | [NotificationsSetup](./kibana-plugin-core-public.notificationssetup.md) | | | [NotificationsStart](./kibana-plugin-core-public.notificationsstart.md) | | @@ -162,6 +159,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [FatalErrorsStart](./kibana-plugin-core-public.fatalerrorsstart.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. | | [HttpStart](./kibana-plugin-core-public.httpstart.md) | See [HttpSetup](./kibana-plugin-core-public.httpsetup.md) | | [IToasts](./kibana-plugin-core-public.itoasts.md) | Methods for adding and removing global toast messages. See [ToastsApi](./kibana-plugin-core-public.toastsapi.md). | +| [KibanaExecutionContext](./kibana-plugin-core-public.kibanaexecutioncontext.md) | Represents a meta-information about a Kibana entity initiating a search request. | | [MountPoint](./kibana-plugin-core-public.mountpoint.md) | A function that should mount DOM content inside the provided container element and return a handler to unmount it. | | [NavType](./kibana-plugin-core-public.navtype.md) | | | [PluginInitializer](./kibana-plugin-core-public.plugininitializer.md) | The plugin export at the root of a plugin's public directory should conform to this interface. | diff --git a/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.get.md b/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.get.md deleted file mode 100644 index d152b9a0c5df2..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.get.md +++ /dev/null @@ -1,17 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ExecutionContextSetup](./kibana-plugin-core-server.executioncontextsetup.md) > [get](./kibana-plugin-core-server.executioncontextsetup.get.md) - -## ExecutionContextSetup.get() method - -Retrieves an opearation meta-data for the current async context. - -Signature: - -```typescript -get(): IExecutionContextContainer | undefined; -``` -Returns: - -`IExecutionContextContainer | undefined` - diff --git a/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.md b/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.md index 137df77769c8d..24591648ad953 100644 --- a/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.md @@ -15,6 +15,5 @@ export interface ExecutionContextSetup | Method | Description | | --- | --- | -| [get()](./kibana-plugin-core-server.executioncontextsetup.get.md) | Retrieves an opearation meta-data for the current async context. | -| [set(context)](./kibana-plugin-core-server.executioncontextsetup.set.md) | Stores the meta-data of a runtime operation. Data are carried over all async operations automatically. The sequential calls merge provided "context" object shallowly. | +| [withContext(context, fn)](./kibana-plugin-core-server.executioncontextsetup.withcontext.md) | Keeps track of execution context while the passed function is executed. Data are carried over all async operations spawned by the passed function. The nested calls stack the registered context on top of each other. | diff --git a/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.set.md b/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.set.md deleted file mode 100644 index 4c8ba4d21b8c4..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.set.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ExecutionContextSetup](./kibana-plugin-core-server.executioncontextsetup.md) > [set](./kibana-plugin-core-server.executioncontextsetup.set.md) - -## ExecutionContextSetup.set() method - -Stores the meta-data of a runtime operation. Data are carried over all async operations automatically. The sequential calls merge provided "context" object shallowly. - -Signature: - -```typescript -set(context: Partial): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| context | Partial<KibanaServerExecutionContext> | | - -Returns: - -`void` - diff --git a/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.withcontext.md b/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.withcontext.md new file mode 100644 index 0000000000000..87da071203018 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.withcontext.md @@ -0,0 +1,25 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ExecutionContextSetup](./kibana-plugin-core-server.executioncontextsetup.md) > [withContext](./kibana-plugin-core-server.executioncontextsetup.withcontext.md) + +## ExecutionContextSetup.withContext() method + +Keeps track of execution context while the passed function is executed. Data are carried over all async operations spawned by the passed function. The nested calls stack the registered context on top of each other. + +Signature: + +```typescript +withContext(context: KibanaExecutionContext | undefined, fn: (...args: any[]) => R): R; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | KibanaExecutionContext | undefined | | +| fn | (...args: any[]) => R | | + +Returns: + +`R` + diff --git a/docs/development/core/server/kibana-plugin-core-server.iexecutioncontextcontainer.tojson.md b/docs/development/core/server/kibana-plugin-core-server.iexecutioncontextcontainer.tojson.md index f67aa88862fee..6b643f7f72c95 100644 --- a/docs/development/core/server/kibana-plugin-core-server.iexecutioncontextcontainer.tojson.md +++ b/docs/development/core/server/kibana-plugin-core-server.iexecutioncontextcontainer.tojson.md @@ -7,9 +7,9 @@ Signature: ```typescript -toJSON(): Readonly; +toJSON(): Readonly; ``` Returns: -`Readonly` +`Readonly` diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.description.md b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.description.md deleted file mode 100644 index 00c907b578cf3..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.description.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [KibanaExecutionContext](./kibana-plugin-core-server.kibanaexecutioncontext.md) > [description](./kibana-plugin-core-server.kibanaexecutioncontext.description.md) - -## KibanaExecutionContext.description property - -human readable description. For example, a vis title, action name - -Signature: - -```typescript -readonly description: string; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.id.md b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.id.md deleted file mode 100644 index 4ade96691fb14..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.id.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [KibanaExecutionContext](./kibana-plugin-core-server.kibanaexecutioncontext.md) > [id](./kibana-plugin-core-server.kibanaexecutioncontext.id.md) - -## KibanaExecutionContext.id property - -unique value to identify the source - -Signature: - -```typescript -readonly id: string; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md index c21eb1110ed8e..db06f9b13f9f6 100644 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md +++ b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md @@ -2,22 +2,19 @@ [Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [KibanaExecutionContext](./kibana-plugin-core-server.kibanaexecutioncontext.md) -## KibanaExecutionContext interface +## KibanaExecutionContext type +Represents a meta-information about a Kibana entity initiating a search request. Signature: ```typescript -export interface KibanaExecutionContext +export declare type KibanaExecutionContext = { + readonly type: string; + readonly name: string; + readonly id: string; + readonly description: string; + readonly url?: string; + parent?: KibanaExecutionContext; +}; ``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [description](./kibana-plugin-core-server.kibanaexecutioncontext.description.md) | string | human readable description. For example, a vis title, action name | -| [id](./kibana-plugin-core-server.kibanaexecutioncontext.id.md) | string | unique value to identify the source | -| [name](./kibana-plugin-core-server.kibanaexecutioncontext.name.md) | string | public name of a user-facing feature | -| [type](./kibana-plugin-core-server.kibanaexecutioncontext.type.md) | string | Kibana application initated an operation. | -| [url](./kibana-plugin-core-server.kibanaexecutioncontext.url.md) | string | in browser - url to navigate to a current page, on server - endpoint path, for task: task SO url | - diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.name.md b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.name.md deleted file mode 100644 index 92f58c01bcc11..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.name.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [KibanaExecutionContext](./kibana-plugin-core-server.kibanaexecutioncontext.md) > [name](./kibana-plugin-core-server.kibanaexecutioncontext.name.md) - -## KibanaExecutionContext.name property - -public name of a user-facing feature - -Signature: - -```typescript -readonly name: string; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.type.md b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.type.md deleted file mode 100644 index 6941bb150efdd..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.type.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [KibanaExecutionContext](./kibana-plugin-core-server.kibanaexecutioncontext.md) > [type](./kibana-plugin-core-server.kibanaexecutioncontext.type.md) - -## KibanaExecutionContext.type property - -Kibana application initated an operation. - -Signature: - -```typescript -readonly type: string; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.url.md b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.url.md deleted file mode 100644 index dee241cd79398..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.url.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [KibanaExecutionContext](./kibana-plugin-core-server.kibanaexecutioncontext.md) > [url](./kibana-plugin-core-server.kibanaexecutioncontext.url.md) - -## KibanaExecutionContext.url property - -in browser - url to navigate to a current page, on server - endpoint path, for task: task SO url - -Signature: - -```typescript -readonly url?: string; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaserverexecutioncontext.md b/docs/development/core/server/kibana-plugin-core-server.kibanaserverexecutioncontext.md deleted file mode 100644 index f309e4fd0006c..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaserverexecutioncontext.md +++ /dev/null @@ -1,19 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [KibanaServerExecutionContext](./kibana-plugin-core-server.kibanaserverexecutioncontext.md) - -## KibanaServerExecutionContext interface - - -Signature: - -```typescript -export interface KibanaServerExecutionContext extends Partial -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [requestId](./kibana-plugin-core-server.kibanaserverexecutioncontext.requestid.md) | string | | - diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaserverexecutioncontext.requestid.md b/docs/development/core/server/kibana-plugin-core-server.kibanaserverexecutioncontext.requestid.md deleted file mode 100644 index dff3fd7f2e9ff..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaserverexecutioncontext.requestid.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [KibanaServerExecutionContext](./kibana-plugin-core-server.kibanaserverexecutioncontext.md) > [requestId](./kibana-plugin-core-server.kibanaserverexecutioncontext.requestid.md) - -## KibanaServerExecutionContext.requestId property - -Signature: - -```typescript -requestId: string; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index a3f925151af61..c459a48c1ca42 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -110,10 +110,8 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ISavedObjectsPointInTimeFinder](./kibana-plugin-core-server.isavedobjectspointintimefinder.md) | | | [IScopedClusterClient](./kibana-plugin-core-server.iscopedclusterclient.md) | Serves the same purpose as the normal [cluster client](./kibana-plugin-core-server.iclusterclient.md) but exposes an additional asCurrentUser method that doesn't use credentials of the Kibana internal user (as asInternalUser does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API instead. | | [IUiSettingsClient](./kibana-plugin-core-server.iuisettingsclient.md) | Server-side client that provides access to the advanced settings stored in elasticsearch. The settings provide control over the behavior of the Kibana application. For example, a user can specify how to display numeric or date fields. Users can adjust the settings via Management UI. | -| [KibanaExecutionContext](./kibana-plugin-core-server.kibanaexecutioncontext.md) | | | [KibanaRequestEvents](./kibana-plugin-core-server.kibanarequestevents.md) | Request events. | | [KibanaRequestRoute](./kibana-plugin-core-server.kibanarequestroute.md) | Request specific route information exposed to a handler. | -| [KibanaServerExecutionContext](./kibana-plugin-core-server.kibanaserverexecutioncontext.md) | | | [LegacyAPICaller](./kibana-plugin-core-server.legacyapicaller.md) | | | [LegacyCallAPIOptions](./kibana-plugin-core-server.legacycallapioptions.md) | The set of options that defines how API call should be made and result be processed. | | [LegacyElasticsearchError](./kibana-plugin-core-server.legacyelasticsearcherror.md) | @deprecated. The new elasticsearch client doesn't wrap errors anymore. 7.16 | @@ -279,6 +277,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ISavedObjectsImporter](./kibana-plugin-core-server.isavedobjectsimporter.md) | | | [ISavedObjectsRepository](./kibana-plugin-core-server.isavedobjectsrepository.md) | See [SavedObjectsRepository](./kibana-plugin-core-server.savedobjectsrepository.md) | | [ISavedObjectTypeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) | See [SavedObjectTypeRegistry](./kibana-plugin-core-server.savedobjecttyperegistry.md) for documentation. | +| [KibanaExecutionContext](./kibana-plugin-core-server.kibanaexecutioncontext.md) | Represents a meta-information about a Kibana entity initiating a search request. | | [KibanaRequestRouteOptions](./kibana-plugin-core-server.kibanarequestrouteoptions.md) | Route options: If 'GET' or 'OPTIONS' method, body options won't be returned. | | [KibanaResponseFactory](./kibana-plugin-core-server.kibanaresponsefactory.md) | Creates an object containing request response payload, HTTP headers, error details, and other data transmitted to the client. | | [KnownHeaders](./kibana-plugin-core-server.knownheaders.md) | Set of well-known HTTP headers. | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectserrorhelpers.creategenericnotfoundesunavailableerror.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectserrorhelpers.creategenericnotfoundesunavailableerror.md new file mode 100644 index 0000000000000..e05f9466aa9ee --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectserrorhelpers.creategenericnotfoundesunavailableerror.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsErrorHelpers](./kibana-plugin-core-server.savedobjectserrorhelpers.md) > [createGenericNotFoundEsUnavailableError](./kibana-plugin-core-server.savedobjectserrorhelpers.creategenericnotfoundesunavailableerror.md) + +## SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError() method + +Signature: + +```typescript +static createGenericNotFoundEsUnavailableError(type: string, id: string): DecoratedError; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | string | | +| id | string | | + +Returns: + +`DecoratedError` + diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectserrorhelpers.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectserrorhelpers.md index 2dc78f2df3a83..67056c8a3cb50 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectserrorhelpers.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectserrorhelpers.md @@ -18,6 +18,7 @@ export declare class SavedObjectsErrorHelpers | [createBadRequestError(reason)](./kibana-plugin-core-server.savedobjectserrorhelpers.createbadrequesterror.md) | static | | | [createConflictError(type, id, reason)](./kibana-plugin-core-server.savedobjectserrorhelpers.createconflicterror.md) | static | | | [createGenericNotFoundError(type, id)](./kibana-plugin-core-server.savedobjectserrorhelpers.creategenericnotfounderror.md) | static | | +| [createGenericNotFoundEsUnavailableError(type, id)](./kibana-plugin-core-server.savedobjectserrorhelpers.creategenericnotfoundesunavailableerror.md) | static | | | [createIndexAliasNotFoundError(alias)](./kibana-plugin-core-server.savedobjectserrorhelpers.createindexaliasnotfounderror.md) | static | | | [createInvalidVersionError(versionInput)](./kibana-plugin-core-server.savedobjectserrorhelpers.createinvalidversionerror.md) | static | | | [createTooManyRequestsError(type, id)](./kibana-plugin-core-server.savedobjectserrorhelpers.createtoomanyrequestserror.md) | static | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfig.toserializedfieldformat.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfig.toserializedfieldformat.md index 7a75950f9cc6d..73b415f0a0b86 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfig.toserializedfieldformat.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfig.toserializedfieldformat.md @@ -9,9 +9,9 @@ Returns a serialized field format for the field used in this agg. This can be pa Signature: ```typescript -toSerializedFieldFormat(): {} | Ensure, SerializableState>; +toSerializedFieldFormat(): {} | Ensure, SerializableRecord>; ``` Returns: -`{} | Ensure, SerializableState>` +`{} | Ensure, SerializableRecord>` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigs._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigs._constructor_.md index 6ca7a1a88b30e..c4d09001087de 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigs._constructor_.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigs._constructor_.md @@ -13,7 +13,7 @@ constructor(indexPattern: IndexPattern, configStates: Pick & Pick<{ type: string | IAggType; @@ -27,6 +27,6 @@ constructor(indexPattern: IndexPattern, configStates: PickIndexPattern | | -| configStates | Pick<Pick<{
type: string;
enabled?: boolean | undefined;
id?: string | undefined;
params?: {} | import("./agg_config").SerializableState | undefined;
schema?: string | undefined;
}, "schema" | "enabled" | "id" | "params"> & Pick<{
type: string | IAggType;
}, "type"> & Pick<{
type: string | IAggType;
}, never>, "schema" | "type" | "enabled" | "id" | "params">[] | undefined | | +| configStates | Pick<Pick<{
type: string;
enabled?: boolean | undefined;
id?: string | undefined;
params?: {} | import("@kbn/common-utils").SerializableRecord | undefined;
schema?: string | undefined;
}, "schema" | "enabled" | "id" | "params"> & Pick<{
type: string | IAggType;
}, "type"> & Pick<{
type: string | IAggType;
}, never>, "schema" | "type" | "enabled" | "id" | "params">[] | undefined | | | opts | AggConfigsOptions | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigserialized.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigserialized.md new file mode 100644 index 0000000000000..9660a15d94a69 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigserialized.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigSerialized](./kibana-plugin-plugins-data-public.aggconfigserialized.md) + +## AggConfigSerialized type + +\* + +Signature: + +```typescript +export declare type AggConfigSerialized = Ensure<{ + type: string; + enabled?: boolean; + id?: string; + params?: {} | SerializableState; + schema?: string; +}, SerializableState>; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esdslexpressionfunctiondefinition.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esdslexpressionfunctiondefinition.md deleted file mode 100644 index 0bd00e937eaaa..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esdslexpressionfunctiondefinition.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [EsdslExpressionFunctionDefinition](./kibana-plugin-plugins-data-public.esdslexpressionfunctiondefinition.md) - -## EsdslExpressionFunctionDefinition type - -Signature: - -```typescript -export declare type EsdslExpressionFunctionDefinition = ExpressionFunctionDefinition; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esrawresponseexpressiontypedefinition.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esrawresponseexpressiontypedefinition.md deleted file mode 100644 index b95ae3c69bf20..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esrawresponseexpressiontypedefinition.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [EsRawResponseExpressionTypeDefinition](./kibana-plugin-plugins-data-public.esrawresponseexpressiontypedefinition.md) - -## EsRawResponseExpressionTypeDefinition type - -Signature: - -```typescript -export declare type EsRawResponseExpressionTypeDefinition = ExpressionTypeDefinition; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filtermanager.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filtermanager.md index a2028bb5c12c6..7baa23fffe0d3 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filtermanager.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filtermanager.md @@ -24,7 +24,7 @@ export declare class FilterManager implements PersistableStateService | [getAllMigrations](./kibana-plugin-plugins-data-public.filtermanager.getallmigrations.md) | | () => {} | | | [inject](./kibana-plugin-plugins-data-public.filtermanager.inject.md) | | any | | | [migrateToLatest](./kibana-plugin-plugins-data-public.filtermanager.migratetolatest.md) | | any | | -| [telemetry](./kibana-plugin-plugins-data-public.filtermanager.telemetry.md) | | (filters: import("../../../../kibana_utils/common/persistable_state").SerializableState, collector: unknown) => {} | | +| [telemetry](./kibana-plugin-plugins-data-public.filtermanager.telemetry.md) | | (filters: import("@kbn/common-utils").SerializableRecord, collector: unknown) => {} | | ## Methods diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filtermanager.telemetry.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filtermanager.telemetry.md index bab6452c34903..df5b4ea0a26c8 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filtermanager.telemetry.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filtermanager.telemetry.md @@ -7,5 +7,5 @@ Signature: ```typescript -telemetry: (filters: import("../../../../kibana_utils/common/persistable_state").SerializableState, collector: unknown) => {}; +telemetry: (filters: import("@kbn/common-utils").SerializableRecord, collector: unknown) => {}; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getespreference.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getespreference.md deleted file mode 100644 index f872c56c168ce..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.getespreference.md +++ /dev/null @@ -1,23 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [getEsPreference](./kibana-plugin-plugins-data-public.getespreference.md) - -## getEsPreference() function - -Signature: - -```typescript -export declare function getEsPreference(uiSettings: IUiSettingsClient, sessionId?: string): any; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| uiSettings | IUiSettingsClient | | -| sessionId | string | | - -Returns: - -`any` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.add.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.add.md deleted file mode 100644 index 0f3469ae9c550..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.add.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [add](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.add.md) - -## IIndexPatternFieldList.add() method - -Signature: - -```typescript -add(field: FieldSpec): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| field | FieldSpec | | - -Returns: - -`void` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md deleted file mode 100644 index 070e36e303a80..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [getAll](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md) - -## IIndexPatternFieldList.getAll() method - -Signature: - -```typescript -getAll(): IndexPatternField[]; -``` -Returns: - -`IndexPatternField[]` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md deleted file mode 100644 index e277df87fe908..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [getByName](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md) - -## IIndexPatternFieldList.getByName() method - -Signature: - -```typescript -getByName(name: IndexPatternField['name']): IndexPatternField | undefined; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| name | IndexPatternField['name'] | | - -Returns: - -`IndexPatternField | undefined` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md deleted file mode 100644 index 9a7b3ab36b0c1..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [getByType](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md) - -## IIndexPatternFieldList.getByType() method - -Signature: - -```typescript -getByType(type: IndexPatternField['type']): IndexPatternField[]; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| type | IndexPatternField['type'] | | - -Returns: - -`IndexPatternField[]` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md deleted file mode 100644 index b1e13ffaabd07..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.md +++ /dev/null @@ -1,26 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) - -## IIndexPatternFieldList interface - -Signature: - -```typescript -export interface IIndexPatternFieldList extends Array -``` - -## Methods - -| Method | Description | -| --- | --- | -| [add(field)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.add.md) | | -| [getAll()](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getall.md) | | -| [getByName(name)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbyname.md) | | -| [getByType(type)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.getbytype.md) | | -| [remove(field)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.remove.md) | | -| [removeAll()](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md) | | -| [replaceAll(specs)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md) | | -| [toSpec(options)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.tospec.md) | | -| [update(field)](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.update.md) | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.remove.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.remove.md deleted file mode 100644 index 3b6bbb0691930..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.remove.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [remove](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.remove.md) - -## IIndexPatternFieldList.remove() method - -Signature: - -```typescript -remove(field: IFieldType): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| field | IFieldType | | - -Returns: - -`void` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md deleted file mode 100644 index 55e7ca98e2637..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [removeAll](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.removeall.md) - -## IIndexPatternFieldList.removeAll() method - -Signature: - -```typescript -removeAll(): void; -``` -Returns: - -`void` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md deleted file mode 100644 index c7e8cdd578bfe..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [replaceAll](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.replaceall.md) - -## IIndexPatternFieldList.replaceAll() method - -Signature: - -```typescript -replaceAll(specs: FieldSpec[]): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| specs | FieldSpec[] | | - -Returns: - -`void` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.tospec.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.tospec.md deleted file mode 100644 index 0fe62f575a927..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.tospec.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [toSpec](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.tospec.md) - -## IIndexPatternFieldList.toSpec() method - -Signature: - -```typescript -toSpec(options?: { - getFormatterForField?: IndexPattern['getFormatterForField']; - }): IndexPatternFieldMap; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| options | {
getFormatterForField?: IndexPattern['getFormatterForField'];
} | | - -Returns: - -`IndexPatternFieldMap` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.update.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.update.md deleted file mode 100644 index 121ffb65f26a5..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpatternfieldlist.update.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) > [update](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.update.md) - -## IIndexPatternFieldList.update() method - -Signature: - -```typescript -update(field: FieldSpec): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| field | FieldSpec | | - -Returns: - -`void` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterns.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterns.md index 4934672d75f31..75ae06480a781 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterns.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterns.md @@ -17,6 +17,5 @@ indexPatterns: { isNestedField: typeof isNestedField; validate: typeof validateIndexPattern; flattenHitWrapper: typeof flattenHitWrapper; - formatHitProvider: typeof formatHitProvider; } ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterntypemeta.aggs.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterntypemeta.aggs.md deleted file mode 100644 index 46cb435fb19bc..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterntypemeta.aggs.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternTypeMeta](./kibana-plugin-plugins-data-public.indexpatterntypemeta.md) > [aggs](./kibana-plugin-plugins-data-public.indexpatterntypemeta.aggs.md) - -## IndexPatternTypeMeta.aggs property - -Signature: - -```typescript -aggs?: Record; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterntypemeta.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterntypemeta.md deleted file mode 100644 index 19a884862d460..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterntypemeta.md +++ /dev/null @@ -1,19 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternTypeMeta](./kibana-plugin-plugins-data-public.indexpatterntypemeta.md) - -## IndexPatternTypeMeta interface - -Signature: - -```typescript -export interface TypeMeta -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [aggs](./kibana-plugin-plugins-data-public.indexpatterntypemeta.aggs.md) | Record<string, AggregationRestrictions> | | -| [params](./kibana-plugin-plugins-data-public.indexpatterntypemeta.params.md) | {
rollup_index: string;
} | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterntypemeta.params.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterntypemeta.params.md deleted file mode 100644 index 12646a39188a0..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatterntypemeta.params.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternTypeMeta](./kibana-plugin-plugins-data-public.indexpatterntypemeta.md) > [params](./kibana-plugin-plugins-data-public.indexpatterntypemeta.params.md) - -## IndexPatternTypeMeta.params property - -Signature: - -```typescript -params?: { - rollup_index: string; - }; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.inputtimerange.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.inputtimerange.md deleted file mode 100644 index 649355a5fffb5..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.inputtimerange.md +++ /dev/null @@ -1,14 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [InputTimeRange](./kibana-plugin-plugins-data-public.inputtimerange.md) - -## InputTimeRange type - -Signature: - -```typescript -export declare type InputTimeRange = TimeRange | { - from: Moment; - to: Moment; -}; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index 3716f5cb4febf..760f6d8651428 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -18,10 +18,7 @@ | [IndexPatternField](./kibana-plugin-plugins-data-public.indexpatternfield.md) | | | [IndexPatternsService](./kibana-plugin-plugins-data-public.indexpatternsservice.md) | | | [OptionedParamType](./kibana-plugin-plugins-data-public.optionedparamtype.md) | | -| [PainlessError](./kibana-plugin-plugins-data-public.painlesserror.md) | | -| [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) | | | [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) | \* | -| [SearchTimeoutError](./kibana-plugin-plugins-data-public.searchtimeouterror.md) | Request Failure - When an entire multi request fails | | [TimeHistory](./kibana-plugin-plugins-data-public.timehistory.md) | | ## Enumerations @@ -34,7 +31,6 @@ | [QuerySuggestionTypes](./kibana-plugin-plugins-data-public.querysuggestiontypes.md) | | | [SearchSessionState](./kibana-plugin-plugins-data-public.searchsessionstate.md) | Possible state that current session can be in | | [SortDirection](./kibana-plugin-plugins-data-public.sortdirection.md) | | -| [TimeoutErrorMode](./kibana-plugin-plugins-data-public.timeouterrormode.md) | | ## Functions @@ -44,7 +40,6 @@ | [generateFilters(filterManager, field, values, operation, index)](./kibana-plugin-plugins-data-public.generatefilters.md) | Generate filter objects, as a result of triggering a filter action on a specific index pattern field. | | [getDefaultQuery(language)](./kibana-plugin-plugins-data-public.getdefaultquery.md) | | | [getDisplayValueFromFilter(filter, indexPatterns)](./kibana-plugin-plugins-data-public.getdisplayvaluefromfilter.md) | | -| [getEsPreference(uiSettings, sessionId)](./kibana-plugin-plugins-data-public.getespreference.md) | | | [getEsQueryConfig(config)](./kibana-plugin-plugins-data-public.getesqueryconfig.md) | | | [getSearchParamsFromRequest(searchRequest, dependencies)](./kibana-plugin-plugins-data-public.getsearchparamsfromrequest.md) | | | [getTime(indexPattern, timeRange, options)](./kibana-plugin-plugins-data-public.gettime.md) | | @@ -68,12 +63,10 @@ | [IEsSearchRequest](./kibana-plugin-plugins-data-public.iessearchrequest.md) | | | [IFieldType](./kibana-plugin-plugins-data-public.ifieldtype.md) | | | [IIndexPattern](./kibana-plugin-plugins-data-public.iindexpattern.md) | | -| [IIndexPatternFieldList](./kibana-plugin-plugins-data-public.iindexpatternfieldlist.md) | | | [IKibanaSearchRequest](./kibana-plugin-plugins-data-public.ikibanasearchrequest.md) | | | [IKibanaSearchResponse](./kibana-plugin-plugins-data-public.ikibanasearchresponse.md) | | | [IndexPatternAttributes](./kibana-plugin-plugins-data-public.indexpatternattributes.md) | Interface for an index pattern saved object | | [IndexPatternSpec](./kibana-plugin-plugins-data-public.indexpatternspec.md) | Static index pattern format Serialized data object, representing index pattern attributes and state | -| [IndexPatternTypeMeta](./kibana-plugin-plugins-data-public.indexpatterntypemeta.md) | | | [ISearchOptions](./kibana-plugin-plugins-data-public.isearchoptions.md) | | | [ISearchSetup](./kibana-plugin-plugins-data-public.isearchsetup.md) | The setup contract exposed by the Search plugin exposes the search strategy extension point. | | [ISearchStart](./kibana-plugin-plugins-data-public.isearchstart.md) | search service | @@ -89,8 +82,6 @@ | [RefreshInterval](./kibana-plugin-plugins-data-public.refreshinterval.md) | | | [SavedQuery](./kibana-plugin-plugins-data-public.savedquery.md) | | | [SavedQueryService](./kibana-plugin-plugins-data-public.savedqueryservice.md) | | -| [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) | | -| [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) | | | [SearchSessionInfoProvider](./kibana-plugin-plugins-data-public.searchsessioninfoprovider.md) | Provide info about current search session to be stored in the Search Session saved object | | [SearchSourceFields](./kibana-plugin-plugins-data-public.searchsourcefields.md) | search source fields | | [WaitUntilNextSessionCompletesOptions](./kibana-plugin-plugins-data-public.waituntilnextsessioncompletesoptions.md) | Options for [waitUntilNextSessionCompletes$()](./kibana-plugin-plugins-data-public.waituntilnextsessioncompletes_.md) | @@ -140,6 +131,7 @@ | Type Alias | Description | | --- | --- | | [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) | | +| [AggConfigSerialized](./kibana-plugin-plugins-data-public.aggconfigserialized.md) | \* | | [AggGroupName](./kibana-plugin-plugins-data-public.agggroupname.md) | | | [AggParam](./kibana-plugin-plugins-data-public.aggparam.md) | | | [AggregationRestrictions](./kibana-plugin-plugins-data-public.aggregationrestrictions.md) | | @@ -148,10 +140,8 @@ | [AutoRefreshDoneFn](./kibana-plugin-plugins-data-public.autorefreshdonefn.md) | | | [CustomFilter](./kibana-plugin-plugins-data-public.customfilter.md) | | | [EsaggsExpressionFunctionDefinition](./kibana-plugin-plugins-data-public.esaggsexpressionfunctiondefinition.md) | | -| [EsdslExpressionFunctionDefinition](./kibana-plugin-plugins-data-public.esdslexpressionfunctiondefinition.md) | | | [EsQueryConfig](./kibana-plugin-plugins-data-public.esqueryconfig.md) | | | [EsQuerySortValue](./kibana-plugin-plugins-data-public.esquerysortvalue.md) | | -| [EsRawResponseExpressionTypeDefinition](./kibana-plugin-plugins-data-public.esrawresponseexpressiontypedefinition.md) | | | [ExecutionContextSearch](./kibana-plugin-plugins-data-public.executioncontextsearch.md) | | | [ExistsFilter](./kibana-plugin-plugins-data-public.existsfilter.md) | | | [ExpressionFunctionKibana](./kibana-plugin-plugins-data-public.expressionfunctionkibana.md) | | @@ -168,7 +158,6 @@ | [IndexPatternLoadExpressionFunctionDefinition](./kibana-plugin-plugins-data-public.indexpatternloadexpressionfunctiondefinition.md) | | | [IndexPatternsContract](./kibana-plugin-plugins-data-public.indexpatternscontract.md) | | | [IndexPatternSelectProps](./kibana-plugin-plugins-data-public.indexpatternselectprops.md) | | -| [InputTimeRange](./kibana-plugin-plugins-data-public.inputtimerange.md) | | | [ISearchGeneric](./kibana-plugin-plugins-data-public.isearchgeneric.md) | | | [ISearchSource](./kibana-plugin-plugins-data-public.isearchsource.md) | search source interface | | [ISessionsClient](./kibana-plugin-plugins-data-public.isessionsclient.md) | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror._constructor_.md deleted file mode 100644 index b8f21de3e086e..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror._constructor_.md +++ /dev/null @@ -1,21 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [PainlessError](./kibana-plugin-plugins-data-public.painlesserror.md) > [(constructor)](./kibana-plugin-plugins-data-public.painlesserror._constructor_.md) - -## PainlessError.(constructor) - -Constructs a new instance of the `PainlessError` class - -Signature: - -```typescript -constructor(err: IEsError, indexPattern?: IndexPattern); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| err | IEsError | | -| indexPattern | IndexPattern | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.geterrormessage.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.geterrormessage.md deleted file mode 100644 index a3b4c51c6c331..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.geterrormessage.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [PainlessError](./kibana-plugin-plugins-data-public.painlesserror.md) > [getErrorMessage](./kibana-plugin-plugins-data-public.painlesserror.geterrormessage.md) - -## PainlessError.getErrorMessage() method - -Signature: - -```typescript -getErrorMessage(application: ApplicationStart): JSX.Element; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| application | ApplicationStart | | - -Returns: - -`JSX.Element` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.indexpattern.md deleted file mode 100644 index 4312f2f8d0c91..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.indexpattern.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [PainlessError](./kibana-plugin-plugins-data-public.painlesserror.md) > [indexPattern](./kibana-plugin-plugins-data-public.painlesserror.indexpattern.md) - -## PainlessError.indexPattern property - -Signature: - -```typescript -indexPattern?: IndexPattern; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.md deleted file mode 100644 index 3a887d358e215..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.md +++ /dev/null @@ -1,31 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [PainlessError](./kibana-plugin-plugins-data-public.painlesserror.md) - -## PainlessError class - -Signature: - -```typescript -export declare class PainlessError extends EsError -``` - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(err, indexPattern)](./kibana-plugin-plugins-data-public.painlesserror._constructor_.md) | | Constructs a new instance of the PainlessError class | - -## Properties - -| Property | Modifiers | Type | Description | -| --- | --- | --- | --- | -| [indexPattern](./kibana-plugin-plugins-data-public.painlesserror.indexpattern.md) | | IndexPattern | | -| [painlessStack](./kibana-plugin-plugins-data-public.painlesserror.painlessstack.md) | | string | | - -## Methods - -| Method | Modifiers | Description | -| --- | --- | --- | -| [getErrorMessage(application)](./kibana-plugin-plugins-data-public.painlesserror.geterrormessage.md) | | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.painlessstack.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.painlessstack.md deleted file mode 100644 index a7e6920b2ae21..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.painlesserror.painlessstack.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [PainlessError](./kibana-plugin-plugins-data-public.painlesserror.md) > [painlessStack](./kibana-plugin-plugins-data-public.painlesserror.painlessstack.md) - -## PainlessError.painlessStack property - -Signature: - -```typescript -painlessStack?: string; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.md index bd60f31bfe8f2..f9ef1d87a2dcc 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.md @@ -39,4 +39,5 @@ export interface QueryStringInputProps | [size](./kibana-plugin-plugins-data-public.querystringinputprops.size.md) | SuggestionsListSize | | | [storageKey](./kibana-plugin-plugins-data-public.querystringinputprops.storagekey.md) | string | | | [submitOnBlur](./kibana-plugin-plugins-data-public.querystringinputprops.submitonblur.md) | boolean | | +| [timeRangeForSuggestionsOverride](./kibana-plugin-plugins-data-public.querystringinputprops.timerangeforsuggestionsoverride.md) | boolean | Override whether autocomplete suggestions are restricted by time range. | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.timerangeforsuggestionsoverride.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.timerangeforsuggestionsoverride.md new file mode 100644 index 0000000000000..baa6c34aeadba --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.timerangeforsuggestionsoverride.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [QueryStringInputProps](./kibana-plugin-plugins-data-public.querystringinputprops.md) > [timeRangeForSuggestionsOverride](./kibana-plugin-plugins-data-public.querystringinputprops.timerangeforsuggestionsoverride.md) + +## QueryStringInputProps.timeRangeForSuggestionsOverride property + +Override whether autocomplete suggestions are restricted by time range. + +Signature: + +```typescript +timeRangeForSuggestionsOverride?: boolean; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.md deleted file mode 100644 index 65b46bf6cba4d..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.md +++ /dev/null @@ -1,23 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) - -## SearchError interface - -Signature: - -```typescript -export interface SearchError -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [message](./kibana-plugin-plugins-data-public.searcherror.message.md) | string | | -| [name](./kibana-plugin-plugins-data-public.searcherror.name.md) | string | | -| [path](./kibana-plugin-plugins-data-public.searcherror.path.md) | string | | -| [status](./kibana-plugin-plugins-data-public.searcherror.status.md) | string | | -| [title](./kibana-plugin-plugins-data-public.searcherror.title.md) | string | | -| [type](./kibana-plugin-plugins-data-public.searcherror.type.md) | string | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.message.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.message.md deleted file mode 100644 index 5e2de2fbf7f42..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.message.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) > [message](./kibana-plugin-plugins-data-public.searcherror.message.md) - -## SearchError.message property - -Signature: - -```typescript -message: string; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.name.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.name.md deleted file mode 100644 index 8ad7bb5fcfd81..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.name.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) > [name](./kibana-plugin-plugins-data-public.searcherror.name.md) - -## SearchError.name property - -Signature: - -```typescript -name: string; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.path.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.path.md deleted file mode 100644 index 833c16e73ea8e..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.path.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) > [path](./kibana-plugin-plugins-data-public.searcherror.path.md) - -## SearchError.path property - -Signature: - -```typescript -path: string; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.status.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.status.md deleted file mode 100644 index ae1a947da0abb..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.status.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) > [status](./kibana-plugin-plugins-data-public.searcherror.status.md) - -## SearchError.status property - -Signature: - -```typescript -status: string; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.title.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.title.md deleted file mode 100644 index aa73ab3b5790c..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.title.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) > [title](./kibana-plugin-plugins-data-public.searcherror.title.md) - -## SearchError.title property - -Signature: - -```typescript -title: string; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.type.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.type.md deleted file mode 100644 index dde447a9059c5..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searcherror.type.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) > [type](./kibana-plugin-plugins-data-public.searcherror.type.md) - -## SearchError.type property - -Signature: - -```typescript -type: string; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md deleted file mode 100644 index 4c67639300883..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md +++ /dev/null @@ -1,20 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [(constructor)](./kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md) - -## SearchInterceptor.(constructor) - -Constructs a new instance of the `SearchInterceptor` class - -Signature: - -```typescript -constructor(deps: SearchInterceptorDeps); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| deps | SearchInterceptorDeps | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md deleted file mode 100644 index e1b27f45c6339..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md +++ /dev/null @@ -1,26 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) - -## SearchInterceptor class - -Signature: - -```typescript -export declare class SearchInterceptor -``` - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(deps)](./kibana-plugin-plugins-data-public.searchinterceptor._constructor_.md) | | Constructs a new instance of the SearchInterceptor class | - -## Methods - -| Method | Modifiers | Description | -| --- | --- | --- | -| [search({ id, ...request }, options)](./kibana-plugin-plugins-data-public.searchinterceptor.search.md) | | Searches using the given search method. Overrides the AbortSignal with one that will abort either when the request times out, or when the original AbortSignal is aborted. Updates pendingCount$ when the request is started/finalized. | -| [showError(e)](./kibana-plugin-plugins-data-public.searchinterceptor.showerror.md) | | | -| [stop()](./kibana-plugin-plugins-data-public.searchinterceptor.stop.md) | | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.search.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.search.md deleted file mode 100644 index ab5ecbac119f3..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.search.md +++ /dev/null @@ -1,27 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [search](./kibana-plugin-plugins-data-public.searchinterceptor.search.md) - -## SearchInterceptor.search() method - -Searches using the given `search` method. Overrides the `AbortSignal` with one that will abort either when the request times out, or when the original `AbortSignal` is aborted. Updates `pendingCount$` when the request is started/finalized. - -Signature: - -```typescript -search({ id, ...request }: IKibanaSearchRequest, options?: IAsyncSearchOptions): import("rxjs").Observable>; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| { id, ...request } | IKibanaSearchRequest | | -| options | IAsyncSearchOptions | | - -Returns: - -`import("rxjs").Observable>` - -`Observable` emitting the search response or an error. - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.showerror.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.showerror.md deleted file mode 100644 index 92e851c783dd0..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.showerror.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [showError](./kibana-plugin-plugins-data-public.searchinterceptor.showerror.md) - -## SearchInterceptor.showError() method - -Signature: - -```typescript -showError(e: Error): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| e | Error | | - -Returns: - -`void` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.stop.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.stop.md deleted file mode 100644 index e0d77c5d13537..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.stop.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [stop](./kibana-plugin-plugins-data-public.searchinterceptor.stop.md) - -## SearchInterceptor.stop() method - -Signature: - -```typescript -stop(): void; -``` -Returns: - -`void` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.bfetch.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.bfetch.md deleted file mode 100644 index 5b7c635c71529..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.bfetch.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) > [bfetch](./kibana-plugin-plugins-data-public.searchinterceptordeps.bfetch.md) - -## SearchInterceptorDeps.bfetch property - -Signature: - -```typescript -bfetch: BfetchPublicSetup; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.http.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.http.md deleted file mode 100644 index 66c31bb6fcf80..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.http.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) > [http](./kibana-plugin-plugins-data-public.searchinterceptordeps.http.md) - -## SearchInterceptorDeps.http property - -Signature: - -```typescript -http: CoreSetup['http']; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.md deleted file mode 100644 index 543566b783c23..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) - -## SearchInterceptorDeps interface - -Signature: - -```typescript -export interface SearchInterceptorDeps -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [bfetch](./kibana-plugin-plugins-data-public.searchinterceptordeps.bfetch.md) | BfetchPublicSetup | | -| [http](./kibana-plugin-plugins-data-public.searchinterceptordeps.http.md) | CoreSetup['http'] | | -| [session](./kibana-plugin-plugins-data-public.searchinterceptordeps.session.md) | ISessionService | | -| [startServices](./kibana-plugin-plugins-data-public.searchinterceptordeps.startservices.md) | Promise<[CoreStart, any, unknown]> | | -| [toasts](./kibana-plugin-plugins-data-public.searchinterceptordeps.toasts.md) | ToastsSetup | | -| [uiSettings](./kibana-plugin-plugins-data-public.searchinterceptordeps.uisettings.md) | CoreSetup['uiSettings'] | | -| [usageCollector](./kibana-plugin-plugins-data-public.searchinterceptordeps.usagecollector.md) | SearchUsageCollector | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.session.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.session.md deleted file mode 100644 index 40d00483317ba..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.session.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) > [session](./kibana-plugin-plugins-data-public.searchinterceptordeps.session.md) - -## SearchInterceptorDeps.session property - -Signature: - -```typescript -session: ISessionService; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.startservices.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.startservices.md deleted file mode 100644 index 855d0652058b8..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.startservices.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) > [startServices](./kibana-plugin-plugins-data-public.searchinterceptordeps.startservices.md) - -## SearchInterceptorDeps.startServices property - -Signature: - -```typescript -startServices: Promise<[CoreStart, any, unknown]>; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.toasts.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.toasts.md deleted file mode 100644 index 1f560dfa5cf7c..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.toasts.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) > [toasts](./kibana-plugin-plugins-data-public.searchinterceptordeps.toasts.md) - -## SearchInterceptorDeps.toasts property - -Signature: - -```typescript -toasts: ToastsSetup; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.uisettings.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.uisettings.md deleted file mode 100644 index a34d223c34ac2..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.uisettings.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) > [uiSettings](./kibana-plugin-plugins-data-public.searchinterceptordeps.uisettings.md) - -## SearchInterceptorDeps.uiSettings property - -Signature: - -```typescript -uiSettings: CoreSetup['uiSettings']; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.usagecollector.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.usagecollector.md deleted file mode 100644 index 21afce1927676..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.usagecollector.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) > [usageCollector](./kibana-plugin-plugins-data-public.searchinterceptordeps.usagecollector.md) - -## SearchInterceptorDeps.usageCollector property - -Signature: - -```typescript -usageCollector?: SearchUsageCollector; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror._constructor_.md deleted file mode 100644 index b4eecca665e82..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror._constructor_.md +++ /dev/null @@ -1,21 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchTimeoutError](./kibana-plugin-plugins-data-public.searchtimeouterror.md) > [(constructor)](./kibana-plugin-plugins-data-public.searchtimeouterror._constructor_.md) - -## SearchTimeoutError.(constructor) - -Constructs a new instance of the `SearchTimeoutError` class - -Signature: - -```typescript -constructor(err: Record, mode: TimeoutErrorMode); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| err | Record<string, any> | | -| mode | TimeoutErrorMode | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror.geterrormessage.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror.geterrormessage.md deleted file mode 100644 index 58ef953c9d7db..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror.geterrormessage.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchTimeoutError](./kibana-plugin-plugins-data-public.searchtimeouterror.md) > [getErrorMessage](./kibana-plugin-plugins-data-public.searchtimeouterror.geterrormessage.md) - -## SearchTimeoutError.getErrorMessage() method - -Signature: - -```typescript -getErrorMessage(application: ApplicationStart): JSX.Element; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| application | ApplicationStart | | - -Returns: - -`JSX.Element` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror.md deleted file mode 100644 index 5c0bec04dcfbc..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror.md +++ /dev/null @@ -1,32 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchTimeoutError](./kibana-plugin-plugins-data-public.searchtimeouterror.md) - -## SearchTimeoutError class - -Request Failure - When an entire multi request fails - -Signature: - -```typescript -export declare class SearchTimeoutError extends KbnError -``` - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(err, mode)](./kibana-plugin-plugins-data-public.searchtimeouterror._constructor_.md) | | Constructs a new instance of the SearchTimeoutError class | - -## Properties - -| Property | Modifiers | Type | Description | -| --- | --- | --- | --- | -| [mode](./kibana-plugin-plugins-data-public.searchtimeouterror.mode.md) | | TimeoutErrorMode | | - -## Methods - -| Method | Modifiers | Description | -| --- | --- | --- | -| [getErrorMessage(application)](./kibana-plugin-plugins-data-public.searchtimeouterror.geterrormessage.md) | | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror.mode.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror.mode.md deleted file mode 100644 index d534a73eca2ec..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchtimeouterror.mode.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchTimeoutError](./kibana-plugin-plugins-data-public.searchtimeouterror.md) > [mode](./kibana-plugin-plugins-data-public.searchtimeouterror.mode.md) - -## SearchTimeoutError.mode property - -Signature: - -```typescript -mode: TimeoutErrorMode; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timeouterrormode.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timeouterrormode.md deleted file mode 100644 index bbf789b7dcf26..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.timeouterrormode.md +++ /dev/null @@ -1,19 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [TimeoutErrorMode](./kibana-plugin-plugins-data-public.timeouterrormode.md) - -## TimeoutErrorMode enum - -Signature: - -```typescript -export declare enum TimeoutErrorMode -``` - -## Enumeration Members - -| Member | Value | Description | -| --- | --- | --- | -| CHANGE | 1 | | -| CONTACT | 0 | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggconfigoptions.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggconfigoptions.md deleted file mode 100644 index effb2e798ad6f..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggconfigoptions.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggConfigOptions](./kibana-plugin-plugins-data-server.aggconfigoptions.md) - -## AggConfigOptions type - -Signature: - -```typescript -export declare type AggConfigOptions = Assign; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggavg.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggavg.md deleted file mode 100644 index dd5884c0a7c47..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggavg.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggAvg](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggavg.md) - -## AggFunctionsMapping.aggAvg property - -Signature: - -```typescript -aggAvg: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketavg.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketavg.md deleted file mode 100644 index 9a36328eade20..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketavg.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggBucketAvg](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketavg.md) - -## AggFunctionsMapping.aggBucketAvg property - -Signature: - -```typescript -aggBucketAvg: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketmax.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketmax.md deleted file mode 100644 index 7880300497a8c..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketmax.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggBucketMax](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketmax.md) - -## AggFunctionsMapping.aggBucketMax property - -Signature: - -```typescript -aggBucketMax: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketmin.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketmin.md deleted file mode 100644 index d806b610e4ad2..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketmin.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggBucketMin](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketmin.md) - -## AggFunctionsMapping.aggBucketMin property - -Signature: - -```typescript -aggBucketMin: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketsum.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketsum.md deleted file mode 100644 index 17f1d24f2736f..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketsum.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggBucketSum](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketsum.md) - -## AggFunctionsMapping.aggBucketSum property - -Signature: - -```typescript -aggBucketSum: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcardinality.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcardinality.md deleted file mode 100644 index fd31251fd6b22..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcardinality.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggCardinality](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcardinality.md) - -## AggFunctionsMapping.aggCardinality property - -Signature: - -```typescript -aggCardinality: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcount.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcount.md deleted file mode 100644 index 65aae8bc15dfe..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcount.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggCount](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcount.md) - -## AggFunctionsMapping.aggCount property - -Signature: - -```typescript -aggCount: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcumulativesum.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcumulativesum.md deleted file mode 100644 index 7c5d29391594a..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcumulativesum.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggCumulativeSum](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcumulativesum.md) - -## AggFunctionsMapping.aggCumulativeSum property - -Signature: - -```typescript -aggCumulativeSum: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggdatehistogram.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggdatehistogram.md deleted file mode 100644 index ca018cc6881e2..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggdatehistogram.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggDateHistogram](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggdatehistogram.md) - -## AggFunctionsMapping.aggDateHistogram property - -Signature: - -```typescript -aggDateHistogram: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggdaterange.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggdaterange.md deleted file mode 100644 index dc2019e761e49..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggdaterange.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggDateRange](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggdaterange.md) - -## AggFunctionsMapping.aggDateRange property - -Signature: - -```typescript -aggDateRange: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggderivative.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggderivative.md deleted file mode 100644 index c77054ca0a39b..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggderivative.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggDerivative](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggderivative.md) - -## AggFunctionsMapping.aggDerivative property - -Signature: - -```typescript -aggDerivative: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilter.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilter.md deleted file mode 100644 index 6f77cd69ca1a6..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilter.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggFilter](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilter.md) - -## AggFunctionsMapping.aggFilter property - -Signature: - -```typescript -aggFilter: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilteredmetric.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilteredmetric.md deleted file mode 100644 index 9885a0afa40c6..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilteredmetric.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggFilteredMetric](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilteredmetric.md) - -## AggFunctionsMapping.aggFilteredMetric property - -Signature: - -```typescript -aggFilteredMetric: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilters.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilters.md deleted file mode 100644 index 59cc96785ddb0..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilters.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggFilters](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilters.md) - -## AggFunctionsMapping.aggFilters property - -Signature: - -```typescript -aggFilters: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeobounds.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeobounds.md deleted file mode 100644 index e43df684f792b..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeobounds.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggGeoBounds](./kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeobounds.md) - -## AggFunctionsMapping.aggGeoBounds property - -Signature: - -```typescript -aggGeoBounds: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeocentroid.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeocentroid.md deleted file mode 100644 index bad7afcdd0179..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeocentroid.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggGeoCentroid](./kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeocentroid.md) - -## AggFunctionsMapping.aggGeoCentroid property - -Signature: - -```typescript -aggGeoCentroid: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeohash.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeohash.md deleted file mode 100644 index 45aca882bb383..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeohash.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggGeoHash](./kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeohash.md) - -## AggFunctionsMapping.aggGeoHash property - -Signature: - -```typescript -aggGeoHash: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeotile.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeotile.md deleted file mode 100644 index 91322c1dadac3..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeotile.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggGeoTile](./kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeotile.md) - -## AggFunctionsMapping.aggGeoTile property - -Signature: - -```typescript -aggGeoTile: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agghistogram.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agghistogram.md deleted file mode 100644 index b9bf9b549e3e2..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.agghistogram.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggHistogram](./kibana-plugin-plugins-data-server.aggfunctionsmapping.agghistogram.md) - -## AggFunctionsMapping.aggHistogram property - -Signature: - -```typescript -aggHistogram: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggiprange.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggiprange.md deleted file mode 100644 index 76f9e2c25a6db..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggiprange.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggIpRange](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggiprange.md) - -## AggFunctionsMapping.aggIpRange property - -Signature: - -```typescript -aggIpRange: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmax.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmax.md deleted file mode 100644 index b4ef663ac002d..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmax.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggMax](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmax.md) - -## AggFunctionsMapping.aggMax property - -Signature: - -```typescript -aggMax: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmedian.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmedian.md deleted file mode 100644 index f84f500d9a24b..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmedian.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggMedian](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmedian.md) - -## AggFunctionsMapping.aggMedian property - -Signature: - -```typescript -aggMedian: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmin.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmin.md deleted file mode 100644 index 80e78f9ddead6..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmin.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggMin](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmin.md) - -## AggFunctionsMapping.aggMin property - -Signature: - -```typescript -aggMin: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmovingavg.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmovingavg.md deleted file mode 100644 index c182c56f1dcab..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmovingavg.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggMovingAvg](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmovingavg.md) - -## AggFunctionsMapping.aggMovingAvg property - -Signature: - -```typescript -aggMovingAvg: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggpercentileranks.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggpercentileranks.md deleted file mode 100644 index bad66bec9682f..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggpercentileranks.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggPercentileRanks](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggpercentileranks.md) - -## AggFunctionsMapping.aggPercentileRanks property - -Signature: - -```typescript -aggPercentileRanks: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggpercentiles.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggpercentiles.md deleted file mode 100644 index 7ce8f3f46c315..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggpercentiles.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggPercentiles](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggpercentiles.md) - -## AggFunctionsMapping.aggPercentiles property - -Signature: - -```typescript -aggPercentiles: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggrange.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggrange.md deleted file mode 100644 index 0ff87e450185b..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggrange.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggRange](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggrange.md) - -## AggFunctionsMapping.aggRange property - -Signature: - -```typescript -aggRange: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggserialdiff.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggserialdiff.md deleted file mode 100644 index f36ee39b68d1f..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggserialdiff.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggSerialDiff](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggserialdiff.md) - -## AggFunctionsMapping.aggSerialDiff property - -Signature: - -```typescript -aggSerialDiff: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsignificantterms.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsignificantterms.md deleted file mode 100644 index 4e9bfbedf6ec9..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsignificantterms.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggSignificantTerms](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsignificantterms.md) - -## AggFunctionsMapping.aggSignificantTerms property - -Signature: - -```typescript -aggSignificantTerms: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsinglepercentile.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsinglepercentile.md deleted file mode 100644 index d1418d7245d73..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsinglepercentile.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggSinglePercentile](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsinglepercentile.md) - -## AggFunctionsMapping.aggSinglePercentile property - -Signature: - -```typescript -aggSinglePercentile: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggstddeviation.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggstddeviation.md deleted file mode 100644 index 065a65262027a..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggstddeviation.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggStdDeviation](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggstddeviation.md) - -## AggFunctionsMapping.aggStdDeviation property - -Signature: - -```typescript -aggStdDeviation: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsum.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsum.md deleted file mode 100644 index 35521ab040d8d..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsum.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggSum](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsum.md) - -## AggFunctionsMapping.aggSum property - -Signature: - -```typescript -aggSum: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggterms.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggterms.md deleted file mode 100644 index efc6218107a13..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggterms.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggTerms](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggterms.md) - -## AggFunctionsMapping.aggTerms property - -Signature: - -```typescript -aggTerms: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggtophit.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggtophit.md deleted file mode 100644 index 3733486cf2214..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.aggtophit.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) > [aggTopHit](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggtophit.md) - -## AggFunctionsMapping.aggTopHit property - -Signature: - -```typescript -aggTopHit: ReturnType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.md deleted file mode 100644 index 6b5f854c155f3..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggfunctionsmapping.md +++ /dev/null @@ -1,53 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) - -## AggFunctionsMapping interface - -A global list of the expression function definitions for each agg type function. - -Signature: - -```typescript -export interface AggFunctionsMapping -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [aggAvg](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggavg.md) | ReturnType<typeof aggAvg> | | -| [aggBucketAvg](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketavg.md) | ReturnType<typeof aggBucketAvg> | | -| [aggBucketMax](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketmax.md) | ReturnType<typeof aggBucketMax> | | -| [aggBucketMin](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketmin.md) | ReturnType<typeof aggBucketMin> | | -| [aggBucketSum](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggbucketsum.md) | ReturnType<typeof aggBucketSum> | | -| [aggCardinality](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcardinality.md) | ReturnType<typeof aggCardinality> | | -| [aggCount](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcount.md) | ReturnType<typeof aggCount> | | -| [aggCumulativeSum](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggcumulativesum.md) | ReturnType<typeof aggCumulativeSum> | | -| [aggDateHistogram](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggdatehistogram.md) | ReturnType<typeof aggDateHistogram> | | -| [aggDateRange](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggdaterange.md) | ReturnType<typeof aggDateRange> | | -| [aggDerivative](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggderivative.md) | ReturnType<typeof aggDerivative> | | -| [aggFilter](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilter.md) | ReturnType<typeof aggFilter> | | -| [aggFilteredMetric](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilteredmetric.md) | ReturnType<typeof aggFilteredMetric> | | -| [aggFilters](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggfilters.md) | ReturnType<typeof aggFilters> | | -| [aggGeoBounds](./kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeobounds.md) | ReturnType<typeof aggGeoBounds> | | -| [aggGeoCentroid](./kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeocentroid.md) | ReturnType<typeof aggGeoCentroid> | | -| [aggGeoHash](./kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeohash.md) | ReturnType<typeof aggGeoHash> | | -| [aggGeoTile](./kibana-plugin-plugins-data-server.aggfunctionsmapping.agggeotile.md) | ReturnType<typeof aggGeoTile> | | -| [aggHistogram](./kibana-plugin-plugins-data-server.aggfunctionsmapping.agghistogram.md) | ReturnType<typeof aggHistogram> | | -| [aggIpRange](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggiprange.md) | ReturnType<typeof aggIpRange> | | -| [aggMax](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmax.md) | ReturnType<typeof aggMax> | | -| [aggMedian](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmedian.md) | ReturnType<typeof aggMedian> | | -| [aggMin](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmin.md) | ReturnType<typeof aggMin> | | -| [aggMovingAvg](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggmovingavg.md) | ReturnType<typeof aggMovingAvg> | | -| [aggPercentileRanks](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggpercentileranks.md) | ReturnType<typeof aggPercentileRanks> | | -| [aggPercentiles](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggpercentiles.md) | ReturnType<typeof aggPercentiles> | | -| [aggRange](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggrange.md) | ReturnType<typeof aggRange> | | -| [aggSerialDiff](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggserialdiff.md) | ReturnType<typeof aggSerialDiff> | | -| [aggSignificantTerms](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsignificantterms.md) | ReturnType<typeof aggSignificantTerms> | | -| [aggSinglePercentile](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsinglepercentile.md) | ReturnType<typeof aggSinglePercentile> | | -| [aggStdDeviation](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggstddeviation.md) | ReturnType<typeof aggStdDeviation> | | -| [aggSum](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggsum.md) | ReturnType<typeof aggSum> | | -| [aggTerms](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggterms.md) | ReturnType<typeof aggTerms> | | -| [aggTopHit](./kibana-plugin-plugins-data-server.aggfunctionsmapping.aggtophit.md) | ReturnType<typeof aggTopHit> | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.agggrouplabels.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.agggrouplabels.md deleted file mode 100644 index cf0caee6ac33e..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.agggrouplabels.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggGroupLabels](./kibana-plugin-plugins-data-server.agggrouplabels.md) - -## AggGroupLabels variable - -Signature: - -```typescript -AggGroupLabels: { - buckets: string; - metrics: string; - none: string; -} -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.agggroupname.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.agggroupname.md deleted file mode 100644 index 403294eba1367..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.agggroupname.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggGroupName](./kibana-plugin-plugins-data-server.agggroupname.md) - -## AggGroupName type - -Signature: - -```typescript -export declare type AggGroupName = $Values; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.agggroupnames.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.agggroupnames.md deleted file mode 100644 index 11d194723c521..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.agggroupnames.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggGroupNames](./kibana-plugin-plugins-data-server.agggroupnames.md) - -## AggGroupNames variable - -Signature: - -```typescript -AggGroupNames: Readonly<{ - Buckets: "buckets"; - Metrics: "metrics"; - None: "none"; -}> -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparam.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparam.md deleted file mode 100644 index 893501666b9a0..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparam.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggParam](./kibana-plugin-plugins-data-server.aggparam.md) - -## AggParam type - -Signature: - -```typescript -export declare type AggParam = BaseParamType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.display.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.display.md deleted file mode 100644 index 1030056e16afe..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.display.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggParamOption](./kibana-plugin-plugins-data-server.aggparamoption.md) > [display](./kibana-plugin-plugins-data-server.aggparamoption.display.md) - -## AggParamOption.display property - -Signature: - -```typescript -display: string; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.enabled.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.enabled.md deleted file mode 100644 index 8b1fcc4a1bbd0..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.enabled.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggParamOption](./kibana-plugin-plugins-data-server.aggparamoption.md) > [enabled](./kibana-plugin-plugins-data-server.aggparamoption.enabled.md) - -## AggParamOption.enabled() method - -Signature: - -```typescript -enabled?(agg: AggConfig): boolean; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| agg | AggConfig | | - -Returns: - -`boolean` - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.md deleted file mode 100644 index a7ddcf395cab4..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.md +++ /dev/null @@ -1,25 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggParamOption](./kibana-plugin-plugins-data-server.aggparamoption.md) - -## AggParamOption interface - -Signature: - -```typescript -export interface AggParamOption -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [display](./kibana-plugin-plugins-data-server.aggparamoption.display.md) | string | | -| [val](./kibana-plugin-plugins-data-server.aggparamoption.val.md) | string | | - -## Methods - -| Method | Description | -| --- | --- | -| [enabled(agg)](./kibana-plugin-plugins-data-server.aggparamoption.enabled.md) | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.val.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.val.md deleted file mode 100644 index 2c87c91c294d9..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamoption.val.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggParamOption](./kibana-plugin-plugins-data-server.aggparamoption.md) > [val](./kibana-plugin-plugins-data-server.aggparamoption.val.md) - -## AggParamOption.val property - -Signature: - -```typescript -val: string; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype._constructor_.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype._constructor_.md deleted file mode 100644 index 2e1b16855987e..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype._constructor_.md +++ /dev/null @@ -1,20 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggParamType](./kibana-plugin-plugins-data-server.aggparamtype.md) > [(constructor)](./kibana-plugin-plugins-data-server.aggparamtype._constructor_.md) - -## AggParamType.(constructor) - -Constructs a new instance of the `AggParamType` class - -Signature: - -```typescript -constructor(config: Record); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| config | Record<string, any> | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype.allowedaggs.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype.allowedaggs.md deleted file mode 100644 index 36179a9ce3569..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype.allowedaggs.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggParamType](./kibana-plugin-plugins-data-server.aggparamtype.md) > [allowedAggs](./kibana-plugin-plugins-data-server.aggparamtype.allowedaggs.md) - -## AggParamType.allowedAggs property - -Signature: - -```typescript -allowedAggs: string[]; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype.makeagg.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype.makeagg.md deleted file mode 100644 index bd5d2fca77659..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype.makeagg.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggParamType](./kibana-plugin-plugins-data-server.aggparamtype.md) > [makeAgg](./kibana-plugin-plugins-data-server.aggparamtype.makeagg.md) - -## AggParamType.makeAgg property - -Signature: - -```typescript -makeAgg: (agg: TAggConfig, state?: AggConfigSerialized) => TAggConfig; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype.md deleted file mode 100644 index 00c1906dd880b..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.aggparamtype.md +++ /dev/null @@ -1,25 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AggParamType](./kibana-plugin-plugins-data-server.aggparamtype.md) - -## AggParamType class - -Signature: - -```typescript -export declare class AggParamType extends BaseParamType -``` - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(config)](./kibana-plugin-plugins-data-server.aggparamtype._constructor_.md) | | Constructs a new instance of the AggParamType class | - -## Properties - -| Property | Modifiers | Type | Description | -| --- | --- | --- | --- | -| [allowedAggs](./kibana-plugin-plugins-data-server.aggparamtype.allowedaggs.md) | | string[] | | -| [makeAgg](./kibana-plugin-plugins-data-server.aggparamtype.makeagg.md) | | (agg: TAggConfig, state?: AggConfigSerialized) => TAggConfig | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.expiration_time_in_millis.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.expiration_time_in_millis.md deleted file mode 100644 index eab2fbc6431c6..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.expiration_time_in_millis.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AsyncSearchResponse](./kibana-plugin-plugins-data-server.asyncsearchresponse.md) > [expiration\_time\_in\_millis](./kibana-plugin-plugins-data-server.asyncsearchresponse.expiration_time_in_millis.md) - -## AsyncSearchResponse.expiration\_time\_in\_millis property - -Signature: - -```typescript -expiration_time_in_millis: number; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.id.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.id.md deleted file mode 100644 index d3b61be9b08b3..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.id.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AsyncSearchResponse](./kibana-plugin-plugins-data-server.asyncsearchresponse.md) > [id](./kibana-plugin-plugins-data-server.asyncsearchresponse.id.md) - -## AsyncSearchResponse.id property - -Signature: - -```typescript -id?: string; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.is_partial.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.is_partial.md deleted file mode 100644 index 1d1a5ccd1ac69..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.is_partial.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AsyncSearchResponse](./kibana-plugin-plugins-data-server.asyncsearchresponse.md) > [is\_partial](./kibana-plugin-plugins-data-server.asyncsearchresponse.is_partial.md) - -## AsyncSearchResponse.is\_partial property - -Signature: - -```typescript -is_partial: boolean; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.is_running.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.is_running.md deleted file mode 100644 index 17af7a39acfe7..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.is_running.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AsyncSearchResponse](./kibana-plugin-plugins-data-server.asyncsearchresponse.md) > [is\_running](./kibana-plugin-plugins-data-server.asyncsearchresponse.is_running.md) - -## AsyncSearchResponse.is\_running property - -Signature: - -```typescript -is_running: boolean; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.md deleted file mode 100644 index 2f11e03f82b5f..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.md +++ /dev/null @@ -1,23 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AsyncSearchResponse](./kibana-plugin-plugins-data-server.asyncsearchresponse.md) - -## AsyncSearchResponse interface - -Signature: - -```typescript -export interface AsyncSearchResponse -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [expiration\_time\_in\_millis](./kibana-plugin-plugins-data-server.asyncsearchresponse.expiration_time_in_millis.md) | number | | -| [id](./kibana-plugin-plugins-data-server.asyncsearchresponse.id.md) | string | | -| [is\_partial](./kibana-plugin-plugins-data-server.asyncsearchresponse.is_partial.md) | boolean | | -| [is\_running](./kibana-plugin-plugins-data-server.asyncsearchresponse.is_running.md) | boolean | | -| [response](./kibana-plugin-plugins-data-server.asyncsearchresponse.response.md) | estypes.SearchResponse<T> | | -| [start\_time\_in\_millis](./kibana-plugin-plugins-data-server.asyncsearchresponse.start_time_in_millis.md) | number | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.response.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.response.md deleted file mode 100644 index 9370e21542e37..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.response.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AsyncSearchResponse](./kibana-plugin-plugins-data-server.asyncsearchresponse.md) > [response](./kibana-plugin-plugins-data-server.asyncsearchresponse.response.md) - -## AsyncSearchResponse.response property - -Signature: - -```typescript -response: estypes.SearchResponse; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.start_time_in_millis.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.start_time_in_millis.md deleted file mode 100644 index 91db5f06d9b2f..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.asyncsearchresponse.start_time_in_millis.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [AsyncSearchResponse](./kibana-plugin-plugins-data-server.asyncsearchresponse.md) > [start\_time\_in\_millis](./kibana-plugin-plugins-data-server.asyncsearchresponse.start_time_in_millis.md) - -## AsyncSearchResponse.start\_time\_in\_millis property - -Signature: - -```typescript -start_time_in_millis: number; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.bucket_types.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.bucket_types.md deleted file mode 100644 index 568e435754545..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.bucket_types.md +++ /dev/null @@ -1,28 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [BUCKET\_TYPES](./kibana-plugin-plugins-data-server.bucket_types.md) - -## BUCKET\_TYPES enum - -Signature: - -```typescript -export declare enum BUCKET_TYPES -``` - -## Enumeration Members - -| Member | Value | Description | -| --- | --- | --- | -| DATE\_HISTOGRAM | "date_histogram" | | -| DATE\_RANGE | "date_range" | | -| FILTER | "filter" | | -| FILTERS | "filters" | | -| GEOHASH\_GRID | "geohash_grid" | | -| GEOTILE\_GRID | "geotile_grid" | | -| HISTOGRAM | "histogram" | | -| IP\_RANGE | "ip_range" | | -| RANGE | "range" | | -| SIGNIFICANT\_TERMS | "significant_terms" | | -| TERMS | "terms" | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.buildqueryfromfilters.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.buildqueryfromfilters.md deleted file mode 100644 index 83cbcd016f92a..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.buildqueryfromfilters.md +++ /dev/null @@ -1,21 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [buildQueryFromFilters](./kibana-plugin-plugins-data-server.buildqueryfromfilters.md) - -## buildQueryFromFilters variable - -> Warning: This API is now obsolete. -> -> Import from the "@kbn/es-query" package directly instead. 8.1 -> - -Signature: - -```typescript -buildQueryFromFilters: (filters: oldFilter[] | undefined, indexPattern: import("@kbn/es-query").IndexPatternBase | undefined, ignoreFilterIfFieldNotInIndex?: boolean | undefined) => { - must: never[]; - filter: oldFilter[]; - should: never[]; - must_not: oldFilter[]; -} -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.esaggsexpressionfunctiondefinition.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.esaggsexpressionfunctiondefinition.md deleted file mode 100644 index 572c4e0c1eb2f..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.esaggsexpressionfunctiondefinition.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [EsaggsExpressionFunctionDefinition](./kibana-plugin-plugins-data-server.esaggsexpressionfunctiondefinition.md) - -## EsaggsExpressionFunctionDefinition type - -Signature: - -```typescript -export declare type EsaggsExpressionFunctionDefinition = ExpressionFunctionDefinition<'esaggs', Input, Arguments, Output>; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.eskuery.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.eskuery.md index 4989b2b5ad584..f0261648e32ab 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.eskuery.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.eskuery.md @@ -10,6 +10,6 @@ esKuery: { nodeTypes: import("@kbn/es-query/target_types/kuery/node_types").NodeTypes; fromKueryExpression: (expression: any, parseOptions?: Partial | undefined) => import("@kbn/es-query").KueryNode; - toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: Record | undefined, context?: Record | undefined) => import("@kbn/common-utils").JsonObject; + toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: Record | undefined, context?: Record | undefined) => import("@kbn/utility-types").JsonObject; } ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.executioncontextsearch.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.executioncontextsearch.md deleted file mode 100644 index 2f94dbe970d44..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.executioncontextsearch.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ExecutionContextSearch](./kibana-plugin-plugins-data-server.executioncontextsearch.md) - -## ExecutionContextSearch type - -Signature: - -```typescript -export declare type ExecutionContextSearch = { - filters?: Filter[]; - query?: Query | Query[]; - timeRange?: TimeRange; -}; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.expressionfunctionkibana.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.expressionfunctionkibana.md deleted file mode 100644 index d80ff78dd803c..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.expressionfunctionkibana.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ExpressionFunctionKibana](./kibana-plugin-plugins-data-server.expressionfunctionkibana.md) - -## ExpressionFunctionKibana type - -Signature: - -```typescript -export declare type ExpressionFunctionKibana = ExpressionFunctionDefinition<'kibana', ExpressionValueSearchContext | null, object, ExpressionValueSearchContext, ExecutionContext>; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.expressionfunctionkibanacontext.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.expressionfunctionkibanacontext.md deleted file mode 100644 index b67f7b8c4b60d..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.expressionfunctionkibanacontext.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ExpressionFunctionKibanaContext](./kibana-plugin-plugins-data-server.expressionfunctionkibanacontext.md) - -## ExpressionFunctionKibanaContext type - -Signature: - -```typescript -export declare type ExpressionFunctionKibanaContext = ExpressionFunctionDefinition<'kibana_context', KibanaContext | null, Arguments, Promise, ExecutionContext>; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.expressionvaluesearchcontext.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.expressionvaluesearchcontext.md deleted file mode 100644 index 8015482ddec1e..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.expressionvaluesearchcontext.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ExpressionValueSearchContext](./kibana-plugin-plugins-data-server.expressionvaluesearchcontext.md) - -## ExpressionValueSearchContext type - -Signature: - -```typescript -export declare type ExpressionValueSearchContext = ExpressionValueBoxed<'kibana_context', ExecutionContextSearch>; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md deleted file mode 100644 index 19a4bbbbef86c..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getdefaultsearchparams.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [getDefaultSearchParams](./kibana-plugin-plugins-data-server.getdefaultsearchparams.md) - -## getDefaultSearchParams() function - -Signature: - -```typescript -export declare function getDefaultSearchParams(uiSettingsClient: IUiSettingsClient): Promise>; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| uiSettingsClient | IUiSettingsClient | | - -Returns: - -`Promise>` - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getshardtimeout.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getshardtimeout.md deleted file mode 100644 index 87aa32608eb14..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.getshardtimeout.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [getShardTimeout](./kibana-plugin-plugins-data-server.getshardtimeout.md) - -## getShardTimeout() function - -Signature: - -```typescript -export declare function getShardTimeout(config: SharedGlobalConfig): Pick; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| config | SharedGlobalConfig | | - -Returns: - -`Pick` - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iaggconfig.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iaggconfig.md deleted file mode 100644 index 261b6e0b3bac1..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iaggconfig.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IAggConfig](./kibana-plugin-plugins-data-server.iaggconfig.md) - -## IAggConfig type - - AggConfig - - This class represents an aggregation, which is displayed in the left-hand nav of the Visualize app. - -Signature: - -```typescript -export declare type IAggConfig = AggConfig; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iaggtype.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iaggtype.md deleted file mode 100644 index d5868e1b0917e..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iaggtype.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IAggType](./kibana-plugin-plugins-data-server.iaggtype.md) - -## IAggType type - -Signature: - -```typescript -export declare type IAggType = AggType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldparamtype.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldparamtype.md deleted file mode 100644 index 4937245647f4e..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldparamtype.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IFieldParamType](./kibana-plugin-plugins-data-server.ifieldparamtype.md) - -## IFieldParamType type - -Signature: - -```typescript -export declare type IFieldParamType = FieldParamType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.imetricaggtype.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.imetricaggtype.md deleted file mode 100644 index ae779c2b1510f..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.imetricaggtype.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IMetricAggType](./kibana-plugin-plugins-data-server.imetricaggtype.md) - -## IMetricAggType type - -Signature: - -```typescript -export declare type IMetricAggType = MetricAggType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternloadexpressionfunctiondefinition.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternloadexpressionfunctiondefinition.md deleted file mode 100644 index c54802aa42e25..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternloadexpressionfunctiondefinition.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IndexPatternLoadExpressionFunctionDefinition](./kibana-plugin-plugins-data-server.indexpatternloadexpressionfunctiondefinition.md) - -## IndexPatternLoadExpressionFunctionDefinition type - -Signature: - -```typescript -export declare type IndexPatternLoadExpressionFunctionDefinition = ExpressionFunctionDefinition; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatterns.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatterns.md deleted file mode 100644 index 935d7fbacf946..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatterns.md +++ /dev/null @@ -1,14 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [indexPatterns](./kibana-plugin-plugins-data-server.indexpatterns.md) - -## indexPatterns variable - -Signature: - -```typescript -indexPatterns: { - isFilterable: typeof isFilterable; - isNestedField: typeof isNestedField; -} -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsserviceprovider.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsserviceprovider.md deleted file mode 100644 index b5c7d8931ad4b..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsserviceprovider.md +++ /dev/null @@ -1,19 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IndexPatternsServiceProvider](./kibana-plugin-plugins-data-server.indexpatternsserviceprovider.md) - -## IndexPatternsServiceProvider class - -Signature: - -```typescript -export declare class IndexPatternsServiceProvider implements Plugin -``` - -## Methods - -| Method | Modifiers | Description | -| --- | --- | --- | -| [setup(core, { expressions, usageCollection })](./kibana-plugin-plugins-data-server.indexpatternsserviceprovider.setup.md) | | | -| [start(core, { fieldFormats, logger })](./kibana-plugin-plugins-data-server.indexpatternsserviceprovider.start.md) | | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsserviceprovider.setup.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsserviceprovider.setup.md deleted file mode 100644 index aadd32b54b294..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsserviceprovider.setup.md +++ /dev/null @@ -1,23 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IndexPatternsServiceProvider](./kibana-plugin-plugins-data-server.indexpatternsserviceprovider.md) > [setup](./kibana-plugin-plugins-data-server.indexpatternsserviceprovider.setup.md) - -## IndexPatternsServiceProvider.setup() method - -Signature: - -```typescript -setup(core: CoreSetup, { expressions, usageCollection }: IndexPatternsServiceSetupDeps): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| core | CoreSetup<IndexPatternsServiceStartDeps, DataPluginStart> | | -| { expressions, usageCollection } | IndexPatternsServiceSetupDeps | | - -Returns: - -`void` - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsserviceprovider.start.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsserviceprovider.start.md deleted file mode 100644 index 7559695a0a331..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsserviceprovider.start.md +++ /dev/null @@ -1,27 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IndexPatternsServiceProvider](./kibana-plugin-plugins-data-server.indexpatternsserviceprovider.md) > [start](./kibana-plugin-plugins-data-server.indexpatternsserviceprovider.start.md) - -## IndexPatternsServiceProvider.start() method - -Signature: - -```typescript -start(core: CoreStart, { fieldFormats, logger }: IndexPatternsServiceStartDeps): { - indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: ElasticsearchClient) => Promise; - }; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| core | CoreStart | | -| { fieldFormats, logger } | IndexPatternsServiceStartDeps | | - -Returns: - -`{ - indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: ElasticsearchClient) => Promise; - }` - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.aggs.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.aggs.md deleted file mode 100644 index 86bd4ab694e11..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.aggs.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchSetup](./kibana-plugin-plugins-data-server.isearchsetup.md) > [aggs](./kibana-plugin-plugins-data-server.isearchsetup.aggs.md) - -## ISearchSetup.aggs property - -Signature: - -```typescript -aggs: AggsSetup; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.md deleted file mode 100644 index 3e27140e8bc08..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.md +++ /dev/null @@ -1,20 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchSetup](./kibana-plugin-plugins-data-server.isearchsetup.md) - -## ISearchSetup interface - -Signature: - -```typescript -export interface ISearchSetup -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [aggs](./kibana-plugin-plugins-data-server.isearchsetup.aggs.md) | AggsSetup | | -| [registerSearchStrategy](./kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md) | <SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest, SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse>(name: string, strategy: ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse>) => void | Extension point exposed for other plugins to register their own search strategies. | -| [usage](./kibana-plugin-plugins-data-server.isearchsetup.usage.md) | SearchUsage | Used internally for telemetry | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md deleted file mode 100644 index 81571d343495c..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchSetup](./kibana-plugin-plugins-data-server.isearchsetup.md) > [registerSearchStrategy](./kibana-plugin-plugins-data-server.isearchsetup.registersearchstrategy.md) - -## ISearchSetup.registerSearchStrategy property - -Extension point exposed for other plugins to register their own search strategies. - -Signature: - -```typescript -registerSearchStrategy: (name: string, strategy: ISearchStrategy) => void; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.usage.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.usage.md deleted file mode 100644 index 1a94a709cc214..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchsetup.usage.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchSetup](./kibana-plugin-plugins-data-server.isearchsetup.md) > [usage](./kibana-plugin-plugins-data-server.isearchsetup.usage.md) - -## ISearchSetup.usage property - -Used internally for telemetry - -Signature: - -```typescript -usage?: SearchUsage; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.aggs.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.aggs.md deleted file mode 100644 index 8da429a07708c..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.aggs.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) > [aggs](./kibana-plugin-plugins-data-server.isearchstart.aggs.md) - -## ISearchStart.aggs property - -Signature: - -```typescript -aggs: AggsStart; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.asscoped.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.asscoped.md deleted file mode 100644 index 1c65aeb8f137f..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.asscoped.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) > [asScoped](./kibana-plugin-plugins-data-server.isearchstart.asscoped.md) - -## ISearchStart.asScoped property - -Signature: - -```typescript -asScoped: (request: KibanaRequest) => IScopedSearchClient; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md deleted file mode 100644 index 9820e281c3f93..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) > [getSearchStrategy](./kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md) - -## ISearchStart.getSearchStrategy property - -Get other registered search strategies by name (or, by default, the Elasticsearch strategy). For example, if a new strategy needs to use the already-registered ES search strategy, it can use this function to accomplish that. - -Signature: - -```typescript -getSearchStrategy: (name?: string) => ISearchStrategy; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md deleted file mode 100644 index 5a1b0cd265300..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) - -## ISearchStart interface - -Signature: - -```typescript -export interface ISearchStart -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [aggs](./kibana-plugin-plugins-data-server.isearchstart.aggs.md) | AggsStart | | -| [asScoped](./kibana-plugin-plugins-data-server.isearchstart.asscoped.md) | (request: KibanaRequest) => IScopedSearchClient | | -| [getSearchStrategy](./kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md) | (name?: string) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse> | Get other registered search strategies by name (or, by default, the Elasticsearch strategy). For example, if a new strategy needs to use the already-registered ES search strategy, it can use this function to accomplish that. | -| [searchAsInternalUser](./kibana-plugin-plugins-data-server.isearchstart.searchasinternaluser.md) | ISearchStrategy | Search as the internal Kibana system user. This is not a registered search strategy as we don't want to allow access from the client. | -| [searchSource](./kibana-plugin-plugins-data-server.isearchstart.searchsource.md) | {
asScoped: (request: KibanaRequest) => Promise<ISearchStartSearchSource>;
} | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.searchasinternaluser.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.searchasinternaluser.md deleted file mode 100644 index f6a18dafc8518..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.searchasinternaluser.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) > [searchAsInternalUser](./kibana-plugin-plugins-data-server.isearchstart.searchasinternaluser.md) - -## ISearchStart.searchAsInternalUser property - -Search as the internal Kibana system user. This is not a registered search strategy as we don't want to allow access from the client. - -Signature: - -```typescript -searchAsInternalUser: ISearchStrategy; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.searchsource.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.searchsource.md deleted file mode 100644 index 66a43fe29c43b..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.searchsource.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) > [searchSource](./kibana-plugin-plugins-data-server.isearchstart.searchsource.md) - -## ISearchStart.searchSource property - -Signature: - -```typescript -searchSource: { - asScoped: (request: KibanaRequest) => Promise; - }; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kibanacontext.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kibanacontext.md deleted file mode 100644 index 1ddc43c633b26..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kibanacontext.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [KibanaContext](./kibana-plugin-plugins-data-server.kibanacontext.md) - -## KibanaContext type - -Signature: - -```typescript -export declare type KibanaContext = ExpressionValueSearchContext; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md index 0363aa1ce6442..9c3d0f6f41d0a 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md @@ -8,21 +8,17 @@ | Class | Description | | --- | --- | -| [AggParamType](./kibana-plugin-plugins-data-server.aggparamtype.md) | | | [IndexPattern](./kibana-plugin-plugins-data-server.indexpattern.md) | | | [IndexPatternField](./kibana-plugin-plugins-data-server.indexpatternfield.md) | | | [IndexPatternsFetcher](./kibana-plugin-plugins-data-server.indexpatternsfetcher.md) | | | [IndexPatternsService](./kibana-plugin-plugins-data-server.indexpatternsservice.md) | | -| [IndexPatternsServiceProvider](./kibana-plugin-plugins-data-server.indexpatternsserviceprovider.md) | | | [NoSearchIdInSessionError](./kibana-plugin-plugins-data-server.nosearchidinsessionerror.md) | | -| [OptionedParamType](./kibana-plugin-plugins-data-server.optionedparamtype.md) | | | [Plugin](./kibana-plugin-plugins-data-server.plugin.md) | | ## Enumerations | Enumeration | Description | | --- | --- | -| [BUCKET\_TYPES](./kibana-plugin-plugins-data-server.bucket_types.md) | | | [METRIC\_TYPES](./kibana-plugin-plugins-data-server.metric_types.md) | | ## Functions @@ -30,23 +26,16 @@ | Function | Description | | --- | --- | | [getCapabilitiesForRollupIndices(indices)](./kibana-plugin-plugins-data-server.getcapabilitiesforrollupindices.md) | | -| [getDefaultSearchParams(uiSettingsClient)](./kibana-plugin-plugins-data-server.getdefaultsearchparams.md) | | | [getEsQueryConfig(config)](./kibana-plugin-plugins-data-server.getesqueryconfig.md) | | -| [getShardTimeout(config)](./kibana-plugin-plugins-data-server.getshardtimeout.md) | | | [getTime(indexPattern, timeRange, options)](./kibana-plugin-plugins-data-server.gettime.md) | | | [parseInterval(interval)](./kibana-plugin-plugins-data-server.parseinterval.md) | | | [plugin(initializerContext)](./kibana-plugin-plugins-data-server.plugin.md) | Static code to be shared externally | -| [searchUsageObserver(logger, usage, { isRestore })](./kibana-plugin-plugins-data-server.searchusageobserver.md) | Rxjs observer for easily doing tap(searchUsageObserver(logger, usage)) in an rxjs chain. | | [shouldReadFieldFromDocValues(aggregatable, esType)](./kibana-plugin-plugins-data-server.shouldreadfieldfromdocvalues.md) | | -| [usageProvider(core)](./kibana-plugin-plugins-data-server.usageprovider.md) | | ## Interfaces | Interface | Description | | --- | --- | -| [AggFunctionsMapping](./kibana-plugin-plugins-data-server.aggfunctionsmapping.md) | A global list of the expression function definitions for each agg type function. | -| [AggParamOption](./kibana-plugin-plugins-data-server.aggparamoption.md) | | -| [AsyncSearchResponse](./kibana-plugin-plugins-data-server.asyncsearchresponse.md) | | | [AsyncSearchStatusResponse](./kibana-plugin-plugins-data-server.asyncsearchstatusresponse.md) | | | [FieldDescriptor](./kibana-plugin-plugins-data-server.fielddescriptor.md) | | | [IEsSearchRequest](./kibana-plugin-plugins-data-server.iessearchrequest.md) | | @@ -55,23 +44,15 @@ | [IScopedSearchClient](./kibana-plugin-plugins-data-server.iscopedsearchclient.md) | | | [ISearchOptions](./kibana-plugin-plugins-data-server.isearchoptions.md) | | | [ISearchSessionService](./kibana-plugin-plugins-data-server.isearchsessionservice.md) | | -| [ISearchSetup](./kibana-plugin-plugins-data-server.isearchsetup.md) | | -| [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) | | | [ISearchStrategy](./kibana-plugin-plugins-data-server.isearchstrategy.md) | Search strategy interface contains a search method that takes in a request and returns a promise that resolves to a response. | -| [OptionedValueProp](./kibana-plugin-plugins-data-server.optionedvalueprop.md) | | | [PluginSetup](./kibana-plugin-plugins-data-server.pluginsetup.md) | | | [PluginStart](./kibana-plugin-plugins-data-server.pluginstart.md) | | -| [RefreshInterval](./kibana-plugin-plugins-data-server.refreshinterval.md) | | | [SearchStrategyDependencies](./kibana-plugin-plugins-data-server.searchstrategydependencies.md) | | -| [SearchUsage](./kibana-plugin-plugins-data-server.searchusage.md) | | ## Variables | Variable | Description | | --- | --- | -| [AggGroupLabels](./kibana-plugin-plugins-data-server.agggrouplabels.md) | | -| [AggGroupNames](./kibana-plugin-plugins-data-server.agggroupnames.md) | | -| [buildQueryFromFilters](./kibana-plugin-plugins-data-server.buildqueryfromfilters.md) | | | [castEsToKbnFieldTypeName](./kibana-plugin-plugins-data-server.castestokbnfieldtypename.md) | | | [config](./kibana-plugin-plugins-data-server.config.md) | | | [ES\_SEARCH\_STRATEGY](./kibana-plugin-plugins-data-server.es_search_strategy.md) | | @@ -80,8 +61,6 @@ | [esQuery](./kibana-plugin-plugins-data-server.esquery.md) | | | [exporters](./kibana-plugin-plugins-data-server.exporters.md) | | | [INDEX\_PATTERN\_SAVED\_OBJECT\_TYPE](./kibana-plugin-plugins-data-server.index_pattern_saved_object_type.md) | \* | -| [indexPatterns](./kibana-plugin-plugins-data-server.indexpatterns.md) | | -| [mergeCapabilitiesWithFields](./kibana-plugin-plugins-data-server.mergecapabilitieswithfields.md) | | | [search](./kibana-plugin-plugins-data-server.search.md) | | | [UI\_SETTINGS](./kibana-plugin-plugins-data-server.ui_settings.md) | | @@ -89,24 +68,10 @@ | Type Alias | Description | | --- | --- | -| [AggConfigOptions](./kibana-plugin-plugins-data-server.aggconfigoptions.md) | | -| [AggGroupName](./kibana-plugin-plugins-data-server.agggroupname.md) | | -| [AggParam](./kibana-plugin-plugins-data-server.aggparam.md) | | -| [EsaggsExpressionFunctionDefinition](./kibana-plugin-plugins-data-server.esaggsexpressionfunctiondefinition.md) | | | [EsQueryConfig](./kibana-plugin-plugins-data-server.esqueryconfig.md) | | -| [ExecutionContextSearch](./kibana-plugin-plugins-data-server.executioncontextsearch.md) | | -| [ExpressionFunctionKibana](./kibana-plugin-plugins-data-server.expressionfunctionkibana.md) | | -| [ExpressionFunctionKibanaContext](./kibana-plugin-plugins-data-server.expressionfunctionkibanacontext.md) | | -| [ExpressionValueSearchContext](./kibana-plugin-plugins-data-server.expressionvaluesearchcontext.md) | | | [Filter](./kibana-plugin-plugins-data-server.filter.md) | | -| [IAggConfig](./kibana-plugin-plugins-data-server.iaggconfig.md) | AggConfig This class represents an aggregation, which is displayed in the left-hand nav of the Visualize app. | -| [IAggType](./kibana-plugin-plugins-data-server.iaggtype.md) | | | [IEsSearchResponse](./kibana-plugin-plugins-data-server.iessearchresponse.md) | | -| [IFieldParamType](./kibana-plugin-plugins-data-server.ifieldparamtype.md) | | | [IFieldSubType](./kibana-plugin-plugins-data-server.ifieldsubtype.md) | | -| [IMetricAggType](./kibana-plugin-plugins-data-server.imetricaggtype.md) | | -| [IndexPatternLoadExpressionFunctionDefinition](./kibana-plugin-plugins-data-server.indexpatternloadexpressionfunctiondefinition.md) | | -| [KibanaContext](./kibana-plugin-plugins-data-server.kibanacontext.md) | | | [KueryNode](./kibana-plugin-plugins-data-server.kuerynode.md) | | | [ParsedInterval](./kibana-plugin-plugins-data-server.parsedinterval.md) | | | [SearchRequestHandlerContext](./kibana-plugin-plugins-data-server.searchrequesthandlercontext.md) | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.mergecapabilitieswithfields.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.mergecapabilitieswithfields.md deleted file mode 100644 index 4befc100c1089..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.mergecapabilitieswithfields.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [mergeCapabilitiesWithFields](./kibana-plugin-plugins-data-server.mergecapabilitieswithfields.md) - -## mergeCapabilitiesWithFields variable - -Signature: - -```typescript -mergeCapabilitiesWithFields: (rollupIndexCapabilities: { - [key: string]: any; -}, fieldsFromFieldCapsApi: Record, previousFields?: FieldDescriptor[]) => FieldDescriptor[] -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedparamtype._constructor_.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedparamtype._constructor_.md deleted file mode 100644 index 3b2fd2218709a..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedparamtype._constructor_.md +++ /dev/null @@ -1,20 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [OptionedParamType](./kibana-plugin-plugins-data-server.optionedparamtype.md) > [(constructor)](./kibana-plugin-plugins-data-server.optionedparamtype._constructor_.md) - -## OptionedParamType.(constructor) - -Constructs a new instance of the `OptionedParamType` class - -Signature: - -```typescript -constructor(config: Record); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| config | Record<string, any> | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedparamtype.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedparamtype.md deleted file mode 100644 index 6bf2ef4baa915..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedparamtype.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [OptionedParamType](./kibana-plugin-plugins-data-server.optionedparamtype.md) - -## OptionedParamType class - -Signature: - -```typescript -export declare class OptionedParamType extends BaseParamType -``` - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(config)](./kibana-plugin-plugins-data-server.optionedparamtype._constructor_.md) | | Constructs a new instance of the OptionedParamType class | - -## Properties - -| Property | Modifiers | Type | Description | -| --- | --- | --- | --- | -| [options](./kibana-plugin-plugins-data-server.optionedparamtype.options.md) | | OptionedValueProp[] | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedparamtype.options.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedparamtype.options.md deleted file mode 100644 index 868619ad5a9e0..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedparamtype.options.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [OptionedParamType](./kibana-plugin-plugins-data-server.optionedparamtype.md) > [options](./kibana-plugin-plugins-data-server.optionedparamtype.options.md) - -## OptionedParamType.options property - -Signature: - -```typescript -options: OptionedValueProp[]; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.disabled.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.disabled.md deleted file mode 100644 index e0a21a8727614..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.disabled.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [OptionedValueProp](./kibana-plugin-plugins-data-server.optionedvalueprop.md) > [disabled](./kibana-plugin-plugins-data-server.optionedvalueprop.disabled.md) - -## OptionedValueProp.disabled property - -Signature: - -```typescript -disabled?: boolean; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.iscompatible.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.iscompatible.md deleted file mode 100644 index de3ecc0b97a64..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.iscompatible.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [OptionedValueProp](./kibana-plugin-plugins-data-server.optionedvalueprop.md) > [isCompatible](./kibana-plugin-plugins-data-server.optionedvalueprop.iscompatible.md) - -## OptionedValueProp.isCompatible property - -Signature: - -```typescript -isCompatible: (agg: IAggConfig) => boolean; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.md deleted file mode 100644 index ef2440035c83b..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.md +++ /dev/null @@ -1,21 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [OptionedValueProp](./kibana-plugin-plugins-data-server.optionedvalueprop.md) - -## OptionedValueProp interface - -Signature: - -```typescript -export interface OptionedValueProp -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [disabled](./kibana-plugin-plugins-data-server.optionedvalueprop.disabled.md) | boolean | | -| [isCompatible](./kibana-plugin-plugins-data-server.optionedvalueprop.iscompatible.md) | (agg: IAggConfig) => boolean | | -| [text](./kibana-plugin-plugins-data-server.optionedvalueprop.text.md) | string | | -| [value](./kibana-plugin-plugins-data-server.optionedvalueprop.value.md) | string | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.text.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.text.md deleted file mode 100644 index 0a2b3ac708038..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.text.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [OptionedValueProp](./kibana-plugin-plugins-data-server.optionedvalueprop.md) > [text](./kibana-plugin-plugins-data-server.optionedvalueprop.text.md) - -## OptionedValueProp.text property - -Signature: - -```typescript -text: string; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.value.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.value.md deleted file mode 100644 index 76618558d0479..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.optionedvalueprop.value.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [OptionedValueProp](./kibana-plugin-plugins-data-server.optionedvalueprop.md) > [value](./kibana-plugin-plugins-data-server.optionedvalueprop.value.md) - -## OptionedValueProp.value property - -Signature: - -```typescript -value: string; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md deleted file mode 100644 index ebb983de29942..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.md +++ /dev/null @@ -1,19 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [RefreshInterval](./kibana-plugin-plugins-data-server.refreshinterval.md) - -## RefreshInterval interface - -Signature: - -```typescript -export interface RefreshInterval -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [pause](./kibana-plugin-plugins-data-server.refreshinterval.pause.md) | boolean | | -| [value](./kibana-plugin-plugins-data-server.refreshinterval.value.md) | number | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.pause.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.pause.md deleted file mode 100644 index d045a3c0b9a21..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.pause.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [RefreshInterval](./kibana-plugin-plugins-data-server.refreshinterval.md) > [pause](./kibana-plugin-plugins-data-server.refreshinterval.pause.md) - -## RefreshInterval.pause property - -Signature: - -```typescript -pause: boolean; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.value.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.value.md deleted file mode 100644 index 8b48d97a649c0..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.refreshinterval.value.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [RefreshInterval](./kibana-plugin-plugins-data-server.refreshinterval.md) > [value](./kibana-plugin-plugins-data-server.refreshinterval.value.md) - -## RefreshInterval.value property - -Signature: - -```typescript -value: number; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.search.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.search.md index 7072f25489db2..79ff117a33050 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.search.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.search.md @@ -11,32 +11,9 @@ search: { aggs: { CidrMask: typeof CidrMask; dateHistogramInterval: typeof dateHistogramInterval; - intervalOptions: ({ - display: string; - val: string; - enabled(agg: import("../common").IBucketAggConfig): boolean; - } | { - display: string; - val: string; - })[]; - InvalidEsCalendarIntervalError: typeof InvalidEsCalendarIntervalError; - InvalidEsIntervalFormatError: typeof InvalidEsIntervalFormatError; IpAddress: typeof IpAddress; - isNumberType: (agg: import("../common").AggConfig) => boolean; - isStringType: (agg: import("../common").AggConfig) => boolean; - isType: (...types: string[]) => (agg: import("../common").AggConfig) => boolean; - isValidEsInterval: typeof isValidEsInterval; - isValidInterval: typeof isValidInterval; - parentPipelineType: string; - parseEsInterval: typeof parseEsInterval; parseInterval: typeof parseInterval; - propFilter: typeof propFilter; - siblingPipelineType: string; - termsAggFilter: string[]; - toAbsoluteDates: typeof toAbsoluteDates; calcAutoIntervalLessThan: typeof calcAutoIntervalLessThan; }; - tabifyAggResponse: typeof tabifyAggResponse; - tabifyGetColumns: typeof tabifyGetColumns; } ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusage.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusage.md deleted file mode 100644 index d867509e915b6..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusage.md +++ /dev/null @@ -1,19 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchUsage](./kibana-plugin-plugins-data-server.searchusage.md) - -## SearchUsage interface - -Signature: - -```typescript -export interface SearchUsage -``` - -## Methods - -| Method | Description | -| --- | --- | -| [trackError()](./kibana-plugin-plugins-data-server.searchusage.trackerror.md) | | -| [trackSuccess(duration)](./kibana-plugin-plugins-data-server.searchusage.tracksuccess.md) | | - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusage.trackerror.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusage.trackerror.md deleted file mode 100644 index 212133588f62d..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusage.trackerror.md +++ /dev/null @@ -1,15 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchUsage](./kibana-plugin-plugins-data-server.searchusage.md) > [trackError](./kibana-plugin-plugins-data-server.searchusage.trackerror.md) - -## SearchUsage.trackError() method - -Signature: - -```typescript -trackError(): Promise; -``` -Returns: - -`Promise` - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusage.tracksuccess.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusage.tracksuccess.md deleted file mode 100644 index b58f440c7dccf..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusage.tracksuccess.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [SearchUsage](./kibana-plugin-plugins-data-server.searchusage.md) > [trackSuccess](./kibana-plugin-plugins-data-server.searchusage.tracksuccess.md) - -## SearchUsage.trackSuccess() method - -Signature: - -```typescript -trackSuccess(duration: number): Promise; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| duration | number | | - -Returns: - -`Promise` - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusageobserver.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusageobserver.md deleted file mode 100644 index e9c7b33766e56..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.searchusageobserver.md +++ /dev/null @@ -1,32 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [searchUsageObserver](./kibana-plugin-plugins-data-server.searchusageobserver.md) - -## searchUsageObserver() function - -Rxjs observer for easily doing `tap(searchUsageObserver(logger, usage))` in an rxjs chain. - -Signature: - -```typescript -export declare function searchUsageObserver(logger: Logger, usage?: SearchUsage, { isRestore }?: ISearchOptions): { - next(response: IEsSearchResponse): void; - error(): void; -}; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| logger | Logger | | -| usage | SearchUsage | | -| { isRestore } | ISearchOptions | | - -Returns: - -`{ - next(response: IEsSearchResponse): void; - error(): void; -}` - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.usageprovider.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.usageprovider.md deleted file mode 100644 index ad5c61b5c85a1..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.usageprovider.md +++ /dev/null @@ -1,22 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [usageProvider](./kibana-plugin-plugins-data-server.usageprovider.md) - -## usageProvider() function - -Signature: - -```typescript -export declare function usageProvider(core: CoreSetup): SearchUsage; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| core | CoreSetup | | - -Returns: - -`SearchUsage` - diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md index 07ede291e33d2..77db30e967782 100644 --- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md @@ -13,10 +13,11 @@ export declare type EmbeddableInput = { id: string; lastReloadRequestTime?: number; hidePanelTitles?: boolean; - enhancements?: SerializableState; + enhancements?: SerializableRecord; disabledActions?: string[]; disableTriggers?: boolean; searchSessionId?: string; syncColors?: boolean; + executionContext?: KibanaExecutionContext; }; ``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.md index c54ebe4b1712d..978873b6efbc1 100644 --- a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.md +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.md @@ -7,7 +7,7 @@ Signature: ```typescript -export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

+export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

``` ## Properties diff --git a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.md b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.md index 09ff48a92158d..34462de422218 100644 --- a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.md +++ b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.md @@ -7,7 +7,7 @@ Signature: ```typescript -export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

+export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

``` ## Properties diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.getexecutioncontext.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.getexecutioncontext.md index bfe1925a21f68..bc27adbed1d9a 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.getexecutioncontext.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.getexecutioncontext.md @@ -9,5 +9,5 @@ Contains the meta-data about the source of the expression. Signature: ```typescript -getExecutionContext: () => IExecutionContextContainer | undefined; +getExecutionContext: () => KibanaExecutionContext | undefined; ``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.md index 38165a1683316..8b876a7bcc3d6 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.md @@ -9,7 +9,7 @@ Signature: ```typescript -export interface ExecutionContext +export interface ExecutionContext ``` ## Properties @@ -17,7 +17,7 @@ export interface ExecutionContextAbortSignal | Adds ability to abort current execution. | -| [getExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.getexecutioncontext.md) | () => IExecutionContextContainer | undefined | Contains the meta-data about the source of the expression. | +| [getExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.getexecutioncontext.md) | () => KibanaExecutionContext | undefined | Contains the meta-data about the source of the expression. | | [getKibanaRequest](./kibana-plugin-plugins-expressions-public.executioncontext.getkibanarequest.md) | () => KibanaRequest | Getter to retrieve the KibanaRequest object inside an expression function. Useful for functions which are running on the server and need to perform operations that are scoped to a specific user. | | [getSearchContext](./kibana-plugin-plugins-expressions-public.executioncontext.getsearchcontext.md) | () => ExecutionContextSearch | Get search context of the expression. | | [getSearchSessionId](./kibana-plugin-plugins-expressions-public.executioncontext.getsearchsessionid.md) | () => string | undefined | Search context in which expression should operate. | diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md index 3e75e9ab3ef6f..8a829659e6fb2 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md @@ -29,7 +29,7 @@ export declare class ExpressionFunction implements PersistableStatestring | A short help text. | | [inject](./kibana-plugin-plugins-expressions-public.expressionfunction.inject.md) | | (state: ExpressionAstFunction['arguments'], references: SavedObjectReference[]) => ExpressionAstFunction['arguments'] | | | [inputTypes](./kibana-plugin-plugins-expressions-public.expressionfunction.inputtypes.md) | | string[] | undefined | Type of inputs that this function supports. | -| [migrations](./kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md) | | {
[key: string]: (state: SerializableState) => SerializableState;
} | | +| [migrations](./kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md) | | {
[key: string]: (state: SerializableRecord) => SerializableRecord;
} | | | [name](./kibana-plugin-plugins-expressions-public.expressionfunction.name.md) | | string | Name of function | | [telemetry](./kibana-plugin-plugins-expressions-public.expressionfunction.telemetry.md) | | (state: ExpressionAstFunction['arguments'], telemetryData: Record<string, any>) => Record<string, any> | | | [type](./kibana-plugin-plugins-expressions-public.expressionfunction.type.md) | | string | Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. | diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md index 28d521f4b3fe1..a8b55dae1592f 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.migrations.md @@ -8,6 +8,6 @@ ```typescript migrations: { - [key: string]: (state: SerializableState) => SerializableState; + [key: string]: (state: SerializableRecord) => SerializableRecord; }; ``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueerror.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueerror.md index 1dee4a139c660..6d30d45690844 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueerror.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueerror.md @@ -9,6 +9,6 @@ ```typescript export declare type ExpressionValueError = ExpressionValueBoxed<'error', { error: ErrorLike; - info?: SerializableState; + info?: SerializableRecord; }>; ``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.executioncontext.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.executioncontext.md index 504f5e2df7d6e..c133621424b5f 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.executioncontext.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.executioncontext.md @@ -7,5 +7,5 @@ Signature: ```typescript -executionContext?: IExecutionContextContainer; +executionContext?: KibanaExecutionContext; ``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md index a228628fece0f..fcb0299e3fb68 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md @@ -19,13 +19,13 @@ export interface IExpressionLoaderParams | [customRenderers](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customrenderers.md) | [] | | | [debug](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.debug.md) | boolean | | | [disableCaching](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.disablecaching.md) | boolean | | -| [executionContext](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.executioncontext.md) | IExecutionContextContainer | | +| [executionContext](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.executioncontext.md) | KibanaExecutionContext | | | [hasCompatibleActions](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.hascompatibleactions.md) | ExpressionRenderHandlerParams['hasCompatibleActions'] | | | [inspectorAdapters](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.inspectoradapters.md) | Adapters | | | [onRenderError](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.onrendererror.md) | RenderErrorHandlerFnType | | | [partial](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.partial.md) | boolean | The flag to toggle on emitting partial results. By default, the partial results are disabled. | | [renderMode](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.rendermode.md) | RenderMode | | -| [searchContext](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md) | SerializableState | | +| [searchContext](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md) | SerializableRecord | | | [searchSessionId](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchsessionid.md) | string | | | [syncColors](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.synccolors.md) | boolean | | | [throttle](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.throttle.md) | number | Throttling of partial results in milliseconds. 0 is disabling the throttling. By default, it equals 1000. | diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md index 6b5fad950c4e9..7b832af0e90d8 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md @@ -7,5 +7,5 @@ Signature: ```typescript -searchContext?: SerializableState; +searchContext?: SerializableRecord; ``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.getexecutioncontext.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.getexecutioncontext.md index b4ceb8f96d698..b692ee1611f97 100644 --- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.getexecutioncontext.md +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.getexecutioncontext.md @@ -9,5 +9,5 @@ Contains the meta-data about the source of the expression. Signature: ```typescript -getExecutionContext: () => IExecutionContextContainer | undefined; +getExecutionContext: () => KibanaExecutionContext | undefined; ``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.md index 3b308ca46ab0a..7a7ead6b9b153 100644 --- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.md +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.md @@ -9,7 +9,7 @@ Signature: ```typescript -export interface ExecutionContext +export interface ExecutionContext ``` ## Properties @@ -17,7 +17,7 @@ export interface ExecutionContextAbortSignal | Adds ability to abort current execution. | -| [getExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.getexecutioncontext.md) | () => IExecutionContextContainer | undefined | Contains the meta-data about the source of the expression. | +| [getExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.getexecutioncontext.md) | () => KibanaExecutionContext | undefined | Contains the meta-data about the source of the expression. | | [getKibanaRequest](./kibana-plugin-plugins-expressions-server.executioncontext.getkibanarequest.md) | () => KibanaRequest | Getter to retrieve the KibanaRequest object inside an expression function. Useful for functions which are running on the server and need to perform operations that are scoped to a specific user. | | [getSearchContext](./kibana-plugin-plugins-expressions-server.executioncontext.getsearchcontext.md) | () => ExecutionContextSearch | Get search context of the expression. | | [getSearchSessionId](./kibana-plugin-plugins-expressions-server.executioncontext.getsearchsessionid.md) | () => string | undefined | Search context in which expression should operate. | diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md index 00c8aa63bfbd8..3b3d60cc27366 100644 --- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md @@ -29,7 +29,7 @@ export declare class ExpressionFunction implements PersistableStatestring | A short help text. | | [inject](./kibana-plugin-plugins-expressions-server.expressionfunction.inject.md) | | (state: ExpressionAstFunction['arguments'], references: SavedObjectReference[]) => ExpressionAstFunction['arguments'] | | | [inputTypes](./kibana-plugin-plugins-expressions-server.expressionfunction.inputtypes.md) | | string[] | undefined | Type of inputs that this function supports. | -| [migrations](./kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md) | | {
[key: string]: (state: SerializableState) => SerializableState;
} | | +| [migrations](./kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md) | | {
[key: string]: (state: SerializableRecord) => SerializableRecord;
} | | | [name](./kibana-plugin-plugins-expressions-server.expressionfunction.name.md) | | string | Name of function | | [telemetry](./kibana-plugin-plugins-expressions-server.expressionfunction.telemetry.md) | | (state: ExpressionAstFunction['arguments'], telemetryData: Record<string, any>) => Record<string, any> | | | [type](./kibana-plugin-plugins-expressions-server.expressionfunction.type.md) | | string | Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. | diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md index 29031a9306b2f..5d9410b62bb13 100644 --- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.migrations.md @@ -8,6 +8,6 @@ ```typescript migrations: { - [key: string]: (state: SerializableState) => SerializableState; + [key: string]: (state: SerializableRecord) => SerializableRecord; }; ``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueerror.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueerror.md index c8132948a8993..2a4f4dc7aab70 100644 --- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueerror.md +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueerror.md @@ -9,6 +9,6 @@ ```typescript export declare type ExpressionValueError = ExpressionValueBoxed<'error', { error: ErrorLike; - info?: SerializableState; + info?: SerializableRecord; }>; ``` diff --git a/docs/setup/connect-to-elasticsearch.asciidoc b/docs/setup/connect-to-elasticsearch.asciidoc index 880c98902983f..25af236845abe 100644 --- a/docs/setup/connect-to-elasticsearch.asciidoc +++ b/docs/setup/connect-to-elasticsearch.asciidoc @@ -46,18 +46,30 @@ image::images/add-data-fleet.png[Add data using Fleet] [[upload-data-kibana]] === Upload a file -experimental[] If your data is in a CSV, JSON, or log file, you can upload it using the {file-data-viz}. You can upload a file up to 100 MB. This value is configurable up to 1 GB in -<>. To upload a file with geospatial data, -refer to <>. +If you have a log file or delimited CSV, TSV, or JSON file, you can upload it, +view its fields and metrics, and optionally import it into {es}. -[role="screenshot"] -image::images/add-data-fv.png[File Data Visualizer] +NOTE: This feature is not intended for use as part of a repeated production +process, but rather for the initial exploration of your data. + +You can upload a file up to 100 MB. This value is configurable up to 1 GB in +<>. To upload a file with geospatial +data, refer to <>. +[role="screenshot"] +image::images/add-data-fv.png[Uploading a file in {kib}] +The {stack-security-features} provide roles and privileges that control which +users can upload files. To upload a file in {kib} and import it into an {es} +index, you'll need: -NOTE: This feature is not intended for use as part of a -repeated production process, but rather for the initial exploration of your data. +* `all` {kib} privileges for *Discover* +* `manage_pipeline` or `manage_ingest_pipelines` cluster privilege +* `create`, `create_index`, `manage`, and `read` index privileges for the index +You can manage your roles, privileges, and spaces in **{stack-manage-app}** in +{kib}. For more information, refer to +<>. [discrete] === Additional options for loading your data diff --git a/docs/user/ml/index.asciidoc b/docs/user/ml/index.asciidoc index a05ff1eeec4a6..842d7cb054f32 100644 --- a/docs/user/ml/index.asciidoc +++ b/docs/user/ml/index.asciidoc @@ -17,7 +17,7 @@ if your data is stored in {es} and contains a time field, you can use the [role="screenshot"] image::user/ml/images/ml-data-visualizer-sample.jpg[{data-viz} for sample flight data] -experimental[] You can also upload a CSV, NDJSON, or log file. The *{data-viz}* +You can also upload a CSV, NDJSON, or log file. The *{data-viz}* identifies the file format and field mappings. You can then optionally import that data into an {es} index. To change the default file size limit, see <>. diff --git a/examples/bfetch_explorer/kibana.json b/examples/bfetch_explorer/kibana.json index f32cdfc13a1fe..4bd4492611812 100644 --- a/examples/bfetch_explorer/kibana.json +++ b/examples/bfetch_explorer/kibana.json @@ -1,7 +1,7 @@ { "id": "bfetchExplorer", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", "server": true, "ui": true, "requiredPlugins": ["bfetch", "developerExamples"], diff --git a/examples/dashboard_embeddable_examples/kibana.json b/examples/dashboard_embeddable_examples/kibana.json index 0753765d99576..e13f19194ef06 100644 --- a/examples/dashboard_embeddable_examples/kibana.json +++ b/examples/dashboard_embeddable_examples/kibana.json @@ -1,10 +1,21 @@ { "id": "dashboardEmbeddableExamples", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", "server": false, "ui": true, - "requiredPlugins": ["embeddable", "embeddableExamples", "dashboard", "developerExamples", "kibanaReact"], + "requiredPlugins": [ + "embeddable", + "embeddableExamples", + "dashboard", + "developerExamples", + "kibanaReact" + ], + "owner": { + "name": "Presentation", + "githubTeam": "kibana-presentation" + }, + "description": "Example app that shows how to embed a dashboard in an application", "optionalPlugins": [], "requiredBundles": ["esUiShared"] } diff --git a/examples/developer_examples/kibana.json b/examples/developer_examples/kibana.json index 8c9ec2e4dcbfc..9e6b54c7af67c 100644 --- a/examples/developer_examples/kibana.json +++ b/examples/developer_examples/kibana.json @@ -1,9 +1,6 @@ { "id": "developerExamples", - "version": "0.0.1", "kibanaVersion": "kibana", - "server": false, - "ui": true, - "requiredPlugins": [], - "optionalPlugins": [] + "version": "0.0.1", + "ui": true } diff --git a/examples/embeddable_examples/kibana.json b/examples/embeddable_examples/kibana.json index 6025d24665901..d725a5c94a9c8 100644 --- a/examples/embeddable_examples/kibana.json +++ b/examples/embeddable_examples/kibana.json @@ -1,9 +1,14 @@ { "id": "embeddableExamples", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", "server": true, "ui": true, + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, + "description": "Example app that shows how to register custom embeddables", "requiredPlugins": ["embeddable", "uiActions", "savedObjects", "dashboard"], "optionalPlugins": [], "extraPublicDirs": ["public/todo", "public/hello_world", "public/todo/todo_ref_embeddable"], diff --git a/examples/embeddable_explorer/kibana.json b/examples/embeddable_explorer/kibana.json index 3eb2e2fa10f84..6ca12eb2e2a30 100644 --- a/examples/embeddable_explorer/kibana.json +++ b/examples/embeddable_explorer/kibana.json @@ -1,9 +1,23 @@ { "id": "embeddableExplorer", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", "server": false, "ui": true, - "requiredPlugins": ["uiActions", "inspector", "embeddable", "embeddableExamples", "developerExamples", "dashboard", "kibanaReact", "savedObjects"], + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, + "description": "Example app that relies on registered functionality in the embeddable_examples plugin", + "requiredPlugins": [ + "uiActions", + "inspector", + "embeddable", + "embeddableExamples", + "developerExamples", + "dashboard", + "kibanaReact", + "savedObjects" + ], "optionalPlugins": [] } diff --git a/examples/expressions_explorer/kibana.json b/examples/expressions_explorer/kibana.json index 038b7eea0ef21..7e2062ff0a588 100644 --- a/examples/expressions_explorer/kibana.json +++ b/examples/expressions_explorer/kibana.json @@ -1,7 +1,7 @@ { "id": "expressionsExplorer", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", "server": false, "ui": true, "requiredPlugins": ["expressions", "inspector", "uiActions", "developerExamples"], diff --git a/examples/hello_world/README.md b/examples/hello_world/README.md new file mode 100755 index 0000000000000..f43c12886f52d --- /dev/null +++ b/examples/hello_world/README.md @@ -0,0 +1,5 @@ +## Hello World + +A very simple Hello World example plugin. + +If you are external, you can view the tutorial [here](../../dev_docs/getting_started/hello_world_plugin.mdx), if you are internal, you can view the tutorial [here](https://docs.elastic.dev/kibana-dev-docs/hello-world-app). diff --git a/examples/hello_world/kibana.json b/examples/hello_world/kibana.json new file mode 100644 index 0000000000000..d3de28c2cbd7a --- /dev/null +++ b/examples/hello_world/kibana.json @@ -0,0 +1,12 @@ +{ + "id": "helloWorld", + "version": "1.0.0", + "kibanaVersion": "kibana", + "ui": true, + "owner": { + "name": "Kibana core", + "githubTeam": "kibana-core" + }, + "description": "A plugin which registers a very simple hello world application.", + "requiredPlugins": ["developerExamples"] +} diff --git a/packages/kbn-common-utils/src/json/index.ts b/examples/hello_world/public/index.ts old mode 100644 new mode 100755 similarity index 76% rename from packages/kbn-common-utils/src/json/index.ts rename to examples/hello_world/public/index.ts index 96c94df1bb48e..51a911493e9aa --- a/packages/kbn-common-utils/src/json/index.ts +++ b/examples/hello_world/public/index.ts @@ -5,5 +5,8 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ +import { HelloWorldPlugin } from './plugin'; -export { JsonArray, JsonValue, JsonObject } from './typed_json'; +export function plugin() { + return new HelloWorldPlugin(); +} diff --git a/examples/hello_world/public/plugin.tsx b/examples/hello_world/public/plugin.tsx new file mode 100755 index 0000000000000..cb648bffbb57c --- /dev/null +++ b/examples/hello_world/public/plugin.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '../../../src/core/public'; +import { DeveloperExamplesSetup } from '../../developer_examples/public'; + +interface SetupDeps { + developerExamples: DeveloperExamplesSetup; +} + +export class HelloWorldPlugin implements Plugin { + public setup(core: CoreSetup, deps: SetupDeps) { + // Register an application into the side navigation menu + core.application.register({ + id: 'helloWorld', + title: 'Hello World', + async mount({ element }: AppMountParameters) { + ReactDOM.render(

Hello World!
, element); + return () => ReactDOM.unmountComponentAtNode(element); + }, + }); + + // This section is only needed to get this example plugin to show up in our Developer Examples. + deps.developerExamples.register({ + appId: 'helloWorld', + title: 'Hello World Application', + description: `Build a plugin that registers an application that simply says "Hello World"`, + }); + } + public start(core: CoreStart) { + return {}; + } + public stop() {} +} diff --git a/examples/hello_world/tsconfig.json b/examples/hello_world/tsconfig.json new file mode 100644 index 0000000000000..7fa03739119b4 --- /dev/null +++ b/examples/hello_world/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": [ + "index.ts", + "common/**/*.ts", + "public/**/*.ts", + "public/**/*.tsx", + "server/**/*.ts", + "../../typings/**/*" + ], + "exclude": [] +} diff --git a/examples/index_pattern_field_editor_example/kibana.json b/examples/index_pattern_field_editor_example/kibana.json index f28223ac7d24b..680f75e8ee4fa 100644 --- a/examples/index_pattern_field_editor_example/kibana.json +++ b/examples/index_pattern_field_editor_example/kibana.json @@ -1,7 +1,7 @@ { "id": "indexPatternFieldEditorExample", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", "server": false, "ui": true, "requiredPlugins": ["data", "indexPatternFieldEditor", "developerExamples"], diff --git a/examples/locator_examples/kibana.json b/examples/locator_examples/kibana.json index df336b2ab3613..a288bf5608c53 100644 --- a/examples/locator_examples/kibana.json +++ b/examples/locator_examples/kibana.json @@ -1,12 +1,15 @@ { "id": "locatorExamples", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", "server": false, "ui": true, + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, + "description": "Example app that registers custom URL locators", "requiredPlugins": ["share"], "optionalPlugins": [], - "extraPublicDirs": [ - "public/locator" - ] + "extraPublicDirs": ["public/locator"] } diff --git a/examples/locator_examples/public/locator.ts b/examples/locator_examples/public/locator.ts index 18caeca08564e..878402d357271 100644 --- a/examples/locator_examples/public/locator.ts +++ b/examples/locator_examples/public/locator.ts @@ -6,16 +6,17 @@ * Side Public License, v 1. */ -import { SerializableState, MigrateFunction } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; +import { MigrateFunction } from 'src/plugins/kibana_utils/common'; import { LocatorDefinition, LocatorPublic } from '../../../src/plugins/share/public'; export const HELLO_LOCATOR = 'HELLO_LOCATOR'; -export interface HelloLocatorV1Params extends SerializableState { +export interface HelloLocatorV1Params extends SerializableRecord { name: string; } -export interface HelloLocatorV2Params extends SerializableState { +export interface HelloLocatorV2Params extends SerializableRecord { firstName: string; lastName: string; } diff --git a/examples/locator_explorer/kibana.json b/examples/locator_explorer/kibana.json index 2ddb165b2826d..7f00461ccf774 100644 --- a/examples/locator_explorer/kibana.json +++ b/examples/locator_explorer/kibana.json @@ -1,9 +1,14 @@ { "id": "locatorExplorer", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", "server": false, "ui": true, + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, + "description": "Example app that shows how to use custom URL locators", "requiredPlugins": ["share", "locatorExamples", "developerExamples"], "optionalPlugins": [] } diff --git a/examples/preboot_example/kibana.json b/examples/preboot_example/kibana.json index b8b5ceb1a9c6c..39bdfc5447dd5 100644 --- a/examples/preboot_example/kibana.json +++ b/examples/preboot_example/kibana.json @@ -1,12 +1,12 @@ { "id": "prebootExample", + "kibanaVersion": "kibana", "owner": { "name": "Core", "githubTeam": "kibana-core" }, "description": "The example of the `preboot` plugin.", "version": "8.0.0", - "kibanaVersion": "kibana", "configPath": ["prebootExample"], "type": "preboot", "server": true, diff --git a/examples/routing_example/README.md b/examples/routing_example/README.md index 0a88707bf70bb..1ac7540508360 100644 --- a/examples/routing_example/README.md +++ b/examples/routing_example/README.md @@ -6,4 +6,4 @@ Read more: - [IRouter API Docs](../../docs/development/core/server/kibana-plugin-core-server.irouter.md) - [HttpHandler (core.http.fetch) API Docs](../../docs/development/core/public/kibana-plugin-core-public.httphandler.md) -- [Routing Conventions](../../STYLEGUIDE.md#api-endpoints) \ No newline at end of file +- [Routing Conventions](../../STYLEGUIDE.mdx#api-endpoints) \ No newline at end of file diff --git a/examples/routing_example/kibana.json b/examples/routing_example/kibana.json index 37851a0da5a85..a2e55901d80b2 100644 --- a/examples/routing_example/kibana.json +++ b/examples/routing_example/kibana.json @@ -1,9 +1,14 @@ { "id": "routingExample", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", "server": true, "ui": true, + "owner": { + "name": "Core", + "githubTeam": "kibana-core" + }, + "description": "A simple example of how to use core's routing services", "requiredPlugins": ["developerExamples"], "optionalPlugins": [] } diff --git a/examples/routing_example/public/app.tsx b/examples/routing_example/public/app.tsx index 7dadde2936e80..c0f01b0b6d534 100644 --- a/examples/routing_example/public/app.tsx +++ b/examples/routing_example/public/app.tsx @@ -63,7 +63,8 @@ function RoutingExplorer({ }, { label: 'Conventions', - href: 'https://github.com/elastic/kibana/tree/master/STYLEGUIDE.md#api-endpoints', + href: + 'https://github.com/elastic/kibana/tree/master/STYLEGUIDE.mdx#api-endpoints', iconType: 'logoGithub', target: '_blank', size: 's', diff --git a/examples/screenshot_mode_example/kibana.json b/examples/screenshot_mode_example/kibana.json index 28e5b39e5337f..66acfe0c931d5 100644 --- a/examples/screenshot_mode_example/kibana.json +++ b/examples/screenshot_mode_example/kibana.json @@ -1,9 +1,14 @@ { "id": "screenshotModeExample", - "version": "1.0.0", "kibanaVersion": "kibana", + "version": "1.0.0", "server": true, "ui": true, + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, + "description": "Example plugin of how to use screenshotMode plugin services", "requiredPlugins": ["navigation", "screenshotMode", "usageCollection", "developerExamples"], "optionalPlugins": [] } diff --git a/examples/search_examples/kibana.json b/examples/search_examples/kibana.json index 83996c2034381..227fd7f1c6261 100644 --- a/examples/search_examples/kibana.json +++ b/examples/search_examples/kibana.json @@ -1,7 +1,12 @@ { "id": "searchExamples", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, + "description": "Example plugin of how to use data plugin search services", "server": true, "ui": true, "requiredPlugins": ["navigation", "data", "developerExamples", "kibanaUtils", "share"], diff --git a/examples/state_containers_examples/kibana.json b/examples/state_containers_examples/kibana.json index 0f0a3a805ecb5..780732ab930c4 100644 --- a/examples/state_containers_examples/kibana.json +++ b/examples/state_containers_examples/kibana.json @@ -1,7 +1,12 @@ { "id": "stateContainersExamples", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, + "description": "Example plugin of how to use kibanaUtils services", "server": false, "ui": true, "requiredPlugins": ["navigation", "data", "developerExamples"], diff --git a/examples/ui_action_examples/kibana.json b/examples/ui_action_examples/kibana.json index 0e0b6b6830b95..717414fc513bd 100644 --- a/examples/ui_action_examples/kibana.json +++ b/examples/ui_action_examples/kibana.json @@ -1,7 +1,12 @@ { "id": "uiActionsExamples", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, + "description": "Example plugin of how to register custom uiActions", "server": false, "ui": true, "requiredPlugins": ["uiActions"], diff --git a/examples/ui_actions_explorer/kibana.json b/examples/ui_actions_explorer/kibana.json index 0a55e60374710..7d853a6042feb 100644 --- a/examples/ui_actions_explorer/kibana.json +++ b/examples/ui_actions_explorer/kibana.json @@ -1,7 +1,12 @@ { "id": "uiActionsExplorer", - "version": "0.0.1", "kibanaVersion": "kibana", + "version": "0.0.1", + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, + "description": "Example plugin of how to use uiActions plugin services", "server": false, "ui": true, "requiredPlugins": ["uiActions", "uiActionsExamples", "developerExamples"], diff --git a/package.json b/package.json index 2058eed5f024d..ca64a4f9c3440 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,6 @@ "@kbn/analytics": "link:bazel-bin/packages/kbn-analytics", "@kbn/apm-config-loader": "link:bazel-bin/packages/kbn-apm-config-loader", "@kbn/apm-utils": "link:bazel-bin/packages/kbn-apm-utils", - "@kbn/common-utils": "link:bazel-bin/packages/kbn-common-utils", "@kbn/config": "link:bazel-bin/packages/kbn-config", "@kbn/config-schema": "link:bazel-bin/packages/kbn-config-schema", "@kbn/crypto": "link:bazel-bin/packages/kbn-crypto", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index fcadedf8630f1..5a8aa75ee255e 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -13,7 +13,6 @@ filegroup( "//packages/kbn-babel-code-parser:build", "//packages/kbn-babel-preset:build", "//packages/kbn-cli-dev-mode:build", - "//packages/kbn-common-utils:build", "//packages/kbn-config:build", "//packages/kbn-config-schema:build", "//packages/kbn-crypto:build", diff --git a/packages/kbn-common-utils/.babelrc b/packages/kbn-analytics/.babelrc similarity index 100% rename from packages/kbn-common-utils/.babelrc rename to packages/kbn-analytics/.babelrc diff --git a/packages/kbn-analytics/.babelrc.browser b/packages/kbn-analytics/.babelrc.browser new file mode 100644 index 0000000000000..dc6a77bbe0bcd --- /dev/null +++ b/packages/kbn-analytics/.babelrc.browser @@ -0,0 +1,3 @@ +{ + "presets": ["@kbn/babel-preset/webpack_preset"] +} diff --git a/packages/kbn-analytics/BUILD.bazel b/packages/kbn-analytics/BUILD.bazel index 9eeaf4dc5842e..9f78d99b78710 100644 --- a/packages/kbn-analytics/BUILD.bazel +++ b/packages/kbn-analytics/BUILD.bazel @@ -1,5 +1,6 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") +load("//src/dev/bazel:index.bzl", "jsts_transpiler") PKG_BASE_NAME = "kbn-analytics" PKG_REQUIRE_NAME = "@kbn/analytics" @@ -21,7 +22,7 @@ NPM_MODULE_EXTRA_FILES = [ "package.json" ] -SRC_DEPS = [ +RUNTIME_DEPS = [ "@npm//moment-timezone", "@npm//tslib", ] @@ -31,7 +32,18 @@ TYPES_DEPS = [ "@npm//@types/node", ] -DEPS = SRC_DEPS + TYPES_DEPS +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + config_file = ".babelrc.browser" +) ts_config( name = "tsconfig", @@ -51,37 +63,24 @@ ts_config( ) ts_project( - name = "tsc", + name = "tsc_types", args = ['--pretty'], srcs = SRCS, - deps = DEPS, + deps = TYPES_DEPS, declaration = True, - declaration_dir = "target_types", declaration_map = True, - incremental = True, - out_dir = "target_node", - source_map = True, + emit_declaration_only = True, + incremental = False, + out_dir = "target_types", root_dir = "src", - tsconfig = ":tsconfig", -) - -ts_project( - name = "tsc_browser", - args = ['--pretty'], - srcs = SRCS, - deps = DEPS, - declaration = False, - incremental = True, - out_dir = "target_web", source_map = True, - root_dir = "src", - tsconfig = ":tsconfig_browser", + tsconfig = ":tsconfig", ) js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = DEPS + [":tsc", ":tsc_browser"], + deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/kbn-analytics/tsconfig.browser.json b/packages/kbn-analytics/tsconfig.browser.json deleted file mode 100644 index 8a65c551d3bc4..0000000000000 --- a/packages/kbn-analytics/tsconfig.browser.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": "../../tsconfig.browser.json", - "compilerOptions": { - "incremental": true, - "outDir": "./target_web", - "stripInternal": true, - "declaration": false, - "isolatedModules": true, - "sourceMap": true, - "sourceRoot": "../../../../../packages/kbn-analytics/src", - "types": [ - "node" - ] - }, - "include": [ - "src/**/*" - ] -} diff --git a/packages/kbn-analytics/tsconfig.json b/packages/kbn-analytics/tsconfig.json index 2eaa88cd3ce5f..b24ed9ea137a5 100644 --- a/packages/kbn-analytics/tsconfig.json +++ b/packages/kbn-analytics/tsconfig.json @@ -1,15 +1,15 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "incremental": true, - "declarationDir": "./target_types", - "outDir": "./target_node", - "stripInternal": true, "declaration": true, "declarationMap": true, + "emitDeclarationOnly": true, + "incremental": false, "isolatedModules": true, + "outDir": "./target_types", "sourceMap": true, "sourceRoot": "../../../../../packages/kbn-analytics/src", + "stripInternal": true, "types": [ "node" ] diff --git a/packages/kbn-apm-config-loader/src/config.ts b/packages/kbn-apm-config-loader/src/config.ts index fe5ed52c53baa..1436d396aae59 100644 --- a/packages/kbn-apm-config-loader/src/config.ts +++ b/packages/kbn-apm-config-loader/src/config.ts @@ -122,6 +122,19 @@ export class ApmConfiguration { config.transactionSampleRate = parseFloat(process.env.ELASTIC_APM_TRANSACTION_SAMPLE_RATE); } + if (process.env.ELASTIC_APM_SERVER_URL) { + config.serverUrl = process.env.ELASTIC_APM_SERVER_URL; + } + + if (process.env.ELASTIC_APM_GLOBAL_LABELS) { + config.globalLabels = Object.fromEntries( + process.env.ELASTIC_APM_GLOBAL_LABELS.split(',').map((p) => { + const [key, ...val] = p.split('='); + return [key, val.join('=')]; + }) + ); + } + return config; } diff --git a/packages/kbn-cli-dev-mode/.babelrc b/packages/kbn-cli-dev-mode/.babelrc new file mode 100644 index 0000000000000..7da72d1779128 --- /dev/null +++ b/packages/kbn-cli-dev-mode/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["@kbn/babel-preset/node_preset"] +} diff --git a/packages/kbn-cli-dev-mode/BUILD.bazel b/packages/kbn-cli-dev-mode/BUILD.bazel index ab1b6601f429b..608c781017dd6 100644 --- a/packages/kbn-cli-dev-mode/BUILD.bazel +++ b/packages/kbn-cli-dev-mode/BUILD.bazel @@ -1,5 +1,6 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") +load("//src/dev/bazel:index.bzl", "jsts_transpiler") PKG_BASE_NAME = "kbn-cli-dev-mode" PKG_REQUIRE_NAME = "@kbn/cli-dev-mode" @@ -23,7 +24,7 @@ NPM_MODULE_EXTRA_FILES = [ "README.md" ] -SRC_DEPS = [ +RUNTIME_DEPS = [ "//packages/kbn-config", "//packages/kbn-config-schema", "//packages/kbn-dev-utils", @@ -46,6 +47,21 @@ SRC_DEPS = [ ] TYPES_DEPS = [ + "//packages/kbn-config", + "//packages/kbn-config-schema", + "//packages/kbn-dev-utils", + "//packages/kbn-logging", + "//packages/kbn-optimizer", + "//packages/kbn-server-http-tools", + "//packages/kbn-std", + "//packages/kbn-utils", + "@npm//argsplit", + "@npm//chokidar", + "@npm//elastic-apm-node", + "@npm//execa", + "@npm//moment", + "@npm//rxjs", + "@npm//supertest", "@npm//@types/hapi__h2o2", "@npm//@types/hapi__hapi", "@npm//@types/getopts", @@ -55,7 +71,11 @@ TYPES_DEPS = [ "@npm//@types/supertest", ] -DEPS = SRC_DEPS + TYPES_DEPS +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) ts_config( name = "tsconfig", @@ -66,23 +86,24 @@ ts_config( ) ts_project( - name = "tsc", + name = "tsc_types", args = ['--pretty'], srcs = SRCS, - deps = DEPS, + deps = TYPES_DEPS, declaration = True, declaration_map = True, - incremental = True, - out_dir = "target", - source_map = True, + emit_declaration_only = True, + incremental = False, + out_dir = "target_types", root_dir = "src", + source_map = True, tsconfig = ":tsconfig", ) js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = DEPS + [":tsc"], + deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/kbn-cli-dev-mode/package.json b/packages/kbn-cli-dev-mode/package.json index ac86ee2ef369b..ac5ec227e92c5 100644 --- a/packages/kbn-cli-dev-mode/package.json +++ b/packages/kbn-cli-dev-mode/package.json @@ -1,7 +1,7 @@ { "name": "@kbn/cli-dev-mode", - "main": "./target/index.js", - "types": "./target/index.d.ts", + "main": "./target_node/index.js", + "types": "./target_types/index.d.ts", "version": "1.0.0", "license": "SSPL-1.0 OR Elastic License 2.0", "private": true, diff --git a/packages/kbn-cli-dev-mode/tsconfig.json b/packages/kbn-cli-dev-mode/tsconfig.json index 0c71ad8e245d4..18fda8b978917 100644 --- a/packages/kbn-cli-dev-mode/tsconfig.json +++ b/packages/kbn-cli-dev-mode/tsconfig.json @@ -1,10 +1,11 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "incremental": true, - "outDir": "./target", "declaration": true, "declarationMap": true, + "emitDeclarationOnly": true, + "incremental": false, + "outDir": "./target_types", "rootDir": "./src", "sourceMap": true, "sourceRoot": "../../../../packages/kbn-cli-dev-mode/src", diff --git a/packages/kbn-common-utils/BUILD.bazel b/packages/kbn-common-utils/BUILD.bazel deleted file mode 100644 index 699f65da408f5..0000000000000 --- a/packages/kbn-common-utils/BUILD.bazel +++ /dev/null @@ -1,89 +0,0 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") - -PKG_BASE_NAME = "kbn-common-utils" -PKG_REQUIRE_NAME = "@kbn/common-utils" - -SOURCE_FILES = glob( - [ - "src/**/*.ts", - ], - exclude = ["**/*.test.*"], -) - -SRCS = SOURCE_FILES - -filegroup( - name = "srcs", - srcs = SRCS, -) - -NPM_MODULE_EXTRA_FILES = [ - "package.json", - "README.md" -] - -RUNTIME_DEPS = [ - "//packages/kbn-config-schema", - "@npm//tslib", -] - -TYPES_DEPS = [ - "//packages/kbn-config-schema", - "@npm//tslib", - "@npm//@types/jest", - "@npm//@types/node", -] - -jsts_transpiler( - name = "target_node", - srcs = SRCS, - build_pkg_name = package_name(), -) - -ts_config( - name = "tsconfig", - src = "tsconfig.json", - deps = [ - "//:tsconfig.base.json", - ], -) - -ts_project( - name = "tsc_types", - args = ['--pretty'], - srcs = SRCS, - deps = TYPES_DEPS, - declaration = True, - declaration_map = True, - emit_declaration_only = True, - incremental = False, - out_dir = "target_types", - source_map = True, - root_dir = "src", - tsconfig = ":tsconfig", -) - -js_library( - name = PKG_BASE_NAME, - srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], - package_name = PKG_REQUIRE_NAME, - visibility = ["//visibility:public"], -) - -pkg_npm( - name = "npm_module", - deps = [ - ":%s" % PKG_BASE_NAME, - ] -) - -filegroup( - name = "build", - srcs = [ - ":npm_module", - ], - visibility = ["//visibility:public"], -) diff --git a/packages/kbn-common-utils/README.md b/packages/kbn-common-utils/README.md deleted file mode 100644 index 7b64c9f18fe89..0000000000000 --- a/packages/kbn-common-utils/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# @kbn/common-utils - -Shared common (client and server sie) utilities shared across packages and plugins. \ No newline at end of file diff --git a/packages/kbn-common-utils/jest.config.js b/packages/kbn-common-utils/jest.config.js deleted file mode 100644 index 08f1995c47423..0000000000000 --- a/packages/kbn-common-utils/jest.config.js +++ /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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -module.exports = { - preset: '@kbn/test', - rootDir: '../..', - roots: ['/packages/kbn-common-utils'], -}; diff --git a/packages/kbn-common-utils/package.json b/packages/kbn-common-utils/package.json deleted file mode 100644 index a9679c2f0fb18..0000000000000 --- a/packages/kbn-common-utils/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@kbn/common-utils", - "main": "./target_node/index.js", - "types": "./target_types/index.d.ts", - "version": "1.0.0", - "license": "SSPL-1.0 OR Elastic License 2.0", - "private": true -} \ No newline at end of file diff --git a/packages/kbn-common-utils/src/index.ts b/packages/kbn-common-utils/src/index.ts deleted file mode 100644 index 1b8bffe4bf158..0000000000000 --- a/packages/kbn-common-utils/src/index.ts +++ /dev/null @@ -1,9 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export * from './json'; diff --git a/packages/kbn-common-utils/src/json/typed_json.ts b/packages/kbn-common-utils/src/json/typed_json.ts deleted file mode 100644 index 06e99b9b65d5a..0000000000000 --- a/packages/kbn-common-utils/src/json/typed_json.ts +++ /dev/null @@ -1,16 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export type JsonValue = null | boolean | number | string | JsonObject | JsonArray; - -export interface JsonObject { - [key: string]: JsonValue; -} - -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface JsonArray extends Array {} diff --git a/packages/kbn-common-utils/tsconfig.json b/packages/kbn-common-utils/tsconfig.json deleted file mode 100644 index 7d1ecaa10a234..0000000000000 --- a/packages/kbn-common-utils/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "emitDeclarationOnly": true, - "incremental": false, - "outDir": "target_types", - "sourceMap": true, - "sourceRoot": "../../../../packages/kbn-common-utils/src", - "types": [ - "jest", - "node" - ] - }, - "include": [ - "src/**/*" - ] -} diff --git a/packages/kbn-config/.babelrc b/packages/kbn-config/.babelrc new file mode 100644 index 0000000000000..7da72d1779128 --- /dev/null +++ b/packages/kbn-config/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["@kbn/babel-preset/node_preset"] +} diff --git a/packages/kbn-config/BUILD.bazel b/packages/kbn-config/BUILD.bazel index bc21f827addd2..b11306be969b0 100644 --- a/packages/kbn-config/BUILD.bazel +++ b/packages/kbn-config/BUILD.bazel @@ -1,5 +1,6 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") +load("//src/dev/bazel:index.bzl", "jsts_transpiler") PKG_BASE_NAME = "kbn-config" PKG_REQUIRE_NAME = "@kbn/config" @@ -28,7 +29,7 @@ NPM_MODULE_EXTRA_FILES = [ "README.md" ] -SRC_DEPS = [ +RUNTIME_DEPS = [ "//packages/elastic-safer-lodash-set", "//packages/kbn-config-schema", "//packages/kbn-logging", @@ -42,6 +43,13 @@ SRC_DEPS = [ ] TYPES_DEPS = [ + "//packages/elastic-safer-lodash-set", + "//packages/kbn-config-schema", + "//packages/kbn-logging", + "//packages/kbn-std", + "//packages/kbn-utility-types", + "@npm//load-json-file", + "@npm//rxjs", "@npm//@types/jest", "@npm//@types/js-yaml", "@npm//@types/lodash", @@ -49,7 +57,11 @@ TYPES_DEPS = [ "@npm//@types/type-detect", ] -DEPS = SRC_DEPS + TYPES_DEPS +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) ts_config( name = "tsconfig", @@ -60,14 +72,15 @@ ts_config( ) ts_project( - name = "tsc", + name = "tsc_types", args = ['--pretty'], srcs = SRCS, - deps = DEPS, + deps = TYPES_DEPS, declaration = True, declaration_map = True, - incremental = True, - out_dir = "target", + emit_declaration_only = True, + incremental = False, + out_dir = "target_types", source_map = True, root_dir = "src", tsconfig = ":tsconfig", @@ -76,7 +89,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = DEPS + [":tsc"], + deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) diff --git a/packages/kbn-config/package.json b/packages/kbn-config/package.json index 56f1855bebbce..e30db61ae0c28 100644 --- a/packages/kbn-config/package.json +++ b/packages/kbn-config/package.json @@ -1,7 +1,7 @@ { "name": "@kbn/config", - "main": "./target/index.js", - "types": "./target/index.d.ts", + "main": "./target_node/index.js", + "types": "./target_types/index.d.ts", "version": "1.0.0", "license": "SSPL-1.0 OR Elastic License 2.0", "private": true diff --git a/packages/kbn-config/tsconfig.json b/packages/kbn-config/tsconfig.json index 115af2c46b549..20855c6073073 100644 --- a/packages/kbn-config/tsconfig.json +++ b/packages/kbn-config/tsconfig.json @@ -1,13 +1,15 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "incremental": true, - "outDir": "./target", - "stripInternal": false, "declaration": true, "declarationMap": true, + "emitDeclarationOnly": true, + "incremental": false, + "outDir": "./target_types", + "rootDir": "src", "sourceMap": true, "sourceRoot": "../../../../packages/kbn-config/src", + "stripInternal": false, "types": [ "jest", "node" diff --git a/packages/kbn-es-query/BUILD.bazel b/packages/kbn-es-query/BUILD.bazel index 7d6e2b4683b9b..1e40918e6b509 100644 --- a/packages/kbn-es-query/BUILD.bazel +++ b/packages/kbn-es-query/BUILD.bazel @@ -31,7 +31,7 @@ NPM_MODULE_EXTRA_FILES = [ ] RUNTIME_DEPS = [ - "//packages/kbn-common-utils", + "//packages/kbn-utility-types", "//packages/kbn-config-schema", "//packages/kbn-i18n", "@npm//@elastic/elasticsearch", @@ -42,7 +42,7 @@ RUNTIME_DEPS = [ ] TYPES_DEPS = [ - "//packages/kbn-common-utils", + "//packages/kbn-utility-types", "//packages/kbn-i18n", "@npm//@elastic/elasticsearch", "@npm//@types/jest", diff --git a/packages/kbn-es-query/src/kuery/ast/ast.ts b/packages/kbn-es-query/src/kuery/ast/ast.ts index 6f43098a752de..030b5a8f1c29a 100644 --- a/packages/kbn-es-query/src/kuery/ast/ast.ts +++ b/packages/kbn-es-query/src/kuery/ast/ast.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { nodeTypes } from '../node_types/index'; import { KQLSyntaxError } from '../kuery_syntax_error'; import { KueryNode, DslQuery, KueryParseOptions } from '../types'; diff --git a/packages/kbn-es-query/src/kuery/node_types/named_arg.ts b/packages/kbn-es-query/src/kuery/node_types/named_arg.ts index b1b202e4323af..1892a4885b705 100644 --- a/packages/kbn-es-query/src/kuery/node_types/named_arg.ts +++ b/packages/kbn-es-query/src/kuery/node_types/named_arg.ts @@ -7,7 +7,7 @@ */ import _ from 'lodash'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import * as ast from '../ast'; import { nodeTypes } from '../node_types'; import { NamedArgTypeBuildNode } from './types'; diff --git a/packages/kbn-es-query/src/kuery/node_types/types.ts b/packages/kbn-es-query/src/kuery/node_types/types.ts index ea8eb5e8a0618..7e6f454418555 100644 --- a/packages/kbn-es-query/src/kuery/node_types/types.ts +++ b/packages/kbn-es-query/src/kuery/node_types/types.ts @@ -10,7 +10,7 @@ * WARNING: these typings are incomplete */ -import { JsonValue } from '@kbn/common-utils'; +import { JsonValue } from '@kbn/utility-types'; import { KueryNode } from '..'; import { IndexPatternBase } from '../..'; diff --git a/packages/kbn-rule-data-utils/BUILD.bazel b/packages/kbn-rule-data-utils/BUILD.bazel index ccd1793feb161..62a48b66b4bce 100644 --- a/packages/kbn-rule-data-utils/BUILD.bazel +++ b/packages/kbn-rule-data-utils/BUILD.bazel @@ -22,8 +22,10 @@ NPM_MODULE_EXTRA_FILES = [ ] SRC_DEPS = [ + "//packages/kbn-es-query", "@npm//tslib", "@npm//utility-types", + "@npm//@elastic/elasticsearch", ] TYPES_DEPS = [ diff --git a/packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts b/packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts index d3d20edffa286..795d194ee8a92 100644 --- a/packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts +++ b/packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts @@ -6,6 +6,9 @@ * Side Public License, v 1. */ +import type { estypes } from '@elastic/elasticsearch'; +import type { EsQueryConfig } from '@kbn/es-query'; + /** * registering a new instance of the rule data client * in a new plugin will require updating the below data structure @@ -24,6 +27,7 @@ export const AlertConsumers = { SYNTHETICS: 'synthetics', } as const; export type AlertConsumers = typeof AlertConsumers[keyof typeof AlertConsumers]; +export type STATUS_VALUES = 'open' | 'acknowledged' | 'closed'; export const mapConsumerToIndexName: Record = { apm: '.alerts-observability-apm', @@ -38,3 +42,57 @@ export type ValidFeatureId = keyof typeof mapConsumerToIndexName; export const validFeatureIds = Object.keys(mapConsumerToIndexName); export const isValidFeatureId = (a: unknown): a is ValidFeatureId => typeof a === 'string' && validFeatureIds.includes(a); + +/** + * Prevent javascript from returning Number.MAX_SAFE_INTEGER when Elasticsearch expects + * Java's Long.MAX_VALUE. This happens when sorting fields by date which are + * unmapped in the provided index + * + * Ref: https://github.com/elastic/elasticsearch/issues/28806#issuecomment-369303620 + * + * return stringified Long.MAX_VALUE if we receive Number.MAX_SAFE_INTEGER + * @param sortIds estypes.SearchSortResults | undefined + * @returns SortResults + */ +export const getSafeSortIds = (sortIds: estypes.SearchSortResults | null | undefined) => { + if (sortIds == null) { + return sortIds; + } + return sortIds.map((sortId) => { + // haven't determined when we would receive a null value for a sort id + // but in case we do, default to sending the stringified Java max_int + if (sortId == null || sortId === '' || sortId >= Number.MAX_SAFE_INTEGER) { + return '9223372036854775807'; + } + return sortId; + }); +}; + +interface GetEsQueryConfigParamType { + allowLeadingWildcards?: EsQueryConfig['allowLeadingWildcards']; + queryStringOptions?: EsQueryConfig['queryStringOptions']; + ignoreFilterIfFieldNotInIndex?: EsQueryConfig['ignoreFilterIfFieldNotInIndex']; + dateFormatTZ?: EsQueryConfig['dateFormatTZ']; +} + +type ConfigKeys = keyof GetEsQueryConfigParamType; + +export const getEsQueryConfig = (params?: GetEsQueryConfigParamType): EsQueryConfig => { + const defaultConfigValues = { + allowLeadingWildcards: true, + queryStringOptions: { analyze_wildcard: true }, + ignoreFilterIfFieldNotInIndex: false, + dateFormatTZ: 'Zulu', + }; + if (params == null) { + return defaultConfigValues; + } + const paramKeysWithValues = Object.keys(params).reduce((acc: EsQueryConfig, key) => { + const configKey = key as ConfigKeys; + if (params[configKey] != null) { + return { [key]: params[configKey], ...acc }; + } + return { [key]: defaultConfigValues[configKey], ...acc }; + }, {} as EsQueryConfig); + return paramKeysWithValues; +}; diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts index f9877447840da..37bb465e8e5b7 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts @@ -200,6 +200,8 @@ export const schema = Joi.object() .default(/Kibana is now available/), }) .default(), + env: Joi.object().unknown().default(), + delayShutdown: Joi.number(), }) .default(), diff --git a/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js b/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js index 3154d77488ba6..6f91304fffa27 100644 --- a/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js +++ b/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js @@ -29,6 +29,7 @@ function extendNodeOptions(installDir) { export async function runKibanaServer({ procs, config, options }) { const { installDir } = options; const runOptions = config.get('kbnTestServer.runOptions'); + const env = config.get('kbnTestServer.env'); await procs.run('kibana', { cmd: getKibanaCmd(installDir), @@ -36,6 +37,7 @@ export async function runKibanaServer({ procs, config, options }) { env: { FORCE_COLOR: 1, ...process.env, + ...env, ...extendNodeOptions(installDir), }, cwd: installDir || KIBANA_ROOT, diff --git a/packages/kbn-test/src/functional_tests/tasks.js b/packages/kbn-test/src/functional_tests/tasks.js index f4dfdcb93fb2b..00b04fcda26db 100644 --- a/packages/kbn-test/src/functional_tests/tasks.js +++ b/packages/kbn-test/src/functional_tests/tasks.js @@ -100,6 +100,12 @@ export async function runTests(options) { await runFtr({ configPath, options: opts }); } finally { try { + const delay = config.get('kbnTestServer.delayShutdown'); + if (typeof delay === 'number') { + log.info('Delaying shutdown of Kibana for', delay, 'ms'); + await new Promise((r) => setTimeout(r, delay)); + } + await procs.stop('kibana'); } finally { if (es) { diff --git a/packages/kbn-typed-react-router-config/src/create_router.test.tsx b/packages/kbn-typed-react-router-config/src/create_router.test.tsx index 97b6d16e3214e..4de4b44196ddd 100644 --- a/packages/kbn-typed-react-router-config/src/create_router.test.tsx +++ b/packages/kbn-typed-react-router-config/src/create_router.test.tsx @@ -27,6 +27,11 @@ describe('createRouter', () => { rangeTo: t.string, }), }), + defaults: { + query: { + rangeFrom: 'now-30m', + }, + }, children: [ { path: '/services', @@ -164,6 +169,20 @@ describe('createRouter', () => { router.getParams('/service-map', history.location, true); }).not.toThrowError(); }); + + it('applies defaults', () => { + history.push('/services?rangeTo=now&transactionType=request'); + + const topLevelParams = router.getParams('/', history.location); + + expect(topLevelParams).toEqual({ + path: {}, + query: { + rangeFrom: 'now-30m', + rangeTo: 'now', + }, + }); + }); }); describe('matchRoutes', () => { @@ -181,6 +200,19 @@ describe('createRouter', () => { router.matchRoutes('/traces', history.location); }).toThrowError('No matching route found for /traces'); }); + + it('applies defaults', () => { + history.push('/services?rangeTo=now&transactionType=request'); + + const matches = router.matchRoutes('/', history.location); + + expect(matches[1]?.match.params).toEqual({ + query: { + rangeFrom: 'now-30m', + rangeTo: 'now', + }, + }); + }); }); describe('link', () => { @@ -241,5 +273,17 @@ describe('createRouter', () => { } as any); }).toThrowError(); }); + + it('applies defaults', () => { + const href = router.link('/traces', { + // @ts-ignore + query: { + rangeTo: 'now', + aggregationType: 'avg', + }, + }); + + expect(href).toEqual('/traces?aggregationType=avg&rangeFrom=now-30m&rangeTo=now'); + }); }); }); diff --git a/packages/kbn-typed-react-router-config/src/create_router.ts b/packages/kbn-typed-react-router-config/src/create_router.ts index 4a8b89560d516..846808cb798f1 100644 --- a/packages/kbn-typed-react-router-config/src/create_router.ts +++ b/packages/kbn-typed-react-router-config/src/create_router.ts @@ -76,10 +76,12 @@ export function createRouter(routes: TRoutes): Router(routes: TRoutes): Router { const params: { path?: Record; query?: Record } | undefined = args[0]; - const paramsWithDefaults = merge({ path: {}, query: {} }, params); + const paramsWithBuiltInDefaults = merge({ path: {}, query: {} }, params); path = path .split('/') .map((part) => { - return part.startsWith(':') ? paramsWithDefaults.path[part.split(':')[1]] : part; + return part.startsWith(':') ? paramsWithBuiltInDefaults.path[part.split(':')[1]] : part; }) .join('/'); @@ -125,15 +127,25 @@ export function createRouter(routes: TRoutes): Router { + return routesByReactRouterConfig.get(match.route)!; + }); + const validationType = mergeRt( ...(compact( - matches.map((match) => { - return routesByReactRouterConfig.get(match.route)?.params; + matchedRoutes.map((match) => { + return match.params; }) ) as [any, any]) ); - const validation = validationType.decode(paramsWithDefaults); + const paramsWithRouteDefaults = merge( + {}, + ...matchedRoutes.map((route) => route.defaults ?? {}), + paramsWithBuiltInDefaults + ); + + const validation = validationType.decode(paramsWithRouteDefaults); if (isLeft(validation)) { throw new Error(PathReporter.report(validation).join('\n')); @@ -141,7 +153,7 @@ export function createRouter(routes: TRoutes): Router(routes: TRoutes): Router { const matches = matchRoutes(...args); return matches.length - ? merge({ path: {}, query: {} }, ...matches.map((match) => match.match.params)) + ? merge( + { path: {}, query: {} }, + ...matches.map((match) => merge({}, match.route?.defaults ?? {}, match.match.params)) + ) : undefined; }, matchRoutes: (...args: any[]) => { diff --git a/packages/kbn-typed-react-router-config/src/types/index.ts b/packages/kbn-typed-react-router-config/src/types/index.ts index f1609d8709620..1d6a77d360007 100644 --- a/packages/kbn-typed-react-router-config/src/types/index.ts +++ b/packages/kbn-typed-react-router-config/src/types/index.ts @@ -56,6 +56,7 @@ interface PlainRoute { element: ReactElement; children?: PlainRoute[]; params?: t.Type; + defaults?: Record>; } interface ReadonlyPlainRoute { @@ -63,6 +64,7 @@ interface ReadonlyPlainRoute { readonly element: ReactElement; readonly children?: readonly ReadonlyPlainRoute[]; readonly params?: t.Type; + readonly defaults?: Record>; } export type Route = PlainRoute | ReadonlyPlainRoute; diff --git a/packages/kbn-utility-types/BUILD.bazel b/packages/kbn-utility-types/BUILD.bazel index 047cbd77f81c0..70f814c30f415 100644 --- a/packages/kbn-utility-types/BUILD.bazel +++ b/packages/kbn-utility-types/BUILD.bazel @@ -7,6 +7,7 @@ PKG_REQUIRE_NAME = "@kbn/utility-types" SOURCE_FILES = glob([ "src/jest/index.ts", + "src/serializable/**", "src/index.ts" ]) diff --git a/packages/kbn-utility-types/src/index.ts b/packages/kbn-utility-types/src/index.ts index 1f5d95e316e1d..921f056c6b755 100644 --- a/packages/kbn-utility-types/src/index.ts +++ b/packages/kbn-utility-types/src/index.ts @@ -9,6 +9,14 @@ import { PromiseType } from 'utility-types'; export { $Values, Assign, Class, Optional, Required } from 'utility-types'; +export type { + JsonArray, + JsonValue, + JsonObject, + SerializableRecord, + Serializable, +} from './serializable'; + /** * A type that may or may not be a `Promise`. */ diff --git a/src/core/types/serializable.ts b/packages/kbn-utility-types/src/serializable/index.ts similarity index 74% rename from src/core/types/serializable.ts rename to packages/kbn-utility-types/src/serializable/index.ts index 19f9c6cb21541..3a248f9aea2ee 100644 --- a/src/core/types/serializable.ts +++ b/packages/kbn-utility-types/src/serializable/index.ts @@ -6,11 +6,21 @@ * Side Public License, v 1. */ +export type JsonValue = null | boolean | number | string | JsonObject | JsonArray; + +export interface JsonObject { + [key: string]: JsonValue; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface JsonArray extends Array {} + export type Serializable = | string | number | boolean | null + | undefined | SerializableArray | SerializableRecord; diff --git a/src/core/kibana.json b/src/core/kibana.json index 49f838dbc4ee5..c312b05be1d2f 100644 --- a/src/core/kibana.json +++ b/src/core/kibana.json @@ -1,7 +1,10 @@ { - "id": "core", - "summary": "The core plugin has core functionality", - "version": "kibana", - "serviceFolders": ["http", "saved_objects", "chrome", "application"] - } - \ No newline at end of file + "id": "core", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, + "summary": "The core plugin has core functionality", + "version": "kibana", + "serviceFolders": ["http", "saved_objects", "chrome", "application"] +} diff --git a/src/core/public/core_system.test.mocks.ts b/src/core/public/core_system.test.mocks.ts index c80c2e3f49775..afb8aec31cccd 100644 --- a/src/core/public/core_system.test.mocks.ts +++ b/src/core/public/core_system.test.mocks.ts @@ -19,7 +19,6 @@ import { uiSettingsServiceMock } from './ui_settings/ui_settings_service.mock'; import { docLinksServiceMock } from './doc_links/doc_links_service.mock'; import { renderingServiceMock } from './rendering/rendering_service.mock'; import { integrationsServiceMock } from './integrations/integrations_service.mock'; -import { executionContextServiceMock } from './execution_context/execution_context_service.mock'; import { coreAppMock } from './core_app/core_app.mock'; export const MockInjectedMetadataService = injectedMetadataServiceMock.create(); @@ -112,14 +111,6 @@ jest.doMock('./integrations', () => ({ IntegrationsService: IntegrationsServiceConstructor, })); -export const MockExecutionContextService = executionContextServiceMock.create(); -export const ExecutionContextServiceConstructor = jest - .fn() - .mockImplementation(() => MockExecutionContextService); -jest.doMock('./execution_context', () => ({ - ExecutionContextService: ExecutionContextServiceConstructor, -})); - export const MockCoreApp = coreAppMock.create(); export const CoreAppConstructor = jest.fn().mockImplementation(() => MockCoreApp); jest.doMock('./core_app', () => ({ diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index efafb25da27ee..8ead0f50785bd 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -30,7 +30,6 @@ import { RenderingServiceConstructor, IntegrationsServiceConstructor, MockIntegrationsService, - MockExecutionContextService, CoreAppConstructor, MockCoreApp, } from './core_system.test.mocks'; @@ -183,11 +182,6 @@ describe('#setup()', () => { await setupCore(); expect(MockCoreApp.setup).toHaveBeenCalledTimes(1); }); - - it('calls executionContext.setup()', async () => { - await setupCore(); - expect(MockExecutionContextService.setup).toHaveBeenCalledTimes(1); - }); }); describe('#start()', () => { @@ -275,11 +269,6 @@ describe('#start()', () => { await startCore(); expect(MockCoreApp.start).toHaveBeenCalledTimes(1); }); - - it('calls executionContext.start()', async () => { - await startCore(); - expect(MockExecutionContextService.start).toHaveBeenCalledTimes(1); - }); }); describe('#stop()', () => { @@ -338,14 +327,6 @@ describe('#stop()', () => { expect(MockCoreApp.stop).toHaveBeenCalled(); }); - it('calls executionContext.stop()', () => { - const coreSystem = createCoreSystem(); - - expect(MockExecutionContextService.stop).not.toHaveBeenCalled(); - coreSystem.stop(); - expect(MockExecutionContextService.stop).toHaveBeenCalled(); - }); - it('clears the rootDomElement', async () => { const rootDomElement = document.createElement('div'); const coreSystem = createCoreSystem({ diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 43e7d443f5c00..e5dcd8f817a0a 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -29,7 +29,6 @@ import { SavedObjectsService } from './saved_objects'; import { IntegrationsService } from './integrations'; import { DeprecationsService } from './deprecations'; import { CoreApp } from './core_app'; -import { ExecutionContextService } from './execution_context'; import type { InternalApplicationSetup, InternalApplicationStart } from './application/types'; interface Params { @@ -84,7 +83,6 @@ export class CoreSystem { private readonly integrations: IntegrationsService; private readonly coreApp: CoreApp; private readonly deprecations: DeprecationsService; - private readonly executionContext: ExecutionContextService; private readonly rootDomElement: HTMLElement; private readonly coreContext: CoreContext; private fatalErrorsSetup: FatalErrorsSetup | null = null; @@ -120,7 +118,6 @@ export class CoreSystem { this.application = new ApplicationService(); this.integrations = new IntegrationsService(); this.deprecations = new DeprecationsService(); - this.executionContext = new ExecutionContextService(); this.plugins = new PluginsService(this.coreContext, injectedMetadata.uiPlugins); this.coreApp = new CoreApp(this.coreContext); @@ -140,7 +137,6 @@ export class CoreSystem { const http = this.http.setup({ injectedMetadata, fatalErrors: this.fatalErrorsSetup }); const uiSettings = this.uiSettings.setup({ http, injectedMetadata }); const notifications = this.notifications.setup({ uiSettings }); - this.executionContext.setup(); const application = this.application.setup({ http }); this.coreApp.setup({ application, http, injectedMetadata, notifications }); @@ -205,7 +201,6 @@ export class CoreSystem { notifications, }); const deprecations = this.deprecations.start({ http }); - const executionContext = this.executionContext.start(); this.coreApp.start({ application, docLinks, http, notifications, uiSettings }); @@ -222,7 +217,6 @@ export class CoreSystem { uiSettings, fatalErrors, deprecations, - executionContext, }; await this.plugins.start(core); @@ -266,7 +260,6 @@ export class CoreSystem { this.i18n.stop(); this.application.stop(); this.deprecations.stop(); - this.executionContext.stop(); this.rootDomElement.textContent = ''; } } diff --git a/src/core/public/execution_context/execution_context_container.test.ts b/src/core/public/execution_context/execution_context_container.test.ts index a4ee355ab40a4..5e4e34d102e5b 100644 --- a/src/core/public/execution_context/execution_context_container.test.ts +++ b/src/core/public/execution_context/execution_context_container.test.ts @@ -29,6 +29,30 @@ describe('KibanaExecutionContext', () => { `); }); + it('includes a parent context to string representation', () => { + const parentContext: KibanaExecutionContext = { + type: 'parent-type', + name: 'parent-name', + id: '41', + description: 'parent-descripton', + }; + + const context: KibanaExecutionContext = { + type: 'test-type', + name: 'test-name', + id: '42', + description: 'test-descripton', + parent: parentContext, + }; + + const value = new ExecutionContextContainer(context).toHeader(); + expect(value).toMatchInlineSnapshot(` + Object { + "x-kbn-context": "%7B%22type%22%3A%22test-type%22%2C%22name%22%3A%22test-name%22%2C%22id%22%3A%2242%22%2C%22description%22%3A%22test-descripton%22%2C%22parent%22%3A%7B%22type%22%3A%22parent-type%22%2C%22name%22%3A%22parent-name%22%2C%22id%22%3A%2241%22%2C%22description%22%3A%22parent-descripton%22%7D%7D", + } + `); + }); + it('trims a string representation of provided execution context if it is bigger max allowed size', () => { const context: KibanaExecutionContext = { type: 'test-type', @@ -65,4 +89,51 @@ describe('KibanaExecutionContext', () => { `); }); }); + describe('toJSON', () => { + it('returns JSON representation of the context', () => { + const context: KibanaExecutionContext = { + type: 'test-type', + name: 'test-name', + id: '42', + description: 'test-descripton', + }; + + const value = new ExecutionContextContainer(context).toJSON(); + expect(value).toEqual(context); + }); + + it('returns JSON representation when the parent context if provided', () => { + const parentAContext: KibanaExecutionContext = { + type: 'parent-a-type', + name: 'parent-a-name', + id: '40', + description: 'parent-a-descripton', + }; + + const parentBContext: KibanaExecutionContext = { + type: 'parent-b-type', + name: 'parent-b-name', + id: '41', + description: 'parent-b-descripton', + parent: parentAContext, + }; + + const context: KibanaExecutionContext = { + type: 'test-type', + name: 'test-name', + id: '42', + description: 'test-descripton', + parent: parentBContext, + }; + + const value = new ExecutionContextContainer(context).toJSON(); + expect(value).toEqual({ + ...context, + parent: { + ...parentBContext, + parent: parentAContext, + }, + }); + }); + }); }); diff --git a/src/core/public/execution_context/execution_context_service.mock.ts b/src/core/public/execution_context/execution_context_service.mock.ts deleted file mode 100644 index 071e61f17c25c..0000000000000 --- a/src/core/public/execution_context/execution_context_service.mock.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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import type { PublicMethodsOf } from '@kbn/utility-types'; -import type { Plugin } from 'src/core/public'; -import type { ExecutionContextServiceStart } from './execution_context_service'; -import type { ExecutionContextContainer } from './execution_context_container'; - -const createContainerMock = () => { - const mock: jest.Mocked> = { - toHeader: jest.fn(), - toJSON: jest.fn(), - }; - return mock; -}; -const createStartContractMock = () => { - const mock: jest.Mocked = { - create: jest.fn().mockReturnValue(createContainerMock()), - }; - return mock; -}; - -const createMock = (): jest.Mocked => ({ - setup: jest.fn(), - start: jest.fn(), - stop: jest.fn(), -}); - -export const executionContextServiceMock = { - create: createMock, - createStartContract: createStartContractMock, - createContainer: createContainerMock, -}; diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts deleted file mode 100644 index 934e68d15be04..0000000000000 --- a/src/core/public/execution_context/execution_context_service.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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import type { CoreService, KibanaExecutionContext } from '../../types'; -import { - ExecutionContextContainer, - IExecutionContextContainer, -} from './execution_context_container'; - -/** - * @public - */ -export interface ExecutionContextServiceStart { - /** - * Creates a context container carrying the meta-data of a runtime operation. - * Provided meta-data will be propagated to Kibana and Elasticsearch servers. - * ```js - * const context = executionContext.create(...); - * http.fetch('/endpoint/', { context }); - * ``` - */ - create: (context: KibanaExecutionContext) => IExecutionContextContainer; -} - -export class ExecutionContextService implements CoreService { - setup() {} - start(): ExecutionContextServiceStart { - return { - create(context: KibanaExecutionContext) { - return new ExecutionContextContainer(context); - }, - }; - } - stop() {} -} diff --git a/src/core/public/execution_context/index.ts b/src/core/public/execution_context/index.ts index d0c8348d864e7..b15a967ac714a 100644 --- a/src/core/public/execution_context/index.ts +++ b/src/core/public/execution_context/index.ts @@ -7,6 +7,4 @@ */ export type { KibanaExecutionContext } from '../../types'; -export { ExecutionContextService } from './execution_context_service'; -export type { ExecutionContextServiceStart } from './execution_context_service'; -export type { IExecutionContextContainer } from './execution_context_container'; +export { ExecutionContextContainer } from './execution_context_container'; diff --git a/src/core/public/http/fetch.test.ts b/src/core/public/http/fetch.test.ts index 67ec816d08430..7e3cd9019b08d 100644 --- a/src/core/public/http/fetch.test.ts +++ b/src/core/public/http/fetch.test.ts @@ -15,7 +15,6 @@ import { first } from 'rxjs/operators'; import { Fetch } from './fetch'; import { BasePath } from './base_path'; import { HttpResponse, HttpFetchOptionsWithPath } from './types'; -import { executionContextServiceMock } from '../execution_context/execution_context_service.mock'; function delay(duration: number) { return new Promise((r) => setTimeout(r, duration)); @@ -230,14 +229,19 @@ describe('Fetch', () => { it('should inject context headers if provided', async () => { fetchMock.get('*', {}); - const executionContainerMock = executionContextServiceMock.createContainer(); - executionContainerMock.toHeader.mockReturnValueOnce({ 'x-kbn-context': 'value' }); + await fetchInstance.fetch('/my/path', { - context: executionContainerMock, + context: { + type: 'test-type', + name: 'test-name', + description: 'test-description', + id: '42', + }, }); expect(fetchMock.lastOptions()!.headers).toMatchObject({ - 'x-kbn-context': 'value', + 'x-kbn-context': + '%7B%22type%22%3A%22test-type%22%2C%22name%22%3A%22test-name%22%2C%22description%22%3A%22test-description%22%2C%22id%22%3A%2242%22%7D', }); }); diff --git a/src/core/public/http/fetch.ts b/src/core/public/http/fetch.ts index fb178a937e18a..372445b2b0902 100644 --- a/src/core/public/http/fetch.ts +++ b/src/core/public/http/fetch.ts @@ -22,6 +22,7 @@ import { HttpFetchError } from './http_fetch_error'; import { HttpInterceptController } from './http_intercept_controller'; import { interceptRequest, interceptResponse } from './intercept'; import { HttpInterceptHaltError } from './http_intercept_halt_error'; +import { ExecutionContextContainer } from '../execution_context'; interface Params { basePath: IBasePath; @@ -124,7 +125,7 @@ export class Fetch { 'Content-Type': 'application/json', ...options.headers, 'kbn-version': this.params.kibanaVersion, - ...options.context?.toHeader(), + ...(options.context ? new ExecutionContextContainer(options.context).toHeader() : {}), }), }; diff --git a/src/core/public/http/types.ts b/src/core/public/http/types.ts index ccf68201bc207..3eb718b318f86 100644 --- a/src/core/public/http/types.ts +++ b/src/core/public/http/types.ts @@ -8,7 +8,7 @@ import { Observable } from 'rxjs'; import { MaybePromise } from '@kbn/utility-types'; -import type { IExecutionContextContainer } from '../execution_context'; +import type { KibanaExecutionContext } from '../execution_context'; /** @public */ export interface HttpSetup { @@ -272,7 +272,7 @@ export interface HttpFetchOptions extends HttpRequestInit { */ asResponse?: boolean; - context?: IExecutionContextContainer; + context?: KibanaExecutionContext; } /** diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 40304d27580ca..e6e6433291873 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -65,7 +65,6 @@ import { ApplicationSetup, Capabilities, ApplicationStart } from './application' import { DocLinksStart } from './doc_links'; import { SavedObjectsStart } from './saved_objects'; import { DeprecationsServiceStart } from './deprecations'; -import type { ExecutionContextServiceStart } from './execution_context'; export type { PackageInfo, @@ -186,8 +185,6 @@ export type { export type { DeprecationsServiceStart, ResolveDeprecationResponse } from './deprecations'; -export type { IExecutionContextContainer, ExecutionContextServiceStart } from './execution_context'; - export type { MountPoint, UnmountCallback, PublicUiSettingsParams } from './types'; export { URL_MAX_LENGTH } from './core_app'; @@ -276,8 +273,6 @@ export interface CoreStart { fatalErrors: FatalErrorsStart; /** {@link DeprecationsServiceStart} */ deprecations: DeprecationsServiceStart; - /** {@link ExecutionContextServiceStart} */ - executionContext: ExecutionContextServiceStart; /** * exposed temporarily until https://github.com/elastic/kibana/issues/41990 done * use *only* to retrieve config values. There is no way to set injected values diff --git a/src/core/public/mocks.ts b/src/core/public/mocks.ts index 63b94ea4ac4e3..bd7623beba651 100644 --- a/src/core/public/mocks.ts +++ b/src/core/public/mocks.ts @@ -25,7 +25,6 @@ import { uiSettingsServiceMock } from './ui_settings/ui_settings_service.mock'; import { savedObjectsServiceMock } from './saved_objects/saved_objects_service.mock'; import { injectedMetadataServiceMock } from './injected_metadata/injected_metadata_service.mock'; import { deprecationsServiceMock } from './deprecations/deprecations_service.mock'; -import { executionContextServiceMock } from './execution_context/execution_context_service.mock'; export { chromeServiceMock } from './chrome/chrome_service.mock'; export { docLinksServiceMock } from './doc_links/doc_links_service.mock'; @@ -40,7 +39,6 @@ export { savedObjectsServiceMock } from './saved_objects/saved_objects_service.m export { scopedHistoryMock } from './application/scoped_history.mock'; export { applicationServiceMock } from './application/application_service.mock'; export { deprecationsServiceMock } from './deprecations/deprecations_service.mock'; -export { executionContextServiceMock } from './execution_context/execution_context_service.mock'; function createCoreSetupMock({ basePath = '', @@ -86,7 +84,6 @@ function createCoreStartMock({ basePath = '' } = {}) { getInjectedVar: injectedMetadataServiceMock.createStartContract().getInjectedVar, }, fatalErrors: fatalErrorsServiceMock.createStartContract(), - executionContext: executionContextServiceMock.createStartContract(), }; return mock; diff --git a/src/core/public/plugins/plugin_context.ts b/src/core/public/plugins/plugin_context.ts index be3cff54aca8e..49c895aa80fc4 100644 --- a/src/core/public/plugins/plugin_context.ts +++ b/src/core/public/plugins/plugin_context.ts @@ -140,6 +140,5 @@ export function createPluginStartContext< }, fatalErrors: deps.fatalErrors, deprecations: deps.deprecations, - executionContext: deps.executionContext, }; } diff --git a/src/core/public/plugins/plugins_service.test.ts b/src/core/public/plugins/plugins_service.test.ts index 3f23889c57de6..06c72823c7752 100644 --- a/src/core/public/plugins/plugins_service.test.ts +++ b/src/core/public/plugins/plugins_service.test.ts @@ -35,7 +35,6 @@ import { CoreSetup, CoreStart, PluginInitializerContext } from '..'; import { docLinksServiceMock } from '../doc_links/doc_links_service.mock'; import { savedObjectsServiceMock } from '../saved_objects/saved_objects_service.mock'; import { deprecationsServiceMock } from '../deprecations/deprecations_service.mock'; -import { executionContextServiceMock } from '../execution_context/execution_context_service.mock'; export let mockPluginInitializers: Map; @@ -105,7 +104,6 @@ describe('PluginsService', () => { savedObjects: savedObjectsServiceMock.createStartContract(), fatalErrors: fatalErrorsServiceMock.createStartContract(), deprecations: deprecationsServiceMock.createStartContract(), - executionContext: executionContextServiceMock.createStartContract(), }; mockStartContext = { ...mockStartDeps, diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 80fd3927e05a3..9de10c3c88534 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -433,8 +433,6 @@ export interface CoreStart { // (undocumented) docLinks: DocLinksStart; // (undocumented) - executionContext: ExecutionContextServiceStart; - // (undocumented) fatalErrors: FatalErrorsStart; // (undocumented) http: HttpStart; @@ -717,11 +715,6 @@ export interface ErrorToastOptions extends ToastOptions { toastMessage?: string; } -// @public (undocumented) -export interface ExecutionContextServiceStart { - create: (context: KibanaExecutionContext) => IExecutionContextContainer; -} - // @public export interface FatalErrorInfo { // (undocumented) @@ -761,7 +754,7 @@ export interface HttpFetchOptions extends HttpRequestInit { asResponse?: boolean; asSystemRequest?: boolean; // (undocumented) - context?: IExecutionContextContainer; + context?: KibanaExecutionContext; headers?: HttpHeadersInit; prependBasePath?: boolean; query?: HttpFetchQuery; @@ -897,14 +890,6 @@ export interface IBasePath { readonly serverBasePath: string; } -// @public (undocumented) -export interface IExecutionContextContainer { - // (undocumented) - toHeader: () => Record; - // (undocumented) - toJSON: () => Readonly; -} - // @public export interface IExternalUrl { validateUrl(relativeOrAbsoluteUrl: string): URL | null; @@ -967,14 +952,15 @@ export interface IUiSettingsClient { set: (key: string, value: any) => Promise; } -// @public (undocumented) -export interface KibanaExecutionContext { - readonly description: string; - readonly id: string; - readonly name: string; +// @public +export type KibanaExecutionContext = { readonly type: string; + readonly name: string; + readonly id: string; + readonly description: string; readonly url?: string; -} + parent?: KibanaExecutionContext; +}; // @public export type MountPoint = (element: T) => UnmountCallback; @@ -1692,6 +1678,6 @@ export interface UserProvidedValues { // Warnings were encountered during analysis: // -// src/core/public/core_system.ts:172:21 - (ae-forgotten-export) The symbol "InternalApplicationStart" needs to be exported by the entry point index.d.ts +// src/core/public/core_system.ts:168:21 - (ae-forgotten-export) The symbol "InternalApplicationStart" needs to be exported by the entry point index.d.ts ``` diff --git a/src/core/server/config/mocks.ts b/src/core/server/config/mocks.ts index 7dc3514d37e97..46f6c3e95cefb 100644 --- a/src/core/server/config/mocks.ts +++ b/src/core/server/config/mocks.ts @@ -6,9 +6,24 @@ * Side Public License, v 1. */ -export { - getEnvOptions, - rawConfigServiceMock, - configServiceMock, - configMock, -} from '@kbn/config/target/mocks'; +import type { + getEnvOptions as getEnvOptionsTyped, + rawConfigServiceMock as rawConfigServiceMockTyped, + configServiceMock as configServiceMockTyped, + configMock as configMockTyped, +} from '@kbn/config/target_types/mocks'; + +import { + getEnvOptions as getEnvOptionsNonTyped, + rawConfigServiceMock as rawConfigServiceMockNonTyped, + configServiceMock as configServiceMockNonTyped, + configMock as configMockNonTyped, + // @ts-expect-error +} from '@kbn/config/target_node/mocks'; + +const getEnvOptions: typeof getEnvOptionsTyped = getEnvOptionsNonTyped; +const rawConfigServiceMock: typeof rawConfigServiceMockTyped = rawConfigServiceMockNonTyped; +const configServiceMock: typeof configServiceMockTyped = configServiceMockNonTyped; +const configMock: typeof configMockTyped = configMockNonTyped; + +export { getEnvOptions, rawConfigServiceMock, configServiceMock, configMock }; diff --git a/src/core/server/elasticsearch/client/cluster_client.ts b/src/core/server/elasticsearch/client/cluster_client.ts index d164736cead07..f81b651843013 100644 --- a/src/core/server/elasticsearch/client/cluster_client.ts +++ b/src/core/server/elasticsearch/client/cluster_client.ts @@ -10,7 +10,6 @@ import { Client } from '@elastic/elasticsearch'; import { Logger } from '../../logging'; import { GetAuthHeaders, Headers, isKibanaRequest, isRealRequest } from '../../http'; import { ensureRawRequest, filterHeaders } from '../../http/router'; -import type { IExecutionContextContainer } from '../../execution_context'; import { ScopeableRequest } from '../types'; import { ElasticsearchClient } from './types'; import { configureClient } from './configure_client'; @@ -64,7 +63,7 @@ export class ClusterClient implements ICustomClusterClient { logger: Logger, type: string, private readonly getAuthHeaders: GetAuthHeaders = noop, - getExecutionContext: () => IExecutionContextContainer | undefined = noop + getExecutionContext: () => string | undefined = noop ) { this.asInternalUser = configureClient(config, { logger, type, getExecutionContext }); this.rootScopedClient = configureClient(config, { diff --git a/src/core/server/elasticsearch/client/configure_client.ts b/src/core/server/elasticsearch/client/configure_client.ts index f2953862c25e0..3c32dd2cfd4f4 100644 --- a/src/core/server/elasticsearch/client/configure_client.ts +++ b/src/core/server/elasticsearch/client/configure_client.ts @@ -14,7 +14,6 @@ import type { TransportRequestParams, TransportRequestOptions, } from '@elastic/elasticsearch/lib/Transport'; -import type { IExecutionContextContainer } from '../../execution_context'; import { Logger } from '../../logging'; import { parseClientOptions, ElasticsearchClientConfig } from './client_config'; @@ -31,14 +30,14 @@ export const configureClient = ( logger: Logger; type: string; scoped?: boolean; - getExecutionContext?: () => IExecutionContextContainer | undefined; + getExecutionContext?: () => string | undefined; } ): Client => { const clientOptions = parseClientOptions(config, scoped); class KibanaTransport extends Transport { request(params: TransportRequestParams, options?: TransportRequestOptions) { const opts = options || {}; - const opaqueId = getExecutionContext()?.toString(); + const opaqueId = getExecutionContext(); if (opaqueId && !opts.opaqueId) { // rewrites headers['x-opaque-id'] if it presents opts.opaqueId = opaqueId; diff --git a/src/core/server/elasticsearch/client/mocks.ts b/src/core/server/elasticsearch/client/mocks.ts index a7fbce7180223..848d9c204bfbf 100644 --- a/src/core/server/elasticsearch/client/mocks.ts +++ b/src/core/server/elasticsearch/client/mocks.ts @@ -141,9 +141,10 @@ export type MockedTransportRequestPromise = TransportRequestPromise & { const createSuccessTransportRequestPromise = ( body: T, - { statusCode = 200 }: { statusCode?: number } = {} + { statusCode = 200 }: { statusCode?: number } = {}, + headers?: Record ): MockedTransportRequestPromise> => { - const response = createApiResponse({ body, statusCode }); + const response = createApiResponse({ body, statusCode, headers }); const promise = Promise.resolve(response); (promise as MockedTransportRequestPromise>).abort = jest.fn(); diff --git a/src/core/server/elasticsearch/elasticsearch_service.ts b/src/core/server/elasticsearch/elasticsearch_service.ts index f983a8b77fe08..acd2204334c0e 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.ts @@ -149,7 +149,7 @@ export class ElasticsearchService this.coreContext.logger.get('elasticsearch'), type, this.getAuthHeaders, - () => this.executionContextClient?.get() + () => this.executionContextClient?.getAsHeader() ); } diff --git a/src/core/server/elasticsearch/index.ts b/src/core/server/elasticsearch/index.ts index d97e3331c7cf5..8bcc841669fc9 100644 --- a/src/core/server/elasticsearch/index.ts +++ b/src/core/server/elasticsearch/index.ts @@ -37,3 +37,4 @@ export type { GetResponse, DeleteDocumentResponse, } from './client'; +export { isSupportedEsServer } from './supported_server_response_check'; diff --git a/src/core/server/elasticsearch/supported_server_response_check.ts b/src/core/server/elasticsearch/supported_server_response_check.ts new file mode 100644 index 0000000000000..6fe812bc58518 --- /dev/null +++ b/src/core/server/elasticsearch/supported_server_response_check.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +export const PRODUCT_RESPONSE_HEADER = 'x-elastic-product'; +/** + * Response headers check to determine if the response is from Elasticsearch + * @param headers Response headers + * @returns boolean + */ +// This check belongs to the elasticsearch service as a dedicated helper method. +export const isSupportedEsServer = (headers: Record | null) => { + return !!headers && headers[PRODUCT_RESPONSE_HEADER] === 'Elasticsearch'; +}; diff --git a/src/core/server/execution_context/execution_context_container.test.ts b/src/core/server/execution_context/execution_context_container.test.ts index e8408d37f40f4..41095815a6b44 100644 --- a/src/core/server/execution_context/execution_context_container.test.ts +++ b/src/core/server/execution_context/execution_context_container.test.ts @@ -5,7 +5,8 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { KibanaServerExecutionContext } from './execution_context_service'; +import type { KibanaExecutionContext } from '../../types'; + import { ExecutionContextContainer, getParentContextFrom, @@ -14,52 +15,80 @@ import { } from './execution_context_container'; describe('KibanaExecutionContext', () => { + describe('constructor', () => { + it('allows context to define parent explicitly', () => { + const parentContext: KibanaExecutionContext = { + type: 'parent-type', + name: 'parent-name', + id: '44', + description: 'parent-descripton', + }; + const parentContainer = new ExecutionContextContainer(parentContext); + + const context: KibanaExecutionContext = { + type: 'test-type', + name: 'test-name', + id: '42', + description: 'test-descripton', + parent: { + type: 'custom-parent-type', + name: 'custom-parent-name', + id: '41', + description: 'custom-parent-descripton', + }, + }; + + const value = new ExecutionContextContainer(context, parentContainer).toJSON(); + expect(value).toEqual(context); + }); + }); + describe('toString', () => { it('returns a string representation of provided execution context', () => { - const context: KibanaServerExecutionContext = { + const context: KibanaExecutionContext = { type: 'test-type', name: 'test-name', id: '42', description: 'test-descripton', - requestId: '1234-5678', }; const value = new ExecutionContextContainer(context).toString(); - expect(value).toMatchInlineSnapshot(`"1234-5678;kibana:test-type:test-name:42"`); + expect(value).toBe('test-type:test-name:42'); }); - it('returns a limited representation if optional properties are omitted', () => { - const context: KibanaServerExecutionContext = { - requestId: '1234-5678', + it('includes a parent context to string representation', () => { + const parentContext: KibanaExecutionContext = { + type: 'parent-type', + name: 'parent-name', + id: '41', + description: 'parent-descripton', }; + const parentContainer = new ExecutionContextContainer(parentContext); - const value = new ExecutionContextContainer(context).toString(); - expect(value).toMatchInlineSnapshot(`"1234-5678"`); + const context: KibanaExecutionContext = { + type: 'test-type', + name: 'test-name', + id: '42', + description: 'test-descripton', + }; + + const value = new ExecutionContextContainer(context, parentContainer).toString(); + expect(value).toBe('parent-type:parent-name:41;test-type:test-name:42'); }); it('returns an escaped string representation of provided execution contextStringified', () => { - const context: KibanaServerExecutionContext = { + const context: KibanaExecutionContext = { id: 'Visualization☺漢字', type: 'test-type', name: 'test-name', - requestId: '1234-5678', + description: 'test-description', }; const value = new ExecutionContextContainer(context).toString(); - expect(value).toMatchInlineSnapshot( - `"1234-5678;kibana:test-type:test-name:Visualization%E2%98%BA%E6%BC%A2%E5%AD%97"` - ); + expect(value).toBe('test-type:test-name:Visualization%E2%98%BA%E6%BC%A2%E5%AD%97'); }); it('trims a string representation of provided execution context if it is bigger max allowed size', () => { - expect( - new Blob([ - new ExecutionContextContainer({ - requestId: '1234-5678'.repeat(1000), - }).toString(), - ]).size - ).toBeLessThanOrEqual(BAGGAGE_MAX_PER_NAME_VALUE_PAIRS); - expect( new Blob([ new ExecutionContextContainer({ @@ -67,7 +96,6 @@ describe('KibanaExecutionContext', () => { name: 'test-name', id: '42'.repeat(1000), description: 'test-descripton', - requestId: '1234-5678', }).toString(), ]).size ).toBeLessThanOrEqual(BAGGAGE_MAX_PER_NAME_VALUE_PAIRS); @@ -76,16 +104,35 @@ describe('KibanaExecutionContext', () => { describe('toJSON', () => { it('returns a context object', () => { - const context: KibanaServerExecutionContext = { + const context: KibanaExecutionContext = { type: 'test-type', name: 'test-name', id: '42', description: 'test-descripton', - requestId: '1234-5678', }; const value = new ExecutionContextContainer(context).toJSON(); - expect(value).toBe(context); + expect(value).toEqual(context); + }); + + it('returns a context object with registed parent object', () => { + const parentContext: KibanaExecutionContext = { + type: 'parent-type', + name: 'parent-name', + id: '41', + description: 'parent-descripton', + }; + const parentContainer = new ExecutionContextContainer(parentContext); + + const context: KibanaExecutionContext = { + type: 'test-type', + name: 'test-name', + id: '42', + description: 'test-descripton', + }; + + const value = new ExecutionContextContainer(context, parentContainer).toJSON(); + expect(value).toEqual({ ...context, parent: parentContext }); }); }); }); @@ -97,7 +144,7 @@ describe('getParentContextFrom', () => { expect(getParentContextFrom({ [BAGGAGE_HEADER]: header })).toEqual(ctx); }); - it('does not throw an exception if given not a valid value', () => { + it('does not throw an exception if given not a valid JSON object', () => { expect(getParentContextFrom({ [BAGGAGE_HEADER]: 'value' })).toBeUndefined(); expect(getParentContextFrom({ [BAGGAGE_HEADER]: '' })).toBeUndefined(); expect(getParentContextFrom({})).toBeUndefined(); diff --git a/src/core/server/execution_context/execution_context_container.ts b/src/core/server/execution_context/execution_context_container.ts index 6c4a5606df152..a81c409ab3e9e 100644 --- a/src/core/server/execution_context/execution_context_container.ts +++ b/src/core/server/execution_context/execution_context_container.ts @@ -5,7 +5,6 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { KibanaServerExecutionContext } from './execution_context_service'; import type { KibanaExecutionContext } from '../../types'; // Switch to the standard Baggage header. blocked by @@ -47,27 +46,23 @@ function enforceMaxLength(header: string): string { */ export interface IExecutionContextContainer { toString(): string; - toJSON(): Readonly; + toJSON(): Readonly; +} + +function stringify(ctx: KibanaExecutionContext): string { + const stringifiedCtx = `${ctx.type}:${ctx.name}:${encodeURIComponent(ctx.id)}`; + return ctx.parent ? `${stringify(ctx.parent)};${stringifiedCtx}` : stringifiedCtx; } export class ExecutionContextContainer implements IExecutionContextContainer { - readonly #context: Readonly; - constructor(context: Readonly) { - this.#context = context; + readonly #context: Readonly; + constructor(context: KibanaExecutionContext, parent?: IExecutionContextContainer) { + this.#context = { parent: parent?.toJSON(), ...context }; } toString(): string { - const ctx = this.#context; - const contextStringified = - ctx.type && ctx.id && ctx.name - ? // id may contain non-ASCII symbols - `kibana:${encodeURIComponent(ctx.type)}:${encodeURIComponent( - ctx.name - )}:${encodeURIComponent(ctx.id)}` - : ''; - const result = contextStringified ? `${ctx.requestId};${contextStringified}` : ctx.requestId; - return enforceMaxLength(result); + return enforceMaxLength(stringify(this.#context)); } - toJSON(): Readonly { + toJSON() { return this.#context; } } diff --git a/src/core/server/execution_context/execution_context_service.mock.ts b/src/core/server/execution_context/execution_context_service.mock.ts index 657805df273ca..2e31145f6c0ee 100644 --- a/src/core/server/execution_context/execution_context_service.mock.ts +++ b/src/core/server/execution_context/execution_context_service.mock.ts @@ -15,9 +15,11 @@ import type { const createExecutionContextMock = () => { const mock: jest.Mocked = { set: jest.fn(), - reset: jest.fn(), + setRequestId: jest.fn(), + withContext: jest.fn(), get: jest.fn(), getParentContextFrom: jest.fn(), + getAsHeader: jest.fn(), }; return mock; }; @@ -28,8 +30,7 @@ const createInternalSetupContractMock = () => { const createSetupContractMock = () => { const mock: jest.Mocked = { - set: jest.fn(), - get: jest.fn(), + withContext: jest.fn(), }; return mock; }; diff --git a/src/core/server/execution_context/execution_context_service.test.ts b/src/core/server/execution_context/execution_context_service.test.ts index 0c213429e1951..3abaa13d11103 100644 --- a/src/core/server/execution_context/execution_context_service.test.ts +++ b/src/core/server/execution_context/execution_context_service.test.ts @@ -25,97 +25,400 @@ describe('ExecutionContextService', () => { service = new ExecutionContextService(core).setup(); }); - it('sets and gets a value in async context', async () => { - const chainA = Promise.resolve().then(async () => { - service.set({ - requestId: '0000', + describe('set', () => { + it('sets and gets a value in async context', async () => { + const chainA = Promise.resolve().then(async () => { + service.set({ + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }); + await delay(500); + return service.get(); + }); + + const chainB = Promise.resolve().then(async () => { + service.set({ + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + }); + await delay(100); + return service.get(); + }); + + expect( + await Promise.all([chainA, chainB]).then((results) => + results.map((result) => result?.toJSON()) + ) + ).toEqual([ + { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + parent: undefined, + }, + + { + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + parent: undefined, + }, + ]); + }); + + it('a sequentual call rewrites the context', async () => { + const result = await Promise.resolve().then(async () => { + service.set({ + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }); + service.set({ + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + }); + + return service.get(); + }); + + expect(result?.toJSON()).toEqual({ + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + parent: undefined, }); - await delay(500); - return service.get(); }); - const chainB = Promise.resolve().then(async () => { + it('emits context to the logs when "set" is called', async () => { service.set({ - requestId: '1111', + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', }); - await delay(100); - return service.get(); - }); - - expect( - await Promise.all([chainA, chainB]).then((results) => - results.map((result) => result?.toJSON()) - ) - ).toEqual([ - { - requestId: '0000', - }, - { - requestId: '1111', - }, - ]); + expect(loggingSystemMock.collect(core.logger).debug).toMatchInlineSnapshot(` + Array [ + Array [ + "set the execution context: {\\"type\\":\\"type-a\\",\\"name\\":\\"name-a\\",\\"id\\":\\"id-a\\",\\"description\\":\\"description-a\\"}", + ], + ] + `); + }); + + it('can be disabled', async () => { + const coreWithDisabledService = mockCoreContext.create(); + coreWithDisabledService.configService.atPath.mockReturnValue( + new BehaviorSubject({ enabled: false }) + ); + const disabledService = new ExecutionContextService(coreWithDisabledService).setup(); + const chainA = await Promise.resolve().then(async () => { + disabledService.set({ + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }); + await delay(100); + return disabledService.get(); + }); + + expect(chainA).toBeUndefined(); + }); }); - it('sets and resets a value in async context', async () => { - const chainA = Promise.resolve().then(async () => { - service.set({ - requestId: '0000', + describe('withContext', () => { + it('sets and gets a value in async context', async () => { + const chainA = service.withContext( + { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }, + async () => { + await delay(10); + return service.get(); + } + ); + + const chainB = service.withContext( + { + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + }, + async () => { + await delay(50); + return service.get(); + } + ); + + expect( + await Promise.all([chainA, chainB]).then((results) => + results.map((result) => result?.toJSON()) + ) + ).toEqual([ + { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + parent: undefined, + }, + { + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + parent: undefined, + }, + ]); + }); + + it('sets the context for a wrapped function only', () => { + service.withContext( + { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }, + async () => { + await delay(10); + return service.get(); + } + ); + + expect(service.get()).toBe(undefined); + }); + + it('a sequentual call does not affect orhers contexts', async () => { + const chainA = service.withContext( + { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }, + async () => { + await delay(50); + return service.get(); + } + ); + + const chainB = service.withContext( + { + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + }, + async () => { + await delay(10); + return service.get(); + } + ); + const result = await Promise.all([chainA, chainB]); + expect(result.map((r) => r?.toJSON())).toEqual([ + { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + parent: undefined, + }, + { + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + parent: undefined, + }, + ]); + }); + + it('supports nested contexts', async () => { + const result = await service.withContext( + { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }, + async () => { + await delay(10); + return service.withContext( + { + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + }, + () => service.get() + ); + } + ); + + expect(result?.toJSON()).toEqual({ + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + parent: { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + parent: undefined, + }, }); - await delay(500); - service.reset(); - return service.get(); }); - const chainB = Promise.resolve().then(async () => { + it('inherits a nested context configured by "set"', async () => { service.set({ - requestId: '1111', + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', }); - await delay(100); - return service.get(); - }); - - expect( - await Promise.all([chainA, chainB]).then((results) => - results.map((result) => result?.toJSON()) - ) - ).toEqual([ - undefined, - { - requestId: '1111', - }, - ]); - }); + const result = await service.withContext( + { + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + }, + async () => { + await delay(10); + return service.get(); + } + ); - it('emits context to the logs when "set" is called', async () => { - service.set({ - requestId: '0000', + expect(result?.toJSON()).toEqual({ + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + parent: { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + parent: undefined, + }, + }); + }); + + it('do not swallow errors', () => { + const error = new Error('oops'); + const promise = service.withContext( + { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }, + async () => { + await delay(10); + throw error; + } + ); + + expect(promise).rejects.toBe(error); + }); + + it('emits context to the logs when "withContext" is called', async () => { + service.withContext( + { + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }, + (i) => i + ); + expect(loggingSystemMock.collect(core.logger).debug).toMatchInlineSnapshot(` + Array [ + Array [ + "stored the execution context: {\\"type\\":\\"type-a\\",\\"name\\":\\"name-a\\",\\"id\\":\\"id-a\\",\\"description\\":\\"description-a\\"}", + ], + ] + `); + }); + + it('can be disabled', async () => { + const coreWithDisabledService = mockCoreContext.create(); + coreWithDisabledService.configService.atPath.mockReturnValue( + new BehaviorSubject({ enabled: false }) + ); + const disabledService = new ExecutionContextService(coreWithDisabledService).setup(); + const result = await disabledService.withContext( + { + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + }, + async () => { + await delay(10); + return service.get(); + } + ); + + expect(result).toBeUndefined(); }); - expect(loggingSystemMock.collect(core.logger).debug).toMatchInlineSnapshot(` - Array [ - Array [ - "stored the execution context: {\\"requestId\\":\\"0000\\"}", - ], - ] - `); }); - }); - describe('config', () => { - it('can be disabled', async () => { - const core = mockCoreContext.create(); - core.configService.atPath.mockReturnValue(new BehaviorSubject({ enabled: false })); - const service = new ExecutionContextService(core).setup(); - const chainA = await Promise.resolve().then(async () => { + describe('getAsHeader', () => { + it('returns request id if no context provided', async () => { + service.setRequestId('1234'); + + expect(service.getAsHeader()).toBe('1234'); + }); + + it('returns request id and registered context', async () => { + service.setRequestId('1234'); service.set({ - requestId: '0000', + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', }); - await delay(100); - return service.get(); + + expect(service.getAsHeader()).toBe('1234;kibana:type-a:name-a:id-a'); }); - expect(chainA).toBeUndefined(); + it('can be disabled', async () => { + const coreWithDisabledService = mockCoreContext.create(); + coreWithDisabledService.configService.atPath.mockReturnValue( + new BehaviorSubject({ enabled: false }) + ); + const disabledService = new ExecutionContextService(coreWithDisabledService).setup(); + disabledService.setRequestId('1234'); + disabledService.set({ + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }); + + expect(disabledService.getAsHeader()).toBeUndefined(); + }); }); + }); + describe('config', () => { it('reacts to config changes', async () => { const core = mockCoreContext.create(); const config$ = new BehaviorSubject({ enabled: false }); @@ -124,7 +427,10 @@ describe('ExecutionContextService', () => { function exec() { return Promise.resolve().then(async () => { service.set({ - requestId: '0000', + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', }); await delay(100); return service.get(); diff --git a/src/core/server/execution_context/execution_context_service.ts b/src/core/server/execution_context/execution_context_service.ts index b187283e27e34..5a8d104cebcd9 100644 --- a/src/core/server/execution_context/execution_context_service.ts +++ b/src/core/server/execution_context/execution_context_service.ts @@ -19,21 +19,26 @@ import { getParentContextFrom, } from './execution_context_container'; -/** - * @public - */ -export interface KibanaServerExecutionContext extends Partial { - requestId: string; -} - /** * @internal */ export interface IExecutionContext { getParentContextFrom(headers: Record): KibanaExecutionContext | undefined; - set(context: Partial): void; - reset(): void; + setRequestId(requestId: string): void; + set(context: KibanaExecutionContext): void; + /** + * The sole purpose of this imperative internal API is to be used by the http service. + * The event-based nature of Hapi server doesn't allow us to wrap a request handler with "withContext". + * Since all the Hapi event lifecycle will lose the execution context. + * Nodejs docs also recommend using AsyncLocalStorage.run() over AsyncLocalStorage.enterWith(). + * https://nodejs.org/api/async_context.html#async_context_asynclocalstorage_enterwith_store + */ get(): IExecutionContextContainer | undefined; + withContext(context: KibanaExecutionContext | undefined, fn: (...args: any[]) => R): R; + /** + * returns serialized representation to send as a header + **/ + getAsHeader(): string | undefined; } /** @@ -51,15 +56,11 @@ export type InternalExecutionContextStart = IExecutionContext; */ export interface ExecutionContextSetup { /** - * Stores the meta-data of a runtime operation. - * Data are carried over all async operations automatically. - * The sequential calls merge provided "context" object shallowly. - **/ - set(context: Partial): void; - /** - * Retrieves an opearation meta-data for the current async context. + * Keeps track of execution context while the passed function is executed. + * Data are carried over all async operations spawned by the passed function. + * The nested calls stack the registered context on top of each other. **/ - get(): IExecutionContextContainer | undefined; + withContext(context: KibanaExecutionContext | undefined, fn: (...args: any[]) => R): R; } /** @@ -70,13 +71,15 @@ export type ExecutionContextStart = ExecutionContextSetup; export class ExecutionContextService implements CoreService { private readonly log: Logger; - private readonly asyncLocalStorage: AsyncLocalStorage; + private readonly contextStore: AsyncLocalStorage; + private readonly requestIdStore: AsyncLocalStorage<{ requestId: string }>; private enabled = false; private configSubscription?: Subscription; constructor(private readonly coreContext: CoreContext) { this.log = coreContext.logger.get('execution_context'); - this.asyncLocalStorage = new AsyncLocalStorage(); + this.contextStore = new AsyncLocalStorage(); + this.requestIdStore = new AsyncLocalStorage<{ requestId: string }>(); } setup(): InternalExecutionContextSetup { @@ -89,8 +92,10 @@ export class ExecutionContextService return { getParentContextFrom, set: this.set.bind(this), - reset: this.reset.bind(this), + withContext: this.withContext.bind(this), + setRequestId: this.setRequestId.bind(this), get: this.get.bind(this), + getAsHeader: this.getAsHeader.bind(this), }; } @@ -98,8 +103,10 @@ export class ExecutionContextService return { getParentContextFrom, set: this.set.bind(this), - reset: this.reset.bind(this), + setRequestId: this.setRequestId.bind(this), + withContext: this.withContext.bind(this), get: this.get.bind(this), + getAsHeader: this.getAsHeader.bind(this), }; } @@ -111,25 +118,43 @@ export class ExecutionContextService } } - private set(context: KibanaServerExecutionContext) { + private set(context: KibanaExecutionContext) { if (!this.enabled) return; - const prevValue = this.asyncLocalStorage.getStore(); - // merges context objects shallowly. repeats the deafult logic of apm.setCustomContext(ctx) - const contextContainer = new ExecutionContextContainer({ ...prevValue?.toJSON(), ...context }); + const contextContainer = new ExecutionContextContainer(context); // we have to use enterWith since Hapi lifecycle model is built on event emitters. // therefore if we wrapped request handler in asyncLocalStorage.run(), we would lose context in other lifecycles. - this.asyncLocalStorage.enterWith(contextContainer); + this.contextStore.enterWith(contextContainer); + this.log.debug(`set the execution context: ${JSON.stringify(contextContainer)}`); + } + + private withContext( + context: KibanaExecutionContext | undefined, + fn: (...args: any[]) => R + ): R { + if (!this.enabled || !context) { + return fn(); + } + const parent = this.contextStore.getStore(); + const contextContainer = new ExecutionContextContainer(context, parent); this.log.debug(`stored the execution context: ${JSON.stringify(contextContainer)}`); + + return this.contextStore.run(contextContainer, fn); } - private reset() { + private setRequestId(requestId: string) { if (!this.enabled) return; - // @ts-expect-error "undefined" is not supported in type definitions, which is wrong - this.asyncLocalStorage.enterWith(undefined); + this.requestIdStore.enterWith({ requestId }); } private get(): IExecutionContextContainer | undefined { if (!this.enabled) return; - return this.asyncLocalStorage.getStore(); + return this.contextStore.getStore(); + } + + private getAsHeader(): string | undefined { + if (!this.enabled) return; + const stringifiedCtx = this.contextStore.getStore()?.toString(); + const requestId = this.requestIdStore.getStore()?.requestId; + return stringifiedCtx ? `${requestId};kibana:${stringifiedCtx}` : requestId; } } diff --git a/src/core/server/execution_context/index.ts b/src/core/server/execution_context/index.ts index f8018c75995e7..d34eed5cc34f1 100644 --- a/src/core/server/execution_context/index.ts +++ b/src/core/server/execution_context/index.ts @@ -14,7 +14,6 @@ export type { ExecutionContextSetup, ExecutionContextStart, IExecutionContext, - KibanaServerExecutionContext, } from './execution_context_service'; export type { IExecutionContextContainer } from './execution_context_container'; export { config } from './execution_context_config'; diff --git a/src/core/server/execution_context/integration_tests/tracing.test.ts b/src/core/server/execution_context/integration_tests/tracing.test.ts index ade67d0dd2605..5451ee222d776 100644 --- a/src/core/server/execution_context/integration_tests/tracing.test.ts +++ b/src/core/server/execution_context/integration_tests/tracing.test.ts @@ -205,7 +205,10 @@ describe('trace', () => { executionContext.set(parentContext); const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping(); return res.ok({ - body: { context: executionContext.get()?.toJSON(), header: headers?.['x-opaque-id'] }, + body: { + context: executionContext.get()?.toJSON(), + header: headers?.['x-opaque-id'], + }, }); }); @@ -237,7 +240,7 @@ describe('trace', () => { await root.start(); const response = await kbnTestServer.request.get(root, '/execution-context').expect(200); - expect(response.body).toEqual({ ...parentContext, requestId: expect.any(String) }); + expect(response.body).toEqual(parentContext); }); it('sets execution context for an async request handler', async () => { @@ -253,7 +256,7 @@ describe('trace', () => { await root.start(); const response = await kbnTestServer.request.get(root, '/execution-context').expect(200); - expect(response.body).toEqual({ ...parentContext, requestId: expect.any(String) }); + expect(response.body).toEqual(parentContext); }); it('execution context is uniq for sequential requests', async () => { @@ -261,8 +264,9 @@ describe('trace', () => { const { createRouter } = http; const router = createRouter(''); + let id = 42; router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - executionContext.set(parentContext); + executionContext.set({ ...parentContext, id: String(id++) }); await delay(100); return res.ok({ body: executionContext.get() }); }); @@ -271,9 +275,8 @@ describe('trace', () => { const responseA = await kbnTestServer.request.get(root, '/execution-context').expect(200); const responseB = await kbnTestServer.request.get(root, '/execution-context').expect(200); - expect(responseA.body).toEqual({ ...parentContext, requestId: expect.any(String) }); - expect(responseB.body).toEqual({ ...parentContext, requestId: expect.any(String) }); - expect(responseA.body.requestId).not.toBe(responseB.body.requestId); + expect(responseA.body).toEqual({ ...parentContext, id: '42' }); + expect(responseB.body).toEqual({ ...parentContext, id: '43' }); }); it('execution context is uniq for concurrent requests', async () => { @@ -283,7 +286,7 @@ describe('trace', () => { const router = createRouter(''); let id = 2; router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - executionContext.set(parentContext); + executionContext.set({ ...parentContext, id: String(id) }); await delay(id-- * 100); return res.ok({ body: executionContext.get() }); }); @@ -298,13 +301,10 @@ describe('trace', () => { responseB, responseC, ]); - expect(bodyA.requestId).toBeDefined(); - expect(bodyB.requestId).toBeDefined(); - expect(bodyC.requestId).toBeDefined(); - expect(bodyA.requestId).not.toBe(bodyB.requestId); - expect(bodyB.requestId).not.toBe(bodyC.requestId); - expect(bodyA.requestId).not.toBe(bodyC.requestId); + expect(bodyA.id).toBe('2'); + expect(bodyB.id).toBe('1'); + expect(bodyC.id).toBe('0'); }); it('execution context is uniq for concurrent requests when "x-opaque-id" provided', async () => { @@ -316,7 +316,8 @@ describe('trace', () => { router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { executionContext.set(parentContext); await delay(id-- * 100); - return res.ok({ body: executionContext.get() }); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping(); + return res.ok({ body: headers || {} }); }); await root.start(); @@ -335,9 +336,9 @@ describe('trace', () => { responseB, responseC, ]); - expect(bodyA.requestId).toBe('req-1'); - expect(bodyB.requestId).toBe('req-2'); - expect(bodyC.requestId).toBe('req-3'); + expect(bodyA['x-opaque-id']).toContain('req-1'); + expect(bodyB['x-opaque-id']).toContain('req-2'); + expect(bodyC['x-opaque-id']).toContain('req-3'); }); it('parses the parent context if present', async () => { @@ -355,7 +356,7 @@ describe('trace', () => { .set(new ExecutionContextContainer(parentContext).toHeader()) .expect(200); - expect(response.body).toEqual({ ...parentContext, requestId: expect.any(String) }); + expect(response.body).toEqual(parentContext); }); it('execution context is the same for all the lifecycle events', async () => { @@ -410,7 +411,7 @@ describe('trace', () => { .set(new ExecutionContextContainer(parentContext).toHeader()) .expect(200); - expect(response.body).toEqual({ ...parentContext, requestId: expect.any(String) }); + expect(response.body).toEqual(parentContext); expect(response.body).toEqual(onPreRoutingContext); expect(response.body).toEqual(onPreAuthContext); @@ -461,32 +462,26 @@ describe('trace', () => { expect(header).toContain('kibana:test-type:test-name:42'); }); - it('a repeat call overwrites the old context', async () => { - const { http, executionContext } = await root.setup(); + it('passes "x-opaque-id" if no execution context is registered', async () => { + const { http } = await root.setup(); const { createRouter } = http; const router = createRouter(''); - const newContext = { - type: 'new-type', - name: 'new-name', - id: '41', - description: 'new-description', - }; router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - executionContext.set(newContext); const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping(); return res.ok({ body: headers || {} }); }); await root.start(); + const myOpaqueId = 'my-opaque-id'; const response = await kbnTestServer.request .get(root, '/execution-context') - .set(new ExecutionContextContainer(parentContext).toHeader()) + .set('x-opaque-id', myOpaqueId) .expect(200); const header = response.body['x-opaque-id']; - expect(header).toContain('kibana:new-type:new-name:41'); + expect(header).toBe(myOpaqueId); }); it('does not affect "x-opaque-id" set by user', async () => { @@ -531,14 +526,83 @@ describe('trace', () => { await root.start(); - const myOpaqueId = 'my-opaque-id'; - const response = await kbnTestServer.request - .get(root, '/execution-context') - .set('x-opaque-id', myOpaqueId) - .expect(200); + const response = await kbnTestServer.request.get(root, '/execution-context').expect(200); const header = response.body['x-opaque-id']; - expect(header).toBe('my-opaque-id;kibana:test-type:test-name:42'); + expect(header).toContain('kibana:test-type:test-name:42'); + }); + + describe('withContext', () => { + it('sets execution context for a nested function', async () => { + const { executionContext, http } = await root.setup(); + const { createRouter } = http; + + const router = createRouter(''); + router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { + return executionContext.withContext(parentContext, () => + res.ok({ body: executionContext.get() }) + ); + }); + + await root.start(); + const response = await kbnTestServer.request.get(root, '/execution-context').expect(200); + expect(response.body).toEqual(parentContext); + }); + + it('set execution context inerits a parent if presented', async () => { + const { executionContext, http } = await root.setup(); + const { createRouter } = http; + + const router = createRouter(''); + const nestedContext = { + type: 'nested-type', + name: 'nested-name', + id: '43', + description: 'nested-description', + }; + router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { + return executionContext.withContext(parentContext, async () => { + await delay(100); + return executionContext.withContext(nestedContext, async () => { + await delay(100); + return res.ok({ body: executionContext.get() }); + }); + }); + }); + + await root.start(); + const response = await kbnTestServer.request.get(root, '/execution-context').expect(200); + expect(response.body).toEqual({ ...nestedContext, parent: parentContext }); + }); + + it('extends the execution context passed from the client-side', async () => { + const { http, executionContext } = await root.setup(); + const { createRouter } = http; + + const router = createRouter(''); + const newContext = { + type: 'new-type', + name: 'new-name', + id: '41', + description: 'new-description', + }; + router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { + const { headers } = await executionContext.withContext(newContext, () => + context.core.elasticsearch.client.asCurrentUser.ping() + ); + return res.ok({ body: headers || {} }); + }); + + await root.start(); + + const response = await kbnTestServer.request + .get(root, '/execution-context') + .set(new ExecutionContextContainer(parentContext).toHeader()) + .expect(200); + + const header = response.body['x-opaque-id']; + expect(header).toContain('kibana:test-type:test-name:42;new-type:new-name:41'); + }); }); }); }); diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 85c035154a7a7..26725aff71b6c 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -337,10 +337,9 @@ export class HttpServer { const requestId = getRequestId(request, config.requestId); const parentContext = executionContext?.getParentContextFrom(request.headers); - executionContext?.set({ - ...parentContext, - requestId, - }); + if (parentContext) executionContext?.set(parentContext); + + executionContext?.setRequestId(requestId); request.app = { ...(request.app ?? {}), diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 191a3bd972f15..6ee95a09de303 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -84,11 +84,7 @@ export type { import type { ExecutionContextSetup, ExecutionContextStart } from './execution_context'; -export type { - IExecutionContextContainer, - KibanaServerExecutionContext, - KibanaExecutionContext, -} from './execution_context'; +export type { IExecutionContextContainer, KibanaExecutionContext } from './execution_context'; export { bootstrap } from './bootstrap'; export type { diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index 29194b1e8fc62..b972c6078ca2b 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -156,7 +156,9 @@ export function createPluginSetupContext( elasticsearch: { legacy: deps.elasticsearch.legacy, }, - executionContext: deps.executionContext, + executionContext: { + withContext: deps.executionContext.withContext, + }, http: { createCookieSessionStorageFactory: deps.http.createCookieSessionStorageFactory, registerRouteHandlerContext: < diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts index f972b537214c0..2a1d6bff0c247 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts @@ -12,7 +12,7 @@ import Util from 'util'; import Semver from 'semver'; import { REPO_ROOT } from '@kbn/dev-utils'; import { Env } from '@kbn/config'; -import { getEnvOptions } from '@kbn/config/target/mocks'; +import { getEnvOptions } from '../../../config/mocks'; import * as kbnTestServer from '../../../../test_helpers/kbn_server'; import { ElasticsearchClient } from '../../../elasticsearch'; import { SavedObjectsRawDoc } from '../../serialization'; diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/migration_7.7.2_xpack_100k.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/migration_7.7.2_xpack_100k.test.ts index 627a20148f943..ed21349a700fc 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/migration_7.7.2_xpack_100k.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/migration_7.7.2_xpack_100k.test.ts @@ -10,7 +10,7 @@ import path from 'path'; import { unlink } from 'fs/promises'; import { REPO_ROOT } from '@kbn/dev-utils'; import { Env } from '@kbn/config'; -import { getEnvOptions } from '@kbn/config/target/mocks'; +import { getEnvOptions } from '../../../config/mocks'; import * as kbnTestServer from '../../../../test_helpers/kbn_server'; import { ElasticsearchClient } from '../../../elasticsearch'; import { InternalCoreStart } from '../../../internal_types'; diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/migration_7_13_0_unknown_types.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/migration_7_13_0_unknown_types.test.ts index f9194521af11d..aded389bbb595 100644 --- a/src/core/server/saved_objects/migrationsv2/integration_tests/migration_7_13_0_unknown_types.test.ts +++ b/src/core/server/saved_objects/migrationsv2/integration_tests/migration_7_13_0_unknown_types.test.ts @@ -15,7 +15,7 @@ import JSON5 from 'json5'; import { ElasticsearchClient } from '../../../elasticsearch'; import { Env } from '@kbn/config'; import { REPO_ROOT } from '@kbn/utils'; -import { getEnvOptions } from '@kbn/config/target/mocks'; +import { getEnvOptions } from '../../../config/mocks'; const kibanaVersion = Env.createDefault(REPO_ROOT, getEnvOptions()).packageInfo.version; const targetIndex = `.kibana_${kibanaVersion}_001`; diff --git a/src/core/server/saved_objects/service/lib/errors.test.ts b/src/core/server/saved_objects/service/lib/errors.test.ts index a366dce626ec2..3bea693429254 100644 --- a/src/core/server/saved_objects/service/lib/errors.test.ts +++ b/src/core/server/saved_objects/service/lib/errors.test.ts @@ -439,4 +439,45 @@ describe('savedObjectsClient/errorTypes', () => { }); }); }); + + describe('NotFoundEsUnavailableError', () => { + it('makes an error identifiable as an EsUnavailable error', () => { + const error = SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError('foo', 'bar'); + expect(SavedObjectsErrorHelpers.isEsUnavailableError(error)).toBe(true); + }); + + it('returns a boom error', () => { + const error = SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError('foo', 'bar'); + expect(error).toHaveProperty('isBoom', true); + }); + + it('decorates the error message with the saved object that was not found', () => { + const error = SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError('foo', 'bar'); + expect(error.output.payload).toHaveProperty( + 'message', + 'x-elastic-product not present or not recognized: Saved object [foo/bar] not found' + ); + }); + + describe('error.output', () => { + it('specifies the saved object that was not found', () => { + const error = SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError( + 'foo', + 'bar' + ); + expect(error.output.payload).toHaveProperty( + 'message', + 'x-elastic-product not present or not recognized: Saved object [foo/bar] not found' + ); + }); + + it('sets statusCode to 503', () => { + const error = SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError( + 'foo', + 'bar' + ); + expect(error.output).toHaveProperty('statusCode', 503); + }); + }); + }); }); diff --git a/src/core/server/saved_objects/service/lib/errors.ts b/src/core/server/saved_objects/service/lib/errors.ts index 581145c7c09d1..c1e1e9589b9ae 100644 --- a/src/core/server/saved_objects/service/lib/errors.ts +++ b/src/core/server/saved_objects/service/lib/errors.ts @@ -202,4 +202,12 @@ export class SavedObjectsErrorHelpers { public static isGeneralError(error: Error | DecoratedError) { return isSavedObjectsClientError(error) && error[code] === CODE_GENERAL_ERROR; } + + public static createGenericNotFoundEsUnavailableError(type: string, id: string) { + const notFoundError = this.createGenericNotFoundError(type, id); + return this.decorateEsUnavailableError( + new Error(`${notFoundError.message}`), + `x-elastic-product not present or not recognized` + ); + } } diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js index 78af9f0753374..c025adce29808 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.js +++ b/src/core/server/saved_objects/service/lib/repository.test.js @@ -44,6 +44,8 @@ const createGenericNotFoundError = (...args) => SavedObjectsErrorHelpers.createGenericNotFoundError(...args).output.payload; const createUnsupportedTypeError = (...args) => SavedObjectsErrorHelpers.createUnsupportedTypeError(...args).output.payload; +const createGenericNotFoundEsUnavailableError = (...args) => + SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError(...args).output.payload; describe('SavedObjectsRepository', () => { let client; @@ -2202,6 +2204,11 @@ describe('SavedObjectsRepository', () => { createGenericNotFoundError(type, id) ); }; + const expectNotFoundEsUnavailableError = async (type, id) => { + await expect(savedObjectsRepository.delete(type, id)).rejects.toThrowError( + createGenericNotFoundEsUnavailableError(type, id) + ); + }; it(`throws when options.namespace is '*'`, async () => { await expect( @@ -2221,7 +2228,11 @@ describe('SavedObjectsRepository', () => { it(`throws when ES is unable to find the document during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + elasticsearchClientMock.createSuccessTransportRequestPromise( + { found: false }, + undefined, + { 'x-elastic-product': 'Elasticsearch' } + ) ); await expectNotFoundError(MULTI_NAMESPACE_ISOLATED_TYPE, id); expect(client.get).toHaveBeenCalledTimes(1); @@ -2229,12 +2240,30 @@ describe('SavedObjectsRepository', () => { it(`throws when ES is unable to find the index during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + elasticsearchClientMock.createSuccessTransportRequestPromise( + {}, + { statusCode: 404 }, + { 'x-elastic-product': 'Elasticsearch' } + ) ); await expectNotFoundError(MULTI_NAMESPACE_ISOLATED_TYPE, id); expect(client.get).toHaveBeenCalledTimes(1); }); + it(`throws when ES is unable to find the document during get with missing Elasticsearch header`, async () => { + client.get.mockResolvedValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + ); + await expectNotFoundEsUnavailableError(MULTI_NAMESPACE_ISOLATED_TYPE, id); + }); + + it(`throws when ES is unable to find the index during get with missing Elasticsearch header`, async () => { + client.get.mockResolvedValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + ); + await expectNotFoundEsUnavailableError(MULTI_NAMESPACE_ISOLATED_TYPE, id); + }); + it(`throws when the type is multi-namespace and the document exists, but not in this namespace`, async () => { const response = getMockGetResponse({ type: MULTI_NAMESPACE_ISOLATED_TYPE, id }, namespace); client.get.mockResolvedValueOnce( @@ -2278,7 +2307,7 @@ describe('SavedObjectsRepository', () => { client.delete.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise({ result: 'not_found' }) ); - await expectNotFoundError(type, id); + await expectNotFoundEsUnavailableError(type, id); expect(client.delete).toHaveBeenCalledTimes(1); }); @@ -2288,7 +2317,7 @@ describe('SavedObjectsRepository', () => { error: { type: 'index_not_found_exception' }, }) ); - await expectNotFoundError(type, id); + await expectNotFoundEsUnavailableError(type, id); expect(client.delete).toHaveBeenCalledTimes(1); }); @@ -3170,7 +3199,11 @@ describe('SavedObjectsRepository', () => { createGenericNotFoundError(type, id) ); }; - + const expectNotFoundEsUnavailableError = async (type, id) => { + await expect(savedObjectsRepository.get(type, id)).rejects.toThrowError( + createGenericNotFoundEsUnavailableError(type, id) + ); + }; it(`throws when options.namespace is '*'`, async () => { await expect( savedObjectsRepository.get(type, id, { namespace: ALL_NAMESPACES_STRING }) @@ -3189,7 +3222,11 @@ describe('SavedObjectsRepository', () => { it(`throws when ES is unable to find the document during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + elasticsearchClientMock.createSuccessTransportRequestPromise( + { found: false }, + undefined, + { 'x-elastic-product': 'Elasticsearch' } + ) ); await expectNotFoundError(type, id); expect(client.get).toHaveBeenCalledTimes(1); @@ -3197,7 +3234,11 @@ describe('SavedObjectsRepository', () => { it(`throws when ES is unable to find the index during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + elasticsearchClientMock.createSuccessTransportRequestPromise( + {}, + { statusCode: 404 }, + { 'x-elastic-product': 'Elasticsearch' } + ) ); await expectNotFoundError(type, id); expect(client.get).toHaveBeenCalledTimes(1); @@ -3213,6 +3254,15 @@ describe('SavedObjectsRepository', () => { }); expect(client.get).toHaveBeenCalledTimes(1); }); + + it(`throws when ES does not return the correct header when finding the document during get`, async () => { + client.get.mockResolvedValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + ); + await expectNotFoundEsUnavailableError(type, id); + + expect(client.get).toHaveBeenCalledTimes(1); + }); }); describe('returns', () => { @@ -3314,9 +3364,12 @@ describe('SavedObjectsRepository', () => { it('because alias is not used and actual object is not found', async () => { const options = { namespace: undefined }; - const response = { found: false }; client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) // for actual target + elasticsearchClientMock.createSuccessTransportRequestPromise( + { found: false }, + undefined, + { 'x-elastic-product': 'Elasticsearch' } + ) // for actual target ); await expectNotFoundError(type, id, options); @@ -3854,26 +3907,34 @@ describe('SavedObjectsRepository', () => { if (registry.isMultiNamespace(type)) { const mockGetResponse = getMockGetResponse({ type, id }, options?.namespace); client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockGetResponse) + elasticsearchClientMock.createSuccessTransportRequestPromise( + { ...mockGetResponse }, + { statusCode: 200 }, + { 'x-elastic-product': 'Elasticsearch' } + ) ); } client.update.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - _id: `${type}:${id}`, - ...mockVersionProps, - result: 'updated', - // don't need the rest of the source for test purposes, just the namespace and namespaces attributes - get: { - _source: { - namespaces: [options?.namespace ?? 'default'], - namespace: options?.namespace, + elasticsearchClientMock.createSuccessTransportRequestPromise( + { + _id: `${type}:${id}`, + ...mockVersionProps, + result: 'updated', + // don't need the rest of the source for test purposes, just the namespace and namespaces attributes + get: { + _source: { + namespaces: [options?.namespace ?? 'default'], + namespace: options?.namespace, - // "includeOriginId" is not an option for the operation; however, if the existing saved object contains an originId attribute, the - // operation will return it in the result. This flag is just used for test purposes to modify the mock cluster call response. - ...(includeOriginId && { originId }), + // "includeOriginId" is not an option for the operation; however, if the existing saved object contains an originId attribute, the + // operation will return it in the result. This flag is just used for test purposes to modify the mock cluster call response. + ...(includeOriginId && { originId }), + }, }, }, - }) + { statusCode: 200 }, + { 'x-elastic-product': 'Elasticsearch' } + ) ); const result = await savedObjectsRepository.update(type, id, attributes, options); expect(client.get).toHaveBeenCalledTimes(registry.isMultiNamespace(type) ? 1 : 0); @@ -4059,6 +4120,11 @@ describe('SavedObjectsRepository', () => { createGenericNotFoundError(type, id) ); }; + const expectNotFoundEsUnavailableError = async (type, id) => { + await expect(savedObjectsRepository.update(type, id)).rejects.toThrowError( + createGenericNotFoundEsUnavailableError(type, id) + ); + }; it(`throws when options.namespace is '*'`, async () => { await expect( @@ -4078,7 +4144,11 @@ describe('SavedObjectsRepository', () => { it(`throws when ES is unable to find the document during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + elasticsearchClientMock.createSuccessTransportRequestPromise( + { found: false }, + undefined, + { 'x-elastic-product': 'Elasticsearch' } + ) ); await expectNotFoundError(MULTI_NAMESPACE_ISOLATED_TYPE, id); expect(client.get).toHaveBeenCalledTimes(1); @@ -4086,12 +4156,32 @@ describe('SavedObjectsRepository', () => { it(`throws when ES is unable to find the index during get`, async () => { client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + elasticsearchClientMock.createSuccessTransportRequestPromise( + {}, + { statusCode: 404 }, + { 'x-elastic-product': 'Elasticsearch' } + ) ); await expectNotFoundError(MULTI_NAMESPACE_ISOLATED_TYPE, id); expect(client.get).toHaveBeenCalledTimes(1); }); + it(`throws when ES is unable to find the document during get with missing Elasticsearch header`, async () => { + client.get.mockResolvedValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise({ found: false }) + ); + await expectNotFoundEsUnavailableError(MULTI_NAMESPACE_ISOLATED_TYPE, id); + expect(client.get).toHaveBeenCalledTimes(1); + }); + + it(`throws when ES is unable to find the index during get with missing Elasticsearch`, async () => { + client.get.mockResolvedValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + ); + await expectNotFoundEsUnavailableError(MULTI_NAMESPACE_ISOLATED_TYPE, id); + expect(client.get).toHaveBeenCalledTimes(1); + }); + it(`throws when type is multi-namespace and the document exists, but not in this namespace`, async () => { const response = getMockGetResponse({ type: MULTI_NAMESPACE_ISOLATED_TYPE, id }, namespace); client.get.mockResolvedValueOnce( diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 6899f8613b07f..7ac4fe87bfc19 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -14,6 +14,7 @@ import { REPOSITORY_RESOLVE_OUTCOME_STATS, } from '../../../core_usage_data'; import type { ElasticsearchClient } from '../../../elasticsearch/'; +import { isSupportedEsServer } from '../../../elasticsearch'; import type { Logger } from '../../../logging'; import { getRootPropertiesObjects, IndexMapping } from '../../mappings'; import { @@ -648,7 +649,7 @@ export class SavedObjectsRepository { } } - const { body, statusCode } = await this.client.delete( + const { body, statusCode, headers } = await this.client.delete( { id: rawId, index: this.getIndexForType(type), @@ -665,9 +666,15 @@ export class SavedObjectsRepository { const deleteDocNotFound = body.result === 'not_found'; const deleteIndexNotFound = body.error && body.error.type === 'index_not_found_exception'; + const esServerSupported = isSupportedEsServer(headers); if (deleteDocNotFound || deleteIndexNotFound) { - // see "404s from missing index" above - throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id); + if (esServerSupported) { + // see "404s from missing index" above + throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id); + } else { + // throw if we can't verify the response is from Elasticsearch + throw SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError(type, id); + } } throw new Error( @@ -1009,19 +1016,19 @@ export class SavedObjectsRepository { if (!this._allowedTypes.includes(type)) { throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id); } - const namespace = normalizeNamespace(options.namespace); - - const { body, statusCode } = await this.client.get( + const { body, statusCode, headers } = await this.client.get( { id: this._serializer.generateRawId(namespace, type, id), index: this.getIndexForType(type), }, { ignore: [404] } ); - const indexNotFound = statusCode === 404; - + // check if we have the elasticsearch header when index is not found and if we do, ensure it is Elasticsearch + if (!isFoundGetResponse(body) && !isSupportedEsServer(headers)) { + throw SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError(type, id); + } if ( !isFoundGetResponse(body) || indexNotFound || @@ -1030,7 +1037,6 @@ export class SavedObjectsRepository { // see "404s from missing index" above throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id); } - return getSavedObjectFromSource(this._registry, type, id, body); } @@ -1248,7 +1254,19 @@ export class SavedObjectsRepository { _source_includes: ['namespace', 'namespaces', 'originId'], require_alias: true, }) + .then((res) => { + const indexNotFound = res.statusCode === 404; + const esServerSupported = isSupportedEsServer(res.headers); + // check if we have the elasticsearch header when index is not found and if we do, ensure it is Elasticsearch + if (indexNotFound && !esServerSupported) { + throw SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError(type, id); + } + return res; + }) .catch((err) => { + if (SavedObjectsErrorHelpers.isEsUnavailableError(err)) { + throw err; + } if (SavedObjectsErrorHelpers.isNotFoundError(err)) { // see "404s from missing index" above throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id); @@ -2070,7 +2088,7 @@ export class SavedObjectsRepository { * @param id The ID of the saved object. * @param namespace The target namespace. * @returns Raw document from Elasticsearch. - * @throws Will throw an error if the saved object is not found, or if it doesn't include the target namespace. + * @throws Will throw an error if the saved object is not found, if it doesn't include the target namespace or if the response is not identifiable as an Elasticsearch response. */ private async preflightCheckIncludesNamespace(type: string, id: string, namespace?: string) { if (!this._registry.isMultiNamespace(type)) { @@ -2078,7 +2096,7 @@ export class SavedObjectsRepository { } const rawId = this._serializer.generateRawId(undefined, type, id); - const { body, statusCode } = await this.client.get( + const { body, statusCode, headers } = await this.client.get( { id: rawId, index: this.getIndexForType(type), @@ -2087,6 +2105,14 @@ export class SavedObjectsRepository { ); const indexFound = statusCode !== 404; + + // check if we have the elasticsearch header when index is not found and if we do, ensure it is Elasticsearch + const esServerSupported = isSupportedEsServer(headers); + + if (!isFoundGetResponse(body) && !esServerSupported) { + throw SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError(type, id); + } + if ( !indexFound || !isFoundGetResponse(body) || diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 7f2ce38a5bdd4..985e0e337d75c 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1048,8 +1048,7 @@ export interface ErrorHttpResponseOptions { // @public (undocumented) export interface ExecutionContextSetup { - get(): IExecutionContextContainer | undefined; - set(context: Partial): void; + withContext(context: KibanaExecutionContext | undefined, fn: (...args: any[]) => R): R; } // @public (undocumented) @@ -1236,7 +1235,7 @@ export interface ICustomClusterClient extends IClusterClient { // @public (undocumented) export interface IExecutionContextContainer { // (undocumented) - toJSON(): Readonly; + toJSON(): Readonly; // (undocumented) toString(): string; } @@ -1357,14 +1356,15 @@ export interface IUiSettingsClient { setMany: (changes: Record) => Promise; } -// @public (undocumented) -export interface KibanaExecutionContext { - readonly description: string; - readonly id: string; - readonly name: string; +// @public +export type KibanaExecutionContext = { readonly type: string; + readonly name: string; + readonly id: string; + readonly description: string; readonly url?: string; -} + parent?: KibanaExecutionContext; +}; // @public export class KibanaRequest { @@ -1437,12 +1437,6 @@ export const kibanaResponseFactory: { noContent: (options?: HttpResponseOptions) => KibanaResponse; }; -// @public (undocumented) -export interface KibanaServerExecutionContext extends Partial { - // (undocumented) - requestId: string; -} - // Warning: (ae-forgotten-export) The symbol "KnownKeys" needs to be exported by the entry point index.d.ts // // @public @@ -2523,6 +2517,8 @@ export class SavedObjectsErrorHelpers { // (undocumented) static createGenericNotFoundError(type?: string | null, id?: string | null): DecoratedError; // (undocumented) + static createGenericNotFoundEsUnavailableError(type: string, id: string): DecoratedError; + // (undocumented) static createIndexAliasNotFoundError(alias: string): DecoratedError; // (undocumented) static createInvalidVersionError(versionInput?: string): DecoratedError; diff --git a/src/core/server/ui_settings/integration_tests/index.test.ts b/src/core/server/ui_settings/integration_tests/index.test.ts index 61e55284a20b8..44d98afdf54f5 100644 --- a/src/core/server/ui_settings/integration_tests/index.test.ts +++ b/src/core/server/ui_settings/integration_tests/index.test.ts @@ -8,7 +8,7 @@ import { Env } from '@kbn/config'; import { REPO_ROOT } from '@kbn/dev-utils'; -import { getEnvOptions } from '@kbn/config/target/mocks'; +import { getEnvOptions } from '../../config/mocks'; import { startServers, stopServers } from './lib'; import { docExistsSuite } from './doc_exists'; import { docMissingSuite } from './doc_missing'; diff --git a/src/core/server/ui_settings/integration_tests/so_migrations.test.ts b/src/core/server/ui_settings/integration_tests/so_migrations.test.ts new file mode 100644 index 0000000000000..6a59e33e9f262 --- /dev/null +++ b/src/core/server/ui_settings/integration_tests/so_migrations.test.ts @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createTestHarness, SavedObjectTestHarness } from '../../../test_helpers/so_migrations'; + +/** + * These tests are a little unnecessary because these migrations are incredibly simple, however + * this file serves as an example of how to use test_helpers/so_migrations. + */ +describe('ui settings migrations', () => { + let testHarness: SavedObjectTestHarness; + + beforeAll(async () => { + testHarness = createTestHarness(); + await testHarness.start(); + }); + + afterAll(async () => { + await testHarness.stop(); + }); + + it('migrates siem:* configs', async () => { + const input = [ + { + type: 'config', + id: '1', + attributes: { + 'siem:value-one': 1000, + 'siem:value-two': 'hello', + }, + references: [], + }, + ]; + expect(await testHarness.migrate(input)).toEqual([ + expect.objectContaining({ + type: 'config', + id: '1', + attributes: { + 'securitySolution:value-one': 1000, + 'securitySolution:value-two': 'hello', + }, + references: [], + }), + ]); + }); + + it('migrates ml:fileDataVisualizerMaxFileSize', async () => { + const input = [ + { + type: 'config', + id: '1', + attributes: { 'ml:fileDataVisualizerMaxFileSize': '1000' }, + // This field can be added if you only want this object to go through the > 7.12.0 migrations + // If this field is omitted the object will be run through all migrations available. + migrationVersion: { config: '7.12.0' }, + references: [], + }, + ]; + expect(await testHarness.migrate(input)).toEqual([ + expect.objectContaining({ + type: 'config', + id: '1', + attributes: { 'fileUpload:maxFileSize': '1000' }, + references: [], + }), + ]); + }); +}); diff --git a/src/core/test_helpers/so_migrations.ts b/src/core/test_helpers/so_migrations.ts new file mode 100644 index 0000000000000..9d14acc53bece --- /dev/null +++ b/src/core/test_helpers/so_migrations.ts @@ -0,0 +1,191 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import * as kbnTestServer from './kbn_server'; +import { SavedObject } from '../types'; +import { SavedObjectsType } from '../server'; + +type ExportOptions = { type: string } | { objects: Array<{ id: string; type: string }> }; + +/** + * Creates a test harness utility running migrations on a fully configured Kibana and Elasticsearch instance with all + * Kibana plugins loaded. Useful for testing more complex migrations that have dependencies on other plugins. Should + * only be used within the jest_integration suite. + * + * @example + * ```ts + * describe('my migrations', () => { + * let testHarness: SavedObjectTestHarness; + * beforeAll(async () => { + * testHarness = createTestHarness(); + * await testHarness.start(); + * }); + * afterAll(() => testHarness.stop()); + * + * + * it('migrates the documents', async () => { + * expect( + * await testHarness.migrate( + * { type: 'my-type', id: 'my-id', attributes: { ... }, references: [] } + * ) + * ).toEqual([ + * expect.objectContaining({ type: 'my-type', id: 'my-id', attributes: { ... }, references: [] }) + * ]); + * }); + * }); + * ``` + */ +export const createTestHarness = () => { + let started = false; + let stopped = false; + let esServer: kbnTestServer.TestElasticsearchUtils; + const { startES } = kbnTestServer.createTestServers({ adjustTimeout: jest.setTimeout }); + const root = kbnTestServer.createRootWithCorePlugins( + // Disable reporting due to browser install issue on CI. See https://github.com/elastic/kibana/issues/102919 + { xpack: { reporting: { enabled: false } } }, + { oss: false } + ); + + /** + * Imports an array of objects into Kibana and applies migrations before persisting to Elasticsearch. Will overwrite + * any existing objects with the same id. + * @param objects + */ + const importObjects = async (objects: SavedObject[]) => { + if (!started) + throw new Error(`SavedObjectTestHarness must be started before objects can be imported`); + if (stopped) throw new Error(`SavedObjectTestHarness cannot import objects after stopped`); + + const response = await kbnTestServer + // Always use overwrite=true flag so we can isolate this harness to migrations + .getSupertest(root, 'post', '/api/saved_objects/_import?overwrite=true') + .set('Content-Type', 'multipart/form-data; boundary=EXAMPLE') + .send( + [ + '--EXAMPLE', + 'Content-Disposition: form-data; name="file"; filename="export.ndjson"', + 'Content-Type: application/ndjson', + '', + ...objects.map((o) => JSON.stringify(o)), + '--EXAMPLE--', + ].join('\r\n') + ) + .expect(200); + + if (response.body.errors?.length > 0) { + throw new Error( + `Errors importing objects: ${JSON.stringify(response.body.errors, undefined, 2)}` + ); + } + }; + + /** + * Exports objects from Kibana with all migrations applied. + * @param options + */ + const exportObjects = async (options: ExportOptions): Promise => { + if (!started) + throw new Error(`SavedObjectTestHarness must be started before objects can be imported`); + if (stopped) throw new Error(`SavedObjectTestHarness cannot import objects after stopped`); + + const response = await kbnTestServer + .getSupertest(root, 'post', '/api/saved_objects/_export') + .send({ + ...options, + excludeExportDetails: true, + }) + .expect(200); + + return parseNdjson(response.text); + }; + + return { + /** + * Start Kibana and Elasticsearch for migration testing. Must be called before `migrate`. + * In most cases, this can be called during your test's `beforeAll` hook and does not need to be called for each + * individual test. + * + * @param customTypes - Additional SO types to register for this test. + */ + start: async ({ customTypes = [] }: { customTypes?: SavedObjectsType[] } = {}) => { + if (started) + throw new Error(`SavedObjectTestHarness already started! Cannot call start again`); + if (stopped) + throw new Error(`SavedObjectTestHarness already stopped! Cannot call start again`); + + esServer = await startES(); + await root.preboot(); + + const { savedObjects } = await root.setup(); + customTypes.forEach((type) => savedObjects.registerType(type)); + + await root.start(); + + await waitForTrue({ + predicate: async () => { + const statusApi = kbnTestServer.getSupertest(root, 'get', '/api/status'); + const response = await statusApi.send(); + return response.status === 200; + }, + }); + + started = true; + }, + + /** + * Stop Kibana and Elasticsearch for migration testing. Must be called after `start`. + * In most cases, this can be called during your test's `afterAll` hook and does not need to be called for each + * individual test. + */ + stop: async () => { + if (!started) throw new Error(`SavedObjectTestHarness not started! Cannot call stop`); + if (stopped) + throw new Error(`SavedObjectTestHarness already stopped! Cannot call stop again`); + + await root.shutdown(); + await esServer.stop(); + stopped = true; + }, + + /** + * Migrates an array of SavedObjects and returns the results. Assumes that the objects will retain the same type + * and id after the migration. When testing migrations that may change a document's type or id, use `importObjects` + * and `exportObjects` directly. + * @param objects + */ + migrate: async (objects: SavedObject[]) => { + await importObjects(objects); + return await exportObjects({ + objects: objects.map(({ type, id }) => ({ type, id })), + }); + }, + + importObjects, + exportObjects, + }; +}; + +export type SavedObjectTestHarness = ReturnType; + +const waitForTrue = async ({ predicate }: { predicate: () => Promise }) => { + let attempt = 0; + do { + attempt++; + const result = await predicate(); + if (result) { + return; + } + + await new Promise((r) => setTimeout(r, attempt * 500)); + } while (attempt <= 10); + + throw new Error(`Predicate never resolved after ${attempt} attempts`); +}; + +const parseNdjson = (ndjson: string): SavedObject[] => + ndjson.split('\n').map((l: string) => JSON.parse(l)); diff --git a/src/core/types/execution_context.ts b/src/core/types/execution_context.ts index df17195d84a9a..8a2d657812da8 100644 --- a/src/core/types/execution_context.ts +++ b/src/core/types/execution_context.ts @@ -6,9 +6,13 @@ * Side Public License, v 1. */ -/** @public */ - -export interface KibanaExecutionContext { +/** + * @public + * Represents a meta-information about a Kibana entity initiating a search request. + */ +// use type to make it compatible with SerializableState +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +export type KibanaExecutionContext = { /** * Kibana application initated an operation. * */ @@ -21,4 +25,6 @@ export interface KibanaExecutionContext { readonly description: string; /** in browser - url to navigate to a current page, on server - endpoint path, for task: task SO url */ readonly url?: string; -} + /** a context that spawned the current context. */ + parent?: KibanaExecutionContext; +}; diff --git a/src/core/types/index.ts b/src/core/types/index.ts index 97f990f608c04..280310aee8c55 100644 --- a/src/core/types/index.ts +++ b/src/core/types/index.ts @@ -15,5 +15,4 @@ export * from './capabilities'; export * from './app_category'; export * from './ui_settings'; export * from './saved_objects'; -export * from './serializable'; export type { KibanaExecutionContext } from './execution_context'; diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index b6e2a7c4b8f02..953bd619c444b 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -11,7 +11,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { I18nProvider } from '@kbn/i18n/react'; import uuid from 'uuid'; -import { CoreStart, IUiSettingsClient } from 'src/core/public'; +import { CoreStart, IUiSettingsClient, KibanaExecutionContext } from 'src/core/public'; import { Start as InspectorStartContract } from 'src/plugins/inspector/public'; import { UiActionsStart } from '../../services/ui_actions'; @@ -68,6 +68,7 @@ export interface InheritedChildInput extends IndexSignature { id: string; searchSessionId?: string; syncColors?: boolean; + executionContext?: KibanaExecutionContext; } export type DashboardReactContextValue = KibanaReactContextValue; @@ -249,6 +250,7 @@ export class DashboardContainer extends Container { const { search: { session }, @@ -102,6 +105,7 @@ export const buildDashboardContainer = async ({ query: data.query, searchSessionId, savedDashboard, + executionContext, }); /** diff --git a/src/plugins/dashboard/public/application/lib/convert_dashboard_state.ts b/src/plugins/dashboard/public/application/lib/convert_dashboard_state.ts index ee2ec2bb14fe4..2e6290ec920c0 100644 --- a/src/plugins/dashboard/public/application/lib/convert_dashboard_state.ts +++ b/src/plugins/dashboard/public/application/lib/convert_dashboard_state.ts @@ -7,6 +7,7 @@ */ import _ from 'lodash'; +import type { KibanaExecutionContext } from 'src/core/public'; import { DashboardSavedObject } from '../../saved_dashboards'; import { getTagsFromSavedDashboard, migrateAppState } from '.'; import { EmbeddablePackageState, ViewMode } from '../../services/embeddable'; @@ -40,6 +41,7 @@ interface StateToDashboardContainerInputProps { query: DashboardBuildContext['query']; incomingEmbeddable?: EmbeddablePackageState; dashboardCapabilities: DashboardBuildContext['dashboardCapabilities']; + executionContext?: KibanaExecutionContext; } interface StateToRawDashboardStateProps { @@ -92,6 +94,7 @@ export const stateToDashboardContainerInput = ({ searchSessionId, savedDashboard, dashboardState, + executionContext, }: StateToDashboardContainerInputProps): DashboardContainerInput => { const { filterManager, timefilter: timefilterService } = queryService; const { timefilter } = timefilterService; @@ -125,6 +128,7 @@ export const stateToDashboardContainerInput = ({ timeRange: { ..._.cloneDeep(timefilter.getTime()), }, + executionContext, }; }; diff --git a/src/plugins/dashboard/public/application/lib/diff_dashboard_state.ts b/src/plugins/dashboard/public/application/lib/diff_dashboard_state.ts index b1abba44891fc..8f0c8acf81022 100644 --- a/src/plugins/dashboard/public/application/lib/diff_dashboard_state.ts +++ b/src/plugins/dashboard/public/application/lib/diff_dashboard_state.ts @@ -29,7 +29,7 @@ export const diffDashboardContainerInput = ( return commonDiffFilters( (originalInput as unknown) as DashboardDiffCommonFilters, (newInput as unknown) as DashboardDiffCommonFilters, - ['searchSessionId', 'lastReloadRequestTime'] + ['searchSessionId', 'lastReloadRequestTime', 'executionContext'] ); }; diff --git a/src/plugins/dashboard/public/locator.ts b/src/plugins/dashboard/public/locator.ts index e154351819ee9..ed4e7a5dd4d4c 100644 --- a/src/plugins/dashboard/public/locator.ts +++ b/src/plugins/dashboard/public/locator.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import type { TimeRange, Filter, Query, QueryState, RefreshInterval } from '../../data/public'; import type { LocatorDefinition, LocatorPublic } from '../../share/public'; import type { SavedDashboardPanel } from '../common/types'; @@ -26,7 +26,7 @@ const cleanEmptyKeys = (stateObj: Record) => { export const DASHBOARD_APP_LOCATOR = 'DASHBOARD_APP_LOCATOR'; -export interface DashboardAppLocatorParams extends SerializableState { +export interface DashboardAppLocatorParams extends SerializableRecord { /** * If given, the dashboard saved object with this id will be loaded. If not given, * a new, unsaved dashboard will be loaded up. @@ -40,7 +40,7 @@ export interface DashboardAppLocatorParams extends SerializableState { /** * Optionally set the refresh interval. */ - refreshInterval?: RefreshInterval & SerializableState; + refreshInterval?: RefreshInterval & SerializableRecord; /** * Optionally apply filers. NOTE: if given and used in conjunction with `dashboardId`, and the @@ -80,7 +80,7 @@ export interface DashboardAppLocatorParams extends SerializableState { /** * List of dashboard panels */ - panels?: SavedDashboardPanel[] & SerializableState; + panels?: SavedDashboardPanel[] & SerializableRecord; /** * Saved query ID diff --git a/src/plugins/dashboard/public/types.ts b/src/plugins/dashboard/public/types.ts index 89c9adb572142..6dc068cf55f4d 100644 --- a/src/plugins/dashboard/public/types.ts +++ b/src/plugins/dashboard/public/types.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { +import type { AppMountParameters, CoreStart, SavedObjectsClientContract, @@ -14,8 +14,8 @@ import { ChromeStart, IUiSettingsClient, PluginInitializerContext, + KibanaExecutionContext, } from 'kibana/public'; - import { History } from 'history'; import { AnyAction, Dispatch } from 'redux'; import { BehaviorSubject, Subject } from 'rxjs'; @@ -86,6 +86,7 @@ export interface DashboardContainerInput extends ContainerInput { panels: { [panelId: string]: DashboardPanelState; }; + executionContext?: KibanaExecutionContext; } /** @@ -131,6 +132,7 @@ export type DashboardBuildContext = Pick< dispatchDashboardStateChange: Dispatch; $triggerDashboardRefresh: Subject<{ force?: boolean }>; $onDashboardStateChange: BehaviorSubject; + executionContext?: KibanaExecutionContext; }; export interface DashboardOptions { diff --git a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.test.ts b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.test.ts index 59dfa92cdbce0..6e1a6ccf1c86e 100644 --- a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.test.ts +++ b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.test.ts @@ -16,7 +16,7 @@ import { createInject, } from '../../common/embeddable/dashboard_container_persistable_state'; import { EmbeddableStateWithType } from 'src/plugins/embeddable/common'; -import { SerializableState } from '../../../kibana_utils/common'; +import { SerializableRecord } from '@kbn/utility-types'; const embeddableSetupMock = createEmbeddableSetupMock(); const extract = createExtract(embeddableSetupMock); @@ -589,7 +589,7 @@ describe('dashboard', () => { it('runs migrations on by value panels only', () => { const newEmbeddableSetupMock = createEmbeddableSetupMock(); newEmbeddableSetupMock.getAllMigrations.mockImplementation(() => ({ - '7.13.0': (state: SerializableState) => { + '7.13.0': (state: SerializableRecord) => { state.superCoolKey = 'ONLY 4 BY VALUE EMBEDDABLES THANK YOU VERY MUCH'; return state; }, diff --git a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts index ceb77ba1b2f9e..7848a2e46487c 100644 --- a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts +++ b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { Serializable } from '@kbn/utility-types'; import { get, flow, mapValues } from 'lodash'; import { SavedObjectAttributes, @@ -29,7 +30,6 @@ import { mergeMigrationFunctionMaps, MigrateFunction, MigrateFunctionsObject, - SerializableValue, } from '../../../kibana_utils/common'; import { replaceIndexPatternReference } from './replace_index_pattern_reference'; @@ -154,8 +154,8 @@ function createExtractPanelReferencesMigration( } type ValueOrReferenceInput = SavedObjectEmbeddableInput & { - attributes?: SerializableValue; - savedVis?: SerializableValue; + attributes?: Serializable; + savedVis?: Serializable; }; // Runs the embeddable migrations on each panel diff --git a/src/plugins/data/common/index_patterns/index.ts b/src/plugins/data/common/index_patterns/index.ts index 7f6249caceb52..340162e8bda70 100644 --- a/src/plugins/data/common/index_patterns/index.ts +++ b/src/plugins/data/common/index_patterns/index.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ +export * from './constants'; export * from './fields'; export * from './types'; export { IndexPatternsService, IndexPatternsContract } from './index_patterns'; export type { IndexPattern } from './index_patterns'; export * from './errors'; export * from './expressions'; -export * from './constants'; diff --git a/src/plugins/data/common/index_patterns/types.ts b/src/plugins/data/common/index_patterns/types.ts index 56a79dd9cfada..0e088d7aa8a8d 100644 --- a/src/plugins/data/common/index_patterns/types.ts +++ b/src/plugins/data/common/index_patterns/types.ts @@ -185,6 +185,7 @@ export interface FieldSpecExportFmt { } /** + * @public * Serialized version of IndexPatternField */ export interface FieldSpec extends IndexPatternFieldBase { diff --git a/src/plugins/data/common/query/persistable_state.ts b/src/plugins/data/common/query/persistable_state.ts index 08cda6eb59fbf..367234e9ff4f0 100644 --- a/src/plugins/data/common/query/persistable_state.ts +++ b/src/plugins/data/common/query/persistable_state.ts @@ -8,7 +8,7 @@ import uuid from 'uuid'; import { Filter } from '@kbn/es-query'; -import { SerializableState } from '../../../kibana_utils/common/persistable_state'; +import type { SerializableRecord } from '@kbn/utility-types'; import { SavedObjectReference } from '../../../../core/types'; export const extract = (filters: Filter[]) => { @@ -51,7 +51,7 @@ export const inject = (filters: Filter[], references: SavedObjectReference[]) => }); }; -export const telemetry = (filters: SerializableState, collector: unknown) => { +export const telemetry = (filters: SerializableRecord, collector: unknown) => { return {}; }; diff --git a/src/plugins/data/common/search/aggs/agg_config.ts b/src/plugins/data/common/search/aggs/agg_config.ts index 90540dc33cb6f..1a70a41e72dd5 100644 --- a/src/plugins/data/common/search/aggs/agg_config.ts +++ b/src/plugins/data/common/search/aggs/agg_config.ts @@ -9,6 +9,7 @@ import moment from 'moment'; import _ from 'lodash'; import { i18n } from '@kbn/i18n'; +import type { SerializableRecord } from '@kbn/utility-types'; import { Assign, Ensure } from '@kbn/utility-types'; import { ISearchOptions, ISearchSource } from 'src/plugins/data/public'; @@ -23,23 +24,16 @@ import { writeParams } from './agg_params'; import { IAggConfigs } from './agg_configs'; import { parseTimeShift } from './utils'; -type State = string | number | boolean | null | undefined | SerializableState; - -/** @internal **/ -export interface SerializableState { - [key: string]: State | State[]; -} - -/** @internal **/ +/** @public **/ export type AggConfigSerialized = Ensure< { type: string; enabled?: boolean; id?: string; - params?: {} | SerializableState; + params?: {} | SerializableRecord; schema?: string; }, - SerializableState + SerializableRecord >; export type AggConfigOptions = Assign; @@ -311,7 +305,7 @@ export class AggConfig { id: this.id, enabled: this.enabled, type: this.type && this.type.name, - params: outParams as SerializableState, + params: outParams as SerializableRecord, ...(this.schema && { schema: this.schema }), }; } @@ -333,7 +327,7 @@ export class AggConfig { */ toSerializedFieldFormat(): | {} - | Ensure, SerializableState> { + | Ensure, SerializableRecord> { return this.type ? this.type.getSerializedFormat(this) : {}; } diff --git a/src/plugins/data/common/search/aggs/buckets/histogram.test.ts b/src/plugins/data/common/search/aggs/buckets/histogram.test.ts index 0a1ac2289b07d..ef5cd85e6f5a2 100644 --- a/src/plugins/data/common/search/aggs/buckets/histogram.test.ts +++ b/src/plugins/data/common/search/aggs/buckets/histogram.test.ts @@ -12,7 +12,7 @@ import { AggTypesDependencies } from '../agg_types'; import { BUCKET_TYPES } from './bucket_agg_types'; import { IBucketHistogramAggConfig, getHistogramBucketAgg, AutoBounds } from './histogram'; import { BucketAggType } from './bucket_agg_type'; -import { SerializableState } from 'src/plugins/expressions/common'; +import { SerializableRecord } from '@kbn/utility-types'; describe('Histogram Agg', () => { let aggTypesDependencies: AggTypesDependencies; @@ -256,7 +256,7 @@ describe('Histogram Agg', () => { }); (aggConfigs.aggs[0] as IBucketHistogramAggConfig).setAutoBounds({ min: 0, max: 1000 }); const serializedAgg = aggConfigs.aggs[0].serialize(); - const serializedIntervalParam = (serializedAgg.params as SerializableState).used_interval; + const serializedIntervalParam = (serializedAgg.params as SerializableRecord).used_interval; expect(serializedIntervalParam).toBe(500); const freshHistogramAggConfig = getAggConfigs({ interval: 100, diff --git a/src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts b/src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts index 7bbdae497644a..0c98d0733c647 100644 --- a/src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts +++ b/src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts @@ -7,15 +7,10 @@ */ import dateMath from '@elastic/datemath'; +import { buildQueryFromFilters } from '@kbn/es-query'; import { memoize } from 'lodash'; import { CoreSetup } from 'src/core/public'; -import { - IIndexPattern, - IFieldType, - UI_SETTINGS, - buildQueryFromFilters, - ValueSuggestionsMethod, -} from '../../../common'; +import { IIndexPattern, IFieldType, UI_SETTINGS, ValueSuggestionsMethod } from '../../../common'; import { TimefilterSetup } from '../../query'; import { AutocompleteUsageCollector } from '../collectors'; diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index fb35d00545040..99c89ac69b795 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -45,7 +45,6 @@ import { isDefault, validateIndexPattern, flattenHitWrapper, - formatHitProvider, } from './index_patterns'; export type { IndexPatternsService } from './index_patterns'; @@ -61,15 +60,9 @@ export const indexPatterns = { isNestedField, validate: validateIndexPattern, flattenHitWrapper, - formatHitProvider, }; -export { - IndexPatternsContract, - IndexPattern, - IIndexPatternFieldList, - IndexPatternField, -} from './index_patterns'; +export { IndexPatternsContract, IndexPattern, IndexPatternField } from './index_patterns'; export { IIndexPattern, @@ -78,7 +71,6 @@ export { KBN_FIELD_TYPES, IndexPatternAttributes, UI_SETTINGS, - TypeMeta as IndexPatternTypeMeta, AggregationRestrictions as IndexPatternAggRestrictions, IndexPatternSpec, IndexPatternLoadExpressionFunctionDefinition, @@ -182,19 +174,10 @@ export type { ISearchStartSearchSource, ISearchGeneric, ISearchSource, - SearchInterceptor, - SearchInterceptorDeps, SearchRequest, SearchSourceFields, - // expression functions and types - EsdslExpressionFunctionDefinition, - EsRawResponseExpressionTypeDefinition, // errors IEsError, - SearchError, - SearchTimeoutError, - TimeoutErrorMode, - PainlessError, Reason, WaitUntilNextSessionCompletesOptions, } from './search'; @@ -203,7 +186,6 @@ export { parseSearchSourceJSON, injectSearchSourceReferences, extractSearchSourceReferences, - getEsPreference, getSearchParamsFromRequest, noSearchSessionStorageCapabilityMessage, SEARCH_SESSIONS_MANAGEMENT_ID, @@ -215,6 +197,7 @@ export { export type { SearchSource, + // TODO: remove these when data_enhanced is merged into data ISessionService, SearchSessionInfoProvider, ISessionsClient, @@ -287,7 +270,6 @@ export type { SavedQuery, SavedQueryService, SavedQueryTimeFilter, - InputTimeRange, TimefilterContract, TimeHistoryContract, QueryStateChange, diff --git a/src/plugins/data/public/index_patterns/index_pattern.stub.ts b/src/plugins/data/public/index_patterns/index_pattern.stub.ts index 36569cafd6611..a203e84af270f 100644 --- a/src/plugins/data/public/index_patterns/index_pattern.stub.ts +++ b/src/plugins/data/public/index_patterns/index_pattern.stub.ts @@ -10,9 +10,10 @@ import sinon from 'sinon'; import { CoreSetup } from 'src/core/public'; import { SerializedFieldFormat } from 'src/plugins/expressions/public'; -import { IFieldType, FieldSpec } from '../../common/index_patterns'; -import { IndexPattern, indexPatterns, KBN_FIELD_TYPES, fieldList } from '../'; +import { IFieldType, FieldSpec, fieldList } from '../../common/index_patterns'; +import { IndexPattern, KBN_FIELD_TYPES } from '../'; import { getFieldFormatsRegistry } from '../test_utils'; +import { flattenHitWrapper, formatHitProvider } from './index_patterns'; export function getStubIndexPattern( pattern: string, @@ -81,11 +82,8 @@ export class StubIndexPattern { }; this.getComputedFields = IndexPattern.prototype.getComputedFields.bind(this); - this.flattenHit = indexPatterns.flattenHitWrapper( - (this as unknown) as IndexPattern, - this.metaFields - ); - this.formatHit = indexPatterns.formatHitProvider( + this.flattenHit = flattenHitWrapper((this as unknown) as IndexPattern, this.metaFields); + this.formatHit = formatHitProvider( (this as unknown) as IndexPattern, registeredFieldFormats.getDefaultInstance(KBN_FIELD_TYPES.STRING) ); diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 64b73ded88eef..2fee05760186b 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -8,13 +8,11 @@ import { $Values } from '@kbn/utility-types'; import { Action } from 'history'; import { Adapters as Adapters_2 } from 'src/plugins/inspector/common'; import { ApiResponse } from '@elastic/elasticsearch/lib/Transport'; -import { ApplicationStart } from 'kibana/public'; import { Assign } from '@kbn/utility-types'; import { BfetchPublicSetup } from 'src/plugins/bfetch/public'; import Boom from '@hapi/boom'; import { ConfigDeprecationProvider } from '@kbn/config'; import { CoreSetup } from 'src/core/public'; -import { CoreSetup as CoreSetup_2 } from 'kibana/public'; import { CoreStart } from 'kibana/public'; import { CoreStart as CoreStart_2 } from 'src/core/public'; import { CustomFilter as CustomFilter_2 } from '@kbn/es-query'; @@ -108,10 +106,10 @@ import { SavedObjectsFindOptions } from 'kibana/public'; import { SavedObjectsFindResponse } from 'kibana/server'; import { SavedObjectsUpdateResponse } from 'kibana/server'; import { SchemaTypeError } from '@kbn/config-schema'; +import { SerializableRecord } from '@kbn/utility-types'; import { SerializedFieldFormat as SerializedFieldFormat_3 } from 'src/plugins/expressions/common'; import { StartServicesAccessor } from 'kibana/public'; import { ToastInputFields } from 'src/core/public/notifications'; -import { ToastsSetup } from 'kibana/public'; import { TransportRequestOptions } from '@elastic/elasticsearch/lib/Transport'; import { TransportRequestParams } from '@elastic/elasticsearch/lib/Transport'; import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport'; @@ -192,8 +190,6 @@ export class AggConfig { parent?: IAggConfigs; // (undocumented) schema?: string; - // Warning: (ae-incompatible-release-tags) The symbol "serialize" is marked as @public, but its signature references "AggConfigSerialized" which is marked as @internal - // // (undocumented) serialize(): AggConfigSerialized; setParams(from: any): void; @@ -203,12 +199,9 @@ export class AggConfig { toDsl(aggConfigs?: IAggConfigs): any; // (undocumented) toExpressionAst(): ExpressionAstExpression | undefined; - // Warning: (ae-incompatible-release-tags) The symbol "toJSON" is marked as @public, but its signature references "AggConfigSerialized" which is marked as @internal - // // @deprecated (undocumented) toJSON(): AggConfigSerialized; - // Warning: (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts - toSerializedFieldFormat(): {} | Ensure, SerializableState_2>; + toSerializedFieldFormat(): {} | Ensure, SerializableRecord>; // (undocumented) get type(): IAggType; set type(type: IAggType); @@ -218,7 +211,6 @@ export class AggConfig { write(aggs?: IAggConfigs): Record; } -// Warning: (ae-incompatible-release-tags) The symbol "AggConfigOptions" is marked as @public, but its signature references "AggConfigSerialized" which is marked as @internal // Warning: (ae-missing-release-tag) "AggConfigOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -235,7 +227,7 @@ export class AggConfigs { type: string; enabled?: boolean | undefined; id?: string | undefined; - params?: {} | import("./agg_config").SerializableState | undefined; + params?: {} | import("@kbn/utility-types").SerializableRecord | undefined; schema?: string | undefined; }, "schema" | "enabled" | "id" | "params"> & Pick<{ type: string | IAggType; @@ -333,14 +325,14 @@ export class AggConfigs { toDsl(): Record; } -// @internal (undocumented) +// @public (undocumented) export type AggConfigSerialized = Ensure<{ type: string; enabled?: boolean; id?: string; - params?: {} | SerializableState_2; + params?: {} | SerializableRecord; schema?: string; -}, SerializableState_2>; +}, SerializableRecord>; // Warning: (ae-missing-release-tag) "AggFunctionsMapping" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -532,8 +524,6 @@ export class AggParamType extends Ba constructor(config: Record); // (undocumented) allowedAggs: string[]; - // Warning: (ae-incompatible-release-tags) The symbol "makeAgg" is marked as @public, but its signature references "AggConfigSerialized" which is marked as @internal - // // (undocumented) makeAgg: (agg: TAggConfig, state?: AggConfigSerialized) => TAggConfig; } @@ -741,15 +731,6 @@ export const ES_SEARCH_STRATEGY = "es"; // @public (undocumented) export type EsaggsExpressionFunctionDefinition = ExpressionFunctionDefinition<'esaggs', Input_36, Arguments_21, Output_36>; -// Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "Input" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "Arguments" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "Output" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "EsdslExpressionFunctionDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type EsdslExpressionFunctionDefinition = ExpressionFunctionDefinition; - // Warning: (ae-missing-release-tag) "esFilters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated @@ -811,7 +792,7 @@ export const esFilters: { export const esKuery: { nodeTypes: import("@kbn/es-query/target_types/kuery/node_types").NodeTypes; fromKueryExpression: (expression: any, parseOptions?: Partial | undefined) => import("@kbn/es-query").KueryNode; - toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: Record | undefined, context?: Record | undefined) => import("@kbn/common-utils").JsonObject; + toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: Record | undefined, context?: Record | undefined) => import("@kbn/utility-types").JsonObject; }; // Warning: (ae-missing-release-tag) "esQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -842,14 +823,6 @@ export type EsQueryConfig = EsQueryConfig_2; // @public (undocumented) export type EsQuerySortValue = Record; -// Warning: (ae-forgotten-export) The symbol "ExpressionTypeDefinition" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "EsRawResponse" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "EsRawResponseExpressionTypeDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type EsRawResponseExpressionTypeDefinition = ExpressionTypeDefinition; - // Warning: (ae-missing-release-tag) "ExecutionContextSearch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -906,6 +879,7 @@ export function extractTimeRange(filters: Filter_2[], timeFieldName?: string): { }; // Warning: (ae-forgotten-export) The symbol "FieldSpec" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "IIndexPatternFieldList" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "fieldList" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -969,7 +943,7 @@ export class FilterManager implements PersistableStateService { static setFiltersStore(filters: Filter_2[], store: FilterStateStore, shouldOverrideStore?: boolean): void; setGlobalFilters(newGlobalFilters: Filter_2[]): void; // (undocumented) - telemetry: (filters: import("../../../../kibana_utils/common/persistable_state").SerializableState, collector: unknown) => {}; + telemetry: (filters: import("@kbn/utility-types").SerializableRecord, collector: unknown) => {}; } // Warning: (ae-missing-release-tag) "generateFilters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -991,12 +965,6 @@ export function getDefaultQuery(language?: QueryLanguage): { // @public (undocumented) export function getDisplayValueFromFilter(filter: Filter, indexPatterns: IIndexPattern[]): string; -// Warning: (ae-forgotten-export) The symbol "IUiSettingsClient" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "getEsPreference" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export function getEsPreference(uiSettings: IUiSettingsClient_2, sessionId?: string): any; - // Warning: (ae-forgotten-export) The symbol "KibanaConfig" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "getEsQueryConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1164,34 +1132,6 @@ export interface IIndexPattern extends IndexPatternBase { type?: string; } -// Warning: (ae-missing-release-tag) "IIndexPatternFieldList" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface IIndexPatternFieldList extends Array { - // (undocumented) - add(field: FieldSpec): void; - // (undocumented) - getAll(): IndexPatternField[]; - // (undocumented) - getByName(name: IndexPatternField['name']): IndexPatternField | undefined; - // (undocumented) - getByType(type: IndexPatternField['type']): IndexPatternField[]; - // (undocumented) - remove(field: IFieldType): void; - // (undocumented) - removeAll(): void; - // (undocumented) - replaceAll(specs: FieldSpec[]): void; - // Warning: (ae-forgotten-export) The symbol "IndexPatternFieldMap" needs to be exported by the entry point index.d.ts - // - // (undocumented) - toSpec(options?: { - getFormatterForField?: IndexPattern['getFormatterForField']; - }): IndexPatternFieldMap; - // (undocumented) - update(field: FieldSpec): void; -} - // Warning: (ae-missing-release-tag) "IKibanaSearchRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1333,7 +1273,8 @@ export class IndexPattern implements IIndexPattern { title: string; toSpec(): IndexPatternSpec; type: string | undefined; - typeMeta?: IndexPatternTypeMeta; + // Warning: (ae-forgotten-export) The symbol "TypeMeta" needs to be exported by the entry point index.d.ts + typeMeta?: TypeMeta; version: string | undefined; } @@ -1454,7 +1395,6 @@ export const indexPatterns: { isNestedField: typeof isNestedField; validate: typeof validateIndexPattern; flattenHitWrapper: typeof flattenHitWrapper; - formatHitProvider: typeof formatHitProvider; }; // Warning: (ae-missing-release-tag) "IndexPatternsContract" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1499,7 +1439,7 @@ export interface IndexPatternSpec { // (undocumented) type?: string; // (undocumented) - typeMeta?: IndexPatternTypeMeta; + typeMeta?: TypeMeta; version?: string; } @@ -1551,18 +1491,6 @@ export enum IndexPatternType { ROLLUP = "rollup" } -// Warning: (ae-missing-release-tag) "TypeMeta" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface IndexPatternTypeMeta { - // (undocumented) - aggs?: Record; - // (undocumented) - params?: { - rollup_index: string; - }; -} - // Warning: (ae-missing-release-tag) "injectReferences" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1570,14 +1498,6 @@ export const injectSearchSourceReferences: (searchSourceFields: SearchSourceFiel indexRefName: string; }, references: SavedObjectReference_2[]) => SearchSourceFields; -// Warning: (ae-missing-release-tag) "InputTimeRange" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type InputTimeRange = TimeRange | { - from: Moment; - to: Moment; -}; - // Warning: (ae-missing-release-tag) "isCompleteResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1785,20 +1705,6 @@ export interface OptionedValueProp { value: string; } -// Warning: (ae-forgotten-export) The symbol "EsError" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "PainlessError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export class PainlessError extends EsError { - constructor(err: IEsError, indexPattern?: IndexPattern); - // (undocumented) - getErrorMessage(application: ApplicationStart): JSX.Element; - // (undocumented) - indexPattern?: IndexPattern; - // (undocumented) - painlessStack?: string; -} - // Warning: (ae-forgotten-export) The symbol "parseEsInterval" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ParsedInterval" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1922,6 +1828,7 @@ export interface QueryStringInputProps { storageKey?: string; // (undocumented) submitOnBlur?: boolean; + timeRangeForSuggestionsOverride?: boolean; } // @public (undocumented) @@ -2163,59 +2070,6 @@ export const SearchBar: React.ComponentClass>; - // (undocumented) - showError(e: Error): void; - // (undocumented) - stop(): void; - } - -// Warning: (ae-missing-release-tag) "SearchInterceptorDeps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface SearchInterceptorDeps { - // (undocumented) - bfetch: BfetchPublicSetup; - // (undocumented) - http: CoreSetup_2['http']; - // (undocumented) - session: ISessionService; - // (undocumented) - startServices: Promise<[CoreStart, any, unknown]>; - // (undocumented) - toasts: ToastsSetup; - // (undocumented) - uiSettings: CoreSetup_2['uiSettings']; - // Warning: (ae-incompatible-release-tags) The symbol "usageCollector" is marked as @public, but its signature references "SearchUsageCollector" which is marked as @internal - // - // (undocumented) - usageCollector?: SearchUsageCollector; -} - // @internal export type SearchRequest = Record; @@ -2331,18 +2185,6 @@ export interface SearchSourceFields { version?: boolean; } -// Warning: (ae-forgotten-export) The symbol "KbnError" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SearchTimeoutError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export class SearchTimeoutError extends KbnError { - constructor(err: Record, mode: TimeoutErrorMode); - // (undocumented) - getErrorMessage(application: ApplicationStart): JSX.Element; - // (undocumented) - mode: TimeoutErrorMode; - } - // @internal (undocumented) export interface SearchUsageCollector { // (undocumented) @@ -2426,16 +2268,6 @@ export class TimeHistory { // @public (undocumented) export type TimeHistoryContract = PublicMethodsOf; -// Warning: (ae-missing-release-tag) "TimeoutErrorMode" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export enum TimeoutErrorMode { - // (undocumented) - CHANGE = 1, - // (undocumented) - CONTACT = 0 -} - // Warning: (ae-missing-release-tag) "TimeRange" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -2490,6 +2322,7 @@ export interface WaitUntilNextSessionCompletesOptions { // Warnings were encountered during analysis: // +// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:52:45 - (ae-forgotten-export) The symbol "IndexPatternFieldMap" needs to be exported by the entry point index.d.ts // src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:66:5 - (ae-forgotten-export) The symbol "FormatFieldFn" needs to be exported by the entry point index.d.ts // src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:139:7 - (ae-forgotten-export) The symbol "FieldAttrSet" needs to be exported by the entry point index.d.ts // src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:170:7 - (ae-forgotten-export) The symbol "RuntimeField" needs to be exported by the entry point index.d.ts @@ -2499,25 +2332,24 @@ export interface WaitUntilNextSessionCompletesOptions { // src/plugins/data/public/deprecated.ts:98:23 - (ae-forgotten-export) The symbol "convertRangeFilterToTimeRangeString" needs to be exported by the entry point index.d.ts // src/plugins/data/public/deprecated.ts:98:23 - (ae-forgotten-export) The symbol "extractTimeFilter" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:27:23 - (ae-forgotten-export) The symbol "datatableToCSV" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:54:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:54:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:54:27 - (ae-forgotten-export) The symbol "validateIndexPattern" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:54:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:54:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:227:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:227:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:227:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:229:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:230:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:239:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:240:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:241:1 - (ae-forgotten-export) The symbol "IpAddress" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:242:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:246:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:247:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:250:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:251:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:254:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:53:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:53:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:53:27 - (ae-forgotten-export) The symbol "validateIndexPattern" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:53:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:210:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:210:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:210:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:212:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:213:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:222:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:223:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:224:1 - (ae-forgotten-export) The symbol "IpAddress" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:225:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:229:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:230:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:233:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:234:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:237:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/public/search/session/session_service.ts:62:5 - (ae-forgotten-export) The symbol "UrlGeneratorStateMapping" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/data/public/query/filter_manager/filter_manager.ts b/src/plugins/data/public/query/filter_manager/filter_manager.ts index bcae190b50773..34af80a483e6b 100644 --- a/src/plugins/data/public/query/filter_manager/filter_manager.ts +++ b/src/plugins/data/public/query/filter_manager/filter_manager.ts @@ -228,15 +228,15 @@ export class FilterManager implements PersistableStateService { }); } - // Filter needs to implement SerializableState + // Filter needs to implement SerializableRecord public extract = extract as any; - // Filter needs to implement SerializableState + // Filter needs to implement SerializableRecord public inject = inject as any; public telemetry = telemetry; - // Filter needs to implement SerializableState + // Filter needs to implement SerializableRecord public migrateToLatest = migrateToLatest as any; public getAllMigrations = getAllMigrations; diff --git a/src/plugins/data/public/search/expressions/esaggs.ts b/src/plugins/data/public/search/expressions/esaggs.ts index c4a6ae3a516df..cf3de20fea50e 100644 --- a/src/plugins/data/public/search/expressions/esaggs.ts +++ b/src/plugins/data/public/search/expressions/esaggs.ts @@ -64,7 +64,7 @@ export function getFunctionDefinition({ timeFields: args.timeFields, timeRange: get(input, 'timeRange', undefined), getNow, - executionContext: getExecutionContext()?.toJSON(), + executionContext: getExecutionContext(), }) ) ); diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index 70f25bd510ef0..09fd818f23703 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -37,6 +37,7 @@ interface Props { indexPatterns: IIndexPattern[]; intl: InjectedIntl; appName: string; + timeRangeForSuggestionsOverride?: boolean; } function FilterBarUI(props: Props) { @@ -65,6 +66,7 @@ function FilterBarUI(props: Props) { onRemove={() => onRemove(i)} indexPatterns={props.indexPatterns} uiSettings={uiSettings!} + timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride} /> )); @@ -112,6 +114,7 @@ function FilterBarUI(props: Props) { onSubmit={onAdd} onCancel={() => setIsAddFilterPopoverOpen(false)} key={JSON.stringify(newFilter)} + timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride} /> diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx index 90ca8e0783a20..7d1765ddd7f79 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx @@ -54,6 +54,7 @@ export interface Props { onSubmit: (filter: Filter) => void; onCancel: () => void; intl: InjectedIntl; + timeRangeForSuggestionsOverride?: boolean; } interface State { @@ -356,6 +357,7 @@ class FilterEditorUI extends Component { value={this.state.params} onChange={this.onParamsChange} data-test-subj="phraseValueInput" + timeRangeForSuggestionsOverride={this.props.timeRangeForSuggestionsOverride} fullWidth /> ); @@ -366,6 +368,7 @@ class FilterEditorUI extends Component { field={this.state.selectedField} values={this.state.params} onChange={this.onParamsChange} + timeRangeForSuggestionsOverride={this.props.timeRangeForSuggestionsOverride} fullWidth /> ); diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_suggestor.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_suggestor.tsx index 779e365969e17..fb3106e6a8f06 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_suggestor.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_suggestor.tsx @@ -17,6 +17,7 @@ export interface PhraseSuggestorProps { kibana: KibanaReactContextValue; indexPattern: IIndexPattern; field?: IFieldType; + timeRangeForSuggestionsOverride?: boolean; } export interface PhraseSuggestorState { @@ -63,7 +64,8 @@ export class PhraseSuggestorUI extends React.Com protected updateSuggestions = debounce(async (query: string = '') => { if (this.abortController) this.abortController.abort(); this.abortController = new AbortController(); - const { indexPattern, field } = this.props as PhraseSuggestorProps; + const { indexPattern, field, timeRangeForSuggestionsOverride } = this + .props as PhraseSuggestorProps; if (!field || !this.isSuggestingValues()) { return; } @@ -74,8 +76,7 @@ export class PhraseSuggestorUI extends React.Com field, query, signal: this.abortController.signal, - // Show all results in filter bar autocomplete - useTimeRange: false, + useTimeRange: timeRangeForSuggestionsOverride, }); this.setState({ suggestions, isLoading: false }); diff --git a/src/plugins/data/public/ui/filter_bar/filter_item.tsx b/src/plugins/data/public/ui/filter_bar/filter_item.tsx index b37fc9108ccd2..acc908e799151 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_item.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_item.tsx @@ -36,6 +36,7 @@ export interface FilterItemProps { intl: InjectedIntl; uiSettings: IUiSettingsClient; hiddenPanelOptions?: PanelOptions[]; + timeRangeForSuggestionsOverride?: boolean; } interface LabelOptions { @@ -253,6 +254,7 @@ export function FilterItem(props: FilterItemProps) { onCancel={() => { setIsPopoverOpen(false); }} + timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride} /> ), diff --git a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx index abb0de19698d7..f71a3d3b0686a 100644 --- a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx @@ -59,6 +59,7 @@ export interface QueryBarTopRowProps { isClearable?: boolean; nonKqlMode?: 'lucene' | 'text'; nonKqlModeHelpText?: string; + timeRangeForSuggestionsOverride?: boolean; } // Needed for React.lazy @@ -190,6 +191,7 @@ export default function QueryBarTopRow(props: QueryBarTopRowProps) { iconType={props.iconType} nonKqlMode={props.nonKqlMode} nonKqlModeHelpText={props.nonKqlModeHelpText} + timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride} /> diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx index 0f660f87266fd..62a561220e7fa 100644 --- a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx @@ -76,6 +76,11 @@ export interface QueryStringInputProps { * @param storageKey this key is used to use user preference between kql and non-kql mode */ storageKey?: string; + + /** + * Override whether autocomplete suggestions are restricted by time range. + */ + timeRangeForSuggestionsOverride?: boolean; } interface Props extends QueryStringInputProps { @@ -211,6 +216,7 @@ export default class QueryStringInputUI extends Component { selectionStart, selectionEnd, signal: this.abortController.signal, + useTimeRange: this.props.timeRangeForSuggestionsOverride, })) || []; return [...suggestions, ...recentSearchSuggestions]; } catch (e) { diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx index 1608b68ed01b2..a03e7b33d2b65 100644 --- a/src/plugins/data/public/ui/search_bar/search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx @@ -14,12 +14,13 @@ import { get, isEqual } from 'lodash'; import { EuiIconProps } from '@elastic/eui'; import { METRIC_TYPE } from '@kbn/analytics'; +import { Query, Filter } from '@kbn/es-query'; import { withKibana, KibanaReactContextValue } from '../../../../kibana_react/public'; import QueryBarTopRow from '../query_string_input/query_bar_top_row'; import { SavedQueryAttributes, TimeHistoryContract, SavedQuery } from '../../query'; import { IDataPluginServices } from '../../types'; -import { TimeRange, Query, Filter, IIndexPattern } from '../../../common'; +import { TimeRange, IIndexPattern } from '../../../common'; import { FilterBar } from '../filter_bar/filter_bar'; import { SavedQueryMeta, SaveQueryForm } from '../saved_query_form'; import { SavedQueryManagementComponent } from '../saved_query_management'; @@ -349,6 +350,8 @@ class SearchBarUI extends Component { /> ); + const timeRangeForSuggestionsOverride = this.props.showDatePicker ? undefined : false; + let queryBar; if (this.shouldRenderQueryBar()) { queryBar = ( @@ -381,6 +384,7 @@ class SearchBarUI extends Component { iconType={this.props.iconType} nonKqlMode={this.props.nonKqlMode} nonKqlModeHelpText={this.props.nonKqlModeHelpText} + timeRangeForSuggestionsOverride={timeRangeForSuggestionsOverride} /> ); } @@ -391,6 +395,7 @@ class SearchBarUI extends Component { // eslint-disable-next-line @typescript-eslint/naming-convention 'globalFilterGroup__wrapper-isVisible': this.state.isFiltersVisible, }); + filterBar = (
{ onFiltersUpdated={this.props.onFiltersUpdated} indexPatterns={this.props.indexPatterns!} appName={this.services.appName} + timeRangeForSuggestionsOverride={timeRangeForSuggestionsOverride} />
); diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index d010819d14e94..2e6f9492d7d48 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -11,7 +11,7 @@ import { ConfigSchema, configSchema } from '../config'; import { DataServerPlugin, DataPluginSetup, DataPluginStart } from './plugin'; export * from './deprecated'; -export { getEsQueryConfig, buildQueryFromFilters } from '../common'; +export { getEsQueryConfig } from '../common'; /** * Exporters (CSV) @@ -33,19 +33,10 @@ export { INDEX_PATTERN_SAVED_OBJECT_TYPE } from '../common'; * Index patterns: */ -import { isNestedField, isFilterable } from '../common'; - -export const indexPatterns = { - isFilterable, - isNestedField, -}; - export { IndexPatternsFetcher, - FieldDescriptor as IndexPatternFieldDescriptor, shouldReadFieldFromDocValues, // used only in logstash_fields fixture FieldDescriptor, - mergeCapabilitiesWithFields, getCapabilitiesForRollupIndices, } from './index_patterns'; @@ -57,7 +48,6 @@ export { IndexPatternAttributes, UI_SETTINGS, IndexPattern, - IndexPatternLoadExpressionFunctionDefinition, IndexPatternsService, IndexPatternsService as IndexPatternsCommonService, } from '../common'; @@ -69,57 +59,18 @@ export { import { // aggs CidrMask, - intervalOptions, - isNumberType, - isStringType, - isType, - parentPipelineType, - propFilter, - siblingPipelineType, - termsAggFilter, dateHistogramInterval, - InvalidEsCalendarIntervalError, - InvalidEsIntervalFormatError, IpAddress, - isValidEsInterval, - isValidInterval, - parseEsInterval, parseInterval, - toAbsoluteDates, // tabify - tabifyAggResponse, - tabifyGetColumns, calcAutoIntervalLessThan, } from '../common'; import { autocompleteConfigDeprecationProvider } from './config_deprecations'; export { // aggs - AggGroupLabels, - AggGroupName, - AggGroupNames, - AggFunctionsMapping, - AggParam, - AggParamOption, - AggParamType, - AggConfigOptions, - BUCKET_TYPES, - EsaggsExpressionFunctionDefinition, - IAggConfig, - IAggConfigs, - IAggType, - IFieldParamType, - IMetricAggType, METRIC_TYPES, - OptionedParamType, - OptionedValueProp, ParsedInterval, - // expressions - ExecutionContextSearch, - ExpressionFunctionKibana, - ExpressionFunctionKibanaContext, - ExpressionValueSearchContext, - KibanaContext, // search ISearchOptions, IEsSearchRequest, @@ -130,23 +81,12 @@ export { export { IScopedSearchClient, ISearchStrategy, - ISearchSetup, - ISearchStart, SearchStrategyDependencies, - getDefaultSearchParams, - getShardTimeout, - getTotalLoaded, - toKibanaSearchResponse, shimHitsTotal, - usageProvider, - searchUsageObserver, - shimAbortSignal, - SearchUsage, SearchSessionService, ISearchSessionService, SearchRequestHandlerContext, DataRequestHandlerContext, - AsyncSearchResponse, AsyncSearchStatusResponse, NoSearchIdInSessionError, } from './search'; @@ -156,26 +96,10 @@ export const search = { aggs: { CidrMask, dateHistogramInterval, - intervalOptions, - InvalidEsCalendarIntervalError, - InvalidEsIntervalFormatError, IpAddress, - isNumberType, - isStringType, - isType, - isValidEsInterval, - isValidInterval, - parentPipelineType, - parseEsInterval, parseInterval, - propFilter, - siblingPipelineType, - termsAggFilter, - toAbsoluteDates, calcAutoIntervalLessThan, }, - tabifyAggResponse, - tabifyGetColumns, }; /** @@ -184,11 +108,9 @@ export const search = { */ export { - // kbn field types castEsToKbnFieldTypeName, getTime, // timefilter - RefreshInterval, TimeRange, // utils parseInterval, @@ -217,5 +139,3 @@ export const config: PluginConfigDescriptor = { }, schema: configSchema, }; - -export type { IndexPatternsServiceProvider } from './index_patterns'; diff --git a/src/plugins/data/server/search/routes/bsearch.ts b/src/plugins/data/server/search/routes/bsearch.ts index e655a19e46f80..43853aa0ea939 100644 --- a/src/plugins/data/server/search/routes/bsearch.ts +++ b/src/plugins/data/server/search/routes/bsearch.ts @@ -33,23 +33,24 @@ export function registerBsearchRoute( onBatchItem: async ({ request: requestData, options }) => { const search = getScoped(request); const { executionContext, ...restOptions } = options || {}; - if (executionContext) executionContextService.set(executionContext); - return search - .search(requestData, restOptions) - .pipe( - first(), - catchError((err) => { - // Re-throw as object, to get attributes passed to the client - // eslint-disable-next-line no-throw-literal - throw { - message: err.message, - statusCode: err.statusCode, - attributes: err.errBody?.error, - }; - }) - ) - .toPromise(); + return executionContextService.withContext(executionContext, () => + search + .search(requestData, restOptions) + .pipe( + first(), + catchError((err) => { + // Re-throw as object, to get attributes passed to the client + // eslint-disable-next-line no-throw-literal + throw { + message: err.message, + statusCode: err.statusCode, + attributes: err.errBody?.error, + }; + }) + ) + .toPromise() + ); }, }; }); diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index 51436dabe05a0..121cd8ebc0af7 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -4,17 +4,13 @@ ```ts -import { $Values } from '@kbn/utility-types'; -import { Adapters } from 'src/plugins/inspector/common'; import { Assign } from '@kbn/utility-types'; import { BfetchServerSetup } from 'src/plugins/bfetch/server'; import { ConfigDeprecationProvider } from '@kbn/config'; import { CoreSetup } from 'src/core/server'; -import { CoreSetup as CoreSetup_2 } from 'kibana/server'; import { CoreStart } from 'kibana/server'; import { CoreStart as CoreStart_2 } from 'src/core/server'; import { Datatable } from 'src/plugins/expressions'; -import { Datatable as Datatable_2 } from 'src/plugins/expressions/common'; import { DatatableColumn } from 'src/plugins/expressions'; import { DatatableColumnType } from 'src/plugins/expressions/common'; import { Duration } from 'moment'; @@ -27,11 +23,8 @@ import { ES_FIELD_TYPES } from '@kbn/field-types'; import { EsQueryConfig as EsQueryConfig_2 } from '@kbn/es-query'; import { estypes } from '@elastic/elasticsearch'; import { EventEmitter } from 'events'; -import { ExecutionContext } from 'src/plugins/expressions/common'; import { ExpressionAstExpression } from 'src/plugins/expressions/common'; -import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common'; import { ExpressionsServerSetup } from 'src/plugins/expressions/server'; -import { ExpressionValueBoxed } from 'src/plugins/expressions/common'; import { Filter as Filter_2 } from '@kbn/es-query'; import { IAggConfigs as IAggConfigs_2 } from 'src/plugins/data/public'; import { IEsSearchResponse as IEsSearchResponse_2 } from 'src/plugins/data/public'; @@ -42,14 +35,12 @@ import { IScopedClusterClient } from 'src/core/server'; import { ISearchOptions as ISearchOptions_2 } from 'src/plugins/data/public'; import { ISearchSource } from 'src/plugins/data/public'; import { IUiSettingsClient } from 'src/core/server'; -import { IUiSettingsClient as IUiSettingsClient_3 } from 'kibana/server'; import { KBN_FIELD_TYPES } from '@kbn/field-types'; import { KibanaExecutionContext } from 'src/core/public'; import { KibanaRequest } from 'src/core/server'; import { KibanaRequest as KibanaRequest_2 } from 'kibana/server'; import { KueryNode as KueryNode_2 } from '@kbn/es-query'; import { Logger } from 'src/core/server'; -import { Logger as Logger_2 } from 'kibana/server'; import { LoggerFactory } from '@kbn/logging'; import { Moment } from 'moment'; import moment from 'moment'; @@ -57,7 +48,6 @@ import { Observable } from 'rxjs'; import { PackageInfo } from '@kbn/config'; import { PathConfigType } from '@kbn/utils'; import { Plugin as Plugin_2 } from 'src/core/server'; -import { Plugin as Plugin_3 } from 'kibana/server'; import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/server'; import { Query } from '@kbn/es-query'; import { RecursiveReadonly } from '@kbn/utility-types'; @@ -70,239 +60,15 @@ import { SavedObjectsClientContract as SavedObjectsClientContract_2 } from 'kiba import { SavedObjectsFindOptions } from 'kibana/server'; import { SavedObjectsFindResponse } from 'kibana/server'; import { SavedObjectsUpdateResponse } from 'kibana/server'; -import { Search } from '@elastic/elasticsearch/api/requestParams'; +import { SerializableRecord } from '@kbn/utility-types'; import { SerializedFieldFormat as SerializedFieldFormat_3 } from 'src/plugins/expressions/common'; -import { SharedGlobalConfig as SharedGlobalConfig_2 } from 'kibana/server'; import { ToastInputFields } from 'src/core/public/notifications'; -import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport'; import { Type } from '@kbn/config-schema'; import { TypeOf } from '@kbn/config-schema'; import { UiCounterMetricType } from '@kbn/analytics'; import { Unit } from '@elastic/datemath'; -import { UsageCollectionSetup as UsageCollectionSetup_2 } from 'src/plugins/usage_collection/server'; - -// Warning: (ae-forgotten-export) The symbol "AggConfigSerialized" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "AggConfigOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type AggConfigOptions = Assign; - -// Warning: (ae-missing-release-tag) "AggFunctionsMapping" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export interface AggFunctionsMapping { - // Warning: (ae-forgotten-export) The symbol "aggAvg" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggAvg: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggBucketAvg" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggBucketAvg: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggBucketMax" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggBucketMax: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggBucketMin" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggBucketMin: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggBucketSum" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggBucketSum: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggCardinality" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggCardinality: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggCount" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggCount: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggCumulativeSum" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggCumulativeSum: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggDateHistogram" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggDateHistogram: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggDateRange" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggDateRange: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggDerivative" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggDerivative: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggFilter" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggFilter: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggFilteredMetric" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggFilteredMetric: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggFilters" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggFilters: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggGeoBounds" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggGeoBounds: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggGeoCentroid" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggGeoCentroid: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggGeoHash" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggGeoHash: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggGeoTile" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggGeoTile: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggHistogram" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggHistogram: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggIpRange" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggIpRange: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggMax" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggMax: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggMedian" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggMedian: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggMin" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggMin: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggMovingAvg" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggMovingAvg: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggPercentileRanks" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggPercentileRanks: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggPercentiles" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggPercentiles: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggRange" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggRange: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggSerialDiff" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggSerialDiff: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggSignificantTerms" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggSignificantTerms: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggSinglePercentile" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggSinglePercentile: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggStdDeviation" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggStdDeviation: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggSum" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggSum: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggTerms" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggTerms: ReturnType; - // Warning: (ae-forgotten-export) The symbol "aggTopHit" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggTopHit: ReturnType; -} - -// Warning: (ae-missing-release-tag) "AggGroupLabels" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const AggGroupLabels: { - buckets: string; - metrics: string; - none: string; -}; - -// Warning: (ae-missing-release-tag) "AggGroupName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type AggGroupName = $Values; - -// Warning: (ae-missing-release-tag) "AggGroupNames" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const AggGroupNames: Readonly<{ - Buckets: "buckets"; - Metrics: "metrics"; - None: "none"; -}>; - -// Warning: (ae-forgotten-export) The symbol "BaseParamType" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "AggParam" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type AggParam = BaseParamType; - -// Warning: (ae-missing-release-tag) "AggParamOption" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface AggParamOption { - // (undocumented) - display: string; - // Warning: (ae-forgotten-export) The symbol "AggConfig" needs to be exported by the entry point index.d.ts - // - // (undocumented) - enabled?(agg: AggConfig): boolean; - // (undocumented) - val: string; -} - -// Warning: (ae-missing-release-tag) "AggParamType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export class AggParamType extends BaseParamType { - constructor(config: Record); - // (undocumented) - allowedAggs: string[]; - // (undocumented) - makeAgg: (agg: TAggConfig, state?: AggConfigSerialized) => TAggConfig; -} - -// Warning: (ae-missing-release-tag) "AsyncSearchResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface AsyncSearchResponse { - // (undocumented) - expiration_time_in_millis: number; - // (undocumented) - id?: string; - // (undocumented) - is_partial: boolean; - // (undocumented) - is_running: boolean; - // (undocumented) - response: estypes.SearchResponse; - // (undocumented) - start_time_in_millis: number; -} +// Warning: (ae-forgotten-export) The symbol "AsyncSearchResponse" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "AsyncSearchStatusResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -313,44 +79,6 @@ export interface AsyncSearchStatusResponse extends Omit { - must: never[]; - filter: Filter_2[]; - should: never[]; - must_not: Filter_2[]; -}; - // Warning: (ae-missing-release-tag) "castEsToKbnFieldTypeName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) @@ -376,14 +104,6 @@ export { ES_FIELD_TYPES } // @public (undocumented) export const ES_SEARCH_STRATEGY = "es"; -// Warning: (ae-forgotten-export) The symbol "Input" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "Arguments" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "Output" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "EsaggsExpressionFunctionDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type EsaggsExpressionFunctionDefinition = ExpressionFunctionDefinition<'esaggs', Input_36, Arguments_21, Output_36>; - // Warning: (ae-missing-release-tag) "esFilters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -405,7 +125,7 @@ export const esFilters: { export const esKuery: { nodeTypes: import("@kbn/es-query/target_types/kuery/node_types").NodeTypes; fromKueryExpression: (expression: any, parseOptions?: Partial | undefined) => import("@kbn/es-query").KueryNode; - toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: Record | undefined, context?: Record | undefined) => import("@kbn/common-utils").JsonObject; + toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: Record | undefined, context?: Record | undefined) => import("@kbn/utility-types").JsonObject; }; // Warning: (ae-missing-release-tag) "esQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -427,15 +147,6 @@ export const esQuery: { // @public @deprecated (undocumented) export type EsQueryConfig = EsQueryConfig_2; -// Warning: (ae-missing-release-tag) "ExecutionContextSearch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type ExecutionContextSearch = { - filters?: Filter[]; - query?: Query | Query[]; - timeRange?: TimeRange; -}; - // Warning: (ae-missing-release-tag) "exporters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -444,26 +155,10 @@ export const exporters: { CSV_MIME_TYPE: string; }; -// Warning: (ae-missing-release-tag) "ExpressionFunctionKibana" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type ExpressionFunctionKibana = ExpressionFunctionDefinition<'kibana', ExpressionValueSearchContext | null, object, ExpressionValueSearchContext, ExecutionContext>; - -// Warning: (ae-forgotten-export) The symbol "Arguments" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ExpressionFunctionKibanaContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type ExpressionFunctionKibanaContext = ExpressionFunctionDefinition<'kibana_context', KibanaContext | null, Arguments_22, Promise, ExecutionContext>; - -// Warning: (ae-missing-release-tag) "ExpressionValueSearchContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type ExpressionValueSearchContext = ExpressionValueBoxed<'kibana_context', ExecutionContextSearch>; - // Warning: (ae-missing-release-tag) "FieldDescriptor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -interface FieldDescriptor { +export interface FieldDescriptor { // (undocumented) aggregatable: boolean; // (undocumented) @@ -482,10 +177,6 @@ interface FieldDescriptor { type: string; } -export { FieldDescriptor } - -export { FieldDescriptor as IndexPatternFieldDescriptor } - // Warning: (ae-missing-release-tag) "Filter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) @@ -500,22 +191,12 @@ export function getCapabilitiesForRollupIndices(indices: Record>; - // Warning: (ae-forgotten-export) The symbol "KibanaConfig" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "getEsQueryConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export function getEsQueryConfig(config: KibanaConfig): EsQueryConfig_2; -// Warning: (ae-missing-release-tag) "getShardTimeout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export function getShardTimeout(config: SharedGlobalConfig_2): Pick; - // Warning: (ae-forgotten-export) The symbol "IIndexPattern" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "getTime" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -525,28 +206,6 @@ export function getTime(indexPattern: IIndexPattern | undefined, timeRange: Time fieldName?: string; }): import("@kbn/es-query").RangeFilter | undefined; -// @internal -export function getTotalLoaded(response: estypes.SearchResponse): { - total: number; - loaded: number; -}; - -// Warning: (ae-missing-release-tag) "IAggConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export type IAggConfig = AggConfig; - -// Warning: (ae-forgotten-export) The symbol "AggConfigs" needs to be exported by the entry point index.d.ts -// -// @internal -export type IAggConfigs = AggConfigs; - -// Warning: (ae-forgotten-export) The symbol "AggType" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "IAggType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type IAggType = AggType; - // Warning: (ae-forgotten-export) The symbol "IKibanaSearchRequest" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "ISearchRequestParams" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "IEsSearchRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -563,12 +222,6 @@ export interface IEsSearchRequest extends IKibanaSearchRequest = IKibanaSearchResponse>; -// Warning: (ae-forgotten-export) The symbol "FieldParamType" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "IFieldParamType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type IFieldParamType = FieldParamType; - // Warning: (ae-missing-release-tag) "IFieldSubType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) @@ -608,12 +261,6 @@ export interface IFieldType extends IndexPatternFieldBase { visualizable?: boolean; } -// Warning: (ae-forgotten-export) The symbol "MetricAggType" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "IMetricAggType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type IMetricAggType = MetricAggType; - // @public (undocumented) export const INDEX_PATTERN_SAVED_OBJECT_TYPE = "index-pattern"; @@ -833,23 +480,6 @@ export class IndexPatternField implements IFieldType { get visualizable(): boolean; } -// Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "Input" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "Arguments" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "Output" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "IndexPatternLoadExpressionFunctionDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type IndexPatternLoadExpressionFunctionDefinition = ExpressionFunctionDefinition; - -// Warning: (ae-missing-release-tag) "indexPatterns" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const indexPatterns: { - isFilterable: typeof isFilterable; - isNestedField: typeof isNestedField; -}; - // Warning: (ae-missing-release-tag) "IndexPatternsFetcher" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -917,22 +547,6 @@ export { IndexPatternsService as IndexPatternsCommonService } export { IndexPatternsService } -// Warning: (ae-forgotten-export) The symbol "IndexPatternsServiceStart" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "IndexPatternsServiceProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export class IndexPatternsServiceProvider implements Plugin_3 { - // Warning: (ae-forgotten-export) The symbol "IndexPatternsServiceStartDeps" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "IndexPatternsServiceSetupDeps" needs to be exported by the entry point index.d.ts - // - // (undocumented) - setup(core: CoreSetup_2, { expressions, usageCollection }: IndexPatternsServiceSetupDeps): void; - // (undocumented) - start(core: CoreStart, { fieldFormats, logger }: IndexPatternsServiceStartDeps): { - indexPatternsServiceFactory: (savedObjectsClient: Pick, elasticsearchClient: ElasticsearchClient_2) => Promise; - }; -} - // Warning: (ae-forgotten-export) The symbol "ISearchClient" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "IScopedSearchClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -981,40 +595,6 @@ export interface ISearchSessionService { asScopedProvider: (core: CoreStart) => (request: KibanaRequest_2) => IScopedSearchSessionsClient; } -// Warning: (ae-missing-release-tag) "ISearchSetup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface ISearchSetup { - // Warning: (ae-forgotten-export) The symbol "SearchEnhancements" needs to be exported by the entry point index.d.ts - // - // @internal (undocumented) - __enhance: (enhancements: SearchEnhancements) => void; - // Warning: (ae-forgotten-export) The symbol "AggsSetup" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggs: AggsSetup; - registerSearchStrategy: (name: string, strategy: ISearchStrategy) => void; - usage?: SearchUsage; -} - -// Warning: (ae-missing-release-tag) "ISearchStart" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface ISearchStart { - // Warning: (ae-forgotten-export) The symbol "AggsStart" needs to be exported by the entry point index.d.ts - // - // (undocumented) - aggs: AggsStart; - // (undocumented) - asScoped: (request: KibanaRequest) => IScopedSearchClient; - getSearchStrategy: (name?: string) => ISearchStrategy; - searchAsInternalUser: ISearchStrategy; - // (undocumented) - searchSource: { - asScoped: (request: KibanaRequest) => Promise; - }; -} - // Warning: (ae-missing-release-tag) "ISearchStrategy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @@ -1029,23 +609,11 @@ export interface ISearchStrategy, previousFields?: FieldDescriptor[]) => FieldDescriptor[]; - // Warning: (ae-missing-release-tag) "METRIC_TYPES" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1106,29 +674,6 @@ export class NoSearchIdInSessionError extends KbnError { constructor(); } -// Warning: (ae-missing-release-tag) "OptionedParamType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export class OptionedParamType extends BaseParamType { - constructor(config: Record); - // (undocumented) - options: OptionedValueProp[]; -} - -// Warning: (ae-missing-release-tag) "OptionedValueProp" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface OptionedValueProp { - // (undocumented) - disabled?: boolean; - // (undocumented) - isCompatible: (agg: IAggConfig) => boolean; - // (undocumented) - text: string; - // (undocumented) - value: string; -} - // Warning: (ae-forgotten-export) The symbol "parseEsInterval" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ParsedInterval" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1188,6 +733,8 @@ export interface PluginSetup { export interface PluginStart { // @deprecated (undocumented) fieldFormats: FieldFormatsStart; + // Warning: (ae-forgotten-export) The symbol "IndexPatternsServiceStart" needs to be exported by the entry point index.d.ts + // // (undocumented) indexPatterns: IndexPatternsServiceStart; // (undocumented) @@ -1196,16 +743,6 @@ export interface PluginStart { export { Query } -// Warning: (ae-missing-release-tag) "RefreshInterval" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface RefreshInterval { - // (undocumented) - pause: boolean; - // (undocumented) - value: number; -} - // Warning: (ae-missing-release-tag) "search" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1213,33 +750,10 @@ export const search: { aggs: { CidrMask: typeof CidrMask; dateHistogramInterval: typeof dateHistogramInterval; - intervalOptions: ({ - display: string; - val: string; - enabled(agg: import("../common").IBucketAggConfig): boolean; - } | { - display: string; - val: string; - })[]; - InvalidEsCalendarIntervalError: typeof InvalidEsCalendarIntervalError; - InvalidEsIntervalFormatError: typeof InvalidEsIntervalFormatError; IpAddress: typeof IpAddress; - isNumberType: (agg: import("../common").AggConfig) => boolean; - isStringType: (agg: import("../common").AggConfig) => boolean; - isType: (...types: string[]) => (agg: import("../common").AggConfig) => boolean; - isValidEsInterval: typeof isValidEsInterval; - isValidInterval: typeof isValidInterval; - parentPipelineType: string; - parseEsInterval: typeof parseEsInterval; parseInterval: typeof parseInterval; - propFilter: typeof propFilter; - siblingPipelineType: string; - termsAggFilter: string[]; - toAbsoluteDates: typeof toAbsoluteDates; calcAutoIntervalLessThan: typeof calcAutoIntervalLessThan; }; - tabifyAggResponse: typeof tabifyAggResponse; - tabifyGetColumns: typeof tabifyGetColumns; }; // Warning: (ae-missing-release-tag) "SearchRequestHandlerContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1282,27 +796,6 @@ export interface SearchStrategyDependencies { uiSettingsClient: IUiSettingsClient; } -// Warning: (ae-missing-release-tag) "SearchUsage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface SearchUsage { - // (undocumented) - trackError(): Promise; - // (undocumented) - trackSuccess(duration: number): Promise; -} - -// Warning: (ae-missing-release-tag) "searchUsageObserver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export function searchUsageObserver(logger: Logger_2, usage?: SearchUsage, { isRestore }?: ISearchOptions): { - next(response: IEsSearchResponse): void; - error(): void; -}; - -// @internal -export const shimAbortSignal: (promise: TransportRequestPromise, signal?: AbortSignal | undefined) => TransportRequestPromise; - // @internal export function shimHitsTotal(response: estypes.SearchResponse, { legacyHitsTotal }?: ISearchOptions): { hits: { @@ -1340,15 +833,6 @@ export type TimeRange = { mode?: 'absolute' | 'relative'; }; -// @internal -export function toKibanaSearchResponse(rawResponse: estypes.SearchResponse): { - total: number; - loaded: number; - rawResponse: estypes.SearchResponse; - isPartial: boolean; - isRunning: boolean; -}; - // Warning: (ae-missing-release-tag) "UI_SETTINGS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1379,11 +863,6 @@ export const UI_SETTINGS: { readonly AUTOCOMPLETE_VALUE_SUGGESTION_METHOD: "autocomplete:valueSuggestionMethod"; }; -// Warning: (ae-missing-release-tag) "usageProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export function usageProvider(core: CoreSetup_2): SearchUsage; - // Warnings were encountered during analysis: // @@ -1392,24 +871,15 @@ export function usageProvider(core: CoreSetup_2): SearchUsage; // src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:139:7 - (ae-forgotten-export) The symbol "FieldAttrSet" needs to be exported by the entry point index.d.ts // src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:170:7 - (ae-forgotten-export) The symbol "RuntimeField" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index.ts:21:23 - (ae-forgotten-export) The symbol "datatableToCSV" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:38:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:38:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:155:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:155:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:157:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:158:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:167:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:168:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:169:1 - (ae-forgotten-export) The symbol "IpAddress" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:173:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:174:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:178:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:181:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:182:1 - (ae-forgotten-export) The symbol "calcAutoIntervalLessThan" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:97:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:98:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:99:1 - (ae-forgotten-export) The symbol "IpAddress" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:101:1 - (ae-forgotten-export) The symbol "calcAutoIntervalLessThan" needs to be exported by the entry point index.d.ts // src/plugins/data/server/plugin.ts:87:88 - (ae-forgotten-export) The symbol "DataEnhancements" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/plugin.ts:109:7 - (ae-forgotten-export) The symbol "ISearchSetup" needs to be exported by the entry point index.d.ts // src/plugins/data/server/plugin.ts:110:7 - (ae-forgotten-export) The symbol "FieldFormatsSetup" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/plugin.ts:116:78 - (ae-forgotten-export) The symbol "ISearchStart" needs to be exported by the entry point index.d.ts // src/plugins/data/server/plugin.ts:117:14 - (ae-forgotten-export) The symbol "FieldFormatsStart" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/search/types.ts:120:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.test.tsx b/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.test.tsx index 7a13f18997b86..dc3c9ebbc75ca 100644 --- a/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.test.tsx +++ b/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.test.tsx @@ -96,7 +96,6 @@ function getProps(timefield?: string) { }) as DataCharts$; return { - isLegacy: false, resetQuery: jest.fn(), savedSearch: savedSearchMock, savedSearchDataChart$: charts$, diff --git a/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.tsx b/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.tsx index 165f708bf7083..7d761aa93b808 100644 --- a/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.tsx +++ b/src/plugins/discover/public/application/apps/main/components/chart/discover_chart.tsx @@ -21,7 +21,6 @@ import { DiscoverServices } from '../../../../../build_services'; const TimechartHeaderMemoized = memo(TimechartHeader); const DiscoverHistogramMemoized = memo(DiscoverHistogram); export function DiscoverChart({ - isLegacy, resetQuery, savedSearch, savedSearchDataChart$, @@ -31,7 +30,6 @@ export function DiscoverChart({ stateContainer, timefield, }: { - isLegacy: boolean; resetQuery: () => void; savedSearch: SavedSearch; savedSearchDataChart$: DataCharts$; @@ -135,10 +133,7 @@ export function DiscoverChart({ })} className="dscTimechart" > -
+
uiSettings.get(DOC_TABLE_LEGACY), [uiSettings]); const useNewFieldsApi = useMemo(() => !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE), [uiSettings]); const resultState = useMemo( @@ -251,7 +250,6 @@ export function DiscoverLayout({ > { const { path } = await locator.getLocation({ columns: ['_source'], interval: 'auto', - sort: [['timestamp, asc']] as string[][] & SerializableState, + sort: [['timestamp, asc']] as string[][] & SerializableRecord, savedQuery: '__savedQueryId__', }); diff --git a/src/plugins/discover/public/locator.ts b/src/plugins/discover/public/locator.ts index fff89903bc465..bc632c7e1ccb7 100644 --- a/src/plugins/discover/public/locator.ts +++ b/src/plugins/discover/public/locator.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import type { TimeRange, Filter, Query, QueryState, RefreshInterval } from '../../data/public'; import type { LocatorDefinition, LocatorPublic } from '../../share/public'; import { esFilters } from '../../data/public'; @@ -14,7 +14,7 @@ import { setStateToKbnUrl } from '../../kibana_utils/public'; export const DISCOVER_APP_LOCATOR = 'DISCOVER_APP_LOCATOR'; -export interface DiscoverAppLocatorParams extends SerializableState { +export interface DiscoverAppLocatorParams extends SerializableRecord { /** * Optionally set saved search ID. */ @@ -33,7 +33,7 @@ export interface DiscoverAppLocatorParams extends SerializableState { /** * Optionally set the refresh interval. */ - refreshInterval?: RefreshInterval & SerializableState; + refreshInterval?: RefreshInterval & SerializableRecord; /** * Optionally apply filters. @@ -69,7 +69,7 @@ export interface DiscoverAppLocatorParams extends SerializableState { /** * Array of the used sorting [[field,direction],...] */ - sort?: string[][] & SerializableState; + sort?: string[][] & SerializableRecord; /** * id of the used saved query diff --git a/src/plugins/embeddable/common/lib/extract.ts b/src/plugins/embeddable/common/lib/extract.ts index a68c2db5ad155..3e820d54965b3 100644 --- a/src/plugins/embeddable/common/lib/extract.ts +++ b/src/plugins/embeddable/common/lib/extract.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { CommonEmbeddableStartContract, EmbeddableStateWithType } from '../types'; import { extractBaseEmbeddableInput } from './migrate_base_input'; -import { SerializableState } from '../../../kibana_utils/common/persistable_state'; export const getExtractFunction = (embeddables: CommonEmbeddableStartContract) => { return (state: EmbeddableStateWithType) => { @@ -30,7 +30,7 @@ export const getExtractFunction = (embeddables: CommonEmbeddableStartContract) = if (!enhancements[key]) return; const enhancementResult = embeddables .getEnhancement(key) - .extract(enhancements[key] as SerializableState); + .extract(enhancements[key] as SerializableRecord); refs.push(...enhancementResult.references); updatedInput.enhancements![key] = enhancementResult.state; }); diff --git a/src/plugins/embeddable/common/lib/inject.ts b/src/plugins/embeddable/common/lib/inject.ts index 169ad615b9b6f..6f72eb5c3721a 100644 --- a/src/plugins/embeddable/common/lib/inject.ts +++ b/src/plugins/embeddable/common/lib/inject.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { CommonEmbeddableStartContract, EmbeddableStateWithType } from '../types'; import { SavedObjectReference } from '../../../../core/types'; import { injectBaseEmbeddableInput } from './migrate_base_input'; -import { SerializableState } from '../../../kibana_utils/common/persistable_state'; export const getInjectFunction = (embeddables: CommonEmbeddableStartContract) => { return (state: EmbeddableStateWithType, references: SavedObjectReference[]) => { @@ -27,7 +27,7 @@ export const getInjectFunction = (embeddables: CommonEmbeddableStartContract) => if (!enhancements[key]) return; updatedInput.enhancements![key] = embeddables .getEnhancement(key) - .inject(enhancements[key] as SerializableState, references); + .inject(enhancements[key] as SerializableRecord, references); }); return updatedInput; diff --git a/src/plugins/embeddable/common/lib/migrate.ts b/src/plugins/embeddable/common/lib/migrate.ts index 7dde9e1d2b2ab..9323c7f56dd03 100644 --- a/src/plugins/embeddable/common/lib/migrate.ts +++ b/src/plugins/embeddable/common/lib/migrate.ts @@ -6,15 +6,15 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { CommonEmbeddableStartContract } from '../types'; import { baseEmbeddableMigrations } from './migrate_base_input'; -import { SerializableState } from '../../../kibana_utils/common/persistable_state'; -export type MigrateFunction = (state: SerializableState, version: string) => SerializableState; +export type MigrateFunction = (state: SerializableRecord, version: string) => SerializableRecord; export const getMigrateFunction = (embeddables: CommonEmbeddableStartContract) => { - const migrateFn: MigrateFunction = (state: SerializableState, version: string) => { - const enhancements = (state.enhancements as SerializableState) || {}; + const migrateFn: MigrateFunction = (state: SerializableRecord, version: string) => { + const enhancements = (state.enhancements as SerializableRecord) || {}; const factory = embeddables.getEmbeddableFactory(state.type as string); let updatedInput = baseEmbeddableMigrations[version] @@ -26,7 +26,7 @@ export const getMigrateFunction = (embeddables: CommonEmbeddableStartContract) = } if (factory?.isContainerType) { - updatedInput.panels = ((state.panels as SerializableState[]) || []).map((panel) => { + updatedInput.panels = ((state.panels as SerializableRecord[]) || []).map((panel) => { return migrateFn(panel, version); }); } @@ -36,7 +36,7 @@ export const getMigrateFunction = (embeddables: CommonEmbeddableStartContract) = if (!enhancements[key]) return; const enhancementDefinition = embeddables.getEnhancement(key); const migratedEnhancement = enhancementDefinition?.migrations?.[version] - ? enhancementDefinition.migrations[version](enhancements[key] as SerializableState) + ? enhancementDefinition.migrations[version](enhancements[key] as SerializableRecord) : enhancements[key]; (updatedInput.enhancements! as Record)[key] = migratedEnhancement; }); diff --git a/src/plugins/embeddable/common/types.ts b/src/plugins/embeddable/common/types.ts index a45700375672f..22d8672e59a37 100644 --- a/src/plugins/embeddable/common/types.ts +++ b/src/plugins/embeddable/common/types.ts @@ -6,7 +6,9 @@ * Side Public License, v 1. */ -import { PersistableStateService, SerializableState } from '../../kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; +import type { KibanaExecutionContext } from 'src/core/public'; +import { PersistableStateService } from '../../kibana_utils/common'; export enum ViewMode { EDIT = 'edit', @@ -28,7 +30,7 @@ export type EmbeddableInput = { /** * Reserved key for enhancements added by other plugins. */ - enhancements?: SerializableState; + enhancements?: SerializableRecord; /** * List of action IDs that this embeddable should not render. @@ -49,6 +51,8 @@ export type EmbeddableInput = { * Flag whether colors should be synced with other panels */ syncColors?: boolean; + + executionContext?: KibanaExecutionContext; }; export interface PanelState { diff --git a/src/plugins/embeddable/public/plugin.tsx b/src/plugins/embeddable/public/plugin.tsx index cfb16da7b46b8..c644e1f3fdc23 100644 --- a/src/plugins/embeddable/public/plugin.tsx +++ b/src/plugins/embeddable/public/plugin.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { Subscription } from 'rxjs'; import { identity } from 'lodash'; +import type { SerializableRecord } from '@kbn/utility-types'; import { getSavedObjectFinder, showSaveModal } from '../../saved_objects/public'; import { UiActionsSetup, UiActionsStart } from '../../ui_actions/public'; import { Start as InspectorStart } from '../../inspector/public'; @@ -39,11 +40,7 @@ import { import { EmbeddableFactoryDefinition } from './lib/embeddables/embeddable_factory_definition'; import { EmbeddableStateTransfer } from './lib/state_transfer'; import { Storage } from '../../kibana_utils/public'; -import { - migrateToLatest, - PersistableStateService, - SerializableState, -} from '../../kibana_utils/common'; +import { migrateToLatest, PersistableStateService } from '../../kibana_utils/common'; import { ATTRIBUTE_SERVICE_KEY, AttributeService } from './lib/attribute_service'; import { AttributeServiceOptions } from './lib/attribute_service/attribute_service'; import { EmbeddableStateWithType } from '../common/types'; @@ -240,7 +237,7 @@ export class EmbeddablePublicPlugin implements Plugin { + ((state: SerializableRecord) => { return { state, references: [] }; }), migrations: enhancement.migrations || {}, @@ -253,7 +250,7 @@ export class EmbeddablePublicPlugin implements Plugin stats, inject: identity, - extract: (state: SerializableState) => { + extract: (state: SerializableRecord) => { return { state, references: [] }; }, migrations: {}, diff --git a/src/plugins/embeddable/public/public.api.md b/src/plugins/embeddable/public/public.api.md index 54fe2a7b0bec2..cf28f65ceaa79 100644 --- a/src/plugins/embeddable/public/public.api.md +++ b/src/plugins/embeddable/public/public.api.md @@ -28,6 +28,7 @@ import { I18nStart as I18nStart_2 } from 'src/core/public'; import { IconType } from '@elastic/eui'; import { IncomingHttpHeaders } from 'http'; import { KibanaClient } from '@elastic/elasticsearch/api/kibana'; +import { KibanaExecutionContext as KibanaExecutionContext_2 } from 'src/core/public'; import { Location } from 'history'; import { LocationDescriptorObject } from 'history'; import { Logger } from '@kbn/logging'; @@ -53,6 +54,7 @@ import { SavedObjectAttributes } from 'kibana/server'; import { SavedObjectAttributes as SavedObjectAttributes_2 } from 'src/core/public'; import { SavedObjectAttributes as SavedObjectAttributes_3 } from 'kibana/public'; import { SchemaTypeError } from '@kbn/config-schema'; +import { SerializableRecord } from '@kbn/utility-types'; import { SimpleSavedObject as SimpleSavedObject_2 } from 'src/core/public'; import { Start as Start_2 } from 'src/plugins/inspector/public'; import { TransportRequestOptions } from '@elastic/elasticsearch/lib/Transport'; @@ -318,7 +320,7 @@ export abstract class Embeddable { +export class EmbeddableChildPanel extends React.Component { constructor(props: EmbeddableChildPanelProps); // (undocumented) [panel: string]: any; @@ -416,11 +418,12 @@ export type EmbeddableInput = { id: string; lastReloadRequestTime?: number; hidePanelTitles?: boolean; - enhancements?: SerializableState; + enhancements?: SerializableRecord; disabledActions?: string[]; disableTriggers?: boolean; searchSessionId?: string; syncColors?: boolean; + executionContext?: KibanaExecutionContext_2; }; // Warning: (ae-missing-release-tag) "EmbeddableInstanceConfiguration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -475,7 +478,7 @@ export interface EmbeddablePackageState { // Warning: (ae-missing-release-tag) "EmbeddablePanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export class EmbeddablePanel extends React.Component { +export class EmbeddablePanel extends React.Component { constructor(props: Props); // (undocumented) closeMyContextMenuPanel: () => void; @@ -618,7 +621,7 @@ export class EmbeddableStateTransfer { // Warning: (ae-missing-release-tag) "EnhancementRegistryDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

{ +export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

{ // (undocumented) id: string; } @@ -895,7 +898,6 @@ export const withEmbeddableSubscription: ; export type EnhancementsRegistry = Map; -export interface EnhancementRegistryDefinition

+export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

{ id: string; } -export interface EnhancementRegistryItem

+export interface EnhancementRegistryItem

extends PersistableState

{ id: string; } diff --git a/src/plugins/embeddable/server/plugin.ts b/src/plugins/embeddable/server/plugin.ts index c85f48e01d486..6f545070040d5 100644 --- a/src/plugins/embeddable/server/plugin.ts +++ b/src/plugins/embeddable/server/plugin.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { CoreSetup, CoreStart, Plugin } from 'kibana/server'; import { identity } from 'lodash'; import { @@ -23,7 +24,6 @@ import { } from '../common/lib'; import { PersistableStateService, - SerializableState, PersistableStateMigrateFn, MigrateFunctionsObject, } from '../../kibana_utils/common'; @@ -96,7 +96,7 @@ export class EmbeddableServerPlugin implements Plugin { + ((state: SerializableRecord) => { return { state, references: [] }; }), migrations: enhancement.migrations || {}, @@ -109,7 +109,7 @@ export class EmbeddableServerPlugin implements Plugin stats, inject: identity, - extract: (state: SerializableState) => { + extract: (state: SerializableRecord) => { return { state, references: [] }; }, migrations: {}, diff --git a/src/plugins/embeddable/server/server.api.md b/src/plugins/embeddable/server/server.api.md index f8f3dcb0aa0ba..e17f40423b00b 100644 --- a/src/plugins/embeddable/server/server.api.md +++ b/src/plugins/embeddable/server/server.api.md @@ -6,7 +6,9 @@ import { CoreSetup } from 'kibana/server'; import { CoreStart } from 'kibana/server'; +import { KibanaExecutionContext } from 'src/core/public'; import { Plugin } from 'kibana/server'; +import { SerializableRecord } from '@kbn/utility-types'; // Warning: (ae-forgotten-export) The symbol "EmbeddableStateWithType" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "PersistableStateDefinition" needs to be exported by the entry point index.d.ts @@ -38,11 +40,10 @@ export interface EmbeddableSetup extends PersistableStateService; -// Warning: (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "EnhancementRegistryDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

{ +export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

{ // (undocumented) id: string; } diff --git a/src/plugins/embeddable/server/types.ts b/src/plugins/embeddable/server/types.ts index a07d036e1bdd8..ba5314692e430 100644 --- a/src/plugins/embeddable/server/types.ts +++ b/src/plugins/embeddable/server/types.ts @@ -6,22 +6,19 @@ * Side Public License, v 1. */ -import { - PersistableState, - PersistableStateDefinition, - SerializableState, -} from '../../kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; +import { PersistableState, PersistableStateDefinition } from '../../kibana_utils/common'; import { EmbeddableStateWithType } from '../common/types'; export type EmbeddableFactoryRegistry = Map; export type EnhancementsRegistry = Map; -export interface EnhancementRegistryDefinition

+export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

{ id: string; } -export interface EnhancementRegistryItem

+export interface EnhancementRegistryItem

extends PersistableState

{ id: string; } diff --git a/src/plugins/expressions/common/execution/types.ts b/src/plugins/expressions/common/execution/types.ts index 19537b3f164e7..06eac98feba67 100644 --- a/src/plugins/expressions/common/execution/types.ts +++ b/src/plugins/expressions/common/execution/types.ts @@ -6,11 +6,12 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import type { KibanaRequest } from 'src/core/server'; -import type { IExecutionContextContainer } from 'src/core/public'; +import type { KibanaExecutionContext } from 'src/core/public'; -import { ExpressionType, SerializableState } from '../expression_types'; +import { ExpressionType } from '../expression_types'; import { Adapters, RequestAdapter } from '../../../inspector/common'; import { TablesAdapter } from '../util/tables_adapter'; @@ -20,7 +21,7 @@ import { TablesAdapter } from '../util/tables_adapter'; */ export interface ExecutionContext< InspectorAdapters extends Adapters = Adapters, - ExecutionContextSearch extends SerializableState = SerializableState + ExecutionContextSearch extends SerializableRecord = SerializableRecord > { /** * Get search context of the expression. @@ -67,7 +68,7 @@ export interface ExecutionContext< /** * Contains the meta-data about the source of the expression. */ - getExecutionContext: () => IExecutionContextContainer | undefined; + getExecutionContext: () => KibanaExecutionContext | undefined; } /** diff --git a/src/plugins/expressions/common/executor/executor.ts b/src/plugins/expressions/common/executor/executor.ts index 930c9a4f04243..2767c8bc6ecbe 100644 --- a/src/plugins/expressions/common/executor/executor.ts +++ b/src/plugins/expressions/common/executor/executor.ts @@ -10,6 +10,7 @@ import { cloneDeep, mapValues } from 'lodash'; import { Observable } from 'rxjs'; +import type { SerializableRecord } from '@kbn/utility-types'; import { ExecutorState, ExecutorContainer } from './container'; import { createExecutorContainer } from './container'; import { AnyExpressionFunctionDefinition, ExpressionFunction } from '../expression_functions'; @@ -25,7 +26,6 @@ import { MigrateFunctionsObject, migrateToLatest, PersistableStateService, - SerializableState, VersionedState, } from '../../../kibana_utils/common'; import { ExpressionExecutionParams } from '../service'; @@ -272,7 +272,7 @@ export class Executor = Record { if (!fn.migrations[version]) return link; const updatedAst = fn.migrations[version](link) as ExpressionAstFunction; diff --git a/src/plugins/expressions/common/expression_functions/expression_function.ts b/src/plugins/expressions/common/expression_functions/expression_function.ts index a4cb114110498..963d2186af733 100644 --- a/src/plugins/expressions/common/expression_functions/expression_function.ts +++ b/src/plugins/expressions/common/expression_functions/expression_function.ts @@ -7,12 +7,13 @@ */ import { identity } from 'lodash'; +import type { SerializableRecord } from '@kbn/utility-types'; import { AnyExpressionFunctionDefinition } from './types'; import { ExpressionFunctionParameter } from './expression_function_parameter'; import { ExpressionValue } from '../expression_types/types'; import { ExpressionAstFunction } from '../ast'; import { SavedObjectReference } from '../../../../core/types'; -import { PersistableState, SerializableState } from '../../../kibana_utils/common'; +import { PersistableState } from '../../../kibana_utils/common'; export class ExpressionFunction implements PersistableState { /** @@ -65,7 +66,7 @@ export class ExpressionFunction implements PersistableState ExpressionAstFunction['arguments']; migrations: { - [key: string]: (state: SerializableState) => SerializableState; + [key: string]: (state: SerializableRecord) => SerializableRecord; }; constructor(functionDefinition: AnyExpressionFunctionDefinition) { diff --git a/src/plugins/expressions/common/expression_types/specs/datatable.ts b/src/plugins/expressions/common/expression_types/specs/datatable.ts index a094ce39d6caa..c268557936ac5 100644 --- a/src/plugins/expressions/common/expression_types/specs/datatable.ts +++ b/src/plugins/expressions/common/expression_types/specs/datatable.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { map, pick, zipObject } from 'lodash'; import { ExpressionTypeDefinition } from '../types'; @@ -13,13 +14,6 @@ import { PointSeries, PointSeriesColumn } from './pointseries'; import { ExpressionValueRender } from './render'; import { SerializedFieldFormat } from '../../types'; -type State = string | number | boolean | null | undefined | SerializableState; - -/** @internal **/ -export interface SerializableState { - [key: string]: State | State[]; -} - const name = 'datatable'; /** @@ -84,7 +78,7 @@ export interface DatatableColumnMeta { /** * any extra parameters for the source that produced this column */ - sourceParams?: SerializableState; + sourceParams?: SerializableRecord; } /** diff --git a/src/plugins/expressions/common/expression_types/specs/error.ts b/src/plugins/expressions/common/expression_types/specs/error.ts index f8a95628c9447..75e49633866f7 100644 --- a/src/plugins/expressions/common/expression_types/specs/error.ts +++ b/src/plugins/expressions/common/expression_types/specs/error.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { ExpressionTypeDefinition, ExpressionValueBoxed } from '../types'; import { ExpressionValueRender } from './render'; import { getType } from '../get_type'; -import { SerializableState } from '../../../../kibana_utils/common'; import { ErrorLike } from '../../util'; const name = 'error'; @@ -18,7 +18,7 @@ export type ExpressionValueError = ExpressionValueBoxed< 'error', { error: ErrorLike; - info?: SerializableState; + info?: SerializableRecord; } >; diff --git a/src/plugins/expressions/common/service/expressions_services.ts b/src/plugins/expressions/common/service/expressions_services.ts index cd52c8c3239de..b4dda3de5c93c 100644 --- a/src/plugins/expressions/common/service/expressions_services.ts +++ b/src/plugins/expressions/common/service/expressions_services.ts @@ -7,9 +7,10 @@ */ import { Observable } from 'rxjs'; +import type { SerializableRecord } from '@kbn/utility-types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import type { KibanaRequest } from 'src/core/server'; -import type { IExecutionContextContainer } from 'src/core/public'; +import type { KibanaExecutionContext } from 'src/core/public'; import { Executor } from '../executor'; import { AnyExpressionRenderDefinition, ExpressionRendererRegistry } from '../expression_renderers'; @@ -18,11 +19,7 @@ import { ExecutionContract, ExecutionResult } from '../execution'; import { AnyExpressionTypeDefinition, ExpressionValueError } from '../expression_types'; import { AnyExpressionFunctionDefinition } from '../expression_functions'; import { SavedObjectReference } from '../../../../core/types'; -import { - PersistableStateService, - SerializableState, - VersionedState, -} from '../../../kibana_utils/common'; +import { PersistableStateService, VersionedState } from '../../../kibana_utils/common'; import { Adapters } from '../../../inspector/common/adapters'; import { clog, @@ -60,7 +57,7 @@ export type ExpressionsServiceSetup = Pick< >; export interface ExpressionExecutionParams { - searchContext?: SerializableState; + searchContext?: SerializableRecord; variables?: Record; @@ -84,7 +81,7 @@ export interface ExpressionExecutionParams { inspectorAdapters?: Adapters; - executionContext?: IExecutionContextContainer; + executionContext?: KibanaExecutionContext; } /** diff --git a/src/plugins/expressions/public/public.api.md b/src/plugins/expressions/public/public.api.md index 529d6653cb7f1..3126af02286c9 100644 --- a/src/plugins/expressions/public/public.api.md +++ b/src/plugins/expressions/public/public.api.md @@ -9,7 +9,7 @@ import { CoreStart } from 'src/core/public'; import { Ensure } from '@kbn/utility-types'; import { EnvironmentMode } from '@kbn/config'; import { EventEmitter } from 'events'; -import { IExecutionContextContainer } from 'src/core/public'; +import { KibanaExecutionContext } from 'src/core/public'; import { KibanaRequest } from 'src/core/server'; import { Observable } from 'rxjs'; import { ObservableLike } from '@kbn/utility-types'; @@ -17,6 +17,7 @@ import { PackageInfo } from '@kbn/config'; import { Plugin as Plugin_2 } from 'src/core/public'; import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/public'; import React from 'react'; +import { SerializableRecord } from '@kbn/utility-types'; import { UnwrapObservable } from '@kbn/utility-types'; import { UnwrapPromiseOrReturn } from '@kbn/utility-types'; @@ -133,13 +134,12 @@ export class Execution = StateContainer, ExecutionPureTransitions>; -// Warning: (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ExecutionContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export interface ExecutionContext { +export interface ExecutionContext { abortSignal: AbortSignal; - getExecutionContext: () => IExecutionContextContainer | undefined; + getExecutionContext: () => KibanaExecutionContext | undefined; getKibanaRequest?: () => KibanaRequest; getSearchContext: () => ExecutionContextSearch; getSearchSessionId: () => string | undefined; @@ -356,7 +356,7 @@ export class ExpressionFunction implements PersistableState SerializableState; + [key: string]: (state: SerializableRecord) => SerializableRecord; }; name: string; // (undocumented) @@ -764,7 +764,7 @@ export type ExpressionValueConverter; // Warning: (ae-missing-release-tag) "ExpressionValueFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -908,7 +908,7 @@ export interface IExpressionLoaderParams { // (undocumented) disableCaching?: boolean; // (undocumented) - executionContext?: IExecutionContextContainer; + executionContext?: KibanaExecutionContext; // (undocumented) hasCompatibleActions?: ExpressionRenderHandlerParams['hasCompatibleActions']; // (undocumented) @@ -923,7 +923,7 @@ export interface IExpressionLoaderParams { // (undocumented) renderMode?: RenderMode; // (undocumented) - searchContext?: SerializableState_2; + searchContext?: SerializableRecord; // (undocumented) searchSessionId?: string; // (undocumented) @@ -1193,7 +1193,6 @@ export type UnmappedTypeStrings = 'date' | 'filter'; // Warnings were encountered during analysis: // // src/plugins/expressions/common/ast/types.ts:29:3 - (ae-forgotten-export) The symbol "ExpressionAstFunctionDebug" needs to be exported by the entry point index.d.ts -// src/plugins/expressions/common/expression_functions/expression_function.ts:68:5 - (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts // src/plugins/expressions/common/expression_types/specs/error.ts:20:5 - (ae-forgotten-export) The symbol "ErrorLike" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/expressions/public/types/index.ts b/src/plugins/expressions/public/types/index.ts index 675ed7eeed7c3..5a2198bb4f2e5 100644 --- a/src/plugins/expressions/public/types/index.ts +++ b/src/plugins/expressions/public/types/index.ts @@ -5,13 +5,14 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { IExecutionContextContainer } from 'src/core/public'; + +import type { SerializableRecord } from '@kbn/utility-types'; +import type { KibanaExecutionContext } from 'src/core/public'; import { Adapters } from '../../../inspector/public'; import { IInterpreterRenderHandlers, ExpressionValue, ExpressionsService, - SerializableState, RenderMode, } from '../../common'; import { ExpressionRenderHandlerParams } from '../render'; @@ -33,7 +34,7 @@ export interface ExpressionInterpreter { } export interface IExpressionLoaderParams { - searchContext?: SerializableState; + searchContext?: SerializableRecord; context?: ExpressionValue; variables?: Record; // Enables debug tracking on each expression in the AST @@ -48,7 +49,7 @@ export interface IExpressionLoaderParams { renderMode?: RenderMode; syncColors?: boolean; hasCompatibleActions?: ExpressionRenderHandlerParams['hasCompatibleActions']; - executionContext?: IExecutionContextContainer; + executionContext?: KibanaExecutionContext; /** * The flag to toggle on emitting partial results. diff --git a/src/plugins/expressions/server/server.api.md b/src/plugins/expressions/server/server.api.md index 236c54db7140c..05b8cb1a033d1 100644 --- a/src/plugins/expressions/server/server.api.md +++ b/src/plugins/expressions/server/server.api.md @@ -8,12 +8,13 @@ import { CoreSetup } from 'src/core/server'; import { CoreStart } from 'src/core/server'; import { Ensure } from '@kbn/utility-types'; import { EventEmitter } from 'events'; -import { IExecutionContextContainer } from 'src/core/public'; +import { KibanaExecutionContext } from 'src/core/public'; import { KibanaRequest } from 'src/core/server'; import { Observable } from 'rxjs'; import { ObservableLike } from '@kbn/utility-types'; import { Plugin as Plugin_2 } from 'src/core/server'; import { PluginInitializerContext } from 'src/core/server'; +import { SerializableRecord } from '@kbn/utility-types'; import { UnwrapObservable } from '@kbn/utility-types'; import { UnwrapPromiseOrReturn } from '@kbn/utility-types'; @@ -131,13 +132,12 @@ export class Execution = StateContainer, ExecutionPureTransitions>; -// Warning: (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ExecutionContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export interface ExecutionContext { +export interface ExecutionContext { abortSignal: AbortSignal; - getExecutionContext: () => IExecutionContextContainer | undefined; + getExecutionContext: () => KibanaExecutionContext | undefined; getKibanaRequest?: () => KibanaRequest; getSearchContext: () => ExecutionContextSearch; getSearchSessionId: () => string | undefined; @@ -328,7 +328,7 @@ export class ExpressionFunction implements PersistableState SerializableState; + [key: string]: (state: SerializableRecord) => SerializableRecord; }; name: string; // (undocumented) @@ -604,7 +604,7 @@ export type ExpressionValueConverter; // Warning: (ae-missing-release-tag) "ExpressionValueFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -947,7 +947,6 @@ export type UnmappedTypeStrings = 'date' | 'filter'; // Warnings were encountered during analysis: // // src/plugins/expressions/common/ast/types.ts:29:3 - (ae-forgotten-export) The symbol "ExpressionAstFunctionDebug" needs to be exported by the entry point index.d.ts -// src/plugins/expressions/common/expression_functions/expression_function.ts:68:5 - (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts // src/plugins/expressions/common/expression_types/specs/error.ts:20:5 - (ae-forgotten-export) The symbol "ErrorLike" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/field_formats/common/converters/boolean.ts b/src/plugins/field_formats/common/converters/boolean.ts index 674e02fac8de0..7019b6423b89e 100644 --- a/src/plugins/field_formats/common/converters/boolean.ts +++ b/src/plugins/field_formats/common/converters/boolean.ts @@ -12,6 +12,7 @@ import { FieldFormat } from '../field_format'; import { TextContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; import { asPrettyString } from '../utils'; +/** @public */ export class BoolFormat extends FieldFormat { static id = FIELD_FORMAT_IDS.BOOLEAN; static title = i18n.translate('fieldFormats.boolean.title', { diff --git a/src/plugins/field_formats/common/converters/bytes.ts b/src/plugins/field_formats/common/converters/bytes.ts index 829063aa07d02..ce875e0950b25 100644 --- a/src/plugins/field_formats/common/converters/bytes.ts +++ b/src/plugins/field_formats/common/converters/bytes.ts @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import { NumeralFormat } from './numeral'; import { FIELD_FORMAT_IDS } from '../types'; +/** @public */ export class BytesFormat extends NumeralFormat { static id = FIELD_FORMAT_IDS.BYTES; static title = i18n.translate('fieldFormats.bytes.title', { diff --git a/src/plugins/field_formats/common/converters/color.tsx b/src/plugins/field_formats/common/converters/color.tsx index d3a6964619cae..417c2481e626b 100644 --- a/src/plugins/field_formats/common/converters/color.tsx +++ b/src/plugins/field_formats/common/converters/color.tsx @@ -16,6 +16,7 @@ import { HtmlContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; import { asPrettyString } from '../utils'; import { DEFAULT_CONVERTER_COLOR } from '../constants/color_default'; +/** @public */ export class ColorFormat extends FieldFormat { static id = FIELD_FORMAT_IDS.COLOR; static title = i18n.translate('fieldFormats.color.title', { diff --git a/src/plugins/field_formats/common/converters/histogram.ts b/src/plugins/field_formats/common/converters/histogram.ts index 586d42ffa7a31..52ddf1bd4ed22 100644 --- a/src/plugins/field_formats/common/converters/histogram.ts +++ b/src/plugins/field_formats/common/converters/histogram.ts @@ -14,6 +14,7 @@ import { BytesFormat } from './bytes'; import { NumberFormat } from './number'; import { PercentFormat } from './percent'; +/** @public */ export class HistogramFormat extends FieldFormat { static id = FIELD_FORMAT_IDS.HISTOGRAM; static fieldType = KBN_FIELD_TYPES.HISTOGRAM; diff --git a/src/plugins/field_formats/common/converters/ip.ts b/src/plugins/field_formats/common/converters/ip.ts index b981eca5db441..ad49d679a3526 100644 --- a/src/plugins/field_formats/common/converters/ip.ts +++ b/src/plugins/field_formats/common/converters/ip.ts @@ -11,6 +11,7 @@ import { KBN_FIELD_TYPES } from '@kbn/field-types'; import { FieldFormat } from '../field_format'; import { TextContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; +/** @public */ export class IpFormat extends FieldFormat { static id = FIELD_FORMAT_IDS.IP; static title = i18n.translate('fieldFormats.ip.title', { diff --git a/src/plugins/field_formats/common/converters/number.ts b/src/plugins/field_formats/common/converters/number.ts index 36470cbd14874..8ba4eabde2143 100644 --- a/src/plugins/field_formats/common/converters/number.ts +++ b/src/plugins/field_formats/common/converters/number.ts @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import { NumeralFormat } from './numeral'; import { FIELD_FORMAT_IDS } from '../types'; +/** @public */ export class NumberFormat extends NumeralFormat { static id = FIELD_FORMAT_IDS.NUMBER; static title = i18n.translate('fieldFormats.number.title', { diff --git a/src/plugins/field_formats/common/converters/percent.ts b/src/plugins/field_formats/common/converters/percent.ts index 3fd70c8ce74a8..497fb088cd416 100644 --- a/src/plugins/field_formats/common/converters/percent.ts +++ b/src/plugins/field_formats/common/converters/percent.ts @@ -11,6 +11,7 @@ import { NumeralFormat } from './numeral'; import { TextContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; import { FORMATS_UI_SETTINGS } from '../constants/ui_settings'; +/** @public */ export class PercentFormat extends NumeralFormat { static id = FIELD_FORMAT_IDS.PERCENT; static title = i18n.translate('fieldFormats.percent.title', { diff --git a/src/plugins/field_formats/common/converters/relative_date.ts b/src/plugins/field_formats/common/converters/relative_date.ts index 6111cbf838b79..cdc54479b150b 100644 --- a/src/plugins/field_formats/common/converters/relative_date.ts +++ b/src/plugins/field_formats/common/converters/relative_date.ts @@ -12,6 +12,7 @@ import { KBN_FIELD_TYPES } from '@kbn/field-types'; import { FieldFormat } from '../field_format'; import { TextContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; +/** @public */ export class RelativeDateFormat extends FieldFormat { static id = FIELD_FORMAT_IDS.RELATIVE_DATE; static title = i18n.translate('fieldFormats.relative_date.title', { diff --git a/src/plugins/field_formats/common/converters/source.tsx b/src/plugins/field_formats/common/converters/source.tsx index b3ed90329d6d4..29bae5a41f2f5 100644 --- a/src/plugins/field_formats/common/converters/source.tsx +++ b/src/plugins/field_formats/common/converters/source.tsx @@ -35,6 +35,7 @@ const TemplateComponent = ({ defPairs }: Props) => { ); }; +/** @public */ export class SourceFormat extends FieldFormat { static id = FIELD_FORMAT_IDS._SOURCE; static title = '_source'; diff --git a/src/plugins/field_formats/common/converters/static_lookup.ts b/src/plugins/field_formats/common/converters/static_lookup.ts index ba5b38ba8b24f..455f4794887f9 100644 --- a/src/plugins/field_formats/common/converters/static_lookup.ts +++ b/src/plugins/field_formats/common/converters/static_lookup.ts @@ -21,6 +21,7 @@ function convertLookupEntriesToMap(lookupEntries: any[]) { ); } +/** @public */ export class StaticLookupFormat extends FieldFormat { static id = FIELD_FORMAT_IDS.STATIC_LOOKUP; static title = i18n.translate('fieldFormats.static_lookup.title', { diff --git a/src/plugins/field_formats/common/converters/string.ts b/src/plugins/field_formats/common/converters/string.ts index 149da871761e2..96cd786147800 100644 --- a/src/plugins/field_formats/common/converters/string.ts +++ b/src/plugins/field_formats/common/converters/string.ts @@ -63,6 +63,7 @@ const TRANSFORM_OPTIONS = [ ]; const DEFAULT_TRANSFORM_OPTION = false; +/** @public */ export class StringFormat extends FieldFormat { static id = FIELD_FORMAT_IDS.STRING; static title = i18n.translate('fieldFormats.string.title', { diff --git a/src/plugins/field_formats/common/converters/truncate.ts b/src/plugins/field_formats/common/converters/truncate.ts index fd8bbcbc46541..2ac4b515325eb 100644 --- a/src/plugins/field_formats/common/converters/truncate.ts +++ b/src/plugins/field_formats/common/converters/truncate.ts @@ -14,6 +14,7 @@ import { TextContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; const omission = '...'; +/** @public */ export class TruncateFormat extends FieldFormat { static id = FIELD_FORMAT_IDS.TRUNCATE; static title = i18n.translate('fieldFormats.truncated_string.title', { diff --git a/src/plugins/field_formats/common/converters/url.ts b/src/plugins/field_formats/common/converters/url.ts index 07d9ed4cd535e..930c94f9ce0fa 100644 --- a/src/plugins/field_formats/common/converters/url.ts +++ b/src/plugins/field_formats/common/converters/url.ts @@ -43,6 +43,7 @@ const URL_TYPES = [ ]; const DEFAULT_URL_TYPE = 'a'; +/** @public */ export class UrlFormat extends FieldFormat { static id = FIELD_FORMAT_IDS.URL; static title = i18n.translate('fieldFormats.url.title', { diff --git a/src/plugins/field_formats/common/index.ts b/src/plugins/field_formats/common/index.ts index f2395eef29c54..b6c58eb12d7cd 100644 --- a/src/plugins/field_formats/common/index.ts +++ b/src/plugins/field_formats/common/index.ts @@ -8,6 +8,8 @@ import { PublicMethodsOf } from '@kbn/utility-types'; import { FieldFormatsRegistry } from './field_formats_registry'; + +/** @public */ type IFieldFormatsRegistry = PublicMethodsOf; export { FieldFormatsRegistry, IFieldFormatsRegistry }; diff --git a/src/plugins/field_formats/common/types.ts b/src/plugins/field_formats/common/types.ts index 9c9112f45373b..c6048e1367a09 100644 --- a/src/plugins/field_formats/common/types.ts +++ b/src/plugins/field_formats/common/types.ts @@ -58,6 +58,7 @@ export enum FIELD_FORMAT_IDS { HISTOGRAM = 'histogram', } +/** @public */ export interface FieldFormatConfig { id: FieldFormatId; params: Record; @@ -73,6 +74,8 @@ export interface FieldFormatConfig { * This matches the signature of the public `core.uiSettings.get`, and * should only be used in scenarios where async access to uiSettings is * not possible. + * + @public */ export type FieldFormatsGetConfigFn = (key: string, defaultOverride?: T) => T; diff --git a/src/plugins/home/kibana.json b/src/plugins/home/kibana.json index 81bfc57a00363..ccf8d39307f34 100644 --- a/src/plugins/home/kibana.json +++ b/src/plugins/home/kibana.json @@ -1,5 +1,9 @@ { "id": "home", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "kibana", "server": true, "ui": true, diff --git a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts index 971b426458ce4..1f0ce6186bb8a 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts @@ -13,25 +13,45 @@ import { SavedObject } from 'kibana/server'; export const getSavedObjects = (): SavedObject[] => [ { - id: '45e07720-b890-11e8-a6d9-e546fe2bba5f', - type: 'visualization', - updated_at: '2021-07-16T20:14:25.894Z', - version: '3', + attributes: { + fieldAttrs: + '{"products.manufacturer":{"count":1},"products.price":{"count":1},"products.product_name":{"count":1},"total_quantity":{"count":1}}', + fieldFormatMap: + '{"taxful_total_price":{"id":"number","params":{"pattern":"$0,0.[00]"}},"products.price":{"id":"number","params":{"pattern":"$0,0.00"}},"taxless_total_price":{"id":"number","params":{"pattern":"$0,0.00"}},"products.taxless_price":{"id":"number","params":{"pattern":"$0,0.00"}},"products.taxful_price":{"id":"number","params":{"pattern":"$0,0.00"}},"products.min_price":{"id":"number","params":{"pattern":"$0,0.00"}},"products.base_unit_price":{"id":"number","params":{"pattern":"$0,0.00"}},"products.base_price":{"id":"number","params":{"pattern":"$0,0.00"}}}', + fields: '[]', + runtimeFieldMap: '{}', + timeFieldName: 'order_date', + title: 'kibana_sample_data_ecommerce', + typeMeta: '{}', + }, + coreMigrationVersion: '8.0.0', + id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', migrationVersion: { - visualization: '7.14.0', + 'index-pattern': '7.11.0', }, + references: [], + type: 'index-pattern', + updated_at: '2021-08-05T12:23:57.577Z', + version: 'WzI1LDFd', + }, + { attributes: { + description: '', + kibanaSavedObjectMeta: { + searchSourceJSON: '{"query":{"query":"","language":"kuery"},"filter":[]}', + }, title: i18n.translate('home.sampleData.ecommerceSpec.promotionTrackingTitle', { defaultMessage: '[eCommerce] Promotion Tracking', }), - visState: - '{"title":"[eCommerce] Promotion Tracking","type":"metrics","aggs":[],"params":{"time_range_mode":"entire_time_range","id":"61ca57f0-469d-11e7-af02-69e470af7417","type":"timeseries","series":[{"id":"ea20ae70-b88d-11e8-a451-f37365e9f268","color":"rgba(211,96,134,1)","split_mode":"everything","metrics":[{"id":"ea20ae71-b88d-11e8-a451-f37365e9f268","type":"sum","field":"taxful_total_price"}],"separate_axis":0,"axis_position":"right","formatter":"number","chart_type":"line","line_width":"2","point_size":"5","fill":"0","stacked":"none","filter":{"query":"products.product_name:*trouser*","language":"lucene"},"label":"Revenue Trousers","value_template":"${{value}}","split_color_mode":"gradient"},{"id":"062d77b0-b88e-11e8-a451-f37365e9f268","color":"rgba(84,179,153,1)","split_mode":"everything","metrics":[{"id":"062d77b1-b88e-11e8-a451-f37365e9f268","type":"sum","field":"taxful_total_price"}],"separate_axis":0,"axis_position":"right","formatter":"number","chart_type":"line","line_width":"2","point_size":"05","fill":"0","stacked":"none","filter":{"query":"products.product_name:*watch*","language":"lucene"},"label":"Revenue Watches","value_template":"${{value}}","split_color_mode":"gradient"},{"id":"61ca57f1-469d-11e7-af02-69e470af7417","color":"rgba(96,146,192,1)","split_mode":"everything","metrics":[{"id":"61ca57f2-469d-11e7-af02-69e470af7417","type":"sum","field":"taxful_total_price"}],"separate_axis":0,"axis_position":"right","formatter":"number","chart_type":"line","line_width":"2","point_size":"5","fill":"0","stacked":"none","filter":{"query":"products.product_name:*bag*","language":"lucene"},"label":"Revenue Bags","value_template":"${{value}}","split_color_mode":"gradient"},{"id":"faa2c170-b88d-11e8-a451-f37365e9f268","color":"rgba(202,142,174,1)","split_mode":"everything","metrics":[{"id":"faa2c171-b88d-11e8-a451-f37365e9f268","type":"sum","field":"taxful_total_price"}],"separate_axis":0,"axis_position":"right","formatter":"number","chart_type":"line","line_width":"2","point_size":"5","fill":"0","stacked":"none","filter":{"query":"products.product_name:*cocktail dress*","language":"lucene"},"label":"Revenue Cocktail Dresses","value_template":"${{value}}","split_color_mode":"gradient"}],"time_field":"order_date","interval":"12h","use_kibana_indexes":true,"axis_position":"left","axis_formatter":"number","axis_scale":"normal","show_legend":1,"show_grid":1,"legend_position":"bottom","annotations":[{"fields":"taxful_total_price","template":"Ring the bell! ${{taxful_total_price}}","query_string":{"query":"taxful_total_price:>250","language":"lucene"},"id":"c8c30be0-b88f-11e8-a451-f37365e9f268","color":"rgba(25,77,51,1)","time_field":"order_date","icon":"fa-bell","ignore_global_filters":1,"ignore_panel_filters":1,"index_pattern_ref_name":"metrics_1_index_pattern"}],"tooltip_mode":"show_all","drop_last_bucket":0,"isModelInvalid":false,"index_pattern_ref_name":"metrics_0_index_pattern"}}', uiStateJSON: '{}', - description: '', version: 1, - kibanaSavedObjectMeta: { - searchSourceJSON: '{"query":{"query":"","language":"kuery"},"filter":[]}', - }, + visState: + '{"title":"[eCommerce] Promotion Tracking","type":"metrics","aggs":[],"params":{"time_range_mode":"entire_time_range","id":"61ca57f0-469d-11e7-af02-69e470af7417","type":"timeseries","series":[{"id":"ea20ae70-b88d-11e8-a451-f37365e9f268","color":"rgba(211,96,134,1)","split_mode":"everything","metrics":[{"id":"ea20ae71-b88d-11e8-a451-f37365e9f268","type":"sum","field":"taxful_total_price"}],"separate_axis":0,"axis_position":"right","formatter":"number","chart_type":"line","line_width":"2","point_size":"5","fill":"0","stacked":"none","filter":{"query":"products.product_name:*trouser*","language":"lucene"},"label":"Revenue Trousers","value_template":"${{value}}","split_color_mode":"gradient"},{"id":"062d77b0-b88e-11e8-a451-f37365e9f268","color":"rgba(84,179,153,1)","split_mode":"everything","metrics":[{"id":"062d77b1-b88e-11e8-a451-f37365e9f268","type":"sum","field":"taxful_total_price"}],"separate_axis":0,"axis_position":"right","formatter":"number","chart_type":"line","line_width":"2","point_size":"05","fill":"0","stacked":"none","filter":{"query":"products.product_name:*watch*","language":"lucene"},"label":"Revenue Watches","value_template":"${{value}}","split_color_mode":"gradient"},{"id":"61ca57f1-469d-11e7-af02-69e470af7417","color":"rgba(96,146,192,1)","split_mode":"everything","metrics":[{"id":"61ca57f2-469d-11e7-af02-69e470af7417","type":"sum","field":"taxful_total_price"}],"separate_axis":0,"axis_position":"right","formatter":"number","chart_type":"line","line_width":"2","point_size":"5","fill":"0","stacked":"none","filter":{"query":"products.product_name:*bag*","language":"lucene"},"label":"Revenue Bags","value_template":"${{value}}","split_color_mode":"gradient"},{"id":"faa2c170-b88d-11e8-a451-f37365e9f268","color":"rgba(202,142,174,1)","split_mode":"everything","metrics":[{"id":"faa2c171-b88d-11e8-a451-f37365e9f268","type":"sum","field":"taxful_total_price"}],"separate_axis":0,"axis_position":"right","formatter":"number","chart_type":"line","line_width":"2","point_size":"5","fill":"0","stacked":"none","filter":{"query":"products.product_name:*cocktail dress*","language":"lucene"},"label":"Revenue Cocktail Dresses","value_template":"${{value}}","split_color_mode":"gradient"}],"time_field":"order_date","interval":"12h","use_kibana_indexes":true,"axis_position":"left","axis_formatter":"number","axis_scale":"normal","show_legend":1,"show_grid":1,"legend_position":"bottom","annotations":[{"fields":"taxful_total_price","template":"Ring the bell! ${{taxful_total_price}}","query_string":{"query":"taxful_total_price:>250","language":"lucene"},"id":"c8c30be0-b88f-11e8-a451-f37365e9f268","color":"rgba(25,77,51,1)","time_field":"order_date","icon":"fa-bell","ignore_global_filters":1,"ignore_panel_filters":1,"index_pattern_ref_name":"metrics_1_index_pattern"}],"tooltip_mode":"show_all","drop_last_bucket":0,"isModelInvalid":false,"index_pattern_ref_name":"metrics_0_index_pattern"}}', + }, + coreMigrationVersion: '8.0.0', + id: '45e07720-b890-11e8-a6d9-e546fe2bba5f', + migrationVersion: { + visualization: '7.14.0', }, references: [ { @@ -45,27 +65,28 @@ export const getSavedObjects = (): SavedObject[] => [ type: 'index-pattern', }, ], + type: 'visualization', + updated_at: '2021-08-05T12:23:57.577Z', + version: 'WzIxLDFd', }, { - id: 'b80e6540-b891-11e8-a6d9-e546fe2bba5f', - type: 'visualization', - updated_at: '2021-07-14T20:45:27.899Z', - version: '2', - migrationVersion: { - visualization: '7.14.0', - }, attributes: { + description: '', + kibanaSavedObjectMeta: { + searchSourceJSON: '{"query":{"query":"","language":"kuery"},"filter":[]}', + }, title: i18n.translate('home.sampleData.ecommerceSpec.soldProductsPerDayTitle', { defaultMessage: '[eCommerce] Sold Products per Day', }), - visState: - '{"title":"[eCommerce] Sold Products per Day","type":"metrics","aggs":[],"params":{"time_range_mode":"entire_time_range","id":"61ca57f0-469d-11e7-af02-69e470af7417","type":"gauge","series":[{"id":"61ca57f1-469d-11e7-af02-69e470af7417","color":"#68BC00","split_mode":"everything","metrics":[{"id":"61ca57f2-469d-11e7-af02-69e470af7417","type":"count"},{"id":"fd1e1b90-e4e3-11eb-8234-cb7bfd534fce","type":"math","variables":[{"id":"00374270-e4e4-11eb-8234-cb7bfd534fce","name":"c","field":"61ca57f2-469d-11e7-af02-69e470af7417"}],"script":"params.c / (params._interval / 1000 / 60 / 60 / 24)"}],"separate_axis":0,"axis_position":"right","formatter":"0.0","chart_type":"line","line_width":1,"point_size":1,"fill":0.5,"stacked":"none","label":"Trxns / day","split_color_mode":"gradient","value_template":""}],"time_field":"order_date","interval":"1d","axis_position":"left","axis_formatter":"number","axis_scale":"normal","show_legend":1,"show_grid":1,"gauge_color_rules":[{"value":150,"id":"6da070c0-b891-11e8-b645-195edeb9de84","gauge":"rgba(104,188,0,1)","operator":"gte"},{"value":150,"id":"9b0cdbc0-b891-11e8-b645-195edeb9de84","gauge":"rgba(244,78,59,1)","operator":"lt"}],"gauge_width":"15","gauge_inner_width":"10","gauge_style":"half","filter":"","gauge_max":"300","use_kibana_indexes":true,"hide_last_value_indicator":true,"tooltip_mode":"show_all","drop_last_bucket":0,"isModelInvalid":false,"index_pattern_ref_name":"metrics_0_index_pattern"}}', uiStateJSON: '{}', - description: '', version: 1, - kibanaSavedObjectMeta: { - searchSourceJSON: '{"query":{"query":"","language":"kuery"},"filter":[]}', - }, + visState: + '{"title":"[eCommerce] Sold Products per Day","type":"metrics","aggs":[],"params":{"time_range_mode":"entire_time_range","id":"61ca57f0-469d-11e7-af02-69e470af7417","type":"gauge","series":[{"id":"61ca57f1-469d-11e7-af02-69e470af7417","color":"#68BC00","split_mode":"everything","metrics":[{"id":"61ca57f2-469d-11e7-af02-69e470af7417","type":"count"},{"id":"fd1e1b90-e4e3-11eb-8234-cb7bfd534fce","type":"math","variables":[{"id":"00374270-e4e4-11eb-8234-cb7bfd534fce","name":"c","field":"61ca57f2-469d-11e7-af02-69e470af7417"}],"script":"params.c / (params._interval / 1000 / 60 / 60 / 24)"}],"separate_axis":0,"axis_position":"right","formatter":"0.0","chart_type":"line","line_width":1,"point_size":1,"fill":0.5,"stacked":"none","label":"Trxns / day","split_color_mode":"gradient","value_template":""}],"time_field":"order_date","interval":"1d","axis_position":"left","axis_formatter":"number","axis_scale":"normal","show_legend":1,"show_grid":1,"gauge_color_rules":[{"value":150,"id":"6da070c0-b891-11e8-b645-195edeb9de84","gauge":"rgba(104,188,0,1)","operator":"gte"},{"value":150,"id":"9b0cdbc0-b891-11e8-b645-195edeb9de84","gauge":"rgba(244,78,59,1)","operator":"lt"}],"gauge_width":"15","gauge_inner_width":"10","gauge_style":"half","filter":"","gauge_max":"300","use_kibana_indexes":true,"hide_last_value_indicator":true,"tooltip_mode":"show_all","drop_last_bucket":0,"isModelInvalid":false,"index_pattern_ref_name":"metrics_0_index_pattern"}}', + }, + coreMigrationVersion: '8.0.0', + id: 'b80e6540-b891-11e8-a6d9-e546fe2bba5f', + migrationVersion: { + visualization: '7.14.0', }, references: [ { @@ -74,21 +95,12 @@ export const getSavedObjects = (): SavedObject[] => [ type: 'index-pattern', }, ], + type: 'visualization', + updated_at: '2021-08-05T12:23:57.577Z', + version: 'WzIyLDFd', }, { - id: '3ba638e0-b894-11e8-a6d9-e546fe2bba5f', - type: 'search', - updated_at: '2021-07-16T20:05:53.880Z', - version: '2', - migrationVersion: { - search: '7.9.3', - }, attributes: { - title: i18n.translate('home.sampleData.ecommerceSpec.ordersTitle', { - defaultMessage: '[eCommerce] Orders', - }), - description: '', - hits: 0, columns: [ 'category', 'taxful_total_price', @@ -97,12 +109,22 @@ export const getSavedObjects = (): SavedObject[] => [ 'products.manufacturer', 'sku', ], - sort: [['order_date', 'desc']], - version: 1, + description: '', + hits: 0, kibanaSavedObjectMeta: { searchSourceJSON: '{"highlightAll":true,"version":true,"query":{"query":"","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', }, + sort: [['order_date', 'desc']], + title: i18n.translate('home.sampleData.ecommerceSpec.ordersTitle', { + defaultMessage: '[eCommerce] Orders', + }), + version: 1, + }, + coreMigrationVersion: '8.0.0', + id: '3ba638e0-b894-11e8-a6d9-e546fe2bba5f', + migrationVersion: { + search: '7.9.3', }, references: [ { @@ -111,225 +133,1286 @@ export const getSavedObjects = (): SavedObject[] => [ type: 'index-pattern', }, ], + type: 'search', + updated_at: '2021-08-05T12:23:57.577Z', + version: 'WzIzLDFd', }, { - id: '9c6f83f0-bb4d-11e8-9c84-77068524bcab', - type: 'visualization', - updated_at: '2018-10-01T15:13:03.270Z', - version: '1', - migrationVersion: {}, attributes: { - title: i18n.translate('home.sampleData.ecommerceSpec.salesCountMapTitle', { - defaultMessage: '[eCommerce] Sales Count Map', - }), - visState: - '{"title":"[eCommerce] Sales Count Map","type":"vega","aggs":[],"params":{"spec":"{\\n $schema: https://vega.github.io/schema/vega/v5.json\\n config: {\\n kibana: {type: \\"map\\", latitude: 25, longitude: -40, zoom: 3}\\n }\\n data: [\\n {\\n name: table\\n url: {\\n index: kibana_sample_data_ecommerce\\n %context%: true\\n %timefield%: order_date\\n body: {\\n size: 0\\n aggs: {\\n gridSplit: {\\n geotile_grid: {field: \\"geoip.location\\", precision: 4, size: 10000}\\n aggs: {\\n gridCentroid: {\\n geo_centroid: {\\n field: \\"geoip.location\\"\\n }\\n }\\n }\\n }\\n }\\n }\\n }\\n format: {property: \\"aggregations.gridSplit.buckets\\"}\\n transform: [\\n {\\n type: geopoint\\n projection: projection\\n fields: [\\n gridCentroid.location.lon\\n gridCentroid.location.lat\\n ]\\n }\\n ]\\n }\\n ]\\n scales: [\\n {\\n name: gridSize\\n type: linear\\n domain: {data: \\"table\\", field: \\"doc_count\\"}\\n range: [\\n 50\\n 1000\\n ]\\n }\\n ]\\n marks: [\\n {\\n name: gridMarker\\n type: symbol\\n from: {data: \\"table\\"}\\n encode: {\\n update: {\\n size: {scale: \\"gridSize\\", field: \\"doc_count\\"}\\n xc: {signal: \\"datum.x\\"}\\n yc: {signal: \\"datum.y\\"}\\n }\\n }\\n },\\n {\\n name: gridLabel\\n type: text\\n from: {data: \\"table\\"}\\n encode: {\\n enter: {\\n fill: {value: \\"firebrick\\"}\\n text: {signal: \\"datum.doc_count\\"}\\n }\\n update: {\\n x: {signal: \\"datum.x\\"}\\n y: {signal: \\"datum.y\\"}\\n dx: {value: -6}\\n dy: {value: 6}\\n fontSize: {value: 18}\\n fontWeight: {value: \\"bold\\"}\\n }\\n }\\n }\\n ]\\n}"}}', - uiStateJSON: '{}', description: '', - version: 1, - kibanaSavedObjectMeta: { - searchSourceJSON: - '{"version":true,"query":{"query":"","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', - }, + layerListJSON: + '[{"id":"0hmz5","alpha":1,"sourceDescriptor":{"type":"EMS_TMS","isAutoSelect":true},"visible":true,"style":{},"type":"VECTOR_TILE","minZoom":0,"maxZoom":24},{"id":"7ameq","label":null,"minZoom":0,"maxZoom":24,"alpha":1,"sourceDescriptor":{"type":"EMS_FILE","id":"world_countries","tooltipProperties":["name","iso2"]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"name":"__kbnjoin__count__741db9c6-8ebb-4ea9-9885-b6b4ac019d14","origin":"join"},"color":"Green to Red","fieldMetaOptions":{"isEnabled":false,"sigma":3}}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"STATIC","options":{"size":10}},"symbolizeAs":{"options":{"value":"circle"}},"icon":{"type":"STATIC","options":{"value":"marker"}}}},"type":"VECTOR","joins":[{"leftField":"iso2","right":{"type":"ES_TERM_SOURCE","id":"741db9c6-8ebb-4ea9-9885-b6b4ac019d14","indexPatternTitle":"kibana_sample_data_ecommerce","term":"geoip.country_iso_code","indexPatternRefName":"layer_1_join_0_index_pattern","metrics":[{"type":"count","label":"sales count"}],"applyGlobalQuery":true}}]},{"id":"jmtgf","label":"United States","minZoom":0,"maxZoom":24,"alpha":1,"sourceDescriptor":{"type":"EMS_FILE","id":"usa_states","tooltipProperties":["name"]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"name":"__kbnjoin__count__30a0ec24-49b6-476a-b4ed-6c1636333695","origin":"join"},"color":"Blues","fieldMetaOptions":{"isEnabled":false,"sigma":3}}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"STATIC","options":{"size":10}},"symbolizeAs":{"options":{"value":"circle"}},"icon":{"type":"STATIC","options":{"value":"marker"}}}},"type":"VECTOR","joins":[{"leftField":"name","right":{"type":"ES_TERM_SOURCE","id":"30a0ec24-49b6-476a-b4ed-6c1636333695","indexPatternTitle":"kibana_sample_data_ecommerce","term":"geoip.region_name","indexPatternRefName":"layer_2_join_0_index_pattern","metrics":[{"type":"count","label":"sales count"}],"applyGlobalQuery":true}}]},{"id":"ui5f8","label":"France","minZoom":0,"maxZoom":24,"alpha":1,"sourceDescriptor":{"type":"EMS_FILE","id":"france_departments","tooltipProperties":["label_en"]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"name":"__kbnjoin__count__e325c9da-73fa-4b3b-8b59-364b99370826","origin":"join"},"color":"Blues","fieldMetaOptions":{"isEnabled":false,"sigma":3}}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"STATIC","options":{"size":10}},"symbolizeAs":{"options":{"value":"circle"}},"icon":{"type":"STATIC","options":{"value":"marker"}}}},"type":"VECTOR","joins":[{"leftField":"label_en","right":{"type":"ES_TERM_SOURCE","id":"e325c9da-73fa-4b3b-8b59-364b99370826","indexPatternTitle":"kibana_sample_data_ecommerce","term":"geoip.region_name","indexPatternRefName":"layer_3_join_0_index_pattern","metrics":[{"type":"count","label":"sales count"}],"applyGlobalQuery":true}}]},{"id":"y3fjb","label":"United Kingdom","minZoom":0,"maxZoom":24,"alpha":1,"sourceDescriptor":{"type":"EMS_FILE","id":"uk_subdivisions","tooltipProperties":["label_en"]},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"name":"__kbnjoin__count__612d805d-8533-43a9-ac0e-cbf51fe63dcd","origin":"join"},"color":"Blues","fieldMetaOptions":{"isEnabled":false,"sigma":3}}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"STATIC","options":{"size":10}},"symbolizeAs":{"options":{"value":"circle"}},"icon":{"type":"STATIC","options":{"value":"marker"}}}},"type":"VECTOR","joins":[{"leftField":"label_en","right":{"type":"ES_TERM_SOURCE","id":"612d805d-8533-43a9-ac0e-cbf51fe63dcd","indexPatternTitle":"kibana_sample_data_ecommerce","term":"geoip.region_name","indexPatternRefName":"layer_4_join_0_index_pattern","metrics":[{"type":"count","label":"sales count"}],"applyGlobalQuery":true}}]},{"id":"c54wk","label":"Sales","minZoom":9,"maxZoom":24,"alpha":1,"sourceDescriptor":{"id":"04c983b0-8cfa-4e6a-a64b-52c10b7008fe","type":"ES_SEARCH","geoField":"geoip.location","limit":2048,"filterByMapBounds":true,"tooltipProperties":["category","customer_gender","manufacturer","order_id","total_quantity","total_unique_products","taxful_total_price","order_date","geoip.region_name","geoip.country_iso_code"],"indexPatternRefName":"layer_5_source_index_pattern","applyGlobalQuery":true,"scalingType":"LIMIT"},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"name":"taxful_total_price","origin":"source"},"color":"Greens","fieldMetaOptions":{"isEnabled":false,"sigma":3}}},"lineColor":{"type":"STATIC","options":{"color":"#FFFFFF"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"STATIC","options":{"size":10}},"symbolizeAs":{"options":{"value":"circle"}},"icon":{"type":"STATIC","options":{"value":"marker"}}}},"type":"VECTOR"},{"id":"qvhh3","label":"Total Sales Revenue","minZoom":0,"maxZoom":9,"alpha":1,"sourceDescriptor":{"type":"ES_GEO_GRID","resolution":"COARSE","id":"aa7f87b8-9dc5-42be-b19e-1a2fa09b6cad","geoField":"geoip.location","requestType":"point","metrics":[{"type":"count","label":"sales count"},{"type":"sum","field":"taxful_total_price","label":"total sales price"}],"indexPatternRefName":"layer_6_source_index_pattern","applyGlobalQuery":true},"visible":true,"style":{"type":"VECTOR","properties":{"fillColor":{"type":"DYNAMIC","options":{"field":{"name":"doc_count","origin":"source"},"color":"Greens","fieldMetaOptions":{"isEnabled":false,"sigma":3}}},"lineColor":{"type":"STATIC","options":{"color":"#cccccc"}},"lineWidth":{"type":"STATIC","options":{"size":1}},"iconSize":{"type":"DYNAMIC","options":{"field":{"name":"sum_of_taxful_total_price","origin":"source"},"minSize":1,"maxSize":20,"fieldMetaOptions":{"isEnabled":false,"sigma":3}}},"labelText":{"type":"DYNAMIC","options":{"field":{"name":"sum_of_taxful_total_price","origin":"source"},"fieldMetaOptions":{"isEnabled":false,"sigma":3}}},"labelSize":{"type":"DYNAMIC","options":{"field":{"name":"sum_of_taxful_total_price","origin":"source"},"minSize":12,"maxSize":24,"fieldMetaOptions":{"isEnabled":false,"sigma":3}}},"labelBorderSize":{"options":{"size":"MEDIUM"}},"symbolizeAs":{"options":{"value":"circle"}},"icon":{"type":"STATIC","options":{"value":"marker"}}}},"type":"VECTOR"}]', + mapStateJSON: + '{"zoom":2.11,"center":{"lon":-15.07605,"lat":45.88578},"timeFilters":{"from":"now-7d","to":"now"},"refreshConfig":{"isPaused":true,"interval":0},"query":{"query":"","language":"kuery"},"settings":{"autoFitToDataBounds":false}}', + title: '[eCommerce] Orders by Country', + uiStateJSON: '{"isDarkMode":false}', + }, + coreMigrationVersion: '8.0.0', + id: '2c9c1f60-1909-11e9-919b-ffe5949a18d2', + migrationVersion: { + map: '7.14.0', }, references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + name: 'layer_1_join_0_index_pattern', + type: 'index-pattern', + }, + { + id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + name: 'layer_2_join_0_index_pattern', + type: 'index-pattern', + }, + { + id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + name: 'layer_3_join_0_index_pattern', + type: 'index-pattern', + }, + { + id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + name: 'layer_4_join_0_index_pattern', + type: 'index-pattern', + }, + { + id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + name: 'layer_5_source_index_pattern', + type: 'index-pattern', + }, + { + id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', + name: 'layer_6_source_index_pattern', type: 'index-pattern', }, ], + type: 'map', + updated_at: '2021-08-05T12:23:57.577Z', + version: 'WzI5LDFd', }, { - id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - type: 'index-pattern', - updated_at: '2021-07-16T20:08:12.675Z', - version: '2', - migrationVersion: { - 'index-pattern': '7.11.0', - }, attributes: { - title: 'kibana_sample_data_ecommerce', - timeFieldName: 'order_date', - fieldAttrs: - '{"products.manufacturer":{"count":1},"products.price":{"count":1},"products.product_name":{"count":1},"total_quantity":{"count":1}}', - fieldFormatMap: - '{"taxful_total_price":{"id":"number","params":{"pattern":"$0,0.[00]"}},"products.price":{"id":"number","params":{"pattern":"$0,0.00"}},"taxless_total_price":{"id":"number","params":{"pattern":"$0,0.00"}},"products.taxless_price":{"id":"number","params":{"pattern":"$0,0.00"}},"products.taxful_price":{"id":"number","params":{"pattern":"$0,0.00"}},"products.min_price":{"id":"number","params":{"pattern":"$0,0.00"}},"products.base_unit_price":{"id":"number","params":{"pattern":"$0,0.00"}},"products.base_price":{"id":"number","params":{"pattern":"$0,0.00"}}}', - fields: '[]', - runtimeFieldMap: '{}', - typeMeta: '{}', + description: '', + kibanaSavedObjectMeta: { + searchSourceJSON: '{"query":{"query":"","language":"kuery"},"filter":[]}', + }, + title: '[eCommerce] Markdown', + uiStateJSON: '{}', + version: 1, + visState: + '{"title":"[eCommerce] Markdown","type":"markdown","params":{"fontSize":12,"openLinksInNewTab":false,"markdown":"### Sample eCommerce Data\\nThis dashboard contains sample data for you to play with. You can view it, search it, and interact with the visualizations. For more information about Kibana, check our [docs](https://www.elastic.co/guide/en/kibana/current/index.html)."},"aggs":[]}', + }, + coreMigrationVersion: '8.0.0', + id: 'c00d1f90-f5ea-11eb-a78e-83aac3c38a60', + migrationVersion: { + visualization: '7.14.0', }, references: [], + type: 'visualization', + updated_at: '2021-08-05T12:43:35.817Z', + version: 'WzE3MSwxXQ==', }, { - id: '722b74f0-b882-11e8-a6d9-e546fe2bba5f', - type: 'dashboard', - updated_at: '2021-07-16T20:43:03.136Z', - version: '2', - references: [ - { - id: '45e07720-b890-11e8-a6d9-e546fe2bba5f', - name: '5:panel_5', - type: 'visualization', - }, - { - id: 'b80e6540-b891-11e8-a6d9-e546fe2bba5f', - name: '7:panel_7', - type: 'visualization', - }, - { - id: '3ba638e0-b894-11e8-a6d9-e546fe2bba5f', - name: '10:panel_10', - type: 'search', - }, - { - id: '9c6f83f0-bb4d-11e8-9c84-77068524bcab', - name: '11:panel_11', - type: 'map', + attributes: { + description: '', + kibanaSavedObjectMeta: { + searchSourceJSON: '{"query":{"query":"","language":"kuery"},"filter":[]}', }, + title: '[eCommerce] Controls', + uiStateJSON: '{}', + version: 1, + visState: + '{"title":"[eCommerce] Controls","type":"input_control_vis","params":{"controls":[{"id":"1536977437774","fieldName":"manufacturer.keyword","parent":"","label":"Manufacturer","type":"list","options":{"type":"terms","multiselect":true,"dynamicOptions":true,"size":5,"order":"desc"},"indexPatternRefName":"control_0_index_pattern"},{"id":"1536977465554","fieldName":"category.keyword","parent":"","label":"Category","type":"list","options":{"type":"terms","multiselect":true,"dynamicOptions":true,"size":5,"order":"desc"},"indexPatternRefName":"control_1_index_pattern"},{"id":"1536977596163","fieldName":"total_quantity","parent":"","label":"Quantity","type":"range","options":{"decimalPlaces":0,"step":1},"indexPatternRefName":"control_2_index_pattern"}],"updateFiltersOnChange":false,"useTimeFilter":true,"pinFilters":false},"aggs":[]}', + }, + coreMigrationVersion: '8.0.0', + id: 'c3378480-f5ea-11eb-a78e-83aac3c38a60', + migrationVersion: { + visualization: '7.14.0', + }, + references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - 'a5914d17-81fe-4f27-b240-23ac529c1499:control_a5914d17-81fe-4f27-b240-23ac529c1499_0_index_pattern', + name: 'control_0_index_pattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - 'a5914d17-81fe-4f27-b240-23ac529c1499:control_a5914d17-81fe-4f27-b240-23ac529c1499_1_index_pattern', + name: 'control_1_index_pattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - 'a5914d17-81fe-4f27-b240-23ac529c1499:control_a5914d17-81fe-4f27-b240-23ac529c1499_2_index_pattern', + name: 'control_2_index_pattern', type: 'index-pattern', }, + ], + type: 'visualization', + updated_at: '2021-08-05T12:43:41.128Z', + version: 'WzE3NiwxXQ==', + }, + { + attributes: { + state: { + datasourceStates: { + indexpattern: { + layers: { + 'c7478794-6767-4286-9d65-1c0ecd909dd8': { + columnOrder: [ + '8289349e-6d1b-4abf-b164-0208183d2c34', + '041db33b-5c9c-47f3-a5d3-ef5e255d1663', + '041db33b-5c9c-47f3-a5d3-ef5e255d1663X0', + '041db33b-5c9c-47f3-a5d3-ef5e255d1663X1', + ], + columns: { + '041db33b-5c9c-47f3-a5d3-ef5e255d1663': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: '% of target ($10k)', + operationType: 'formula', + params: { + format: { + id: 'percent', + params: { + decimals: 0, + }, + }, + formula: 'sum(taxful_total_price) / 10000 - 1', + isFormulaBroken: false, + }, + references: ['041db33b-5c9c-47f3-a5d3-ef5e255d1663X1'], + scale: 'ratio', + }, + '041db33b-5c9c-47f3-a5d3-ef5e255d1663X0': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Part of Weekly revenue', + operationType: 'sum', + scale: 'ratio', + sourceField: 'taxful_total_price', + }, + '041db33b-5c9c-47f3-a5d3-ef5e255d1663X1': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Part of Weekly revenue', + operationType: 'math', + params: { + tinymathAst: { + args: [ + { + args: ['041db33b-5c9c-47f3-a5d3-ef5e255d1663X0', 10000], + location: { + max: 32, + min: 0, + }, + name: 'divide', + text: 'sum(taxful_total_price) / 10000 ', + type: 'function', + }, + 1, + ], + location: { + max: 35, + min: 0, + }, + name: 'subtract', + text: 'sum(taxful_total_price) / 10000 - 1', + type: 'function', + }, + }, + references: ['041db33b-5c9c-47f3-a5d3-ef5e255d1663X0'], + scale: 'ratio', + }, + '8289349e-6d1b-4abf-b164-0208183d2c34': { + dataType: 'date', + isBucketed: true, + label: 'order_date', + operationType: 'date_histogram', + params: { + interval: '1d', + }, + scale: 'interval', + sourceField: 'order_date', + }, + }, + incompleteColumns: {}, + }, + }, + }, + }, + filters: [], + query: { + language: 'kuery', + query: '', + }, + visualization: { + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: true, + }, + fittingFunction: 'None', + gridlinesVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + layers: [ + { + accessors: ['041db33b-5c9c-47f3-a5d3-ef5e255d1663'], + layerId: 'c7478794-6767-4286-9d65-1c0ecd909dd8', + seriesType: 'bar_stacked', + xAccessor: '8289349e-6d1b-4abf-b164-0208183d2c34', + }, + ], + legend: { + isVisible: true, + position: 'right', + }, + preferredSeriesType: 'bar_stacked', + tickLabelsVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + valueLabels: 'hide', + yLeftExtent: { + mode: 'full', + }, + yRightExtent: { + mode: 'full', + }, + }, + }, + title: '% of target revenue ($10k)', + visualizationType: 'lnsXY', + }, + coreMigrationVersion: '8.0.0', + id: 'c762b7a0-f5ea-11eb-a78e-83aac3c38a60', + migrationVersion: { + lens: '7.14.0', + }, + references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: 'c65434d6-fe64-460f-b07a-c7d267c856ff:indexpattern-datasource-current-indexpattern', + name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - 'c65434d6-fe64-460f-b07a-c7d267c856ff:indexpattern-datasource-layer-c7478794-6767-4286-9d65-1c0ecd909dd8', + name: 'indexpattern-datasource-layer-c7478794-6767-4286-9d65-1c0ecd909dd8', type: 'index-pattern', }, + ], + type: 'lens', + updated_at: '2021-08-05T12:43:48.122Z', + version: 'WzE4NCwxXQ==', + }, + { + attributes: { + state: { + datasourceStates: { + indexpattern: { + layers: { + 'c7478794-6767-4286-9d65-1c0ecd909dd8': { + columnOrder: ['041db33b-5c9c-47f3-a5d3-ef5e255d1663'], + columns: { + '041db33b-5c9c-47f3-a5d3-ef5e255d1663': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Sum of revenue', + operationType: 'sum', + scale: 'ratio', + sourceField: 'taxful_total_price', + }, + }, + incompleteColumns: {}, + }, + }, + }, + }, + filters: [], + query: { + language: 'kuery', + query: '', + }, + visualization: { + accessor: '041db33b-5c9c-47f3-a5d3-ef5e255d1663', + layerId: 'c7478794-6767-4286-9d65-1c0ecd909dd8', + }, + }, + title: 'Sum of revenue', + visualizationType: 'lnsMetric', + }, + coreMigrationVersion: '8.0.0', + id: 'ce02e260-f5ea-11eb-a78e-83aac3c38a60', + migrationVersion: { + lens: '7.14.0', + }, + references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: '2e6ef14d-7b03-46d4-a6b8-a962ee36a805:indexpattern-datasource-current-indexpattern', + name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - '2e6ef14d-7b03-46d4-a6b8-a962ee36a805:indexpattern-datasource-layer-c7478794-6767-4286-9d65-1c0ecd909dd8', + name: 'indexpattern-datasource-layer-c7478794-6767-4286-9d65-1c0ecd909dd8', type: 'index-pattern', }, + ], + type: 'lens', + updated_at: '2021-08-05T12:43:59.238Z', + version: 'WzE4OSwxXQ==', + }, + { + attributes: { + state: { + datasourceStates: { + indexpattern: { + layers: { + '4fb42a8e-b133-43c8-805c-a38472053938': { + columnOrder: ['020bbfdf-9ef8-4802-aa9e-342d2ea0bebf'], + columns: { + '020bbfdf-9ef8-4802-aa9e-342d2ea0bebf': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Median spending', + operationType: 'median', + scale: 'ratio', + sourceField: 'taxful_total_price', + }, + }, + incompleteColumns: {}, + }, + }, + }, + }, + filters: [], + query: { + language: 'kuery', + query: '', + }, + visualization: { + accessor: '020bbfdf-9ef8-4802-aa9e-342d2ea0bebf', + layerId: '4fb42a8e-b133-43c8-805c-a38472053938', + }, + }, + title: 'Median spending', + visualizationType: 'lnsMetric', + }, + coreMigrationVersion: '8.0.0', + id: 'd5f90030-f5ea-11eb-a78e-83aac3c38a60', + migrationVersion: { + lens: '7.14.0', + }, + references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: '5108a3bc-d1cf-4255-8c95-2df52577b956:indexpattern-datasource-current-indexpattern', + name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - '5108a3bc-d1cf-4255-8c95-2df52577b956:indexpattern-datasource-layer-4fb42a8e-b133-43c8-805c-a38472053938', + name: 'indexpattern-datasource-layer-4fb42a8e-b133-43c8-805c-a38472053938', type: 'index-pattern', }, + ], + type: 'lens', + updated_at: '2021-08-05T12:44:12.595Z', + version: 'WzE5NywxXQ==', + }, + { + attributes: { + state: { + datasourceStates: { + indexpattern: { + layers: { + 'b6093a53-884f-42c2-9fcc-ba56cfb66c53': { + columnOrder: [ + '15c45f89-a149-443a-a830-aa8c3a9317db', + '2b41b3d8-2f62-407a-a866-960f254c679d', + 'eadae280-2da3-4d1d-a0e1-f9733f89c15b', + 'ddc92e50-4d5c-413e-b91b-3e504889fa65', + '5e31e5d3-2aaa-4475-a130-3b69bf2f748a', + ], + columns: { + '15c45f89-a149-443a-a830-aa8c3a9317db': { + dataType: 'date', + isBucketed: true, + label: 'order_date', + operationType: 'date_histogram', + params: { + interval: '1d', + }, + scale: 'interval', + sourceField: 'order_date', + }, + '2b41b3d8-2f62-407a-a866-960f254c679d': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Total items', + operationType: 'sum', + scale: 'ratio', + sourceField: 'products.quantity', + }, + '5e31e5d3-2aaa-4475-a130-3b69bf2f748a': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Tx. last week', + operationType: 'count', + scale: 'ratio', + sourceField: 'Records', + timeShift: '1w', + }, + 'ddc92e50-4d5c-413e-b91b-3e504889fa65': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Transactions', + operationType: 'count', + scale: 'ratio', + sourceField: 'Records', + }, + 'eadae280-2da3-4d1d-a0e1-f9733f89c15b': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Last week', + operationType: 'sum', + scale: 'ratio', + sourceField: 'products.quantity', + timeShift: '1w', + }, + }, + incompleteColumns: {}, + }, + }, + }, + }, + filters: [], + query: { + language: 'kuery', + query: '', + }, + visualization: { + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: true, + }, + curveType: 'LINEAR', + fittingFunction: 'None', + gridlinesVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + layers: [ + { + accessors: [ + '2b41b3d8-2f62-407a-a866-960f254c679d', + 'eadae280-2da3-4d1d-a0e1-f9733f89c15b', + '5e31e5d3-2aaa-4475-a130-3b69bf2f748a', + 'ddc92e50-4d5c-413e-b91b-3e504889fa65', + ], + layerId: 'b6093a53-884f-42c2-9fcc-ba56cfb66c53', + position: 'top', + seriesType: 'line', + showGridlines: false, + xAccessor: '15c45f89-a149-443a-a830-aa8c3a9317db', + yConfig: [ + { + color: '#b6e0d5', + forAccessor: 'eadae280-2da3-4d1d-a0e1-f9733f89c15b', + }, + { + color: '#edafc4', + forAccessor: '5e31e5d3-2aaa-4475-a130-3b69bf2f748a', + }, + ], + }, + ], + legend: { + isVisible: true, + position: 'right', + }, + preferredSeriesType: 'line', + tickLabelsVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + valueLabels: 'hide', + yLeftExtent: { + mode: 'full', + }, + yRightExtent: { + mode: 'full', + }, + }, + }, + title: 'Transactions per day', + visualizationType: 'lnsXY', + }, + coreMigrationVersion: '8.0.0', + id: 'dde978b0-f5ea-11eb-a78e-83aac3c38a60', + migrationVersion: { + lens: '7.14.0', + }, + references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: '6bc3fa4a-8f1b-436f-afc1-f3516ee531ce:indexpattern-datasource-current-indexpattern', + name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - '6bc3fa4a-8f1b-436f-afc1-f3516ee531ce:indexpattern-datasource-layer-b6093a53-884f-42c2-9fcc-ba56cfb66c53', + name: 'indexpattern-datasource-layer-b6093a53-884f-42c2-9fcc-ba56cfb66c53', type: 'index-pattern', }, + ], + type: 'lens', + updated_at: '2021-08-05T12:44:25.915Z', + version: 'WzIwMywxXQ==', + }, + { + attributes: { + state: { + datasourceStates: { + indexpattern: { + layers: { + '667067a2-7cdf-4f0e-a9fe-eb4f4f1f2f17': { + columnOrder: ['c52c2003-ae58-4604-bae7-52ba0fb38a01'], + columns: { + 'c52c2003-ae58-4604-bae7-52ba0fb38a01': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Avg. items sold', + operationType: 'average', + params: { + format: { + id: 'number', + params: { + decimals: 1, + }, + }, + }, + scale: 'ratio', + sourceField: 'total_quantity', + }, + }, + incompleteColumns: {}, + }, + }, + }, + }, + filters: [], + query: { + language: 'kuery', + query: '', + }, + visualization: { + accessor: 'c52c2003-ae58-4604-bae7-52ba0fb38a01', + layerId: '667067a2-7cdf-4f0e-a9fe-eb4f4f1f2f17', + }, + }, + title: 'Avg. items sold', + visualizationType: 'lnsMetric', + }, + coreMigrationVersion: '8.0.0', + id: 'e3902840-f5ea-11eb-a78e-83aac3c38a60', + migrationVersion: { + lens: '7.14.0', + }, + references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: '222c1f05-ca21-4e62-a04a-9a059b4534a7:indexpattern-datasource-current-indexpattern', + name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - '222c1f05-ca21-4e62-a04a-9a059b4534a7:indexpattern-datasource-layer-667067a2-7cdf-4f0e-a9fe-eb4f4f1f2f17', + name: 'indexpattern-datasource-layer-667067a2-7cdf-4f0e-a9fe-eb4f4f1f2f17', type: 'index-pattern', }, + ], + type: 'lens', + updated_at: '2021-08-05T12:44:35.396Z', + version: 'WzIwOSwxXQ==', + }, + { + attributes: { + state: { + datasourceStates: { + indexpattern: { + layers: { + '97c63ea6-9305-4755-97d1-0f26817c6f9a': { + columnOrder: [ + '9f61a7df-198e-4754-b34c-81ed544136ba', + 'ebcb19af-0900-4439-949f-d8cd9bccde19', + '5575214b-7f21-4b6c-8bc1-34433c6a0c58', + ], + columns: { + '5575214b-7f21-4b6c-8bc1-34433c6a0c58': { + dataType: 'number', + isBucketed: false, + label: 'Count of records', + operationType: 'count', + scale: 'ratio', + sourceField: 'Records', + }, + '9f61a7df-198e-4754-b34c-81ed544136ba': { + dataType: 'string', + isBucketed: true, + label: 'Top values of category.keyword', + operationType: 'terms', + params: { + missingBucket: false, + orderBy: { + columnId: '5575214b-7f21-4b6c-8bc1-34433c6a0c58', + type: 'column', + }, + orderDirection: 'desc', + otherBucket: true, + size: 10, + }, + scale: 'ordinal', + sourceField: 'category.keyword', + }, + 'ebcb19af-0900-4439-949f-d8cd9bccde19': { + dataType: 'date', + isBucketed: true, + label: 'order_date', + operationType: 'date_histogram', + params: { + interval: '1d', + }, + scale: 'interval', + sourceField: 'order_date', + }, + }, + incompleteColumns: {}, + }, + }, + }, + }, + filters: [], + query: { + language: 'kuery', + query: '', + }, + visualization: { + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: true, + }, + fittingFunction: 'None', + gridlinesVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + layers: [ + { + accessors: ['5575214b-7f21-4b6c-8bc1-34433c6a0c58'], + layerId: '97c63ea6-9305-4755-97d1-0f26817c6f9a', + position: 'top', + seriesType: 'bar_percentage_stacked', + showGridlines: false, + splitAccessor: '9f61a7df-198e-4754-b34c-81ed544136ba', + xAccessor: 'ebcb19af-0900-4439-949f-d8cd9bccde19', + }, + ], + legend: { + isVisible: true, + position: 'right', + }, + preferredSeriesType: 'bar_percentage_stacked', + tickLabelsVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + valueLabels: 'inside', + yLeftExtent: { + mode: 'full', + }, + yRightExtent: { + mode: 'full', + }, + }, + }, + title: 'Breakdown by category', + visualizationType: 'lnsXY', + }, + coreMigrationVersion: '8.0.0', + id: 'eddf7850-f5ea-11eb-a78e-83aac3c38a60', + migrationVersion: { + lens: '7.14.0', + }, + references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: 'a885226c-6830-4731-88a0-8c1d1047841e:indexpattern-datasource-current-indexpattern', + name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - 'a885226c-6830-4731-88a0-8c1d1047841e:indexpattern-datasource-layer-0731ee8b-31c5-4be9-92d9-69ee760465d7', + name: 'indexpattern-datasource-layer-97c63ea6-9305-4755-97d1-0f26817c6f9a', type: 'index-pattern', }, + ], + type: 'lens', + updated_at: '2021-08-05T12:44:52.693Z', + version: 'WzIxNSwxXQ==', + }, + { + attributes: { + state: { + datasourceStates: { + indexpattern: { + layers: { + '0731ee8b-31c5-4be9-92d9-69ee760465d7': { + columnOrder: [ + '7bf8f089-1542-40bd-b349-45fdfc309ac6', + '826b2f39-b616-40b2-a222-972fdc1d7596', + 'cfd45c47-fc41-430c-9e7a-b71dc0c916b0', + 'bf51c1af-443e-49f4-a21f-54c87bfc5677', + 'bf51c1af-443e-49f4-a21f-54c87bfc5677X0', + 'bf51c1af-443e-49f4-a21f-54c87bfc5677X1', + 'bf51c1af-443e-49f4-a21f-54c87bfc5677X2', + ], + columns: { + '7bf8f089-1542-40bd-b349-45fdfc309ac6': { + dataType: 'date', + isBucketed: true, + label: 'order_date', + operationType: 'date_histogram', + params: { + interval: '1d', + }, + scale: 'interval', + sourceField: 'order_date', + }, + '826b2f39-b616-40b2-a222-972fdc1d7596': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'This week', + operationType: 'sum', + scale: 'ratio', + sourceField: 'taxful_total_price', + }, + 'bf51c1af-443e-49f4-a21f-54c87bfc5677': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Difference', + operationType: 'formula', + params: { + format: { + id: 'number', + params: { + decimals: 2, + }, + }, + formula: "sum(taxful_total_price) - sum(taxful_total_price, shift='1w')", + isFormulaBroken: false, + }, + references: ['bf51c1af-443e-49f4-a21f-54c87bfc5677X2'], + scale: 'ratio', + }, + 'bf51c1af-443e-49f4-a21f-54c87bfc5677X0': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Part of Difference', + operationType: 'sum', + scale: 'ratio', + sourceField: 'taxful_total_price', + }, + 'bf51c1af-443e-49f4-a21f-54c87bfc5677X1': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Part of Difference', + operationType: 'sum', + scale: 'ratio', + sourceField: 'taxful_total_price', + timeShift: '1w', + }, + 'bf51c1af-443e-49f4-a21f-54c87bfc5677X2': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Part of Difference', + operationType: 'math', + params: { + tinymathAst: { + args: [ + 'bf51c1af-443e-49f4-a21f-54c87bfc5677X0', + 'bf51c1af-443e-49f4-a21f-54c87bfc5677X1', + ], + location: { + max: 61, + min: 0, + }, + name: 'subtract', + text: "sum(taxful_total_price) - sum(taxful_total_price, shift='1w')", + type: 'function', + }, + }, + references: [ + 'bf51c1af-443e-49f4-a21f-54c87bfc5677X0', + 'bf51c1af-443e-49f4-a21f-54c87bfc5677X1', + ], + scale: 'ratio', + }, + 'cfd45c47-fc41-430c-9e7a-b71dc0c916b0': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: '1 week ago', + operationType: 'sum', + scale: 'ratio', + sourceField: 'taxful_total_price', + timeShift: '1w', + }, + }, + incompleteColumns: {}, + }, + }, + }, + }, + filters: [], + query: { + language: 'kuery', + query: '', + }, + visualization: { + columns: [ + { + columnId: '7bf8f089-1542-40bd-b349-45fdfc309ac6', + }, + { + alignment: 'left', + columnId: '826b2f39-b616-40b2-a222-972fdc1d7596', + }, + { + columnId: 'cfd45c47-fc41-430c-9e7a-b71dc0c916b0', + }, + { + colorMode: 'text', + columnId: 'bf51c1af-443e-49f4-a21f-54c87bfc5677', + isTransposed: false, + palette: { + name: 'custom', + params: { + colorStops: [ + { + color: '#D36086', + stop: -10000, + }, + { + color: '#209280', + stop: 0, + }, + ], + continuity: 'above', + name: 'custom', + rangeMax: 0, + rangeMin: -10000, + rangeType: 'number', + steps: 5, + stops: [ + { + color: '#D36086', + stop: 0, + }, + { + color: '#209280', + stop: 2249.03125, + }, + ], + }, + type: 'palette', + }, + }, + ], + layerId: '0731ee8b-31c5-4be9-92d9-69ee760465d7', + }, + }, + title: 'Daily comparison', + visualizationType: 'lnsDatatable', + }, + coreMigrationVersion: '8.0.0', + id: 'ff6a21b0-f5ea-11eb-a78e-83aac3c38a60', + migrationVersion: { + lens: '7.14.0', + }, + references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: '003bdfc7-4d9e-4bd0-b088-3b18f79588d1:indexpattern-datasource-current-indexpattern', + name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - '003bdfc7-4d9e-4bd0-b088-3b18f79588d1:indexpattern-datasource-layer-97c63ea6-9305-4755-97d1-0f26817c6f9a', + name: 'indexpattern-datasource-layer-0731ee8b-31c5-4be9-92d9-69ee760465d7', type: 'index-pattern', }, + ], + type: 'lens', + updated_at: '2021-08-05T12:45:22.123Z', + version: 'WzIyMiwxXQ==', + }, + { + attributes: { + state: { + datasourceStates: { + indexpattern: { + layers: { + '5ed846c2-a70b-4d9c-a244-f254bef763b8': { + columnOrder: [ + 'd77cdd24-dedc-48dd-9a4b-d34c6f1a6c46', + '7ac31901-277a-46e2-8128-8d684b2c1127', + ], + columns: { + '7ac31901-277a-46e2-8128-8d684b2c1127': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Items', + operationType: 'count', + scale: 'ratio', + sourceField: 'Records', + }, + 'd77cdd24-dedc-48dd-9a4b-d34c6f1a6c46': { + customLabel: true, + dataType: 'string', + isBucketed: true, + label: 'Product name', + operationType: 'terms', + params: { + missingBucket: false, + orderBy: { + columnId: '7ac31901-277a-46e2-8128-8d684b2c1127', + type: 'column', + }, + orderDirection: 'desc', + otherBucket: false, + size: 5, + }, + scale: 'ordinal', + sourceField: 'products.product_name.keyword', + }, + }, + incompleteColumns: {}, + }, + }, + }, + }, + filters: [], + query: { + language: 'kuery', + query: '', + }, + visualization: { + axisTitlesVisibilitySettings: { + x: false, + yLeft: true, + yRight: true, + }, + fittingFunction: 'None', + gridlinesVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + layers: [ + { + accessors: ['7ac31901-277a-46e2-8128-8d684b2c1127'], + layerId: '5ed846c2-a70b-4d9c-a244-f254bef763b8', + position: 'top', + seriesType: 'bar_horizontal', + showGridlines: false, + xAccessor: 'd77cdd24-dedc-48dd-9a4b-d34c6f1a6c46', + }, + ], + legend: { + isVisible: true, + position: 'right', + }, + preferredSeriesType: 'bar_horizontal', + tickLabelsVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + valueLabels: 'inside', + yLeftExtent: { + mode: 'full', + }, + yRightExtent: { + mode: 'full', + }, + }, + }, + title: 'Top products this week', + visualizationType: 'lnsXY', + }, + coreMigrationVersion: '8.0.0', + id: '03071e90-f5eb-11eb-a78e-83aac3c38a60', + migrationVersion: { + lens: '7.14.0', + }, + references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: 'b1697063-c817-4847-aa0d-5bed47137b7e:indexpattern-datasource-current-indexpattern', + name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - 'b1697063-c817-4847-aa0d-5bed47137b7e:indexpattern-datasource-layer-5ed846c2-a70b-4d9c-a244-f254bef763b8', + name: 'indexpattern-datasource-layer-5ed846c2-a70b-4d9c-a244-f254bef763b8', type: 'index-pattern', }, + ], + type: 'lens', + updated_at: '2021-08-05T12:45:28.185Z', + version: 'WzIyOCwxXQ==', + }, + { + attributes: { + state: { + datasourceStates: { + indexpattern: { + layers: { + '5ed846c2-a70b-4d9c-a244-f254bef763b8': { + columnOrder: [ + 'd77cdd24-dedc-48dd-9a4b-d34c6f1a6c46', + '7ac31901-277a-46e2-8128-8d684b2c1127', + ], + columns: { + '7ac31901-277a-46e2-8128-8d684b2c1127': { + customLabel: true, + dataType: 'number', + isBucketed: false, + label: 'Items', + operationType: 'count', + scale: 'ratio', + sourceField: 'Records', + }, + 'd77cdd24-dedc-48dd-9a4b-d34c6f1a6c46': { + customLabel: true, + dataType: 'string', + isBucketed: true, + label: 'Product name', + operationType: 'terms', + params: { + missingBucket: false, + orderBy: { + columnId: '7ac31901-277a-46e2-8128-8d684b2c1127', + type: 'column', + }, + orderDirection: 'desc', + otherBucket: false, + size: 5, + }, + scale: 'ordinal', + sourceField: 'products.product_name.keyword', + }, + }, + incompleteColumns: {}, + }, + }, + }, + }, + filters: [], + query: { + language: 'kuery', + query: '', + }, + visualization: { + axisTitlesVisibilitySettings: { + x: false, + yLeft: true, + yRight: true, + }, + fittingFunction: 'None', + gridlinesVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + layers: [ + { + accessors: ['7ac31901-277a-46e2-8128-8d684b2c1127'], + layerId: '5ed846c2-a70b-4d9c-a244-f254bef763b8', + position: 'top', + seriesType: 'bar_horizontal', + showGridlines: false, + xAccessor: 'd77cdd24-dedc-48dd-9a4b-d34c6f1a6c46', + }, + ], + legend: { + isVisible: true, + position: 'right', + }, + preferredSeriesType: 'bar_horizontal', + tickLabelsVisibilitySettings: { + x: true, + yLeft: true, + yRight: true, + }, + valueLabels: 'inside', + yLeftExtent: { + mode: 'full', + }, + yRightExtent: { + mode: 'full', + }, + }, + }, + title: 'Top products last week', + visualizationType: 'lnsXY', + }, + coreMigrationVersion: '8.0.0', + id: '06379e00-f5eb-11eb-a78e-83aac3c38a60', + migrationVersion: { + lens: '7.14.0', + }, + references: [ { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: '562bb4bd-16b5-4c7e-9dfa-0f24cae6d1ba:indexpattern-datasource-current-indexpattern', + name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern', }, { id: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', - name: - '562bb4bd-16b5-4c7e-9dfa-0f24cae6d1ba:indexpattern-datasource-layer-5ed846c2-a70b-4d9c-a244-f254bef763b8', + name: 'indexpattern-datasource-layer-5ed846c2-a70b-4d9c-a244-f254bef763b8', type: 'index-pattern', }, ], - migrationVersion: { - dashboard: '7.14.0', - }, + type: 'lens', + updated_at: '2021-08-05T12:45:33.536Z', + version: 'WzIzMywxXQ==', + }, + { attributes: { - title: i18n.translate('home.sampleData.ecommerceSpec.revenueDashboardTitle', { - defaultMessage: '[eCommerce] Revenue Dashboard', - }), - hits: 0, description: i18n.translate('home.sampleData.ecommerceSpec.revenueDashboardDescription', { defaultMessage: 'Analyze mock eCommerce orders and revenue', }), + hits: 0, + kibanaSavedObjectMeta: { + searchSourceJSON: '{"query":{"language":"kuery","query":""},"filter":[]}', + }, optionsJSON: '{"hidePanelTitles":false,"useMargins":true}', panelsJSON: - '[{"version":"7.14.0","type":"visualization","gridData":{"x":0,"y":22,"w":24,"h":10,"i":"5"},"panelIndex":"5","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_5"},{"version":"7.14.0","type":"visualization","gridData":{"x":36,"y":15,"w":12,"h":7,"i":"7"},"panelIndex":"7","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_7"},{"version":"7.14.0","type":"search","gridData":{"x":0,"y":55,"w":48,"h":18,"i":"10"},"panelIndex":"10","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_10"},{"version":"7.14.0","type":"map","gridData":{"x":0,"y":32,"w":24,"h":14,"i":"11"},"panelIndex":"11","embeddableConfig":{"isLayerTOCOpen":false,"enhancements":{},"mapCenter":{"lat":45.88578,"lon":-15.07605,"zoom":2.11},"mapBuffer":{"minLon":-90,"minLat":0,"maxLon":45,"maxLat":66.51326},"openTOCDetails":[],"hiddenLayers":[]},"panelRefName":"panel_11"},{"version":"7.14.0","type":"visualization","gridData":{"x":0,"y":0,"w":18,"h":7,"i":"585b11d3-3461-49a7-8f5b-f56521b9dc8b"},"panelIndex":"585b11d3-3461-49a7-8f5b-f56521b9dc8b","embeddableConfig":{"savedVis":{"title":"[eCommerce] Markdown","description":"","type":"markdown","params":{"fontSize":12,"openLinksInNewTab":false,"markdown":"### Sample eCommerce Data\\nThis dashboard contains sample data for you to play with. You can view it, search it, and interact with the visualizations. For more information about Kibana, check our [docs](https://www.elastic.co/guide/en/kibana/current/index.html)."},"uiState":{},"data":{"aggs":[],"searchSource":{"query":{"query":"","language":"kuery"},"filter":[]}}},"enhancements":{}}},{"version":"7.14.0","type":"visualization","gridData":{"x":18,"y":0,"w":30,"h":7,"i":"a5914d17-81fe-4f27-b240-23ac529c1499"},"panelIndex":"a5914d17-81fe-4f27-b240-23ac529c1499","embeddableConfig":{"savedVis":{"title":"[eCommerce] Controls","description":"","type":"input_control_vis","params":{"controls":[{"id":"1536977437774","fieldName":"manufacturer.keyword","parent":"","label":"Manufacturer","type":"list","options":{"type":"terms","multiselect":true,"dynamicOptions":true,"size":5,"order":"desc"},"indexPatternRefName":"control_a5914d17-81fe-4f27-b240-23ac529c1499_0_index_pattern"},{"id":"1536977465554","fieldName":"category.keyword","parent":"","label":"Category","type":"list","options":{"type":"terms","multiselect":true,"dynamicOptions":true,"size":5,"order":"desc"},"indexPatternRefName":"control_a5914d17-81fe-4f27-b240-23ac529c1499_1_index_pattern"},{"id":"1536977596163","fieldName":"total_quantity","parent":"","label":"Quantity","type":"range","options":{"decimalPlaces":0,"step":1},"indexPatternRefName":"control_a5914d17-81fe-4f27-b240-23ac529c1499_2_index_pattern"}],"updateFiltersOnChange":false,"useTimeFilter":true,"pinFilters":false},"uiState":{},"data":{"aggs":[],"searchSource":{"query":{"query":"","language":"kuery"},"filter":[]}}},"enhancements":{}}},{"version":"7.14.0","type":"lens","gridData":{"x":0,"y":7,"w":24,"h":8,"i":"c65434d6-fe64-460f-b07a-c7d267c856ff"},"panelIndex":"c65434d6-fe64-460f-b07a-c7d267c856ff","embeddableConfig":{"attributes":{"title":"","type":"lens","visualizationType":"lnsXY","state":{"datasourceStates":{"indexpattern":{"layers":{"c7478794-6767-4286-9d65-1c0ecd909dd8":{"columns":{"8289349e-6d1b-4abf-b164-0208183d2c34":{"label":"order_date","dataType":"date","operationType":"date_histogram","sourceField":"order_date","isBucketed":true,"scale":"interval","params":{"interval":"1d"}},"041db33b-5c9c-47f3-a5d3-ef5e255d1663X0":{"label":"Part of Weekly revenue","dataType":"number","operationType":"sum","sourceField":"taxful_total_price","isBucketed":false,"scale":"ratio","customLabel":true},"041db33b-5c9c-47f3-a5d3-ef5e255d1663X1":{"label":"Part of Weekly revenue","dataType":"number","operationType":"math","isBucketed":false,"scale":"ratio","params":{"tinymathAst":{"type":"function","name":"subtract","args":[{"type":"function","name":"divide","args":["041db33b-5c9c-47f3-a5d3-ef5e255d1663X0",10000],"location":{"min":0,"max":32},"text":"sum(taxful_total_price) / 10000 "},1],"location":{"min":0,"max":35},"text":"sum(taxful_total_price) / 10000 - 1"}},"references":["041db33b-5c9c-47f3-a5d3-ef5e255d1663X0"],"customLabel":true},"041db33b-5c9c-47f3-a5d3-ef5e255d1663":{"label":"% of target ($10k)","dataType":"number","operationType":"formula","isBucketed":false,"scale":"ratio","params":{"formula":"sum(taxful_total_price) / 10000 - 1","isFormulaBroken":false,"format":{"id":"percent","params":{"decimals":0}}},"references":["041db33b-5c9c-47f3-a5d3-ef5e255d1663X1"],"customLabel":true}},"columnOrder":["8289349e-6d1b-4abf-b164-0208183d2c34","041db33b-5c9c-47f3-a5d3-ef5e255d1663","041db33b-5c9c-47f3-a5d3-ef5e255d1663X0","041db33b-5c9c-47f3-a5d3-ef5e255d1663X1"],"incompleteColumns":{}}}}},"visualization":{"legend":{"isVisible":true,"position":"right"},"valueLabels":"hide","fittingFunction":"None","yLeftExtent":{"mode":"full"},"yRightExtent":{"mode":"full"},"axisTitlesVisibilitySettings":{"x":false,"yLeft":false,"yRight":true},"tickLabelsVisibilitySettings":{"x":true,"yLeft":true,"yRight":true},"gridlinesVisibilitySettings":{"x":true,"yLeft":true,"yRight":true},"preferredSeriesType":"bar_stacked","layers":[{"layerId":"c7478794-6767-4286-9d65-1c0ecd909dd8","seriesType":"bar_stacked","xAccessor":"8289349e-6d1b-4abf-b164-0208183d2c34","accessors":["041db33b-5c9c-47f3-a5d3-ef5e255d1663"]}]},"query":{"query":"","language":"kuery"},"filters":[]},"references":[{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-current-indexpattern"},{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-layer-c7478794-6767-4286-9d65-1c0ecd909dd8"}]},"enhancements":{},"hidePanelTitles":false},"title":"% of target revenue ($10k)"},{"version":"7.14.0","type":"lens","gridData":{"x":24,"y":7,"w":12,"h":8,"i":"2e6ef14d-7b03-46d4-a6b8-a962ee36a805"},"panelIndex":"2e6ef14d-7b03-46d4-a6b8-a962ee36a805","embeddableConfig":{"attributes":{"title":"","type":"lens","visualizationType":"lnsMetric","state":{"datasourceStates":{"indexpattern":{"layers":{"c7478794-6767-4286-9d65-1c0ecd909dd8":{"columns":{"041db33b-5c9c-47f3-a5d3-ef5e255d1663":{"label":"Sum of revenue","dataType":"number","operationType":"sum","sourceField":"taxful_total_price","isBucketed":false,"scale":"ratio","customLabel":true}},"columnOrder":["041db33b-5c9c-47f3-a5d3-ef5e255d1663"],"incompleteColumns":{}}}}},"visualization":{"layerId":"c7478794-6767-4286-9d65-1c0ecd909dd8","accessor":"041db33b-5c9c-47f3-a5d3-ef5e255d1663"},"query":{"query":"","language":"kuery"},"filters":[]},"references":[{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-current-indexpattern"},{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-layer-c7478794-6767-4286-9d65-1c0ecd909dd8"}]},"enhancements":{}}},{"version":"7.14.0","type":"lens","gridData":{"x":36,"y":7,"w":12,"h":8,"i":"5108a3bc-d1cf-4255-8c95-2df52577b956"},"panelIndex":"5108a3bc-d1cf-4255-8c95-2df52577b956","embeddableConfig":{"attributes":{"title":"","type":"lens","visualizationType":"lnsMetric","state":{"datasourceStates":{"indexpattern":{"layers":{"4fb42a8e-b133-43c8-805c-a38472053938":{"columns":{"020bbfdf-9ef8-4802-aa9e-342d2ea0bebf":{"label":"Median spending","dataType":"number","operationType":"median","sourceField":"taxful_total_price","isBucketed":false,"scale":"ratio","customLabel":true}},"columnOrder":["020bbfdf-9ef8-4802-aa9e-342d2ea0bebf"],"incompleteColumns":{}}}}},"visualization":{"layerId":"4fb42a8e-b133-43c8-805c-a38472053938","accessor":"020bbfdf-9ef8-4802-aa9e-342d2ea0bebf"},"query":{"query":"","language":"kuery"},"filters":[]},"references":[{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-current-indexpattern"},{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-layer-4fb42a8e-b133-43c8-805c-a38472053938"}]},"enhancements":{}}},{"version":"7.14.0","type":"lens","gridData":{"x":0,"y":15,"w":24,"h":7,"i":"6bc3fa4a-8f1b-436f-afc1-f3516ee531ce"},"panelIndex":"6bc3fa4a-8f1b-436f-afc1-f3516ee531ce","embeddableConfig":{"attributes":{"title":"","type":"lens","visualizationType":"lnsXY","state":{"datasourceStates":{"indexpattern":{"layers":{"b6093a53-884f-42c2-9fcc-ba56cfb66c53":{"columns":{"15c45f89-a149-443a-a830-aa8c3a9317db":{"label":"order_date","dataType":"date","operationType":"date_histogram","sourceField":"order_date","isBucketed":true,"scale":"interval","params":{"interval":"1d"}},"2b41b3d8-2f62-407a-a866-960f254c679d":{"label":"Total items","dataType":"number","operationType":"sum","sourceField":"products.quantity","isBucketed":false,"scale":"ratio","customLabel":true},"ddc92e50-4d5c-413e-b91b-3e504889fa65":{"label":"Transactions","dataType":"number","operationType":"count","isBucketed":false,"scale":"ratio","sourceField":"Records","customLabel":true},"eadae280-2da3-4d1d-a0e1-f9733f89c15b":{"label":"Last week","dataType":"number","operationType":"sum","sourceField":"products.quantity","isBucketed":false,"scale":"ratio","timeShift":"1w","customLabel":true},"5e31e5d3-2aaa-4475-a130-3b69bf2f748a":{"label":"Tx. last week","dataType":"number","operationType":"count","isBucketed":false,"scale":"ratio","sourceField":"Records","timeShift":"1w","customLabel":true}},"columnOrder":["15c45f89-a149-443a-a830-aa8c3a9317db","2b41b3d8-2f62-407a-a866-960f254c679d","eadae280-2da3-4d1d-a0e1-f9733f89c15b","ddc92e50-4d5c-413e-b91b-3e504889fa65","5e31e5d3-2aaa-4475-a130-3b69bf2f748a"],"incompleteColumns":{}}}}},"visualization":{"legend":{"isVisible":true,"position":"right"},"valueLabels":"hide","fittingFunction":"None","yLeftExtent":{"mode":"full"},"yRightExtent":{"mode":"full"},"axisTitlesVisibilitySettings":{"x":false,"yLeft":false,"yRight":true},"tickLabelsVisibilitySettings":{"x":true,"yLeft":true,"yRight":true},"gridlinesVisibilitySettings":{"x":true,"yLeft":true,"yRight":true},"preferredSeriesType":"line","layers":[{"layerId":"b6093a53-884f-42c2-9fcc-ba56cfb66c53","accessors":["2b41b3d8-2f62-407a-a866-960f254c679d","eadae280-2da3-4d1d-a0e1-f9733f89c15b","5e31e5d3-2aaa-4475-a130-3b69bf2f748a","ddc92e50-4d5c-413e-b91b-3e504889fa65"],"position":"top","seriesType":"line","showGridlines":false,"xAccessor":"15c45f89-a149-443a-a830-aa8c3a9317db","yConfig":[{"forAccessor":"eadae280-2da3-4d1d-a0e1-f9733f89c15b","color":"#b6e0d5"},{"forAccessor":"5e31e5d3-2aaa-4475-a130-3b69bf2f748a","color":"#edafc4"}]}],"curveType":"LINEAR"},"query":{"query":"","language":"kuery"},"filters":[]},"references":[{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-current-indexpattern"},{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-layer-b6093a53-884f-42c2-9fcc-ba56cfb66c53"}]},"enhancements":{}}},{"version":"7.14.0","type":"lens","gridData":{"x":24,"y":15,"w":12,"h":7,"i":"222c1f05-ca21-4e62-a04a-9a059b4534a7"},"panelIndex":"222c1f05-ca21-4e62-a04a-9a059b4534a7","embeddableConfig":{"attributes":{"title":"","type":"lens","visualizationType":"lnsMetric","state":{"datasourceStates":{"indexpattern":{"layers":{"667067a2-7cdf-4f0e-a9fe-eb4f4f1f2f17":{"columns":{"c52c2003-ae58-4604-bae7-52ba0fb38a01":{"label":"Avg. items sold","dataType":"number","operationType":"average","sourceField":"total_quantity","isBucketed":false,"scale":"ratio","params":{"format":{"id":"number","params":{"decimals":1}}},"customLabel":true}},"columnOrder":["c52c2003-ae58-4604-bae7-52ba0fb38a01"],"incompleteColumns":{}}}}},"visualization":{"layerId":"667067a2-7cdf-4f0e-a9fe-eb4f4f1f2f17","accessor":"c52c2003-ae58-4604-bae7-52ba0fb38a01"},"query":{"query":"","language":"kuery"},"filters":[]},"references":[{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-current-indexpattern"},{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-layer-667067a2-7cdf-4f0e-a9fe-eb4f4f1f2f17"}]},"enhancements":{}}},{"version":"7.14.0","type":"lens","gridData":{"x":24,"y":22,"w":24,"h":10,"i":"003bdfc7-4d9e-4bd0-b088-3b18f79588d1"},"panelIndex":"003bdfc7-4d9e-4bd0-b088-3b18f79588d1","embeddableConfig":{"attributes":{"title":"","type":"lens","visualizationType":"lnsXY","state":{"datasourceStates":{"indexpattern":{"layers":{"97c63ea6-9305-4755-97d1-0f26817c6f9a":{"columns":{"9f61a7df-198e-4754-b34c-81ed544136ba":{"label":"Top values of category.keyword","dataType":"string","operationType":"terms","scale":"ordinal","sourceField":"category.keyword","isBucketed":true,"params":{"size":10,"orderBy":{"type":"column","columnId":"5575214b-7f21-4b6c-8bc1-34433c6a0c58"},"orderDirection":"desc","otherBucket":true,"missingBucket":false}},"ebcb19af-0900-4439-949f-d8cd9bccde19":{"label":"order_date","dataType":"date","operationType":"date_histogram","sourceField":"order_date","isBucketed":true,"scale":"interval","params":{"interval":"1d"}},"5575214b-7f21-4b6c-8bc1-34433c6a0c58":{"label":"Count of records","dataType":"number","operationType":"count","isBucketed":false,"scale":"ratio","sourceField":"Records"}},"columnOrder":["9f61a7df-198e-4754-b34c-81ed544136ba","ebcb19af-0900-4439-949f-d8cd9bccde19","5575214b-7f21-4b6c-8bc1-34433c6a0c58"],"incompleteColumns":{}}}}},"visualization":{"legend":{"isVisible":true,"position":"right"},"valueLabels":"inside","fittingFunction":"None","yLeftExtent":{"mode":"full"},"yRightExtent":{"mode":"full"},"axisTitlesVisibilitySettings":{"x":false,"yLeft":false,"yRight":true},"tickLabelsVisibilitySettings":{"x":true,"yLeft":true,"yRight":true},"gridlinesVisibilitySettings":{"x":true,"yLeft":true,"yRight":true},"preferredSeriesType":"bar_percentage_stacked","layers":[{"layerId":"97c63ea6-9305-4755-97d1-0f26817c6f9a","accessors":["5575214b-7f21-4b6c-8bc1-34433c6a0c58"],"position":"top","seriesType":"bar_percentage_stacked","showGridlines":false,"xAccessor":"ebcb19af-0900-4439-949f-d8cd9bccde19","splitAccessor":"9f61a7df-198e-4754-b34c-81ed544136ba"}]},"query":{"query":"","language":"kuery"},"filters":[]},"references":[{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-current-indexpattern"},{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-layer-97c63ea6-9305-4755-97d1-0f26817c6f9a"}]},"enhancements":{}}},{"version":"7.14.0","type":"lens","gridData":{"x":24,"y":32,"w":24,"h":14,"i":"a885226c-6830-4731-88a0-8c1d1047841e"},"panelIndex":"a885226c-6830-4731-88a0-8c1d1047841e","embeddableConfig":{"attributes":{"title":"","type":"lens","visualizationType":"lnsDatatable","state":{"datasourceStates":{"indexpattern":{"layers":{"0731ee8b-31c5-4be9-92d9-69ee760465d7":{"columns":{"7bf8f089-1542-40bd-b349-45fdfc309ac6":{"label":"order_date","dataType":"date","operationType":"date_histogram","sourceField":"order_date","isBucketed":true,"scale":"interval","params":{"interval":"1d"}},"826b2f39-b616-40b2-a222-972fdc1d7596":{"label":"This week","dataType":"number","operationType":"sum","sourceField":"taxful_total_price","isBucketed":false,"scale":"ratio","customLabel":true},"cfd45c47-fc41-430c-9e7a-b71dc0c916b0":{"label":"1 week ago","dataType":"number","operationType":"sum","sourceField":"taxful_total_price","isBucketed":false,"scale":"ratio","timeShift":"1w","customLabel":true},"bf51c1af-443e-49f4-a21f-54c87bfc5677X0":{"label":"Part of Difference","dataType":"number","operationType":"sum","sourceField":"taxful_total_price","isBucketed":false,"scale":"ratio","customLabel":true},"bf51c1af-443e-49f4-a21f-54c87bfc5677X1":{"label":"Part of Difference","dataType":"number","operationType":"sum","sourceField":"taxful_total_price","isBucketed":false,"scale":"ratio","timeShift":"1w","customLabel":true},"bf51c1af-443e-49f4-a21f-54c87bfc5677X2":{"label":"Part of Difference","dataType":"number","operationType":"math","isBucketed":false,"scale":"ratio","params":{"tinymathAst":{"type":"function","name":"subtract","args":["bf51c1af-443e-49f4-a21f-54c87bfc5677X0","bf51c1af-443e-49f4-a21f-54c87bfc5677X1"],"location":{"min":0,"max":61},"text":"sum(taxful_total_price) - sum(taxful_total_price, shift=\'1w\')"}},"references":["bf51c1af-443e-49f4-a21f-54c87bfc5677X0","bf51c1af-443e-49f4-a21f-54c87bfc5677X1"],"customLabel":true},"bf51c1af-443e-49f4-a21f-54c87bfc5677":{"label":"Difference","dataType":"number","operationType":"formula","isBucketed":false,"scale":"ratio","params":{"formula":"sum(taxful_total_price) - sum(taxful_total_price, shift=\'1w\')","isFormulaBroken":false,"format":{"id":"number","params":{"decimals":2}}},"references":["bf51c1af-443e-49f4-a21f-54c87bfc5677X2"],"customLabel":true}},"columnOrder":["7bf8f089-1542-40bd-b349-45fdfc309ac6","826b2f39-b616-40b2-a222-972fdc1d7596","cfd45c47-fc41-430c-9e7a-b71dc0c916b0","bf51c1af-443e-49f4-a21f-54c87bfc5677","bf51c1af-443e-49f4-a21f-54c87bfc5677X0","bf51c1af-443e-49f4-a21f-54c87bfc5677X1","bf51c1af-443e-49f4-a21f-54c87bfc5677X2"],"incompleteColumns":{}}}}},"visualization":{"layerId":"0731ee8b-31c5-4be9-92d9-69ee760465d7","columns":[{"columnId":"7bf8f089-1542-40bd-b349-45fdfc309ac6"},{"columnId":"826b2f39-b616-40b2-a222-972fdc1d7596","alignment":"left"},{"columnId":"cfd45c47-fc41-430c-9e7a-b71dc0c916b0"},{"columnId":"bf51c1af-443e-49f4-a21f-54c87bfc5677","isTransposed":false,"colorMode":"text","palette":{"name":"custom","type":"palette","params":{"steps":5,"stops":[{"color":"#D36086","stop":0},{"color":"#209280","stop":2249.03125}],"continuity":"above","rangeType":"number","colorStops":[{"color":"#D36086","stop":-10000},{"color":"#209280","stop":0}],"rangeMin":-10000,"rangeMax":0,"name":"custom"}}}]},"query":{"query":"","language":"kuery"},"filters":[]},"references":[{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-current-indexpattern"},{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-layer-0731ee8b-31c5-4be9-92d9-69ee760465d7"}]},"enhancements":{}}},{"version":"7.14.0","type":"lens","gridData":{"x":24,"y":46,"w":24,"h":9,"i":"562bb4bd-16b5-4c7e-9dfa-0f24cae6d1ba"},"panelIndex":"562bb4bd-16b5-4c7e-9dfa-0f24cae6d1ba","embeddableConfig":{"attributes":{"title":"","type":"lens","visualizationType":"lnsXY","state":{"datasourceStates":{"indexpattern":{"layers":{"5ed846c2-a70b-4d9c-a244-f254bef763b8":{"columns":{"d77cdd24-dedc-48dd-9a4b-d34c6f1a6c46":{"label":"Product name","dataType":"string","operationType":"terms","scale":"ordinal","sourceField":"products.product_name.keyword","isBucketed":true,"params":{"size":5,"orderBy":{"type":"column","columnId":"7ac31901-277a-46e2-8128-8d684b2c1127"},"orderDirection":"desc","otherBucket":false,"missingBucket":false},"customLabel":true},"7ac31901-277a-46e2-8128-8d684b2c1127":{"label":"Items","dataType":"number","operationType":"count","isBucketed":false,"scale":"ratio","sourceField":"Records","customLabel":true}},"columnOrder":["d77cdd24-dedc-48dd-9a4b-d34c6f1a6c46","7ac31901-277a-46e2-8128-8d684b2c1127"],"incompleteColumns":{}}}}},"visualization":{"legend":{"isVisible":true,"position":"right"},"valueLabels":"inside","fittingFunction":"None","yLeftExtent":{"mode":"full"},"yRightExtent":{"mode":"full"},"axisTitlesVisibilitySettings":{"x":false,"yLeft":true,"yRight":true},"tickLabelsVisibilitySettings":{"x":true,"yLeft":true,"yRight":true},"gridlinesVisibilitySettings":{"x":true,"yLeft":true,"yRight":true},"preferredSeriesType":"bar_horizontal","layers":[{"layerId":"5ed846c2-a70b-4d9c-a244-f254bef763b8","accessors":["7ac31901-277a-46e2-8128-8d684b2c1127"],"position":"top","seriesType":"bar_horizontal","showGridlines":false,"xAccessor":"d77cdd24-dedc-48dd-9a4b-d34c6f1a6c46"}]},"query":{"query":"","language":"kuery"},"filters":[]},"references":[{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-current-indexpattern"},{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-layer-5ed846c2-a70b-4d9c-a244-f254bef763b8"}]},"timeRange":{"from":"now-2w","to":"now-1w"},"hidePanelTitles":false,"enhancements":{}},"title":"Top products last week"},{"version":"7.14.0","type":"lens","gridData":{"x":0,"y":46,"w":24,"h":9,"i":"b1697063-c817-4847-aa0d-5bed47137b7e"},"panelIndex":"b1697063-c817-4847-aa0d-5bed47137b7e","embeddableConfig":{"attributes":{"title":"","type":"lens","visualizationType":"lnsXY","state":{"datasourceStates":{"indexpattern":{"layers":{"5ed846c2-a70b-4d9c-a244-f254bef763b8":{"columns":{"d77cdd24-dedc-48dd-9a4b-d34c6f1a6c46":{"label":"Product name","dataType":"string","operationType":"terms","scale":"ordinal","sourceField":"products.product_name.keyword","isBucketed":true,"params":{"size":5,"orderBy":{"type":"column","columnId":"7ac31901-277a-46e2-8128-8d684b2c1127"},"orderDirection":"desc","otherBucket":false,"missingBucket":false},"customLabel":true},"7ac31901-277a-46e2-8128-8d684b2c1127":{"label":"Items","dataType":"number","operationType":"count","isBucketed":false,"scale":"ratio","sourceField":"Records","customLabel":true}},"columnOrder":["d77cdd24-dedc-48dd-9a4b-d34c6f1a6c46","7ac31901-277a-46e2-8128-8d684b2c1127"],"incompleteColumns":{}}}}},"visualization":{"legend":{"isVisible":true,"position":"right"},"valueLabels":"inside","fittingFunction":"None","yLeftExtent":{"mode":"full"},"yRightExtent":{"mode":"full"},"axisTitlesVisibilitySettings":{"x":false,"yLeft":true,"yRight":true},"tickLabelsVisibilitySettings":{"x":true,"yLeft":true,"yRight":true},"gridlinesVisibilitySettings":{"x":true,"yLeft":true,"yRight":true},"preferredSeriesType":"bar_horizontal","layers":[{"layerId":"5ed846c2-a70b-4d9c-a244-f254bef763b8","accessors":["7ac31901-277a-46e2-8128-8d684b2c1127"],"position":"top","seriesType":"bar_horizontal","showGridlines":false,"xAccessor":"d77cdd24-dedc-48dd-9a4b-d34c6f1a6c46"}]},"query":{"query":"","language":"kuery"},"filters":[]},"references":[{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-current-indexpattern"},{"type":"index-pattern","id":"ff959d40-b880-11e8-a6d9-e546fe2bba5f","name":"indexpattern-datasource-layer-5ed846c2-a70b-4d9c-a244-f254bef763b8"}]},"hidePanelTitles":false,"enhancements":{}},"title":"Top products this week"}]', - version: 1, - timeRestore: true, - timeTo: 'now', - timeFrom: 'now-7d', + '[{"version":"8.0.0-SNAPSHOT","type":"visualization","gridData":{"x":0,"y":22,"w":24,"h":10,"i":"5"},"panelIndex":"5","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_5"},{"version":"8.0.0-SNAPSHOT","type":"visualization","gridData":{"x":36,"y":15,"w":12,"h":7,"i":"7"},"panelIndex":"7","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_7"},{"version":"8.0.0-SNAPSHOT","type":"search","gridData":{"x":0,"y":55,"w":48,"h":18,"i":"10"},"panelIndex":"10","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_10"},{"version":"8.0.0-SNAPSHOT","type":"map","gridData":{"x":0,"y":32,"w":24,"h":14,"i":"11"},"panelIndex":"11","embeddableConfig":{"isLayerTOCOpen":false,"enhancements":{},"mapCenter":{"lat":45.88578,"lon":-15.07605,"zoom":2.11},"mapBuffer":{"minLon":-135,"minLat":0,"maxLon":90,"maxLat":66.51326},"openTOCDetails":[],"hiddenLayers":[]},"panelRefName":"panel_11"},{"version":"8.0.0-SNAPSHOT","type":"visualization","gridData":{"x":0,"y":0,"w":18,"h":7,"i":"a71cf076-6895-491c-8878-63592e429ed5"},"panelIndex":"a71cf076-6895-491c-8878-63592e429ed5","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_a71cf076-6895-491c-8878-63592e429ed5"},{"version":"8.0.0-SNAPSHOT","type":"visualization","gridData":{"x":18,"y":0,"w":30,"h":7,"i":"adc0a2f4-481c-45eb-b422-0ea59a3e5163"},"panelIndex":"adc0a2f4-481c-45eb-b422-0ea59a3e5163","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_adc0a2f4-481c-45eb-b422-0ea59a3e5163"},{"version":"8.0.0-SNAPSHOT","type":"lens","gridData":{"x":0,"y":7,"w":24,"h":8,"i":"7077b79f-2a99-4fcb-bbd4-456982843278"},"panelIndex":"7077b79f-2a99-4fcb-bbd4-456982843278","embeddableConfig":{"enhancements":{},"hidePanelTitles":false},"title":"% of target revenue ($10k)","panelRefName":"panel_7077b79f-2a99-4fcb-bbd4-456982843278"},{"version":"8.0.0-SNAPSHOT","type":"lens","gridData":{"x":24,"y":7,"w":12,"h":8,"i":"19a3c101-ad2e-4421-a71b-a4734ec1f03e"},"panelIndex":"19a3c101-ad2e-4421-a71b-a4734ec1f03e","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_19a3c101-ad2e-4421-a71b-a4734ec1f03e"},{"version":"8.0.0-SNAPSHOT","type":"lens","gridData":{"x":36,"y":7,"w":12,"h":8,"i":"491469e7-7d24-4216-aeb3-bca00e5c8c1b"},"panelIndex":"491469e7-7d24-4216-aeb3-bca00e5c8c1b","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_491469e7-7d24-4216-aeb3-bca00e5c8c1b"},{"version":"8.0.0-SNAPSHOT","type":"lens","gridData":{"x":0,"y":15,"w":24,"h":7,"i":"a1b03eb9-a36b-4e12-aa1b-bb29b5d6c4ef"},"panelIndex":"a1b03eb9-a36b-4e12-aa1b-bb29b5d6c4ef","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_a1b03eb9-a36b-4e12-aa1b-bb29b5d6c4ef"},{"version":"8.0.0-SNAPSHOT","type":"lens","gridData":{"x":24,"y":15,"w":12,"h":7,"i":"da51079b-952f-43dc-96e6-6f9415a3708b"},"panelIndex":"da51079b-952f-43dc-96e6-6f9415a3708b","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_da51079b-952f-43dc-96e6-6f9415a3708b"},{"version":"8.0.0-SNAPSHOT","type":"lens","gridData":{"x":24,"y":22,"w":24,"h":10,"i":"64fd5dcf-30c5-4f5a-a78c-70b1fbf87e5b"},"panelIndex":"64fd5dcf-30c5-4f5a-a78c-70b1fbf87e5b","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_64fd5dcf-30c5-4f5a-a78c-70b1fbf87e5b"},{"version":"8.0.0-SNAPSHOT","type":"lens","gridData":{"x":24,"y":32,"w":24,"h":14,"i":"bd330ede-2eef-4e2a-8100-22a21abf5038"},"panelIndex":"bd330ede-2eef-4e2a-8100-22a21abf5038","embeddableConfig":{"enhancements":{}},"panelRefName":"panel_bd330ede-2eef-4e2a-8100-22a21abf5038"},{"version":"8.0.0-SNAPSHOT","type":"lens","gridData":{"x":0,"y":46,"w":24,"h":9,"i":"b897d4be-cf83-46fb-a111-c7fbec9ef403"},"panelIndex":"b897d4be-cf83-46fb-a111-c7fbec9ef403","embeddableConfig":{"hidePanelTitles":false,"enhancements":{}},"title":"Top products this week","panelRefName":"panel_b897d4be-cf83-46fb-a111-c7fbec9ef403"},{"version":"8.0.0-SNAPSHOT","type":"lens","gridData":{"x":24,"y":46,"w":24,"h":9,"i":"e0f68f93-30f2-4da7-889a-6cd128a68d3f"},"panelIndex":"e0f68f93-30f2-4da7-889a-6cd128a68d3f","embeddableConfig":{"timeRange":{"from":"now-2w","to":"now-1w"},"hidePanelTitles":false,"enhancements":{}},"title":"Top products last week","panelRefName":"panel_e0f68f93-30f2-4da7-889a-6cd128a68d3f"}]', refreshInterval: { pause: true, value: 0, }, - kibanaSavedObjectMeta: { - searchSourceJSON: '{"query":{"language":"kuery","query":""},"filter":[]}', - }, + timeFrom: 'now-7d', + timeRestore: true, + timeTo: 'now', + title: i18n.translate('home.sampleData.ecommerceSpec.revenueDashboardTitle', { + defaultMessage: '[eCommerce] Revenue Dashboard', + }), + version: 1, + }, + coreMigrationVersion: '8.0.0', + id: '722b74f0-b882-11e8-a6d9-e546fe2bba5f', + migrationVersion: { + dashboard: '7.14.0', }, + references: [ + { + id: '45e07720-b890-11e8-a6d9-e546fe2bba5f', + name: '5:panel_5', + type: 'visualization', + }, + { + id: 'b80e6540-b891-11e8-a6d9-e546fe2bba5f', + name: '7:panel_7', + type: 'visualization', + }, + { + id: '3ba638e0-b894-11e8-a6d9-e546fe2bba5f', + name: '10:panel_10', + type: 'search', + }, + { + id: '2c9c1f60-1909-11e9-919b-ffe5949a18d2', + name: '11:panel_11', + type: 'map', + }, + { + id: 'c00d1f90-f5ea-11eb-a78e-83aac3c38a60', + name: 'a71cf076-6895-491c-8878-63592e429ed5:panel_a71cf076-6895-491c-8878-63592e429ed5', + type: 'visualization', + }, + { + id: 'c3378480-f5ea-11eb-a78e-83aac3c38a60', + name: 'adc0a2f4-481c-45eb-b422-0ea59a3e5163:panel_adc0a2f4-481c-45eb-b422-0ea59a3e5163', + type: 'visualization', + }, + { + id: 'c762b7a0-f5ea-11eb-a78e-83aac3c38a60', + name: '7077b79f-2a99-4fcb-bbd4-456982843278:panel_7077b79f-2a99-4fcb-bbd4-456982843278', + type: 'lens', + }, + { + id: 'ce02e260-f5ea-11eb-a78e-83aac3c38a60', + name: '19a3c101-ad2e-4421-a71b-a4734ec1f03e:panel_19a3c101-ad2e-4421-a71b-a4734ec1f03e', + type: 'lens', + }, + { + id: 'd5f90030-f5ea-11eb-a78e-83aac3c38a60', + name: '491469e7-7d24-4216-aeb3-bca00e5c8c1b:panel_491469e7-7d24-4216-aeb3-bca00e5c8c1b', + type: 'lens', + }, + { + id: 'dde978b0-f5ea-11eb-a78e-83aac3c38a60', + name: 'a1b03eb9-a36b-4e12-aa1b-bb29b5d6c4ef:panel_a1b03eb9-a36b-4e12-aa1b-bb29b5d6c4ef', + type: 'lens', + }, + { + id: 'e3902840-f5ea-11eb-a78e-83aac3c38a60', + name: 'da51079b-952f-43dc-96e6-6f9415a3708b:panel_da51079b-952f-43dc-96e6-6f9415a3708b', + type: 'lens', + }, + { + id: 'eddf7850-f5ea-11eb-a78e-83aac3c38a60', + name: '64fd5dcf-30c5-4f5a-a78c-70b1fbf87e5b:panel_64fd5dcf-30c5-4f5a-a78c-70b1fbf87e5b', + type: 'lens', + }, + { + id: 'ff6a21b0-f5ea-11eb-a78e-83aac3c38a60', + name: 'bd330ede-2eef-4e2a-8100-22a21abf5038:panel_bd330ede-2eef-4e2a-8100-22a21abf5038', + type: 'lens', + }, + { + id: '03071e90-f5eb-11eb-a78e-83aac3c38a60', + name: 'b897d4be-cf83-46fb-a111-c7fbec9ef403:panel_b897d4be-cf83-46fb-a111-c7fbec9ef403', + type: 'lens', + }, + { + id: '06379e00-f5eb-11eb-a78e-83aac3c38a60', + name: 'e0f68f93-30f2-4da7-889a-6cd128a68d3f:panel_e0f68f93-30f2-4da7-889a-6cd128a68d3f', + type: 'lens', + }, + ], + type: 'dashboard', + updated_at: '2021-08-05T12:45:46.525Z', + version: 'WzIzOSwxXQ==', }, ]; diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap index 2ab8037639f85..2b71d1882b0cf 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/bytes/__snapshots__/bytes.test.tsx.snap @@ -43,6 +43,7 @@ exports[`BytesFormatEditor should render normally 1`] = ` labelType="label" > { this.onColorChange( { @@ -120,6 +121,7 @@ export class ColorFormatEditor extends DefaultFormatEditor { this.onColorChange( { @@ -144,6 +146,7 @@ export class ColorFormatEditor extends DefaultFormatEditor { this.onColorChange( { @@ -168,6 +171,7 @@ export class ColorFormatEditor extends DefaultFormatEditor { this.onColorChange( { @@ -220,6 +224,7 @@ export class ColorFormatEditor extends DefaultFormatEditor items.length > 1, + 'data-test-subj': 'colorEditorRemoveColor', }, ], }, @@ -229,7 +234,12 @@ export class ColorFormatEditor extends DefaultFormatEditor - + { return { @@ -126,6 +127,7 @@ export class DurationFormatEditor extends DefaultFormatEditor< isInvalid={!!error} > { return { diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap index 4d42e3848d3cd..8b59c0da10167 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/number/__snapshots__/number.test.tsx.snap @@ -43,6 +43,7 @@ exports[`NumberFormatEditor should render normally 1`] = ` labelType="label" > { diff --git a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap index fce51e8fa3871..7d8ab5e682a3e 100644 --- a/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap +++ b/src/plugins/index_pattern_field_editor/public/components/field_format_editor/editors/percent/__snapshots__/percent.test.tsx.snap @@ -43,6 +43,7 @@ exports[`PercentFormatEditor should render normally 1`] = ` labelType="label" > { this.onLookupChange( { @@ -105,6 +106,7 @@ export class StaticLookupFormatEditor extends DefaultFormatEditor { this.onLookupChange( { @@ -136,6 +138,7 @@ export class StaticLookupFormatEditor extends DefaultFormatEditor items.length > 1, }, ], @@ -147,7 +150,12 @@ export class StaticLookupFormatEditor extends DefaultFormatEditor - + { if (e.target.checkValidity()) { this.onChange({ diff --git a/src/plugins/input_control_vis/public/components/editor/field_select.tsx b/src/plugins/input_control_vis/public/components/editor/field_select.tsx index 5d3f2ef81bf08..d0925ee15d4b1 100644 --- a/src/plugins/input_control_vis/public/components/editor/field_select.tsx +++ b/src/plugins/input_control_vis/public/components/editor/field_select.tsx @@ -12,7 +12,7 @@ import React, { Component } from 'react'; import { injectI18n, FormattedMessage, InjectedIntlProps } from '@kbn/i18n/react'; import { EuiFormRow, EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; -import { IndexPattern, IFieldType } from '../../../../data/public'; +import { IndexPattern, IndexPatternField } from '../../../../data/public'; interface FieldSelectUiState { isLoading: boolean; @@ -25,7 +25,7 @@ export type FieldSelectUiProps = InjectedIntlProps & { indexPatternId: string; onChange: (value: any) => void; fieldName?: string; - filterField?: (field: IFieldType) => boolean; + filterField?: (field: IndexPatternField) => boolean; controlIndex: number; }; @@ -96,7 +96,7 @@ class FieldSelectUi extends Component { const fields: Array> = []; indexPattern.fields .filter(this.props.filterField ?? (() => true)) - .forEach((field: IFieldType) => { + .forEach((field: IndexPatternField) => { const fieldsList = fieldsByTypeMap.get(field.type) ?? []; fieldsList.push(field.name); fieldsByTypeMap.set(field.type, fieldsList); diff --git a/src/plugins/input_control_vis/public/components/editor/list_control_editor.tsx b/src/plugins/input_control_vis/public/components/editor/list_control_editor.tsx index 474238d01e4c8..2501d1d14e14e 100644 --- a/src/plugins/input_control_vis/public/components/editor/list_control_editor.tsx +++ b/src/plugins/input_control_vis/public/components/editor/list_control_editor.tsx @@ -14,7 +14,7 @@ import { EuiFormRow, EuiFieldNumber, EuiSwitch, EuiSelect } from '@elastic/eui'; import { IndexPatternSelectFormRow } from './index_pattern_select_form_row'; import { FieldSelect } from './field_select'; import { ControlParams, ControlParamsOptions } from '../../editor_utils'; -import { IndexPattern, IFieldType, IndexPatternSelectProps } from '../../../../data/public'; +import { IndexPattern, IndexPatternField, IndexPatternSelectProps } from '../../../../data/public'; import { InputControlVisDependencies } from '../../plugin'; interface ListControlEditorState { @@ -40,7 +40,7 @@ interface ListControlEditorProps { deps: InputControlVisDependencies; } -function filterField(field: IFieldType) { +function filterField(field: IndexPatternField) { return ( Boolean(field.aggregatable) && ['number', 'boolean', 'date', 'ip', 'string'].includes(field.type) @@ -116,7 +116,7 @@ export class ListControlEditor extends PureComponent< return; } - const field = (indexPattern.fields as IFieldType[]).find( + const field = (indexPattern.fields as IndexPatternField[]).find( ({ name }) => name === this.props.controlParams.fieldName ); if (!field) { diff --git a/src/plugins/input_control_vis/public/components/editor/range_control_editor.tsx b/src/plugins/input_control_vis/public/components/editor/range_control_editor.tsx index 8be9e176cecc9..38af22ab261d9 100644 --- a/src/plugins/input_control_vis/public/components/editor/range_control_editor.tsx +++ b/src/plugins/input_control_vis/public/components/editor/range_control_editor.tsx @@ -14,7 +14,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { IndexPatternSelectFormRow } from './index_pattern_select_form_row'; import { FieldSelect } from './field_select'; import { ControlParams, ControlParamsOptions } from '../../editor_utils'; -import { IndexPattern, IFieldType, IndexPatternSelectProps } from '../../../../data/public'; +import { IndexPattern, IndexPatternField, IndexPatternSelectProps } from '../../../../data/public'; import { InputControlVisDependencies } from '../../plugin'; interface RangeControlEditorProps { @@ -35,7 +35,7 @@ interface RangeControlEditorState { IndexPatternSelect: ComponentType | null; } -function filterField(field: IFieldType) { +function filterField(field: IndexPatternField) { return field.type === 'number'; } diff --git a/src/plugins/input_control_vis/public/control/filter_manager/range_filter_manager.ts b/src/plugins/input_control_vis/public/control/filter_manager/range_filter_manager.ts index 989b02712c25e..6d39df2d80d4d 100644 --- a/src/plugins/input_control_vis/public/control/filter_manager/range_filter_manager.ts +++ b/src/plugins/input_control_vis/public/control/filter_manager/range_filter_manager.ts @@ -9,7 +9,12 @@ import _ from 'lodash'; import { FilterManager } from './filter_manager'; -import { esFilters, RangeFilter, RangeFilterParams, IFieldType } from '../../../../data/public'; +import { + esFilters, + RangeFilter, + RangeFilterParams, + IndexPatternField, +} from '../../../../data/public'; interface SliderValue { min?: string | number; @@ -53,7 +58,7 @@ export class RangeFilterManager extends FilterManager { const indexPattern = this.getIndexPattern()!; const newFilter = esFilters.buildRangeFilter( // TODO: Fix type to be required - indexPattern.fields.getByName(this.fieldName) as IFieldType, + indexPattern.fields.getByName(this.fieldName) as IndexPatternField, toRange(value), indexPattern ); diff --git a/src/plugins/input_control_vis/public/control/list_control_factory.ts b/src/plugins/input_control_vis/public/control/list_control_factory.ts index 84fdf53e3c5f6..342e05460b8f2 100644 --- a/src/plugins/input_control_vis/public/control/list_control_factory.ts +++ b/src/plugins/input_control_vis/public/control/list_control_factory.ts @@ -9,7 +9,7 @@ import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import { - IFieldType, + IndexPatternField, TimefilterContract, SearchSourceFields, DataPublicPluginStart, @@ -26,7 +26,7 @@ function getEscapedQuery(query = '') { } interface TermsAggArgs { - field?: IFieldType; + field?: IndexPatternField; size: number | null; direction: string; query?: string; diff --git a/src/plugins/input_control_vis/public/control/range_control_factory.ts b/src/plugins/input_control_vis/public/control/range_control_factory.ts index 9c87f608bb618..906762266a7b3 100644 --- a/src/plugins/input_control_vis/public/control/range_control_factory.ts +++ b/src/plugins/input_control_vis/public/control/range_control_factory.ts @@ -9,14 +9,18 @@ import _ from 'lodash'; import { i18n } from '@kbn/i18n'; -import { IFieldType, TimefilterContract, DataPublicPluginStart } from 'src/plugins/data/public'; +import { + IndexPatternField, + TimefilterContract, + DataPublicPluginStart, +} from 'src/plugins/data/public'; import { Control, noValuesDisableMsg, noIndexPatternMsg } from './control'; import { RangeFilterManager } from './filter_manager/range_filter_manager'; import { createSearchSource } from './create_search_source'; import { ControlParams } from '../editor_utils'; import { InputControlVisDependencies } from '../plugin'; -const minMaxAgg = (field?: IFieldType) => { +const minMaxAgg = (field?: IndexPatternField) => { const aggBody: any = {}; if (field) { if (field.scripted) { diff --git a/src/plugins/kibana_overview/kibana.json b/src/plugins/kibana_overview/kibana.json index f09fe0cc16a31..1b052a239ba31 100644 --- a/src/plugins/kibana_overview/kibana.json +++ b/src/plugins/kibana_overview/kibana.json @@ -1,5 +1,9 @@ { "id": "kibanaOverview", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "kibana", "server": false, "ui": true, diff --git a/src/plugins/kibana_react/public/page_template/page_template.scss b/src/plugins/kibana_react/public/page_template/page_template.scss index 63acf168007b7..631511cd0475f 100644 --- a/src/plugins/kibana_react/public/page_template/page_template.scss +++ b/src/plugins/kibana_react/public/page_template/page_template.scss @@ -8,6 +8,6 @@ } &.kbnPageTemplate__pageSideBar--shrink { - min-width: $euiSizeXXL + $euiSize; + min-width: $euiSizeXXL; } } diff --git a/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav.scss b/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav.scss index 80442f548c037..e1854dbfe3c6d 100644 --- a/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav.scss +++ b/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav.scss @@ -1,6 +1,13 @@ $euiSideNavEmphasizedBackgroundColor: transparentize($euiColorLightShade, .7); +@import '@elastic/eui/src/components/side_nav/mixins'; + +// Put the page background color in the flyout version too +.kbnPageTemplateSolutionNav__flyout { + background-color: $euiPageBackgroundColor; +} .kbnPageTemplateSolutionNav { + @include euiSideNavEmbellish; @include euiYScroll; @include euiBreakpoint('m' ,'l', 'xl') { diff --git a/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav.tsx b/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav.tsx index bffaccda89c6a..2165cb1cc101b 100644 --- a/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav.tsx +++ b/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav.tsx @@ -41,11 +41,11 @@ export type KibanaPageTemplateSolutionNavProps = EuiSideNavProps<{}> & { onCollapse?: () => void; }; -const negativeTabIndex = (items: Array>) => { +const setTabIndex = (items: Array>, isHidden: boolean) => { return items.map((item) => { // @ts-ignore-next-line Can be removed on close of https://github.com/elastic/eui/issues/4925 - item.tabIndex = -1; - item.items = item.items && negativeTabIndex(item.items); + item.tabIndex = isHidden ? -1 : undefined; + item.items = item.items && setTabIndex(item.items, isHidden); return item; }); }; @@ -121,7 +121,7 @@ export const KibanaPageTemplateSolutionNav: FunctionComponent ); @@ -140,6 +140,7 @@ export const KibanaPageTemplateSolutionNav: FunctionComponent {sideNav} diff --git a/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav_collapse_button.scss b/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav_collapse_button.scss index 8748f72fa51d8..61cea7962d956 100644 --- a/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav_collapse_button.scss +++ b/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav_collapse_button.scss @@ -6,7 +6,7 @@ z-index: 2; @include euiCanAnimate { - transition: opacity $euiAnimSpeedFast, left $euiAnimSpeedFast; + transition: opacity $euiAnimSpeedFast, left $euiAnimSpeedFast, background $euiAnimSpeedFast; } &:hover, @@ -24,10 +24,24 @@ .kbnPageTemplate__pageSideBar:hover & { transition-delay: $euiAnimSpeedSlow * 2; } + + &:not(&-isCollapsed) { + background-color: $euiColorEmptyShade !important; // Override all states + } } +// Make the button take up the entire area of the collapsed navigation .kbnPageTemplateSolutionNavCollapseButton-isCollapsed { - left: $euiSizeM !important; opacity: 1 !important; transition-delay: 0s !important; + left: 0 !important; + right: 0; + top: 0; + bottom: 0; + height: 100%; + width: 100%; + border-radius: 0; + // Keep the icon at the top instead of it getting shifted to the center of the page + padding-top: $euiSizeL + $euiSizeS; + align-items: flex-start; } diff --git a/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav_collapse_button.tsx b/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav_collapse_button.tsx index 922fe54beaddd..65e36d781f821 100644 --- a/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav_collapse_button.tsx +++ b/src/plugins/kibana_react/public/page_template/solution_nav/solution_nav_collapse_button.tsx @@ -47,9 +47,9 @@ export const KibanaPageTemplateSolutionNavCollapseButton: FunctionComponent objValue(srcValue(state)); + return (state: SerializableRecord) => objValue(srcValue(state)); }; return mergeWith({ ...obj1 }, obj2, customizer); diff --git a/src/plugins/kibana_utils/common/persistable_state/migrate_to_latest.test.ts b/src/plugins/kibana_utils/common/persistable_state/migrate_to_latest.test.ts index 32fb652d41632..2a857b821aced 100644 --- a/src/plugins/kibana_utils/common/persistable_state/migrate_to_latest.test.ts +++ b/src/plugins/kibana_utils/common/persistable_state/migrate_to_latest.test.ts @@ -6,19 +6,20 @@ * Side Public License, v 1. */ -import { SerializableState, MigrateFunction } from './types'; +import { SerializableRecord } from '@kbn/utility-types'; +import { MigrateFunction } from './types'; import { migrateToLatest } from './migrate_to_latest'; -interface StateV1 extends SerializableState { +interface StateV1 extends SerializableRecord { name: string; } -interface StateV2 extends SerializableState { +interface StateV2 extends SerializableRecord { firstName: string; lastName: string; } -interface StateV3 extends SerializableState { +interface StateV3 extends SerializableRecord { firstName: string; lastName: string; isAdmin: boolean; diff --git a/src/plugins/kibana_utils/common/persistable_state/migrate_to_latest.ts b/src/plugins/kibana_utils/common/persistable_state/migrate_to_latest.ts index 6f81d0a7b9b63..9481e333819bd 100644 --- a/src/plugins/kibana_utils/common/persistable_state/migrate_to_latest.ts +++ b/src/plugins/kibana_utils/common/persistable_state/migrate_to_latest.ts @@ -7,9 +7,10 @@ */ import { compare } from 'semver'; -import { SerializableState, VersionedState, MigrateFunctionsObject } from './types'; +import { SerializableRecord } from '@kbn/utility-types'; +import { VersionedState, MigrateFunctionsObject } from './types'; -export function migrateToLatest( +export function migrateToLatest( migrations: MigrateFunctionsObject, { state, version: oldVersion }: VersionedState ): S { diff --git a/src/plugins/kibana_utils/common/persistable_state/types.ts b/src/plugins/kibana_utils/common/persistable_state/types.ts index a2d1751297a9f..6fea0a3a4eab6 100644 --- a/src/plugins/kibana_utils/common/persistable_state/types.ts +++ b/src/plugins/kibana_utils/common/persistable_state/types.ts @@ -6,18 +6,9 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { SavedObjectReference } from '../../../../core/types'; -/** - * Serializable state is something is a POJO JavaScript object that can be - * serialized to a JSON string. - */ -export type SerializableState = { - [key: string]: Serializable; -}; -export type SerializableValue = string | number | boolean | null | undefined | SerializableState; -export type Serializable = SerializableValue | SerializableValue[]; - /** * Versioned state is a POJO JavaScript object that can be serialized to JSON, * and which also contains the version information. The version is stored in @@ -35,7 +26,7 @@ export type Serializable = SerializableValue | SerializableValue[]; * }; * ``` */ -export interface VersionedState { +export interface VersionedState { version: string; state: S; } @@ -50,7 +41,7 @@ export interface VersionedState * * @todo Maybe rename it to `PersistableStateItem`? */ -export interface PersistableState

{ +export interface PersistableState

{ /** * Function which reports telemetry information. This function is essentially * a "reducer" - it receives the existing "stats" object and returns an @@ -101,8 +92,8 @@ export interface PersistableState

}; export type MigrateFunction< - FromVersion extends SerializableState = SerializableState, - ToVersion extends SerializableState = SerializableState + FromVersion extends SerializableRecord = SerializableRecord, + ToVersion extends SerializableRecord = SerializableRecord > = (state: FromVersion) => ToVersion; /** @@ -111,21 +102,21 @@ export type MigrateFunction< * @param version */ export type PersistableStateMigrateFn = ( - state: SerializableState, + state: SerializableRecord, version: string -) => SerializableState; +) => SerializableRecord; /** * @todo Shall we remove this? */ -export type PersistableStateDefinition

= Partial< +export type PersistableStateDefinition

= Partial< PersistableState

>; /** * @todo Add description. */ -export interface PersistableStateService

{ +export interface PersistableStateService

{ /** * Function which reports telemetry information. This function is essentially * a "reducer" - it receives the existing "stats" object and returns an diff --git a/src/plugins/kibana_utils/public/ui/configurable.ts b/src/plugins/kibana_utils/public/ui/configurable.ts index 70f91915771f8..cf02b9e977d16 100644 --- a/src/plugins/kibana_utils/public/ui/configurable.ts +++ b/src/plugins/kibana_utils/public/ui/configurable.ts @@ -6,14 +6,14 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { UiComponent } from '../../common/ui/ui_component'; -import { SerializableState } from '../../common'; /** * Represents something that can be configured by user using UI. */ export interface Configurable< - Config extends SerializableState = SerializableState, + Config extends SerializableRecord = SerializableRecord, Context = object > { /** @@ -36,7 +36,7 @@ export interface Configurable< * Props provided to `CollectConfig` component on every re-render. */ export interface CollectConfigProps< - Config extends SerializableState = SerializableState, + Config extends SerializableRecord = SerializableRecord, Context = object > { /** diff --git a/src/plugins/legacy_export/kibana.json b/src/plugins/legacy_export/kibana.json index f382cab1e655d..6c1b9ab5e9591 100644 --- a/src/plugins/legacy_export/kibana.json +++ b/src/plugins/legacy_export/kibana.json @@ -1,5 +1,9 @@ { "id": "legacyExport", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "kibana", "server": true, "ui": false diff --git a/src/plugins/management/common/locator.ts b/src/plugins/management/common/locator.ts index 7dbf5e2888011..f56b2885be092 100644 --- a/src/plugins/management/common/locator.ts +++ b/src/plugins/management/common/locator.ts @@ -6,13 +6,13 @@ * Side Public License, v 1. */ -import { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import { LocatorDefinition, LocatorPublic } from 'src/plugins/share/common'; import { MANAGEMENT_APP_ID } from './contants'; export const MANAGEMENT_APP_LOCATOR = 'MANAGEMENT_APP_LOCATOR'; -export interface ManagementAppLocatorParams extends SerializableState { +export interface ManagementAppLocatorParams extends SerializableRecord { sectionId: string; appId?: string; } diff --git a/src/plugins/newsfeed/kibana.json b/src/plugins/newsfeed/kibana.json index 0e7ae7cd11c35..004c35005950c 100644 --- a/src/plugins/newsfeed/kibana.json +++ b/src/plugins/newsfeed/kibana.json @@ -1,5 +1,9 @@ { "id": "newsfeed", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "kibana", "server": true, "ui": true, diff --git a/src/plugins/saved_objects/kibana.json b/src/plugins/saved_objects/kibana.json index 589aafbd2aaf5..27fd92a219d8d 100644 --- a/src/plugins/saved_objects/kibana.json +++ b/src/plugins/saved_objects/kibana.json @@ -1,5 +1,9 @@ { "id": "savedObjects", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "kibana", "server": true, "ui": true, diff --git a/src/plugins/saved_objects_management/kibana.json b/src/plugins/saved_objects_management/kibana.json index 6c6d11d053c0f..48e61eb9e4da5 100644 --- a/src/plugins/saved_objects_management/kibana.json +++ b/src/plugins/saved_objects_management/kibana.json @@ -1,5 +1,9 @@ { "id": "savedObjectsManagement", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "kibana", "server": true, "ui": true, diff --git a/src/plugins/saved_objects_tagging_oss/kibana.json b/src/plugins/saved_objects_tagging_oss/kibana.json index 90a0380883f7a..c7576014b3a89 100644 --- a/src/plugins/saved_objects_tagging_oss/kibana.json +++ b/src/plugins/saved_objects_tagging_oss/kibana.json @@ -1,5 +1,9 @@ { "id": "savedObjectsTaggingOss", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "kibana", "server": false, "ui": true, diff --git a/src/plugins/share/common/url_service/__tests__/setup.ts b/src/plugins/share/common/url_service/__tests__/setup.ts index fea3e1b945f99..1662b1f4a2d49 100644 --- a/src/plugins/share/common/url_service/__tests__/setup.ts +++ b/src/plugins/share/common/url_service/__tests__/setup.ts @@ -6,11 +6,11 @@ * Side Public License, v 1. */ -import type { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import { LocatorDefinition } from '../locators'; import { UrlService, UrlServiceDependencies } from '../url_service'; -export interface TestLocatorState extends SerializableState { +export interface TestLocatorState extends SerializableRecord { savedObjectId: string; showFlyout: boolean; pageNumber: number; diff --git a/src/plugins/share/common/url_service/locators/locator.ts b/src/plugins/share/common/url_service/locators/locator.ts index bae57b6d8a31d..a251e87702c7f 100644 --- a/src/plugins/share/common/url_service/locators/locator.ts +++ b/src/plugins/share/common/url_service/locators/locator.ts @@ -6,9 +6,10 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; import type { SavedObjectReference } from 'kibana/server'; import { DependencyList } from 'react'; -import type { PersistableState, SerializableState } from 'src/plugins/kibana_utils/common'; +import type { PersistableState } from 'src/plugins/kibana_utils/common'; import { useLocatorUrl } from './use_locator_url'; import type { LocatorDefinition, @@ -30,7 +31,7 @@ export interface LocatorDependencies { getUrl: (location: KibanaLocation, getUrlParams: LocatorGetUrlParams) => Promise; } -export class Locator

implements LocatorPublic

{ +export class Locator

implements LocatorPublic

{ public readonly migrations: PersistableState

['migrations']; constructor( diff --git a/src/plugins/share/common/url_service/locators/locator_client.ts b/src/plugins/share/common/url_service/locators/locator_client.ts index fc6b23f94a386..587083551aa6d 100644 --- a/src/plugins/share/common/url_service/locators/locator_client.ts +++ b/src/plugins/share/common/url_service/locators/locator_client.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import type { LocatorDependencies } from './locator'; import type { LocatorDefinition, LocatorPublic, ILocatorClient } from './types'; import { Locator } from './locator'; @@ -27,7 +27,7 @@ export class LocatorClient implements ILocatorClient { * @param definition A definition of URL locator. * @returns A public interface of URL locator. */ - public create

(definition: LocatorDefinition

): LocatorPublic

{ + public create

(definition: LocatorDefinition

): LocatorPublic

{ const locator = new Locator

(definition, this.deps); this.locators.set(definition.id, locator); @@ -41,7 +41,7 @@ export class LocatorClient implements ILocatorClient { * @param id ID of a URL locator. * @returns A public interface of a registered URL locator. */ - public get

(id: string): undefined | LocatorPublic

{ + public get

(id: string): undefined | LocatorPublic

{ return this.locators.get(id); } } diff --git a/src/plugins/share/common/url_service/locators/types.ts b/src/plugins/share/common/url_service/locators/types.ts index 0429d52a8f52d..ba9c6c9185d23 100644 --- a/src/plugins/share/common/url_service/locators/types.ts +++ b/src/plugins/share/common/url_service/locators/types.ts @@ -6,8 +6,9 @@ * Side Public License, v 1. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { DependencyList } from 'react'; -import { PersistableState, SerializableState } from 'src/plugins/kibana_utils/common'; +import { PersistableState } from 'src/plugins/kibana_utils/common'; /** * URL locator registry. @@ -18,20 +19,20 @@ export interface ILocatorClient { * * @param urlGenerator Definition of the new locator. */ - create

(locatorDefinition: LocatorDefinition

): LocatorPublic

; + create

(locatorDefinition: LocatorDefinition

): LocatorPublic

; /** * Retrieve a previously registered locator. * * @param id Unique ID of the locator. */ - get

(id: string): undefined | LocatorPublic

; + get

(id: string): undefined | LocatorPublic

; } /** * A convenience interface used to define and register a locator. */ -export interface LocatorDefinition

+export interface LocatorDefinition

extends Partial> { /** * Unique ID of the locator. Should be constant and unique across Kibana. @@ -50,7 +51,7 @@ export interface LocatorDefinition

/** * Public interface of a registered locator. */ -export interface LocatorPublic

extends PersistableState

{ +export interface LocatorPublic

extends PersistableState

{ /** * Returns a reference to a Kibana client-side location. * diff --git a/src/plugins/share/common/url_service/locators/use_locator_url.ts b/src/plugins/share/common/url_service/locators/use_locator_url.ts index a84c712e16248..a8fefc5010bcf 100644 --- a/src/plugins/share/common/url_service/locators/use_locator_url.ts +++ b/src/plugins/share/common/url_service/locators/use_locator_url.ts @@ -8,10 +8,10 @@ import { DependencyList, useEffect, useState } from 'react'; import useMountedState from 'react-use/lib/useMountedState'; -import { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import { LocatorGetUrlParams, LocatorPublic } from '../../../common/url_service'; -export const useLocatorUrl =

( +export const useLocatorUrl =

( locator: LocatorPublic

| null | undefined, params: P, getUrlParams?: LocatorGetUrlParams, diff --git a/src/plugins/share/public/mocks.ts b/src/plugins/share/public/mocks.ts index 7d21ef5c8fca0..3333878676e20 100644 --- a/src/plugins/share/public/mocks.ts +++ b/src/plugins/share/public/mocks.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { SerializableState } from 'src/plugins/kibana_utils/common'; +import { SerializableRecord } from '@kbn/utility-types'; import { SharePluginSetup, SharePluginStart } from '.'; import { LocatorPublic, UrlService } from '../common/url_service'; @@ -42,7 +42,7 @@ const createStartContract = (): Start => { return startContract; }; -const createLocator = (): jest.Mocked< +const createLocator = (): jest.Mocked< LocatorPublic > => ({ getLocation: jest.fn(), diff --git a/src/plugins/share/public/url_service/redirect/redirect_manager.ts b/src/plugins/share/public/url_service/redirect/redirect_manager.ts index ad99be43f678a..494fb623a48af 100644 --- a/src/plugins/share/public/url_service/redirect/redirect_manager.ts +++ b/src/plugins/share/public/url_service/redirect/redirect_manager.ts @@ -9,8 +9,8 @@ import type { CoreSetup } from 'src/core/public'; import { i18n } from '@kbn/i18n'; import { BehaviorSubject } from 'rxjs'; +import type { SerializableRecord } from '@kbn/utility-types'; import { migrateToLatest } from '../../../../kibana_utils/common'; -import type { SerializableState } from '../../../../kibana_utils/common'; import type { UrlService } from '../../../common/url_service'; import { render } from './render'; import { parseSearchParams } from './util/parse_search_params'; @@ -23,7 +23,7 @@ export interface RedirectOptions { version: string; /** Locator params. */ - params: unknown & SerializableState; + params: unknown & SerializableRecord; } export interface RedirectManagerDependencies { diff --git a/src/plugins/share/public/url_service/redirect/util/parse_search_params.ts b/src/plugins/share/public/url_service/redirect/util/parse_search_params.ts index a60c1d1b68a97..7745e6dad43b1 100644 --- a/src/plugins/share/public/url_service/redirect/util/parse_search_params.ts +++ b/src/plugins/share/public/url_service/redirect/util/parse_search_params.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import { i18n } from '@kbn/i18n'; import type { RedirectOptions } from '../redirect_manager'; @@ -63,7 +63,7 @@ export function parseSearchParams(urlSearch: string): RedirectOptions { throw new Error(message); } - let params: unknown & SerializableState; + let params: unknown & SerializableRecord; try { params = JSON.parse(paramsJson); } catch { diff --git a/src/plugins/telemetry/kibana.json b/src/plugins/telemetry/kibana.json index a9895ba2e5e9c..09cc6accb68f4 100644 --- a/src/plugins/telemetry/kibana.json +++ b/src/plugins/telemetry/kibana.json @@ -1,5 +1,9 @@ { "id": "telemetry", + "owner": { + "name": "Kibana Telemetry", + "githubTeam": "kibana-telemetry" + }, "version": "kibana", "server": true, "ui": true, diff --git a/src/plugins/telemetry_collection_manager/kibana.json b/src/plugins/telemetry_collection_manager/kibana.json index f4278265834a4..e435ceb37d46a 100644 --- a/src/plugins/telemetry_collection_manager/kibana.json +++ b/src/plugins/telemetry_collection_manager/kibana.json @@ -1,5 +1,9 @@ { "id": "telemetryCollectionManager", + "owner": { + "name": "Kibana Telemetry", + "githubTeam": "kibana-telemetry" + }, "version": "kibana", "server": true, "ui": false, diff --git a/src/plugins/telemetry_management_section/kibana.json b/src/plugins/telemetry_management_section/kibana.json index dbbc2fc4ac2a4..9fc2b75c28316 100644 --- a/src/plugins/telemetry_management_section/kibana.json +++ b/src/plugins/telemetry_management_section/kibana.json @@ -1,5 +1,9 @@ { "id": "telemetryManagementSection", + "owner": { + "name": "Kibana Telemetry", + "githubTeam": "kibana-telemetry" + }, "version": "kibana", "server": false, "ui": true, diff --git a/src/plugins/ui_actions/public/public.api.md b/src/plugins/ui_actions/public/public.api.md index f8c473a3e2c0a..8e4e61d4cafc7 100644 --- a/src/plugins/ui_actions/public/public.api.md +++ b/src/plugins/ui_actions/public/public.api.md @@ -13,6 +13,7 @@ import { Plugin } from 'src/core/public'; import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/public'; import { PublicMethodsOf } from '@kbn/utility-types'; import React from 'react'; +import { SerializableRecord } from '@kbn/utility-types'; import { UiComponent } from 'src/plugins/kibana_utils/public'; // Warning: (ae-missing-release-tag) "Action" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/src/plugins/usage_collection/kibana.json b/src/plugins/usage_collection/kibana.json index 6ef78018c7d7f..de7c28ef90557 100644 --- a/src/plugins/usage_collection/kibana.json +++ b/src/plugins/usage_collection/kibana.json @@ -1,5 +1,9 @@ { "id": "usageCollection", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "configPath": ["usageCollection"], "version": "kibana", "server": true, diff --git a/src/plugins/vis_type_timelion/common/vis_data.ts b/src/plugins/vis_type_timelion/common/vis_data.ts index e3041f43a8f19..bab6198be603e 100644 --- a/src/plugins/vis_type_timelion/common/vis_data.ts +++ b/src/plugins/vis_type_timelion/common/vis_data.ts @@ -30,4 +30,5 @@ export interface VisSeries { color?: string; data: Array>; stack: boolean; + _hide?: boolean; } diff --git a/src/plugins/vis_type_timelion/public/components/series/area.tsx b/src/plugins/vis_type_timelion/public/components/series/area.tsx index 589a488d3acad..73e16d97684d5 100644 --- a/src/plugins/vis_type_timelion/public/components/series/area.tsx +++ b/src/plugins/vis_type_timelion/public/components/series/area.tsx @@ -6,6 +6,8 @@ * Side Public License, v 1. */ +// @ts-ignore +import chroma from 'chroma-js'; import React from 'react'; import { AreaSeries, ScaleType, CurveType, AreaSeriesStyle, PointShape } from '@elastic/charts'; import type { VisSeries } from '../../../common/vis_data'; @@ -19,6 +21,16 @@ interface AreaSeriesComponentProps { const isShowLines = (lines: VisSeries['lines'], points: VisSeries['points']) => lines?.show ? true : points?.show ? false : true; +const getPointFillColor = (points: VisSeries['points'], color: string | undefined) => { + const pointFillColor = points?.fillColor || points?.fill === undefined ? 'white' : color; + return ( + pointFillColor && + chroma(pointFillColor) + .alpha(points?.fill ?? 1) + .css() + ); +}; + const getAreaSeriesStyle = ({ color, lines, points }: AreaSeriesComponentProps['visData']) => ({ line: { @@ -33,8 +45,8 @@ const getAreaSeriesStyle = ({ color, lines, points }: AreaSeriesComponentProps[' visible: lines?.show ?? points?.show ?? true, }, point: { - fill: points?.fillColor ?? color, - opacity: points?.lineWidth !== undefined ? (points.fill || 1) * 10 : 10, + fill: getPointFillColor(points, color), + opacity: 1, radius: points?.radius ?? 3, stroke: color, strokeWidth: points?.lineWidth ?? 2, @@ -53,7 +65,7 @@ export const AreaSeriesComponent = ({ index, groupId, visData }: AreaSeriesCompo yScaleType={ScaleType.Linear} xAccessor={0} yAccessors={[1]} - data={visData.data} + data={visData._hide ? [] : visData.data} sortIndex={index} color={visData.color} stackAccessors={visData.stack ? [0] : undefined} diff --git a/src/plugins/vis_type_timelion/public/components/series/bar.tsx b/src/plugins/vis_type_timelion/public/components/series/bar.tsx index 6a97c8fea9690..0a26fb51c32c6 100644 --- a/src/plugins/vis_type_timelion/public/components/series/bar.tsx +++ b/src/plugins/vis_type_timelion/public/components/series/bar.tsx @@ -27,14 +27,12 @@ const getBarSeriesStyle = ({ color, bars }: BarSeriesComponentProps['visData']) return { rectBorder: { - stroke: color, - strokeWidth: Math.max(1, bars.lineWidth ? Math.ceil(bars.lineWidth / 2) : 1), - visible: true, + visible: false, }, rect: { fill: color, opacity, - widthPixel: 1, + widthPixel: Math.max(1, bars.lineWidth ?? 1), }, } as BarSeriesStyle; }; @@ -48,7 +46,7 @@ export const BarSeriesComponent = ({ index, groupId, visData }: BarSeriesCompone yScaleType={ScaleType.Linear} xAccessor={0} yAccessors={[1]} - data={visData.data} + data={visData._hide ? [] : visData.data} sortIndex={index} enableHistogramMode={false} color={visData.color} diff --git a/src/plugins/vis_type_timeseries/public/request_handler.ts b/src/plugins/vis_type_timeseries/public/request_handler.ts index 66dbdaaabcddb..0a110dd65d5e9 100644 --- a/src/plugins/vis_type_timeseries/public/request_handler.ts +++ b/src/plugins/vis_type_timeseries/public/request_handler.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { IExecutionContextContainer } from 'src/core/public'; +import type { KibanaExecutionContext } from 'src/core/public'; import { getTimezone } from './application/lib/get_timezone'; import { getUISettings, getDataStart, getCoreStart } from './services'; import { ROUTES } from '../common/constants'; @@ -19,7 +19,7 @@ interface MetricsRequestHandlerParams { uiState: Record; visParams: TimeseriesVisParams; searchSessionId?: string; - executionContext?: IExecutionContextContainer; + executionContext?: KibanaExecutionContext; } export const metricsRequestHandler = async ({ diff --git a/src/plugins/vis_type_vega/public/data_model/search_api.test.ts b/src/plugins/vis_type_vega/public/data_model/search_api.test.ts new file mode 100644 index 0000000000000..d0739453e43ec --- /dev/null +++ b/src/plugins/vis_type_vega/public/data_model/search_api.test.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { extendSearchParamsWithRuntimeFields } from './search_api'; +import { dataPluginMock } from '../../../data/public/mocks'; + +import { getSearchParamsFromRequest, DataPublicPluginStart } from '../../../data/public'; + +const mockComputedFields = ( + dataStart: DataPublicPluginStart, + index: string, + runtimeFields: Record +) => { + dataStart.indexPatterns.find = jest.fn().mockReturnValue([ + { + title: index, + getComputedFields: () => ({ + runtimeFields, + }), + }, + ]); +}; + +describe('extendSearchParamsWithRuntimeFields', () => { + let dataStart: DataPublicPluginStart; + + beforeEach(() => { + dataStart = dataPluginMock.createStartContract(); + }); + + test('should inject default runtime_mappings for known indexes', async () => { + const requestParams = {}; + const runtimeFields = { foo: {} }; + + mockComputedFields(dataStart, 'index', runtimeFields); + + expect( + await extendSearchParamsWithRuntimeFields(dataStart.indexPatterns, requestParams, 'index') + ).toMatchInlineSnapshot(` + Object { + "body": Object { + "runtime_mappings": Object { + "foo": Object {}, + }, + }, + } + `); + }); + + test('should use runtime mappings from spec if it is specified', async () => { + const requestParams = ({ + body: { + runtime_mappings: { + test: {}, + }, + }, + } as unknown) as ReturnType; + const runtimeFields = { foo: {} }; + + mockComputedFields(dataStart, 'index', runtimeFields); + + expect( + await extendSearchParamsWithRuntimeFields(dataStart.indexPatterns, requestParams, 'index') + ).toMatchInlineSnapshot(` + Object { + "body": Object { + "runtime_mappings": Object { + "test": Object {}, + }, + }, + } + `); + }); +}); diff --git a/src/plugins/vis_type_vega/public/data_model/search_api.ts b/src/plugins/vis_type_vega/public/data_model/search_api.ts index c6aba6eccdc9f..7a468b7bfce18 100644 --- a/src/plugins/vis_type_vega/public/data_model/search_api.ts +++ b/src/plugins/vis_type_vega/public/data_model/search_api.ts @@ -8,8 +8,7 @@ import { combineLatest, from } from 'rxjs'; import { map, tap, switchMap } from 'rxjs/operators'; -import { CoreStart, IUiSettingsClient } from 'kibana/public'; -import { getData } from '../services'; +import type { CoreStart, IUiSettingsClient } from 'kibana/public'; import { getSearchParamsFromRequest, SearchRequest, @@ -17,22 +16,28 @@ import { IEsSearchResponse, } from '../../../data/public'; import { search as dataPluginSearch } from '../../../data/public'; -import { VegaInspectorAdapters } from '../vega_inspector'; -import { RequestResponder } from '../../../inspector/public'; +import type { VegaInspectorAdapters } from '../vega_inspector'; +import type { RequestResponder } from '../../../inspector/public'; -const extendSearchParamsWithRuntimeFields = async ( +/** @internal **/ +export const extendSearchParamsWithRuntimeFields = async ( + indexPatterns: SearchAPIDependencies['indexPatterns'], requestParams: ReturnType, indexPatternString?: string ) => { if (indexPatternString) { - const indexPattern = (await getData().indexPatterns.find(indexPatternString)).find( - (index) => index.title === indexPatternString - ); - const runtimeFields = indexPattern?.getComputedFields().runtimeFields; + let runtimeMappings = requestParams.body?.runtime_mappings; + + if (!runtimeMappings) { + const indexPattern = (await indexPatterns.find(indexPatternString)).find( + (index) => index.title === indexPatternString + ); + runtimeMappings = indexPattern?.getComputedFields().runtimeFields; + } return { ...requestParams, - body: { ...requestParams.body, runtime_mappings: runtimeFields }, + body: { ...requestParams.body, runtime_mappings: runtimeMappings }, }; } @@ -43,6 +48,7 @@ export interface SearchAPIDependencies { uiSettings: IUiSettingsClient; injectedMetadata: CoreStart['injectedMetadata']; search: DataPublicPluginStart['search']; + indexPatterns: DataPublicPluginStart['indexPatterns']; } export class SearchAPI { @@ -54,7 +60,7 @@ export class SearchAPI { ) {} search(searchRequests: SearchRequest[]) { - const { search } = this.dependencies; + const { search, indexPatterns } = this.dependencies; const requestResponders: any = {}; return combineLatest( @@ -64,15 +70,19 @@ export class SearchAPI { getConfig: this.dependencies.uiSettings.get.bind(this.dependencies.uiSettings), }); - if (this.inspectorAdapters) { - requestResponders[requestId] = this.inspectorAdapters.requests.start(requestId, { - ...request, - searchSessionId: this.searchSessionId, - }); - requestResponders[requestId].json(requestParams.body); - } - - return from(extendSearchParamsWithRuntimeFields(requestParams, request.index)).pipe( + return from( + extendSearchParamsWithRuntimeFields(indexPatterns, requestParams, request.index) + ).pipe( + tap((params) => { + /** inspect request data **/ + if (this.inspectorAdapters) { + requestResponders[requestId] = this.inspectorAdapters.requests.start(requestId, { + ...request, + searchSessionId: this.searchSessionId, + }); + requestResponders[requestId].json(params.body); + } + }), switchMap((params) => search .search( diff --git a/src/plugins/vis_type_vega/public/vega_request_handler.ts b/src/plugins/vis_type_vega/public/vega_request_handler.ts index eba5f9a40c9d9..4c523714a2530 100644 --- a/src/plugins/vis_type_vega/public/vega_request_handler.ts +++ b/src/plugins/vis_type_vega/public/vega_request_handler.ts @@ -45,10 +45,13 @@ export function createVegaRequestHandler( searchSessionId, }: VegaRequestHandlerParams) { if (!searchAPI) { + const { search, indexPatterns } = getData(); + searchAPI = new SearchAPI( { uiSettings, - search: getData().search, + search, + indexPatterns, injectedMetadata: getInjectedMetadata(), }, context.abortSignal, diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_map_view/view.test.ts b/src/plugins/vis_type_vega/public/vega_view/vega_map_view/view.test.ts index ee3bf305e9427..17a098649ebbf 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_map_view/view.test.ts +++ b/src/plugins/vis_type_vega/public/vega_view/vega_map_view/view.test.ts @@ -129,6 +129,7 @@ describe('vega_map_view/view', () => { JSON.stringify(vegaMap), new SearchAPI({ search: dataPluginStart.search, + indexPatterns: dataPluginStart.indexPatterns, uiSettings: coreStart.uiSettings, injectedMetadata: coreStart.injectedMetadata, }), diff --git a/src/plugins/vis_type_vega/public/vega_visualization.test.js b/src/plugins/vis_type_vega/public/vega_visualization.test.js index 776f8898b3e3a..ba1121b8894e0 100644 --- a/src/plugins/vis_type_vega/public/vega_visualization.test.js +++ b/src/plugins/vis_type_vega/public/vega_visualization.test.js @@ -92,6 +92,7 @@ describe('VegaVisualizations', () => { JSON.stringify(vegaliteGraph), new SearchAPI({ search: dataPluginStart.search, + indexPatterns: dataPluginStart.indexPatterns, uiSettings: coreStart.uiSettings, injectedMetadata: coreStart.injectedMetadata, }), @@ -123,6 +124,7 @@ describe('VegaVisualizations', () => { JSON.stringify(vegaGraph), new SearchAPI({ search: dataPluginStart.search, + indexPatterns: dataPluginStart.indexPatterns, uiSettings: coreStart.uiSettings, injectedMetadata: coreStart.injectedMetadata, }), diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts index d7ea04daae1ae..b71542a8beeea 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -384,6 +384,15 @@ export class VisualizeEmbeddable }; private async updateHandler() { + const context = { + type: 'visualization', + name: this.vis.type.title, + id: this.vis.id ?? 'an_unsaved_vis', + description: this.vis.title || this.input.title || this.vis.type.name, + url: this.output.editUrl, + parent: this.parent?.getInput().executionContext, + }; + const expressionParams: IExpressionLoaderParams = { searchContext: { timeRange: this.timeRange, @@ -394,13 +403,7 @@ export class VisualizeEmbeddable syncColors: this.input.syncColors, uiState: this.vis.uiState, inspectorAdapters: this.inspectorAdapters, - executionContext: this.deps.start().core.executionContext.create({ - type: 'visualization', - name: this.vis.type.name, - id: this.vis.id ?? 'an_unsaved_vis', - description: this.vis.title ?? this.vis.type.title, - url: this.output.editUrl, - }), + executionContext: context, }; if (this.abortController) { this.abortController.abort(); diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx index fd22489eb7556..872132416352f 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx @@ -59,10 +59,7 @@ interface VisualizationAttributes extends SavedObjectAttributes { export interface VisualizeEmbeddableFactoryDeps { start: StartServicesGetter< - Pick< - VisualizationsStartDeps, - 'inspector' | 'embeddable' | 'savedObjectsClient' | 'executionContext' - > + Pick >; } diff --git a/src/plugins/visualizations/public/mocks.ts b/src/plugins/visualizations/public/mocks.ts index 97800ef40e8ad..901593626a945 100644 --- a/src/plugins/visualizations/public/mocks.ts +++ b/src/plugins/visualizations/public/mocks.ts @@ -64,7 +64,6 @@ const createInstance = async () => { getAttributeService: jest.fn(), savedObjectsClient: coreMock.createStart().savedObjects.client, savedObjects: savedObjectsPluginMock.createStartContract(), - executionContext: coreMock.createStart().executionContext, }); return { diff --git a/src/plugins/visualizations/public/plugin.ts b/src/plugins/visualizations/public/plugin.ts index f5b2f0edd044e..ae97080b31fc5 100644 --- a/src/plugins/visualizations/public/plugin.ts +++ b/src/plugins/visualizations/public/plugin.ts @@ -54,7 +54,6 @@ import type { Plugin, ApplicationStart, SavedObjectsClientContract, - ExecutionContextServiceStart, } from '../../../core/public'; import type { UsageCollectionSetup } from '../../usage_collection/public'; import type { UiActionsStart } from '../../ui_actions/public'; @@ -104,7 +103,6 @@ export interface VisualizationsStartDeps { getAttributeService: EmbeddableStart['getAttributeService']; savedObjects: SavedObjectsStart; savedObjectsClient: SavedObjectsClientContract; - executionContext: ExecutionContextServiceStart; } /** diff --git a/src/plugins/visualizations/server/embeddable/visualize_embeddable_factory.ts b/src/plugins/visualizations/server/embeddable/visualize_embeddable_factory.ts index 0f549584af672..043f6195cf7b4 100644 --- a/src/plugins/visualizations/server/embeddable/visualize_embeddable_factory.ts +++ b/src/plugins/visualizations/server/embeddable/visualize_embeddable_factory.ts @@ -8,7 +8,7 @@ import { flow } from 'lodash'; import { EmbeddableRegistryDefinition } from 'src/plugins/embeddable/server'; -import { SerializableState } from '../../../kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import { commonAddSupportOfDualIndexSelectionModeInTSVB, commonHideTSVBLastValueIndicator, @@ -18,42 +18,42 @@ import { commonMigrateTagCloud, } from '../migrations/visualization_common_migrations'; -const byValueAddSupportOfDualIndexSelectionModeInTSVB = (state: SerializableState) => { +const byValueAddSupportOfDualIndexSelectionModeInTSVB = (state: SerializableRecord) => { return { ...state, savedVis: commonAddSupportOfDualIndexSelectionModeInTSVB(state.savedVis), }; }; -const byValueHideTSVBLastValueIndicator = (state: SerializableState) => { +const byValueHideTSVBLastValueIndicator = (state: SerializableRecord) => { return { ...state, savedVis: commonHideTSVBLastValueIndicator(state.savedVis), }; }; -const byValueRemoveDefaultIndexPatternAndTimeFieldFromTSVBModel = (state: SerializableState) => { +const byValueRemoveDefaultIndexPatternAndTimeFieldFromTSVBModel = (state: SerializableRecord) => { return { ...state, savedVis: commonRemoveDefaultIndexPatternAndTimeFieldFromTSVBModel(state.savedVis), }; }; -const byValueAddEmptyValueColorRule = (state: SerializableState) => { +const byValueAddEmptyValueColorRule = (state: SerializableRecord) => { return { ...state, savedVis: commonAddEmptyValueColorRule(state.savedVis), }; }; -const byValueMigrateVislibPie = (state: SerializableState) => { +const byValueMigrateVislibPie = (state: SerializableRecord) => { return { ...state, savedVis: commonMigrateVislibPie(state.savedVis), }; }; -const byValueMigrateTagcloud = (state: SerializableState) => { +const byValueMigrateTagcloud = (state: SerializableRecord) => { return { ...state, savedVis: commonMigrateTagCloud(state.savedVis), diff --git a/test/api_integration/apis/suggestions/suggestions.js b/test/api_integration/apis/suggestions/suggestions.js index ca43641d881cd..ea8da57eda065 100644 --- a/test/api_integration/apis/suggestions/suggestions.js +++ b/test/api_integration/apis/suggestions/suggestions.js @@ -5,6 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ +import expect from '@kbn/expect'; export default function ({ getService }) { const esArchiver = getService('esArchiver'); @@ -12,46 +13,227 @@ export default function ({ getService }) { const supertest = getService('supertest'); describe('Suggestions API', function () { - before(async () => { - await esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index'); - await kibanaServer.importExport.load( - 'test/api_integration/fixtures/kbn_archiver/index_patterns/basic_kibana.json' - ); - }); - after(async () => { - await esArchiver.unload( - 'test/api_integration/fixtures/es_archiver/index_patterns/basic_index' - ); - await kibanaServer.importExport.unload( - 'test/api_integration/fixtures/kbn_archiver/index_patterns/basic_kibana.json' - ); + describe('non time based', () => { + before(async () => { + await esArchiver.load( + 'test/api_integration/fixtures/es_archiver/index_patterns/basic_index' + ); + await kibanaServer.importExport.load( + 'test/api_integration/fixtures/kbn_archiver/index_patterns/basic_kibana.json' + ); + }); + after(async () => { + await esArchiver.unload( + 'test/api_integration/fixtures/es_archiver/index_patterns/basic_index' + ); + await kibanaServer.importExport.unload( + 'test/api_integration/fixtures/kbn_archiver/index_patterns/basic_kibana.json' + ); + }); + it('should return 200 without a query', () => + supertest + .post('/api/kibana/suggestions/values/basic_index') + .send({ + field: 'baz.keyword', + query: '', + }) + .expect(200) + .then(({ body }) => { + expect(body).to.have.length(1); + expect(body).to.contain('hello'); + })); + + it('should return 200 without a query and with method set to terms_agg', () => + supertest + .post('/api/kibana/suggestions/values/basic_index') + .send({ + field: 'baz.keyword', + method: 'terms_agg', + query: '', + }) + .expect(200) + .then(({ body }) => { + expect(body).to.have.length(1); + expect(body).to.contain('hello'); + })); + + it('should return 200 without a query and with method set to terms_enum', () => + supertest + .post('/api/kibana/suggestions/values/basic_index') + .send({ + field: 'baz.keyword', + method: 'terms_enum', + query: '', + }) + .expect(200) + .then(({ body }) => { + expect(body).to.have.length(1); + expect(body).to.contain('hello'); + })); + + it('should return 200 with special characters', () => + supertest + .post('/api/kibana/suggestions/values/basic_index') + .send({ + field: 'baz.keyword', + query: ' { + expect(body).to.be.empty(); + })); + + it('should support nested fields', () => + supertest + .post('/api/kibana/suggestions/values/basic_index') + .send({ + field: 'nestedField.child', + query: 'nes', + }) + .expect(200, ['nestedValue'])); + + it('should return 404 if index is not found', () => + supertest + .post('/api/kibana/suggestions/values/not_found') + .send({ + field: 'baz.keyword', + query: '1', + }) + .expect(404)); + + it('should return 400 without a query', () => + supertest + .post('/api/kibana/suggestions/values/basic_index') + .send({ + field: 'baz.keyword', + }) + .expect(400)); + + it('should return 400 with a bad method', () => + supertest + .post('/api/kibana/suggestions/values/basic_index') + .send({ + field: 'baz.keyword', + query: '', + method: 'cookie', + }) + .expect(400)); }); - it('should return 200 with special characters', () => - supertest - .post('/api/kibana/suggestions/values/basic_index') - .send({ - field: 'baz.keyword', - query: ' - supertest - .post('/api/kibana/suggestions/values/basic_index') - .send({ - field: 'nestedField.child', - query: 'nes', - }) - .expect(200, ['nestedValue'])); - - it('should return 404 if index is not found', () => - supertest - .post('/api/kibana/suggestions/values/not_found') - .send({ - field: 'baz.keyword', - query: '1', - }) - .expect(404)); + describe('time based', () => { + before(async () => { + await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); + await kibanaServer.importExport.load( + 'test/api_integration/fixtures/kbn_archiver/saved_objects/basic.json' + ); + }); + + after(async () => { + await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional'); + + await kibanaServer.importExport.unload( + 'test/api_integration/fixtures/kbn_archiver/saved_objects/basic.json' + ); + }); + + it('filter is applied on a document level with terms_agg', () => + supertest + .post('/api/kibana/suggestions/values/logstash-*') + .send({ + field: 'extension.raw', + query: '', + method: 'terms_agg', + filters: [ + { + range: { + '@timestamp': { + gte: '2015-09-19T23:43:00.000Z', + lte: '2015-09-20T00:25:00.000Z', + format: 'strict_date_optional_time', + }, + }, + }, + ], + }) + .expect(200) + .then(({ body }) => { + expect(body).to.have.length(1); + expect(body).to.contain('jpg'); + })); + + it('filter returns all results because it was applied on an index level with terms_enum', () => + supertest + .post('/api/kibana/suggestions/values/logstash-*') + .send({ + field: 'extension.raw', + query: '', + method: 'terms_enum', + filters: [ + { + range: { + '@timestamp': { + gte: '2015-09-19T23:43:00.000Z', + lte: '2015-09-20T00:25:00.000Z', + format: 'strict_date_optional_time', + }, + }, + }, + ], + }) + .expect(200) + .then(({ body }) => { + // All indices have + expect(body).to.have.length(5); + })); + + it('filter is applied on an index level with terms_enum - find in range', () => + supertest + .post('/api/kibana/suggestions/values/logstash-*') + .send({ + field: 'request.raw', + query: '/uploads/anatoly-art', + method: 'terms_enum', + filters: [ + { + range: { + '@timestamp': { + gte: '2015-09-22T00:00:00.000Z', + lte: '2015-09-23T00:00:00.000Z', + format: 'strict_date_optional_time', + }, + }, + }, + ], + }) + .expect(200) + .then(({ body }) => { + expect(body).to.have.length(2); + })); + + it('filter is applied on an index level with terms_enum - DONT find in range', () => { + supertest + .post('/api/kibana/suggestions/values/logstash-*') + .send({ + field: 'request.raw', + query: '/uploads/anatoly-art', + method: 'terms_enum', + filters: [ + { + range: { + '@timestamp': { + gte: '2015-09-23T00:00:00.000Z', + lte: '2015-09-24T00:00:00.000Z', + format: 'strict_date_optional_time', + }, + }, + }, + ], + }) + .expect(200) + .then(({ body }) => { + expect(body).to.have.length(0); + }); + }); + }); }); } diff --git a/test/common/services/index.ts b/test/common/services/index.ts index 370d289093517..c04bd778468a9 100644 --- a/test/common/services/index.ts +++ b/test/common/services/index.ts @@ -15,6 +15,7 @@ import { RandomnessService } from './randomness'; import { SecurityServiceProvider } from './security'; import { EsDeleteAllIndicesProvider } from './es_delete_all_indices'; import { SavedObjectInfoService } from './saved_object_info'; +import { IndexPatternsService } from './index_patterns'; export const services = { deployment: DeploymentService, @@ -26,4 +27,5 @@ export const services = { security: SecurityServiceProvider, esDeleteAllIndices: EsDeleteAllIndicesProvider, savedObjectInfo: SavedObjectInfoService, + indexPatterns: IndexPatternsService, }; diff --git a/test/common/services/index_patterns.ts b/test/common/services/index_patterns.ts new file mode 100644 index 0000000000000..5b6d20990b6d1 --- /dev/null +++ b/test/common/services/index_patterns.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { FtrService } from '../ftr_provider_context'; +import { IndexPatternSpec } from '../../../src/plugins/data/common'; + +export class IndexPatternsService extends FtrService { + private readonly kibanaServer = this.ctx.getService('kibanaServer'); + + /** + * Create a new index pattern + */ + async create( + indexPattern: { title: string }, + { override = false }: { override: boolean } = { override: false } + ): Promise { + const response = await this.kibanaServer.request<{ + index_pattern: IndexPatternSpec; + }>({ + path: '/api/index_patterns/index_pattern', + method: 'POST', + body: { + override, + index_pattern: indexPattern, + }, + }); + + return response.data.index_pattern; + } +} diff --git a/test/examples/hello_world/index.ts b/test/examples/hello_world/index.ts new file mode 100644 index 0000000000000..d1a37968a9a6c --- /dev/null +++ b/test/examples/hello_world/index.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from 'test/functional/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function ({ getService, getPageObjects, loadTestFile }: FtrProviderContext) { + const retry = getService('retry'); + const testSubjects = getService('testSubjects'); + const PageObjects = getPageObjects(['common']); + + describe('Hello world', function () { + before(async () => { + this.tags('ciGroup2'); + await PageObjects.common.navigateToApp('helloWorld'); + }); + + it('renders hello world text', async () => { + await retry.try(async () => { + const message = await testSubjects.getVisibleText('helloWorldDiv'); + expect(message).to.be('Hello World!'); + }); + }); + }); +} diff --git a/test/functional/apps/management/_field_formatter.js b/test/functional/apps/management/_field_formatter.js deleted file mode 100644 index 383b4faecc40c..0000000000000 --- a/test/functional/apps/management/_field_formatter.js +++ /dev/null @@ -1,53 +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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -export default function ({ getService, getPageObjects }) { - const esArchiver = getService('esArchiver'); - const kibanaServer = getService('kibanaServer'); - const browser = getService('browser'); - const PageObjects = getPageObjects(['settings']); - const testSubjects = getService('testSubjects'); - - describe('field formatter', function () { - this.tags(['skipFirefox']); - - before(async function () { - await browser.setWindowSize(1200, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/discover'); - await kibanaServer.uiSettings.replace({}); - await kibanaServer.uiSettings.update({}); - }); - - after(async function afterAll() { - await PageObjects.settings.navigateTo(); - await esArchiver.emptyKibanaIndex(); - }); - - describe('set and change field formatter', function describeIndexTests() { - // addresses https://github.com/elastic/kibana/issues/93349 - it('can change format more than once', async function () { - await PageObjects.settings.navigateTo(); - await PageObjects.settings.clickKibanaIndexPatterns(); - await PageObjects.settings.clickIndexPatternLogstash(); - await PageObjects.settings.clickAddField(); - await PageObjects.settings.setFieldType('Long'); - const formatRow = await testSubjects.find('formatRow'); - const formatRowToggle = ( - await formatRow.findAllByCssSelector('[data-test-subj="toggle"]') - )[0]; - - await formatRowToggle.click(); - await PageObjects.settings.setFieldFormat('duration'); - await PageObjects.settings.setFieldFormat('bytes'); - await PageObjects.settings.setFieldFormat('duration'); - await testSubjects.click('euiFlyoutCloseButton'); - await PageObjects.settings.closeIndexPatternFieldEditor(); - }); - }); - }); -} diff --git a/test/functional/apps/management/_field_formatter.ts b/test/functional/apps/management/_field_formatter.ts new file mode 100644 index 0000000000000..60c1bbe7b3d1d --- /dev/null +++ b/test/functional/apps/management/_field_formatter.ts @@ -0,0 +1,571 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { ES_FIELD_TYPES } from '@kbn/field-types'; +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { FIELD_FORMAT_IDS } from '../../../../src/plugins/field_formats/common'; +import { WebElementWrapper } from '../../services/lib/web_element_wrapper'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); + const browser = getService('browser'); + const PageObjects = getPageObjects(['settings', 'common']); + const testSubjects = getService('testSubjects'); + const es = getService('es'); + const indexPatterns = getService('indexPatterns'); + const toasts = getService('toasts'); + + describe('field formatter', function () { + this.tags(['skipFirefox']); + + before(async function () { + await browser.setWindowSize(1200, 800); + await esArchiver.load('test/functional/fixtures/es_archiver/discover'); + await kibanaServer.uiSettings.replace({}); + await kibanaServer.uiSettings.update({}); + }); + + after(async function afterAll() { + await PageObjects.settings.navigateTo(); + await esArchiver.emptyKibanaIndex(); + }); + + describe('set and change field formatter', function describeIndexTests() { + // addresses https://github.com/elastic/kibana/issues/93349 + it('can change format more than once', async function () { + await PageObjects.settings.navigateTo(); + await PageObjects.settings.clickKibanaIndexPatterns(); + await PageObjects.settings.clickIndexPatternLogstash(); + await PageObjects.settings.clickAddField(); + await PageObjects.settings.setFieldType('Long'); + const formatRow = await testSubjects.find('formatRow'); + const formatRowToggle = ( + await formatRow.findAllByCssSelector('[data-test-subj="toggle"]') + )[0]; + + await formatRowToggle.click(); + await PageObjects.settings.setFieldFormat('duration'); + await PageObjects.settings.setFieldFormat('bytes'); + await PageObjects.settings.setFieldFormat('duration'); + await testSubjects.click('euiFlyoutCloseButton'); + await PageObjects.settings.closeIndexPatternFieldEditor(); + }); + }); + + /** + * The purpose of these tests is to cover **editing experience** of different field formats editors, + * The logic of each converter is extensively covered by unit tests. + * TODO: these tests also could check field formats behaviour with different combinations of browser locale, timezone and ui settings + */ + describe('field format editors', () => { + describe('String format', () => { + testFormatEditors([ + { + fieldType: ES_FIELD_TYPES.TEXT, + fieldValue: 'A regular text', + applyFormatterType: FIELD_FORMAT_IDS.STRING, + expectFormattedValue: 'A regular text', + + // check available formats for ES_FIELD_TYPES.TEXT + expectFormatterTypes: [ + FIELD_FORMAT_IDS.BOOLEAN, + FIELD_FORMAT_IDS.COLOR, + FIELD_FORMAT_IDS.STATIC_LOOKUP, + FIELD_FORMAT_IDS.STRING, + FIELD_FORMAT_IDS.TRUNCATE, + FIELD_FORMAT_IDS.URL, + ], + }, + { + fieldType: ES_FIELD_TYPES.TEXT, + fieldValue: 'A regular text', + applyFormatterType: FIELD_FORMAT_IDS.STRING, + expectFormattedValue: 'a regular text', + beforeSave: async () => { + await testSubjects.selectValue('stringEditorTransform', 'lower'); + }, + }, + { + fieldType: ES_FIELD_TYPES.KEYWORD, + fieldValue: 'a keyword', + applyFormatterType: FIELD_FORMAT_IDS.STRING, + expectFormattedValue: 'A KEYWORD', + beforeSave: async () => { + await testSubjects.selectValue('stringEditorTransform', 'upper'); + }, + // check available formats for ES_FIELD_TYPES.KEYWORD + expectFormatterTypes: [ + FIELD_FORMAT_IDS.BOOLEAN, + FIELD_FORMAT_IDS.COLOR, + FIELD_FORMAT_IDS.STATIC_LOOKUP, + FIELD_FORMAT_IDS.STRING, + FIELD_FORMAT_IDS.TRUNCATE, + FIELD_FORMAT_IDS.URL, + ], + }, + { + fieldType: ES_FIELD_TYPES.KEYWORD, + fieldValue: 'a keyword', + applyFormatterType: FIELD_FORMAT_IDS.STRING, + expectFormattedValue: 'A Keyword', + beforeSave: async () => { + await testSubjects.selectValue('stringEditorTransform', 'title'); + }, + }, + { + fieldType: ES_FIELD_TYPES.KEYWORD, + fieldValue: 'com.organizations.project.ClassName', + applyFormatterType: FIELD_FORMAT_IDS.STRING, + expectFormattedValue: 'c.o.p.ClassName', + beforeSave: async () => { + await testSubjects.selectValue('stringEditorTransform', 'short'); + }, + }, + { + fieldType: ES_FIELD_TYPES.KEYWORD, + fieldValue: 'SGVsbG8gd29ybGQ=', + applyFormatterType: FIELD_FORMAT_IDS.STRING, + expectFormattedValue: 'Hello world', + beforeSave: async () => { + await testSubjects.selectValue('stringEditorTransform', 'base64'); + }, + }, + { + fieldType: ES_FIELD_TYPES.KEYWORD, + fieldValue: '%EC%95%88%EB%85%95%20%ED%82%A4%EB%B0%94%EB%82%98', + applyFormatterType: FIELD_FORMAT_IDS.STRING, + expectFormattedValue: '안녕 키바나', + beforeSave: async () => { + await testSubjects.selectValue('stringEditorTransform', 'urlparam'); + }, + }, + { + fieldType: ES_FIELD_TYPES.KEYWORD, + fieldValue: '123456789', + applyFormatterType: FIELD_FORMAT_IDS.TRUNCATE, + expectFormattedValue: '123...', + beforeSave: async () => { + await testSubjects.setValue('truncateEditorLength', '3'); + }, + }, + { + fieldType: ES_FIELD_TYPES.INTEGER, + fieldValue: 324, + applyFormatterType: FIELD_FORMAT_IDS.STRING, + expectFormattedValue: '324', + // check available formats for ES_FIELD_TYPES.INTEGER + expectFormatterTypes: [ + FIELD_FORMAT_IDS.BOOLEAN, + FIELD_FORMAT_IDS.BYTES, + FIELD_FORMAT_IDS.COLOR, + FIELD_FORMAT_IDS.DURATION, + FIELD_FORMAT_IDS.NUMBER, + FIELD_FORMAT_IDS.PERCENT, + FIELD_FORMAT_IDS.STATIC_LOOKUP, + FIELD_FORMAT_IDS.STRING, + FIELD_FORMAT_IDS.URL, + ], + }, + ]); + }); + + describe('Number format', () => { + testFormatEditors([ + { + fieldType: ES_FIELD_TYPES.LONG, + fieldValue: 324, + applyFormatterType: FIELD_FORMAT_IDS.NUMBER, + expectFormattedValue: '324', + // check available formats for ES_FIELD_TYPES.LONG + expectFormatterTypes: [ + FIELD_FORMAT_IDS.BOOLEAN, + FIELD_FORMAT_IDS.BYTES, + FIELD_FORMAT_IDS.COLOR, + FIELD_FORMAT_IDS.DURATION, + FIELD_FORMAT_IDS.NUMBER, + FIELD_FORMAT_IDS.PERCENT, + FIELD_FORMAT_IDS.STATIC_LOOKUP, + FIELD_FORMAT_IDS.STRING, + FIELD_FORMAT_IDS.URL, + ], + }, + { + fieldType: ES_FIELD_TYPES.LONG, + fieldValue: 324, + applyFormatterType: FIELD_FORMAT_IDS.NUMBER, + expectFormattedValue: '+324', + beforeSave: async () => { + await testSubjects.setValue('numberEditorFormatPattern', '+0,0'); + }, + }, + ]); + }); + + describe('URL format', () => { + testFormatEditors([ + { + fieldType: ES_FIELD_TYPES.LONG, + fieldValue: 100, + applyFormatterType: FIELD_FORMAT_IDS.URL, + expectFormattedValue: 'https://elastic.co/?value=100', + beforeSave: async () => { + await testSubjects.setValue( + 'urlEditorUrlTemplate', + 'https://elastic.co/?value={{value}}' + ); + }, + expect: async (renderedValueContainer) => { + expect( + await (await renderedValueContainer.findByTagName('a')).getAttribute('href') + ).to.be('https://elastic.co/?value=100'); + }, + }, + { + fieldType: ES_FIELD_TYPES.LONG, + fieldValue: 100, + applyFormatterType: FIELD_FORMAT_IDS.URL, + expectFormattedValue: 'url label', + beforeSave: async () => { + await testSubjects.setValue( + 'urlEditorUrlTemplate', + 'https://elastic.co/?value={{value}}' + ); + await testSubjects.setValue('urlEditorLabelTemplate', 'url label'); + }, + expect: async (renderedValueContainer) => { + expect( + await (await renderedValueContainer.findByTagName('a')).getAttribute('href') + ).to.be('https://elastic.co/?value=100'); + }, + }, + ]); + }); + + describe('Date format', () => { + testFormatEditors([ + { + fieldType: ES_FIELD_TYPES.DATE, + fieldValue: '2021-08-05T15:05:37.151Z', + applyFormatterType: FIELD_FORMAT_IDS.DATE, + expectFormattedValue: 'Aug 5, 2021', + beforeSave: async () => { + await testSubjects.setValue('dateEditorPattern', 'MMM D, YYYY'); + }, + // check available formats for ES_FIELD_TYPES.DATE + expectFormatterTypes: [ + FIELD_FORMAT_IDS.DATE, + FIELD_FORMAT_IDS.DATE_NANOS, + FIELD_FORMAT_IDS.RELATIVE_DATE, + FIELD_FORMAT_IDS.STRING, + FIELD_FORMAT_IDS.URL, + ], + }, + { + fieldType: ES_FIELD_TYPES.DATE_NANOS, + fieldValue: '2015-01-01T12:10:30.123456789Z', + applyFormatterType: FIELD_FORMAT_IDS.DATE, + expectFormattedValue: 'Jan 1, 2015 @ 12:10:30.123', + // check available formats for ES_FIELD_TYPES.DATE_NANOS + expectFormatterTypes: [ + FIELD_FORMAT_IDS.DATE, + FIELD_FORMAT_IDS.DATE_NANOS, + FIELD_FORMAT_IDS.RELATIVE_DATE, + FIELD_FORMAT_IDS.STRING, + FIELD_FORMAT_IDS.URL, + ], + }, + { + fieldType: ES_FIELD_TYPES.DATE_NANOS, + fieldValue: '2015-01-01T12:10:30.123456789Z', + applyFormatterType: FIELD_FORMAT_IDS.DATE_NANOS, + expectFormattedValue: 'Jan 1, 2015 @ 12:10:30.123456789', + }, + ]); + }); + + describe('Static lookup format', () => { + testFormatEditors([ + { + fieldType: ES_FIELD_TYPES.KEYWORD, + fieldValue: 'look me up', + applyFormatterType: FIELD_FORMAT_IDS.STATIC_LOOKUP, + expectFormattedValue: 'looked up!', + beforeSave: async () => { + await testSubjects.click('staticLookupEditorAddEntry'); + await testSubjects.setValue('~staticLookupEditorKey', 'look me up'); + await testSubjects.setValue('~staticLookupEditorValue', 'looked up!'); + }, + }, + { + fieldType: ES_FIELD_TYPES.BOOLEAN, + fieldValue: 'true', + applyFormatterType: FIELD_FORMAT_IDS.STATIC_LOOKUP, + // check available formats for ES_FIELD_TYPES.BOOLEAN + expectFormatterTypes: [ + FIELD_FORMAT_IDS.BOOLEAN, + FIELD_FORMAT_IDS.STATIC_LOOKUP, + FIELD_FORMAT_IDS.STRING, + FIELD_FORMAT_IDS.URL, + ], + expectFormattedValue: 'yes', + beforeSave: async () => { + await testSubjects.click('staticLookupEditorAddEntry'); + await testSubjects.setValue('~staticLookupEditorKey', 'true'); + await testSubjects.setValue('~staticLookupEditorValue', 'yes'); + await testSubjects.setValue('staticLookupEditorUnknownValue', 'no'); + }, + }, + { + fieldType: ES_FIELD_TYPES.BOOLEAN, + fieldValue: 'false', + applyFormatterType: FIELD_FORMAT_IDS.STATIC_LOOKUP, + expectFormattedValue: 'no', + beforeSave: async () => { + await testSubjects.click('staticLookupEditorAddEntry'); + await testSubjects.setValue('~staticLookupEditorKey', 'true'); + await testSubjects.setValue('~staticLookupEditorValue', 'yes'); + await testSubjects.setValue('staticLookupEditorUnknownValue', 'no'); + }, + }, + { + fieldType: ES_FIELD_TYPES.BOOLEAN, + fieldValue: 'false', + applyFormatterType: FIELD_FORMAT_IDS.STATIC_LOOKUP, + expectFormattedValue: 'false', + beforeSave: async () => { + await testSubjects.click('staticLookupEditorAddEntry'); + await testSubjects.setValue('~staticLookupEditorKey', 'true'); + await testSubjects.setValue('~staticLookupEditorValue', 'yes'); + }, + }, + ]); + }); + + describe('Other formats', () => { + testFormatEditors([ + { + fieldType: ES_FIELD_TYPES.LONG, + fieldValue: 123292, + applyFormatterType: FIELD_FORMAT_IDS.DURATION, + expectFormattedValue: '2 minutes', + beforeSave: async () => { + await testSubjects.setValue('durationEditorInputFormat', 'milliseconds'); + }, + }, + { + fieldType: ES_FIELD_TYPES.DOUBLE, + fieldValue: 0.1, + applyFormatterType: FIELD_FORMAT_IDS.PERCENT, + // check available formats for ES_FIELD_TYPES.DOUBLE + expectFormatterTypes: [ + FIELD_FORMAT_IDS.BOOLEAN, + FIELD_FORMAT_IDS.BYTES, + FIELD_FORMAT_IDS.COLOR, + FIELD_FORMAT_IDS.DURATION, + FIELD_FORMAT_IDS.NUMBER, + FIELD_FORMAT_IDS.PERCENT, + FIELD_FORMAT_IDS.STATIC_LOOKUP, + FIELD_FORMAT_IDS.STRING, + FIELD_FORMAT_IDS.URL, + ], + expectFormattedValue: '10.0%', + beforeSave: async () => { + await testSubjects.setValue('numberEditorFormatPattern', '0.0%'); + }, + }, + { + fieldType: ES_FIELD_TYPES.LONG, + fieldValue: 1990000000, + applyFormatterType: FIELD_FORMAT_IDS.BYTES, + expectFormattedValue: '2GB', + beforeSave: async () => { + await testSubjects.setValue('numberEditorFormatPattern', '0b'); + }, + }, + { + fieldType: ES_FIELD_TYPES.KEYWORD, + fieldValue: 'red', + applyFormatterType: FIELD_FORMAT_IDS.COLOR, + expectFormattedValue: 'red', + beforeSave: async () => { + await testSubjects.click('colorEditorAddColor'); + await testSubjects.setValue('~colorEditorKeyPattern', 'red'); + await testSubjects.setValue('~colorEditorColorPicker', '#ffffff'); + await testSubjects.setValue('~colorEditorBackgroundPicker', '#ff0000'); + }, + expect: async (renderedValueContainer) => { + const span = await renderedValueContainer.findByTagName('span'); + expect(await span.getComputedStyle('color')).to.be('rgba(255, 255, 255, 1)'); + expect(await span.getComputedStyle('background-color')).to.be('rgba(255, 0, 0, 1)'); + }, + }, + ]); + }); + }); + }); + + /** + * Runs a field format editors tests covering data setup, editing a field and checking a resulting formatting in Discover app + * TODO: might be useful to reuse this util for runtime fields formats tests + * @param specs - {@link FieldFormatEditorSpecDescriptor} + */ + function testFormatEditors(specs: FieldFormatEditorSpecDescriptor[]) { + const indexTitle = 'field_formats_management_functional_tests'; + let indexPatternId: string; + let testDocumentId: string; + + before(async () => { + if ((await es.indices.exists({ index: indexTitle })).body) { + await es.indices.delete({ index: indexTitle }); + } + + await es.indices.create({ + index: indexTitle, + body: { + mappings: { + properties: specs.reduce((properties, spec, index) => { + properties[`${index}`] = { type: spec.fieldType }; + return properties; + }, {} as Record), + }, + }, + }); + + const docResult = await es.index({ + index: indexTitle, + body: specs.reduce((properties, spec, index) => { + properties[`${index}`] = spec.fieldValue; + return properties; + }, {} as Record), + refresh: 'wait_for', + }); + testDocumentId = docResult.body._id; + + const indexPatternResult = await indexPatterns.create( + { title: indexTitle }, + { override: true } + ); + indexPatternId = indexPatternResult.id!; + }); + + describe('edit formats', () => { + before(async () => { + await PageObjects.settings.navigateTo(); + await PageObjects.settings.clickKibanaIndexPatterns(); + await PageObjects.settings.clickIndexPatternByName(indexTitle); + }); + + afterEach(async () => { + try { + await PageObjects.settings.controlChangeSave(); + } catch (e) { + // in case previous test failed in a state when save is disabled + await PageObjects.settings.controlChangeCancel(); + } + + await toasts.dismissAllToasts(); // dismiss "saved" toast, otherwise it could overlap save button for a next test + }); + + specs.forEach((spec, index) => { + const fieldName = `${index}`; + it( + `edit field format of "${fieldName}" field to "${spec.applyFormatterType}"` + + spec.expectFormatterTypes + ? `, and check available formats types` + : '', + async () => { + await PageObjects.settings.filterField(fieldName); + await PageObjects.settings.openControlsByName(fieldName); + await PageObjects.settings.toggleRow('formatRow'); + + if (spec.expectFormatterTypes) { + expect( + ( + await Promise.all( + ( + await (await testSubjects.find('editorSelectedFormatId')).findAllByTagName( + 'option' + ) + ).map((option) => option.getAttribute('value')) + ) + ).filter(Boolean) + ).to.eql(spec.expectFormatterTypes); + } + + await PageObjects.settings.setFieldFormat(spec.applyFormatterType); + if (spec.beforeSave) { + await spec.beforeSave(await testSubjects.find('formatRow')); + } + } + ); + }); + }); + + describe('check formats', async () => { + before(async () => { + await PageObjects.common.navigateToApp('discover', { + hash: `/doc/${indexPatternId}/${indexTitle}?id=${testDocumentId}`, + }); + await testSubjects.exists('doc-hit'); + }); + + specs.forEach((spec, index) => { + it(`check field format of "${index}" field`, async () => { + const renderedValue = await testSubjects.find(`tableDocViewRow-${index}-value`); + const text = await renderedValue.getVisibleText(); + expect(text).to.be(spec.expectFormattedValue); + if (spec.expect) { + await spec.expect(renderedValue); + } + }); + }); + }); + } +} + +/** + * Describes a field format editor test + */ +interface FieldFormatEditorSpecDescriptor { + /** + * Raw field value to put into document + */ + fieldValue: string | number | boolean | null; + /** + * Explicitly specify a type for a {@link fieldValue} + */ + fieldType: ES_FIELD_TYPES; + /** + * Type of a field formatter to apply + */ + applyFormatterType: FIELD_FORMAT_IDS; + + /** + * Optionally check available formats for {@link fieldType} + */ + expectFormatterTypes?: FIELD_FORMAT_IDS[]; + + /** + * Function to execute before field format is applied. + * Use it set specific configuration params for applied field formatter + * @param formatRowContainer - field format editor container + */ + beforeSave?: (formatRowContainer: WebElementWrapper) => Promise; + + /** + * An expected formatted value rendered by Discover app, + * Use this for final assertion + */ + expectFormattedValue: string; + + /** + * Run additional assertions on rendered element + */ + expect?: (renderedValueContainer: WebElementWrapper) => Promise; +} diff --git a/test/functional/apps/visualize/_linked_saved_searches.ts b/test/functional/apps/visualize/_linked_saved_searches.ts index cfb20cf4b59b8..6fa8acac8e781 100644 --- a/test/functional/apps/visualize/_linked_saved_searches.ts +++ b/test/functional/apps/visualize/_linked_saved_searches.ts @@ -32,6 +32,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async () => { await PageObjects.visualize.initTests(); await PageObjects.common.navigateToApp('discover'); + await PageObjects.timePicker.setDefaultAbsoluteRange(); await filterBar.addFilter('extension.raw', 'is', 'jpg'); await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.discover.saveSearch(savedSearchName); diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts index 9cdd33ef768f9..ab581beeb8b3b 100644 --- a/test/functional/page_objects/settings_page.ts +++ b/test/functional/page_objects/settings_page.ts @@ -73,6 +73,14 @@ export class SettingsPageObject extends FtrService { ); } + async getAdvancedSettingAriaCheckbox(propertyName: string) { + this.log.debug('in getAdvancedSettingAriaCheckbox'); + return await this.testSubjects.getAttribute( + `advancedSetting-editField-${propertyName}`, + 'aria-checked' + ); + } + async clearAdvancedSettings(propertyName: string) { await this.testSubjects.click(`advancedSetting-resetField-${propertyName}`); await this.header.waitUntilLoadingHasFinished(); @@ -113,7 +121,14 @@ export class SettingsPageObject extends FtrService { await this.header.waitUntilLoadingHasFinished(); } - async toggleAdvancedSettingCheckbox(propertyName: string) { + async toggleAdvancedSettingCheckbox(propertyName: string, value?: boolean) { + let curValue: string | undefined; + if (value !== undefined) { + curValue = await this.getAdvancedSettingAriaCheckbox(propertyName); + + if (curValue === (value ? 'true' : 'false')) return; + } + await this.testSubjects.click(`advancedSetting-editField-${propertyName}`); await this.header.waitUntilLoadingHasFinished(); await this.testSubjects.click(`advancedSetting-saveButton`); diff --git a/test/plugin_functional/test_suites/core_plugins/execution_context.ts b/test/plugin_functional/test_suites/core_plugins/execution_context.ts index 93dc494ba5d6d..7dc9922dca51d 100644 --- a/test/plugin_functional/test_suites/core_plugins/execution_context.ts +++ b/test/plugin_functional/test_suites/core_plugins/execution_context.ts @@ -25,13 +25,13 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide await browser.execute(async () => { const coreStart = window._coreProvider.start.core; - const context = coreStart.executionContext.create({ + const context = { type: 'visualization', name: 'execution_context_app', // add a non-ASCII symbols to make sure it doesn't break the context propagation mechanism id: 'Visualization☺漢字', description: 'какое-то странное описание', - }); + }; const result = await coreStart.http.get('/execution_context/pass', { context, diff --git a/vars/workers.groovy b/vars/workers.groovy index 4f9fc789a04b3..ca1c6b57c18bb 100644 --- a/vars/workers.groovy +++ b/vars/workers.groovy @@ -99,8 +99,10 @@ def base(Map params, Closure closure) { withEnv([ "CI=true", "HOME=${env.JENKINS_HOME}", + "PR_NUMBER=${env.ghprbPullId ?: ''}", "PR_SOURCE_BRANCH=${env.ghprbSourceBranch ?: ''}", "PR_TARGET_BRANCH=${env.ghprbTargetBranch ?: ''}", + "PR_MERGE_BASE=${checkoutInfo.mergeBase ?: ''}", "PR_AUTHOR=${env.ghprbPullAuthorLogin ?: ''}", "TEST_BROWSER_HEADLESS=1", "GIT_COMMIT=${checkoutInfo.commit}", diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/app1_hello_world_drilldown/app1_hello_world_drilldown.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/app1_hello_world_drilldown/app1_hello_world_drilldown.tsx index d6979749b7efe..2db7255e607d0 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/app1_hello_world_drilldown/app1_hello_world_drilldown.tsx +++ b/x-pack/examples/ui_actions_enhanced_examples/public/drilldowns/app1_hello_world_drilldown/app1_hello_world_drilldown.tsx @@ -7,13 +7,13 @@ import React from 'react'; import { EuiFieldText, EuiFormRow } from '@elastic/eui'; +import type { SerializableRecord } from '@kbn/utility-types'; import { reactToUiComponent } from '../../../../../../src/plugins/kibana_react/public'; import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../../plugins/ui_actions_enhanced/public'; import { CollectConfigProps as CollectConfigPropsBase } from '../../../../../../src/plugins/kibana_utils/public'; import { SAMPLE_APP1_CLICK_TRIGGER, SampleApp1ClickContext } from '../../triggers'; -import { SerializableState } from '../../../../../../src/plugins/kibana_utils/common'; -export interface Config extends SerializableState { +export interface Config extends SerializableRecord { name: string; } diff --git a/x-pack/plugins/alerting/common/alert_navigation.ts b/x-pack/plugins/alerting/common/alert_navigation.ts index 7c9e428f9a09e..6ac21232b51a5 100644 --- a/x-pack/plugins/alerting/common/alert_navigation.ts +++ b/x-pack/plugins/alerting/common/alert_navigation.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; export interface AlertUrlNavigation { path: string; } diff --git a/x-pack/plugins/alerting/public/alert_navigation_registry/types.ts b/x-pack/plugins/alerting/public/alert_navigation_registry/types.ts index 12ac906142647..ea36d0edd1366 100644 --- a/x-pack/plugins/alerting/public/alert_navigation_registry/types.ts +++ b/x-pack/plugins/alerting/public/alert_navigation_registry/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { SanitizedAlert } from '../../common'; /** diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization.mock.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization.mock.ts index 8cd98b17f5d37..8560e9a2d9335 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization.mock.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization.mock.ts @@ -15,6 +15,7 @@ const createAlertingAuthorizationMock = () => { const mocked: AlertingAuthorizationMock = { ensureAuthorized: jest.fn(), filterByRuleTypeAuthorization: jest.fn(), + getAuthorizationFilter: jest.fn(), getFindAuthorizationFilter: jest.fn(), getAugmentedRuleTypesWithAuthorization: jest.fn(), getSpaceId: jest.fn(), diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts index fd57298f7d93b..ed14c2dd7f0ae 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts @@ -8,7 +8,7 @@ import Boom from '@hapi/boom'; import { map, mapValues, fromPairs, has } from 'lodash'; import { KibanaRequest } from 'src/core/server'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { RuleTypeRegistry } from '../types'; import { SecurityPluginSetup } from '../../../security/server'; import { RegistryRuleType } from '../rule_type_registry'; @@ -281,11 +281,23 @@ export class AlertingAuthorization { filter?: KueryNode | JsonObject; ensureRuleTypeIsAuthorized: (ruleTypeId: string, consumer: string, auth: string) => void; logSuccessfulAuthorization: () => void; + }> { + return this.getAuthorizationFilter(authorizationEntity, filterOpts, ReadOperations.Find); + } + + public async getAuthorizationFilter( + authorizationEntity: AlertingAuthorizationEntity, + filterOpts: AlertingAuthorizationFilterOpts, + operation: WriteOperations | ReadOperations + ): Promise<{ + filter?: KueryNode | JsonObject; + ensureRuleTypeIsAuthorized: (ruleTypeId: string, consumer: string, auth: string) => void; + logSuccessfulAuthorization: () => void; }> { if (this.authorization && this.shouldCheckAuthorization()) { const { username, authorizedRuleTypes } = await this.augmentRuleTypesWithAuthorization( this.ruleTypeRegistry.list(), - [ReadOperations.Find], + [operation], authorizationEntity ); diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.ts index 32b3bcc866577..c8000d9892678 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization_kuery.ts @@ -6,7 +6,7 @@ */ import { remove } from 'lodash'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { EsQueryConfig, nodeBuilder, toElasticsearchQuery, KueryNode } from '@kbn/es-query'; import { RegistryAlertTypeWithAuth } from './alerting_authorization'; diff --git a/x-pack/plugins/alerting/server/routes/lib/rewrite_request_case.ts b/x-pack/plugins/alerting/server/routes/lib/rewrite_request_case.ts index f5455d1a63093..2874f9567231b 100644 --- a/x-pack/plugins/alerting/server/routes/lib/rewrite_request_case.ts +++ b/x-pack/plugins/alerting/server/routes/lib/rewrite_request_case.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { JsonValue } from '@kbn/common-utils'; +import { JsonValue } from '@kbn/utility-types'; type RenameAlertToRule = K extends `alertTypeId` ? `ruleTypeId` diff --git a/x-pack/plugins/apm/public/components/alerting/error_count_alert_trigger/index.tsx b/x-pack/plugins/apm/public/components/alerting/error_count_alert_trigger/index.tsx index 3c79a2475bf29..a06520f1c5bfc 100644 --- a/x-pack/plugins/apm/public/components/alerting/error_count_alert_trigger/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/error_count_alert_trigger/index.tsx @@ -8,6 +8,7 @@ import { i18n } from '@kbn/i18n'; import { defaults, omit } from 'lodash'; import React from 'react'; +import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { ForLastExpression } from '../../../../../triggers_actions_ui/public'; import { asInteger } from '../../../../common/utils/formatters'; import { useEnvironmentsFetcher } from '../../../hooks/use_environments_fetcher'; @@ -47,6 +48,7 @@ export function ErrorCountAlertTrigger(props: Props) { threshold: 25, windowSize: 1, windowUnit: 'm', + environment: ENVIRONMENT_ALL.value, } ); diff --git a/x-pack/plugins/apm/public/components/alerting/fields.tsx b/x-pack/plugins/apm/public/components/alerting/fields.tsx index 2e16599c02716..8480fd276cb74 100644 --- a/x-pack/plugins/apm/public/components/alerting/fields.tsx +++ b/x-pack/plugins/apm/public/components/alerting/fields.tsx @@ -9,7 +9,10 @@ import { EuiSelect, EuiExpression, EuiFieldNumber } from '@elastic/eui'; import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiSelectOption } from '@elastic/eui'; -import { getEnvironmentLabel } from '../../../common/environment_filter_values'; +import { + ENVIRONMENT_ALL, + getEnvironmentLabel, +} from '../../../common/environment_filter_values'; import { PopoverExpression } from './service_alert_trigger/popover_expression'; const ALL_OPTION = i18n.translate('xpack.apm.alerting.fields.all_option', { @@ -42,7 +45,7 @@ export function EnvironmentField({ // "1" means "All" is the only option and we should not show a select. if (options.length === 1) { - return ; + return ; } return ( diff --git a/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx b/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx index c54f32d805818..2a73cba0a63d5 100644 --- a/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx @@ -9,6 +9,7 @@ import { EuiSelect } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { defaults, map, omit } from 'lodash'; import React from 'react'; +import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { CoreStart } from '../../../../../../../src/core/public'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; import { ForLastExpression } from '../../../../../triggers_actions_ui/public'; @@ -90,6 +91,8 @@ export function TransactionDurationAlertTrigger(props: Props) { threshold: 1500, windowSize: 5, windowUnit: 'm', + environment: ENVIRONMENT_ALL.value, + transactionType: transactionTypes[0], } ); diff --git a/x-pack/plugins/apm/public/components/alerting/transaction_duration_anomaly_alert_trigger/index.tsx b/x-pack/plugins/apm/public/components/alerting/transaction_duration_anomaly_alert_trigger/index.tsx index 97ce73a746329..519b18cd3a6b6 100644 --- a/x-pack/plugins/apm/public/components/alerting/transaction_duration_anomaly_alert_trigger/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/transaction_duration_anomaly_alert_trigger/index.tsx @@ -8,6 +8,7 @@ import { i18n } from '@kbn/i18n'; import { defaults, omit } from 'lodash'; import React from 'react'; +import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { ANOMALY_SEVERITY } from '../../../../common/ml_constants'; import { useServiceTransactionTypesFetcher } from '../../../context/apm_service/use_service_transaction_types_fetcher'; import { useEnvironmentsFetcher } from '../../../hooks/use_environments_fetcher'; @@ -60,6 +61,7 @@ export function TransactionDurationAnomalyAlertTrigger(props: Props) { windowSize: 15, windowUnit: 'm', anomalySeverityType: ANOMALY_SEVERITY.CRITICAL, + environment: ENVIRONMENT_ALL.value, } ); diff --git a/x-pack/plugins/apm/public/components/alerting/transaction_error_rate_alert_trigger/index.tsx b/x-pack/plugins/apm/public/components/alerting/transaction_error_rate_alert_trigger/index.tsx index 6118f99e4bd9f..8f2e212a22681 100644 --- a/x-pack/plugins/apm/public/components/alerting/transaction_error_rate_alert_trigger/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/transaction_error_rate_alert_trigger/index.tsx @@ -7,6 +7,7 @@ import { defaults, omit } from 'lodash'; import React from 'react'; +import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { CoreStart } from '../../../../../../../src/core/public'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; import { ForLastExpression } from '../../../../../triggers_actions_ui/public'; @@ -57,6 +58,7 @@ export function TransactionErrorRateAlertTrigger(props: Props) { threshold: 30, windowSize: 5, windowUnit: 'm', + environment: ENVIRONMENT_ALL.value, } ); diff --git a/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_error_rate_chart.tsx b/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_error_rate_chart.tsx index 8dc47dc6549fc..bcdc4aae5ded1 100644 --- a/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_error_rate_chart.tsx +++ b/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_error_rate_chart.tsx @@ -15,6 +15,7 @@ import { useTimeRange } from '../../../hooks/use_time_range'; import { Coordinate, TimeSeries } from '../../../../typings/timeseries'; import { TimeseriesChart } from '../../shared/charts/timeseries_chart'; import { useTheme } from '../../../hooks/use_theme'; +import { useApmParams } from '../../../hooks/use_apm_params'; function yLabelFormat(y?: number | null) { return asPercent(y || 0, 1); @@ -25,7 +26,11 @@ export function BackendErrorRateChart({ height }: { height: number }) { const theme = useTheme(); - const { start, end } = useTimeRange(); + const { + query: { rangeFrom, rangeTo }, + } = useApmParams('/backends/:backendName/overview'); + + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); const { urlParams: { kuery, environment }, diff --git a/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_latency_chart.tsx b/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_latency_chart.tsx index 0f855edfae770..472295e69c20a 100644 --- a/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_latency_chart.tsx +++ b/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_latency_chart.tsx @@ -19,13 +19,18 @@ import { getMaxY, getResponseTimeTickFormatter, } from '../../shared/charts/transaction_charts/helper'; +import { useApmParams } from '../../../hooks/use_apm_params'; export function BackendLatencyChart({ height }: { height: number }) { const { backendName } = useApmBackendContext(); const theme = useTheme(); - const { start, end } = useTimeRange(); + const { + query: { rangeFrom, rangeTo }, + } = useApmParams('/backends/:backendName/overview'); + + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); const { urlParams: { kuery, environment }, diff --git a/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_throughput_chart.tsx b/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_throughput_chart.tsx index 0b962742051b4..6088d315866db 100644 --- a/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_throughput_chart.tsx +++ b/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_throughput_chart.tsx @@ -15,13 +15,18 @@ import { useTimeRange } from '../../../hooks/use_time_range'; import { Coordinate, TimeSeries } from '../../../../typings/timeseries'; import { TimeseriesChart } from '../../shared/charts/timeseries_chart'; import { useTheme } from '../../../hooks/use_theme'; +import { useApmParams } from '../../../hooks/use_apm_params'; export function BackendThroughputChart({ height }: { height: number }) { const { backendName } = useApmBackendContext(); const theme = useTheme(); - const { start, end } = useTimeRange(); + const { + query: { rangeFrom, rangeTo }, + } = useApmParams('/backends/:backendName/overview'); + + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); const { urlParams: { kuery, environment }, diff --git a/x-pack/plugins/apm/public/components/app/backend_detail_overview/index.tsx b/x-pack/plugins/apm/public/components/app/backend_detail_overview/index.tsx index cef0b4e410c38..fdcb6bdf38e42 100644 --- a/x-pack/plugins/apm/public/components/app/backend_detail_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/backend_detail_overview/index.tsx @@ -27,7 +27,7 @@ import { BackendDetailTemplate } from '../../routing/templates/backend_detail_te export function BackendDetailOverview() { const { path: { backendName }, - query, + query: { rangeFrom, rangeTo }, } = useApmParams('/backends/:backendName/overview'); const apmRouter = useApmRouter(); @@ -35,13 +35,16 @@ export function BackendDetailOverview() { useBreadcrumb([ { title: BackendInventoryTitle, - href: apmRouter.link('/backends'), + href: apmRouter.link('/backends', { query: { rangeFrom, rangeTo } }), }, { title: backendName, href: apmRouter.link('/backends/:backendName/overview', { path: { backendName }, - query, + query: { + rangeFrom, + rangeTo, + }, }), }, ]); diff --git a/x-pack/plugins/apm/public/components/app/error_group_details/index.tsx b/x-pack/plugins/apm/public/components/app/error_group_details/index.tsx index 3b7dea1e64060..cf4cc68865977 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_details/index.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_details/index.tsx @@ -101,6 +101,7 @@ export function ErrorGroupDetails() { const { path: { groupId }, + query: { rangeFrom, rangeTo }, } = useApmParams('/services/:serviceName/errors/:groupId'); useBreadcrumb({ @@ -110,6 +111,10 @@ export function ErrorGroupDetails() { serviceName, groupId, }, + query: { + rangeFrom, + rangeTo, + }, }), }); diff --git a/x-pack/plugins/apm/public/components/app/service_dependencies/service_dependencies_breakdown_chart.tsx b/x-pack/plugins/apm/public/components/app/service_dependencies/service_dependencies_breakdown_chart.tsx index a33b0db7c4baf..1ce6d54754719 100644 --- a/x-pack/plugins/apm/public/components/app/service_dependencies/service_dependencies_breakdown_chart.tsx +++ b/x-pack/plugins/apm/public/components/app/service_dependencies/service_dependencies_breakdown_chart.tsx @@ -18,13 +18,14 @@ export function ServiceDependenciesBreakdownChart({ }: { height: number; }) { - const { start, end } = useTimeRange(); const { serviceName } = useApmServiceContext(); const { - query: { kuery, environment }, + query: { kuery, environment, rangeFrom, rangeTo }, } = useApmParams('/services/:serviceName/dependencies'); + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); + const { data, status } = useFetcher( (callApmApi) => { return callApmApi({ diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx index a883df469729d..f50816809df07 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx @@ -13,6 +13,7 @@ import { EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { TypeOf } from '@kbn/typed-react-router-config'; import { orderBy } from 'lodash'; import React, { useMemo } from 'react'; import { ValuesType } from 'utility-types'; @@ -34,6 +35,7 @@ import { import { useApmParams } from '../../../../hooks/use_apm_params'; import { APIReturnType } from '../../../../services/rest/createCallApmApi'; import { unit } from '../../../../utils/style'; +import { ApmRoutes } from '../../../routing/apm_route_config'; import { EnvironmentBadge } from '../../../shared/EnvironmentBadge'; import { ITableColumn, ManagedTable } from '../../../shared/managed_table'; import { ServiceLink } from '../../../shared/service_link'; @@ -64,7 +66,7 @@ export function getServiceColumns({ comparisonData, breakPoints, }: { - query: Record; + query: TypeOf['query']; showTransactionTypeColumn: boolean; breakPoints: BreakPoints; comparisonData?: ServicesDetailedStatisticsAPIResponse; diff --git a/x-pack/plugins/apm/public/components/app/service_map/Popover/service_contents.tsx b/x-pack/plugins/apm/public/components/app/service_map/Popover/service_contents.tsx index b486e5e19fb03..274e25b342d2a 100644 --- a/x-pack/plugins/apm/public/components/app/service_map/Popover/service_contents.tsx +++ b/x-pack/plugins/apm/public/components/app/service_map/Popover/service_contents.tsx @@ -10,6 +10,7 @@ import { EuiButton, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; +import { useApmParams } from '../../../../hooks/use_apm_params'; import type { ContentsProps } from '.'; import { NodeStats } from '../../../../../common/service_map'; import { useUrlParams } from '../../../../context/url_params_context/use_url_params'; @@ -17,14 +18,29 @@ import { useApmRouter } from '../../../../hooks/use_apm_router'; import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; import { AnomalyDetection } from './anomaly_detection'; import { StatsList } from './stats_list'; +import { useTimeRange } from '../../../../hooks/use_time_range'; export function ServiceContents({ onFocusClick, nodeData }: ContentsProps) { const apmRouter = useApmRouter(); const { - urlParams: { environment, start, end }, + urlParams: { environment }, } = useUrlParams(); + const { query } = useApmParams('/*'); + + if ( + !('rangeFrom' in query && 'rangeTo' in query) || + !query.rangeFrom || + !query.rangeTo + ) { + throw new Error('Expected rangeFrom and rangeTo to be set'); + } + + const { rangeFrom, rangeTo } = query; + + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); + const serviceName = nodeData.id!; const { data = { transactionStats: {} } as NodeStats, status } = useFetcher( @@ -49,10 +65,12 @@ export function ServiceContents({ onFocusClick, nodeData }: ContentsProps) { const detailsUrl = apmRouter.link('/services/:serviceName', { path: { serviceName }, + query: { rangeFrom, rangeTo }, }); const focusUrl = apmRouter.link('/services/:serviceName/service-map', { path: { serviceName }, + query: { rangeFrom, rangeTo }, }); const { serviceAnomalyStats } = nodeData; diff --git a/x-pack/plugins/apm/public/components/routing/home/index.tsx b/x-pack/plugins/apm/public/components/routing/home/index.tsx index 10f88d3e8b4cc..1502038b378b2 100644 --- a/x-pack/plugins/apm/public/components/routing/home/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/home/index.tsx @@ -53,14 +53,24 @@ export const BackendInventoryTitle = i18n.translate( export const home = { path: '/', element: , - params: t.partial({ - query: t.partial({ - rangeFrom: t.string, - rangeTo: t.string, - environment: t.string, - kuery: t.string, - }), + params: t.type({ + query: t.intersection([ + t.partial({ + environment: t.string, + kuery: t.string, + }), + t.type({ + rangeFrom: t.string, + rangeTo: t.string, + }), + ]), }), + defaults: { + query: { + rangeFrom: 'now-15m', + rangeTo: 'now', + }, + }, children: [ page({ path: '/services', diff --git a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx index 5771d21b77a3a..9716dd01561e5 100644 --- a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx @@ -66,19 +66,29 @@ export const serviceDetail = { serviceName: t.string, }), }), - t.partial({ - query: t.partial({ - environment: t.string, - rangeFrom: t.string, - rangeTo: t.string, - comparisonEnabled: t.string, - comparisonType: t.string, - latencyAggregationType: t.string, - transactionType: t.string, - kuery: t.string, - }), + t.type({ + query: t.intersection([ + t.type({ + rangeFrom: t.string, + rangeTo: t.string, + }), + t.partial({ + environment: t.string, + comparisonEnabled: t.string, + comparisonType: t.string, + latencyAggregationType: t.string, + transactionType: t.string, + kuery: t.string, + }), + ]), }), ]), + defaults: { + query: { + rangeFrom: 'now-15m', + rangeTo: 'now', + }, + }, children: [ page({ path: '/overview', diff --git a/x-pack/plugins/apm/public/components/shared/backend_link.tsx b/x-pack/plugins/apm/public/components/shared/backend_link.tsx index 069631b9f17ac..84ce37391b369 100644 --- a/x-pack/plugins/apm/public/components/shared/backend_link.tsx +++ b/x-pack/plugins/apm/public/components/shared/backend_link.tsx @@ -18,7 +18,7 @@ const StyledLink = euiStyled(EuiLink)`${truncate('100%')};`; interface BackendLinkProps { backendName: string; - query?: TypeOf['query']; + query: TypeOf['query']; subtype?: string; type?: string; } diff --git a/x-pack/plugins/apm/public/components/shared/charts/helper/get_alert_annotations.test.tsx b/x-pack/plugins/apm/public/components/shared/charts/helper/get_alert_annotations.test.tsx index 4f3ac31517020..81c4af44c90a3 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/helper/get_alert_annotations.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/helper/get_alert_annotations.test.tsx @@ -41,6 +41,7 @@ const alert: Alert = { 'rule.name': ['Latency threshold | frontend-rum'], [ALERT_DURATION]: [62879000], [ALERT_STATUS]: ['open'], + [SPACE_IDS]: ['myfakespaceid'], tags: ['apm', 'service.name:frontend-rum'], 'transaction.type': ['page-load'], [ALERT_PRODUCER]: ['apm'], diff --git a/x-pack/plugins/apm/public/components/shared/service_link.tsx b/x-pack/plugins/apm/public/components/shared/service_link.tsx index d61f55fe53cf0..d79243315c773 100644 --- a/x-pack/plugins/apm/public/components/shared/service_link.tsx +++ b/x-pack/plugins/apm/public/components/shared/service_link.tsx @@ -19,7 +19,7 @@ const StyledLink = euiStyled(EuiLink)`${truncate('100%')};`; interface ServiceLinkProps { agentName?: AgentName; - query?: TypeOf['query']; + query: TypeOf['query']; serviceName: string; } diff --git a/x-pack/plugins/apm/public/hooks/use_comparison.ts b/x-pack/plugins/apm/public/hooks/use_comparison.ts index b84942657dc9d..2875d973a5e18 100644 --- a/x-pack/plugins/apm/public/hooks/use_comparison.ts +++ b/x-pack/plugins/apm/public/hooks/use_comparison.ts @@ -10,6 +10,7 @@ import { getTimeRangeComparison, } from '../components/shared/time_comparison/get_time_range_comparison'; import { useUrlParams } from '../context/url_params_context/use_url_params'; +import { useApmParams } from './use_apm_params'; import { useTheme } from './use_theme'; import { useTimeRange } from './use_time_range'; @@ -17,7 +18,16 @@ export function useComparison() { const theme = useTheme(); const comparisonChartTheme = getComparisonChartTheme(theme); - const { start, end } = useTimeRange(); + const { query } = useApmParams('/*'); + + if (!('rangeFrom' in query && 'rangeTo' in query)) { + throw new Error('rangeFrom or rangeTo not defined in query'); + } + + const { start, end } = useTimeRange({ + rangeFrom: query.rangeFrom, + rangeTo: query.rangeTo, + }); const { urlParams: { comparisonType, comparisonEnabled }, diff --git a/x-pack/plugins/apm/public/hooks/use_time_range.test.ts b/x-pack/plugins/apm/public/hooks/use_time_range.test.ts new file mode 100644 index 0000000000000..dbdd7de171650 --- /dev/null +++ b/x-pack/plugins/apm/public/hooks/use_time_range.test.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + act, + renderHook, + RenderHookResult, +} from '@testing-library/react-hooks'; +import { useTimeRange } from './use_time_range'; + +describe('useTimeRange', () => { + let hook: RenderHookResult< + Parameters[0], + ReturnType + >; + + beforeEach(() => { + Date.now = jest.fn(() => new Date(Date.UTC(2021, 0, 1, 12)).valueOf()); + + hook = renderHook( + (props) => { + const { rangeFrom, rangeTo } = props; + return useTimeRange({ rangeFrom, rangeTo }); + }, + { initialProps: { rangeFrom: 'now-15m', rangeTo: 'now' } } + ); + }); + + afterEach(() => {}); + + it('returns the parsed range on first render', () => { + expect(hook.result.current.start).toEqual('2021-01-01T11:45:00.000Z'); + expect(hook.result.current.end).toEqual('2021-01-01T12:00:00.000Z'); + }); + + it('only changes the parsed range when rangeFrom/rangeTo change', () => { + Date.now = jest.fn(() => new Date(Date.UTC(2021, 0, 1, 13)).valueOf()); + + hook.rerender({ rangeFrom: 'now-15m', rangeTo: 'now' }); + + expect(hook.result.current.start).toEqual('2021-01-01T11:45:00.000Z'); + expect(hook.result.current.end).toEqual('2021-01-01T12:00:00.000Z'); + + hook.rerender({ rangeFrom: 'now-30m', rangeTo: 'now' }); + + expect(hook.result.current.start).toEqual('2021-01-01T12:30:00.000Z'); + expect(hook.result.current.end).toEqual('2021-01-01T13:00:00.000Z'); + }); + + it('updates when refreshTimeRange is called', async () => { + Date.now = jest.fn(() => new Date(Date.UTC(2021, 0, 1, 13)).valueOf()); + + hook.rerender({ rangeFrom: 'now-15m', rangeTo: 'now' }); + + expect(hook.result.current.start).toEqual('2021-01-01T11:45:00.000Z'); + expect(hook.result.current.end).toEqual('2021-01-01T12:00:00.000Z'); + + act(() => { + hook.result.current.refreshTimeRange(); + }); + + expect(hook.result.current.start).toEqual('2021-01-01T12:45:00.000Z'); + expect(hook.result.current.end).toEqual('2021-01-01T13:00:00.000Z'); + }); +}); diff --git a/x-pack/plugins/apm/public/hooks/use_time_range.ts b/x-pack/plugins/apm/public/hooks/use_time_range.ts index 7afdfb7db6a04..8263767a402dd 100644 --- a/x-pack/plugins/apm/public/hooks/use_time_range.ts +++ b/x-pack/plugins/apm/public/hooks/use_time_range.ts @@ -5,19 +5,46 @@ * 2.0. */ -import { useUrlParams } from '../context/url_params_context/use_url_params'; +import { isEqual } from 'lodash'; +import { useCallback, useRef, useState } from 'react'; +import { getDateRange } from '../context/url_params_context/helpers'; -export function useTimeRange() { - const { - urlParams: { start, end }, - } = useUrlParams(); +export function useTimeRange({ + rangeFrom, + rangeTo, +}: { + rangeFrom: string; + rangeTo: string; +}) { + const rangeRef = useRef({ rangeFrom, rangeTo }); + + const [timeRangeId, setTimeRangeId] = useState(0); + + const stateRef = useRef(getDateRange({ state: {}, rangeFrom, rangeTo })); + + const updateParsedTime = useCallback(() => { + stateRef.current = getDateRange({ state: {}, rangeFrom, rangeTo }); + }, [rangeFrom, rangeTo]); + + if (!isEqual(rangeRef.current, { rangeFrom, rangeTo })) { + updateParsedTime(); + } + + const { start, end } = stateRef.current; + + const refreshTimeRange = useCallback(() => { + updateParsedTime(); + setTimeRangeId((id) => id + 1); + }, [setTimeRangeId, updateParsedTime]); if (!start || !end) { - throw new Error('Time range not set'); + throw new Error('start and/or end were unexpectedly not set'); } return { start, end, + refreshTimeRange, + timeRangeId, }; } diff --git a/x-pack/plugins/banners/kibana.json b/x-pack/plugins/banners/kibana.json index 3e9441aaa2726..ba8cbda647013 100644 --- a/x-pack/plugins/banners/kibana.json +++ b/x-pack/plugins/banners/kibana.json @@ -1,5 +1,9 @@ { "id": "banners", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "8.0.0", "kibanaVersion": "kibana", "server": true, diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/csv.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/csv.test.ts index 6feb22b2ef15e..7401bbb6aabee 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/csv.test.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/csv.test.ts @@ -5,10 +5,11 @@ * 2.0. */ +import { SerializableRecord } from '@kbn/utility-types'; import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib'; import { getFunctionErrors } from '../../../i18n'; import { csv } from './csv'; -import { Datatable, ExecutionContext, SerializableState } from 'src/plugins/expressions'; +import { Datatable, ExecutionContext } from 'src/plugins/expressions'; import { Adapters } from 'src/plugins/inspector'; const errors = getFunctionErrors().csv; @@ -39,7 +40,7 @@ one,1 two,2 fourty two,42`, }, - {} as ExecutionContext + {} as ExecutionContext ) ).toEqual(expected); }); @@ -55,7 +56,7 @@ two\t2 fourty two\t42`, delimiter: '\t', }, - {} as ExecutionContext + {} as ExecutionContext ) ).toEqual(expected); @@ -69,7 +70,7 @@ two%SPLIT%2 fourty two%SPLIT%42`, delimiter: '%SPLIT%', }, - {} as ExecutionContext + {} as ExecutionContext ) ).toEqual(expected); }); @@ -82,7 +83,7 @@ fourty two%SPLIT%42`, data: `name,number\rone,1\rtwo,2\rfourty two,42`, newline: '\r', }, - {} as ExecutionContext + {} as ExecutionContext ) ).toEqual(expected); }); @@ -106,7 +107,7 @@ fourty two%SPLIT%42`, data: `foo," bar ", baz, " buz " 1,2,3,4`, }, - {} as ExecutionContext + {} as ExecutionContext ) ).toEqual(expectedResult); }); @@ -134,7 +135,7 @@ fourty two%SPLIT%42`, 1," best ",3, " ok" " good", bad, better , " worst " `, }, - {} as ExecutionContext + {} as ExecutionContext ) ).toEqual(expectedResult); }); @@ -149,7 +150,7 @@ one|1 two.2 fourty two,42`, }, - {} as ExecutionContext + {} as ExecutionContext ); }).toThrow(new RegExp(errors.invalidInputCSV().message)); }); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/dropdown_control.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/dropdown_control.test.ts index 6f785f1b9d479..b64761bb5a822 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/dropdown_control.test.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/dropdown_control.test.ts @@ -8,8 +8,9 @@ import { functionWrapper } from '../../../../../../src/plugins/presentation_util/common/lib'; import { testTable, relationalTable } from './__fixtures__/test_tables'; import { dropdownControl } from './dropdownControl'; -import { ExecutionContext, SerializableState } from 'src/plugins/expressions'; +import { ExecutionContext } from 'src/plugins/expressions'; import { Adapters } from 'src/plugins/inspector'; +import { SerializableRecord } from '@kbn/utility-types'; describe('dropdownControl', () => { const fn = functionWrapper(dropdownControl); @@ -19,14 +20,14 @@ describe('dropdownControl', () => { fn( testTable, { filterColumn: 'name', valueColumn: 'name' }, - {} as ExecutionContext + {} as ExecutionContext ) ).toHaveProperty('type', 'render'); expect( fn( testTable, { filterColumn: 'name', valueColumn: 'name' }, - {} as ExecutionContext + {} as ExecutionContext ) ).toHaveProperty('as', 'dropdown_filter'); }); @@ -43,18 +44,21 @@ describe('dropdownControl', () => { fn( testTable, { valueColumn: 'name' }, - {} as ExecutionContext + {} as ExecutionContext )?.value?.choices ).toEqual(uniqueNames); }); it('returns an empty array when provided an invalid column', () => { expect( - fn(testTable, { valueColumn: 'foo' }, {} as ExecutionContext) - ?.value?.choices + fn( + testTable, + { valueColumn: 'foo' }, + {} as ExecutionContext + )?.value?.choices ).toEqual([]); expect( - fn(testTable, { valueColumn: '' }, {} as ExecutionContext) + fn(testTable, { valueColumn: '' }, {} as ExecutionContext) ?.value?.choices ).toEqual([]); }); @@ -67,7 +71,7 @@ describe('dropdownControl', () => { fn( relationalTable, { valueColumn: 'id', labelColumn: 'name' }, - {} as ExecutionContext + {} as ExecutionContext )?.value?.choices ).toEqual(expectedChoices); }); @@ -77,22 +81,28 @@ describe('dropdownControl', () => { describe('filterColumn', () => { it('sets which column the filter is applied to', () => { expect( - fn(testTable, { filterColumn: 'name' }, {} as ExecutionContext) - ?.value + fn( + testTable, + { filterColumn: 'name' }, + {} as ExecutionContext + )?.value ).toHaveProperty('column', 'name'); expect( fn( testTable, { filterColumn: 'name', valueColumn: 'price' }, - {} as ExecutionContext + {} as ExecutionContext )?.value ).toHaveProperty('column', 'name'); }); it('defaults to valueColumn if not provided', () => { expect( - fn(testTable, { valueColumn: 'price' }, {} as ExecutionContext) - ?.value + fn( + testTable, + { valueColumn: 'price' }, + {} as ExecutionContext + )?.value ).toHaveProperty('column', 'price'); }); }); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/index.js b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/index.js index b6343f5ca7ca4..bc77f347530b7 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/index.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/index.js @@ -5,142 +5,128 @@ * 2.0. */ -import React, { Component } from 'react'; -import { compose, withPropsOnChange, withHandlers } from 'recompose'; +import React, { useState, useCallback, useEffect } from 'react'; import PropTypes from 'prop-types'; import { EuiSelect, EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; import { sortBy } from 'lodash'; import { getType } from '@kbn/interpreter/common'; -import { createStatefulPropHoc } from '../../../../public/components/enhance/stateful_prop'; import { templateFromReactComponent } from '../../../../public/lib/template_from_react_component'; import { ArgumentStrings } from '../../../../i18n'; import { SimpleMathFunction } from './simple_math_function'; import { getFormObject } from './get_form_object'; const { DataColumn: strings } = ArgumentStrings; + const maybeQuoteValue = (val) => (val.match(/\s/) ? `'${val}'` : val); +const valueNotSet = (val) => !val || val.length === 0; -// TODO: Garbage, we could make a much nicer math form that can handle way more. -class DatacolumnArgInput extends Component { - static propTypes = { - columns: PropTypes.array.isRequired, - onValueChange: PropTypes.func.isRequired, - mathValue: PropTypes.object.isRequired, - setMathFunction: PropTypes.func.isRequired, - typeInstance: PropTypes.object.isRequired, - renderError: PropTypes.func.isRequired, - argId: PropTypes.string.isRequired, - }; - - inputRefs = {}; - - render() { - const { - onValueChange, - columns, - mathValue, - setMathFunction, - renderError, - argId, - typeInstance, - } = this.props; - - if (mathValue.error) { - renderError(); - return null; - } - - const allowedTypes = typeInstance.options.allowedTypes || false; - const onlyShowMathFunctions = typeInstance.options.onlyMath || false; - const valueNotSet = (val) => !val || val.length === 0; - - const updateFunctionValue = () => { - const fn = this.inputRefs.fn.value; - const column = this.inputRefs.column.value; +const getMathValue = (argValue, columns) => { + if (getType(argValue) !== 'string') { + return { error: 'argValue is not a string type' }; + } + try { + const matchedCol = columns.find(({ name }) => argValue === name); + const val = matchedCol ? maybeQuoteValue(matchedCol.name) : argValue; + const mathValue = getFormObject(val); + return { ...mathValue, column: mathValue.column || '' }; + } catch (e) { + return { error: e.message }; + } +}; +// TODO: Garbage, we could make a much nicer math form that can handle way more. +const DatacolumnArgInput = ({ + onValueChange, + columns, + argValue, + renderError, + argId, + typeInstance, +}) => { + const [mathValue, setMathValue] = useState(getMathValue(argValue, columns)); + + useEffect(() => { + setMathValue(getMathValue(argValue, columns)); + }, [argValue, columns]); + + const allowedTypes = typeInstance.options.allowedTypes || false; + const onlyShowMathFunctions = typeInstance.options.onlyMath || false; + + const updateFunctionValue = useCallback( + (fn, column) => { // if setting size, auto-select the first column if no column is already set if (fn === 'size') { - const col = column || (columns[0] && columns[0].name); + const col = column || (columns[0] && columns[0].name) || ''; if (col) { return onValueChange(`${fn}(${maybeQuoteValue(col)})`); } } - // this.inputRefs.column is the column selection, if there is no value, do nothing + // if there is no column value, do nothing if (valueNotSet(column)) { - return setMathFunction(fn); + return setMathValue({ ...mathValue, fn }); } - // this.inputRefs.fn is the math function to use, if it's not set, just use the value input + // if fn is not set, just use the value input if (valueNotSet(fn)) { return onValueChange(column); } - // this.inputRefs.fn has a value, so use it as a math.js expression + // fn has a value, so use it as a math.js expression onValueChange(`${fn}(${maybeQuoteValue(column)})`); - }; - - const column = - columns.map((col) => col.name).find((colName) => colName === mathValue.column) || ''; - - const options = [{ value: '', text: 'select column', disabled: true }]; - - sortBy(columns, 'name').forEach((column) => { - if (allowedTypes && !allowedTypes.includes(column.type)) { - return; - } - options.push({ value: column.name, text: column.name }); - }); - - return ( - - - (this.inputRefs.fn = ref)} - onlymath={onlyShowMathFunctions} - onChange={updateFunctionValue} - /> - - - (this.inputRefs.column = ref)} - onChange={updateFunctionValue} - /> - - - ); + }, + [mathValue, onValueChange, columns] + ); + + const onChangeFn = useCallback( + ({ target: { value } }) => updateFunctionValue(value, mathValue.column), + [mathValue.column, updateFunctionValue] + ); + + const onChangeColumn = useCallback( + ({ target: { value } }) => updateFunctionValue(mathValue.fn, value), + [mathValue.fn, updateFunctionValue] + ); + + if (mathValue.error) { + renderError(); + return null; } -} -const EnhancedDatacolumnArgInput = compose( - withPropsOnChange(['argValue', 'columns'], ({ argValue, columns }) => ({ - mathValue: ((argValue) => { - if (getType(argValue) !== 'string') { - return { error: 'argValue is not a string type' }; - } - try { - const matchedCol = columns.find(({ name }) => argValue === name); - const val = matchedCol ? maybeQuoteValue(matchedCol.name) : argValue; - return getFormObject(val); - } catch (e) { - return { error: e.message }; - } - })(argValue), - })), - createStatefulPropHoc('mathValue', 'setMathValue'), - withHandlers({ - setMathFunction: ({ mathValue, setMathValue }) => (fn) => setMathValue({ ...mathValue, fn }), - }) -)(DatacolumnArgInput); - -EnhancedDatacolumnArgInput.propTypes = { - argValue: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, + const firstColumnOption = { value: '', text: 'select column', disabled: true }; + const options = sortBy(columns, 'name') + .filter((column) => !allowedTypes || allowedTypes.includes(column.type)) + .map(({ name }) => ({ value: name, text: name })); + + return ( + + + + + + + + + ); +}; + +DatacolumnArgInput.propTypes = { columns: PropTypes.array.isRequired, + onValueChange: PropTypes.func.isRequired, + typeInstance: PropTypes.object.isRequired, + renderError: PropTypes.func.isRequired, + argId: PropTypes.string.isRequired, + argValue: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired, }; export const datacolumn = () => ({ @@ -148,5 +134,5 @@ export const datacolumn = () => ({ displayName: strings.getDisplayName(), help: strings.getHelp(), default: '""', - simpleTemplate: templateFromReactComponent(EnhancedDatacolumnArgInput), + simpleTemplate: templateFromReactComponent(DatacolumnArgInput), }); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/simple_math_function.js b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/simple_math_function.js index c54b44d3cc5ba..5fd859a789d85 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/simple_math_function.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/simple_math_function.js @@ -12,7 +12,7 @@ import { ArgumentStrings } from '../../../../i18n'; const { DataColumn: strings } = ArgumentStrings; -export const SimpleMathFunction = ({ onChange, value, inputRef, onlymath }) => { +export const SimpleMathFunction = ({ onChange, value, onlymath }) => { const options = [ { text: strings.getOptionAverage(), value: 'mean' }, { text: strings.getOptionCount(), value: 'size' }, @@ -29,15 +29,12 @@ export const SimpleMathFunction = ({ onChange, value, inputRef, onlymath }) => { options.unshift({ text: strings.getOptionValue(), value: '' }); } - return ( - - ); + return ; }; SimpleMathFunction.propTypes = { onChange: PropTypes.func, value: PropTypes.string, - inputRef: PropTypes.func, onlymath: PropTypes.bool, }; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/index.tsx similarity index 72% rename from x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/index.ts rename to x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/index.tsx index 986b39f8ea2e6..ef5eb18b44590 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/index.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/date_format/index.tsx @@ -5,9 +5,10 @@ * 2.0. */ -import { compose, withProps } from 'recompose'; +import React from 'react'; import moment from 'moment'; -import { DateFormatArgInput as Component, Props as ComponentProps } from './date_format'; +import { Assign } from '@kbn/utility-types'; +import { DateFormatArgInput, Props as ComponentProps } from './date_format'; import { templateFromReactComponent } from '../../../../public/lib/template_from_react_component'; import { ArgumentFactory } from '../../../../types/arguments'; import { ArgumentStrings } from '../../../../i18n'; @@ -16,6 +17,10 @@ import { SetupInitializer } from '../../../plugin'; const { DateFormat: strings } = ArgumentStrings; +const getDateFormatArgInput = (defaultDateFormats: ComponentProps['dateFormats']) => ( + props: Assign +) => ; + export const dateFormatInitializer: SetupInitializer> = ( core, plugins @@ -35,12 +40,10 @@ export const dateFormatInitializer: SetupInitializer(withProps({ dateFormats }))(Component); - return () => ({ name: 'dateFormat', displayName: strings.getDisplayName(), help: strings.getHelp(), - simpleTemplate: templateFromReactComponent(DateFormatArgInput), + simpleTemplate: templateFromReactComponent(getDateFormatArgInput(dateFormats)), }); }; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/index.tsx similarity index 77% rename from x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/index.ts rename to x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/index.tsx index 7c7d573bcd76c..e1d86ba3ff9d2 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/index.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/index.tsx @@ -5,8 +5,9 @@ * 2.0. */ -import { compose, withProps } from 'recompose'; -import { NumberFormatArgInput as Component, Props as ComponentProps } from './number_format'; +import React from 'react'; +import { Assign } from '@kbn/utility-types'; +import { NumberFormatArgInput, Props as ComponentProps } from './number_format'; import { templateFromReactComponent } from '../../../../public/lib/template_from_react_component'; import { ArgumentFactory } from '../../../../types/arguments'; import { ArgumentStrings } from '../../../../i18n'; @@ -15,6 +16,10 @@ import { FORMATS_UI_SETTINGS } from '../../../../../../../src/plugins/field_form const { NumberFormat: strings } = ArgumentStrings; +const getNumberFormatArgInput = (defaultNumberFormats: ComponentProps['numberFormats']) => ( + props: Assign +) => ; + export const numberFormatInitializer: SetupInitializer> = ( core, plugins @@ -35,14 +40,10 @@ export const numberFormatInitializer: SetupInitializer(withProps({ numberFormats }))( - Component - ); - return () => ({ name: 'numberFormat', displayName: strings.getDisplayName(), help: strings.getHelp(), - simpleTemplate: templateFromReactComponent(NumberFormatArgInput), + simpleTemplate: templateFromReactComponent(getNumberFormatArgInput(numberFormats)), }); }; diff --git a/x-pack/plugins/canvas/public/components/arg_form/arg_form.js b/x-pack/plugins/canvas/public/components/arg_form/arg_form.js index 88cb529fcdb8d..0f22307c9cd1c 100644 --- a/x-pack/plugins/canvas/public/components/arg_form/arg_form.js +++ b/x-pack/plugins/canvas/public/components/arg_form/arg_form.js @@ -5,9 +5,8 @@ * 2.0. */ -import React, { PureComponent } from 'react'; +import React, { useRef, useEffect } from 'react'; import PropTypes from 'prop-types'; -import { compose, branch, renderComponent } from 'recompose'; import { ErrorBoundary } from '../enhance/error_boundary'; import { ArgSimpleForm } from './arg_simple_form'; import { ArgTemplateForm } from './arg_template_form'; @@ -16,132 +15,131 @@ import { AdvancedFailure } from './advanced_failure'; import { ArgLabel } from './arg_label'; import { PendingArgValue } from './pending_arg_value'; -const branches = [ - // rendered argType args should be resolved, but are not - branch(({ argTypeInstance, resolvedArgValue }) => { - const { argType } = argTypeInstance; +const isPending = (argTypeInstance, resolvedArgValue) => { + const { argType } = argTypeInstance; - // arg does not need to be resolved, no need to branch - if (!argType.resolveArgValue) { - return false; - } + // arg does not need to be resolved, no need to branch + if (!argType.resolveArgValue) { + return false; + } - // arg needs to be resolved, render pending if the value is not defined - return typeof resolvedArgValue === 'undefined'; - }, renderComponent(PendingArgValue)), -]; + // arg needs to be resolved, render pending if the value is not defined + return typeof resolvedArgValue === 'undefined'; +}; // This is what is being generated by render() from the Arg class. It is called in FunctionForm -class ArgFormComponent extends PureComponent { - componentDidMount() { - // keep track of whether or not the component is mounted, to prevent rogue setState calls - this._isMounted = true; - } - - componentWillUnmount() { - this._isMounted = false; +export const ArgForm = (props) => { + const { + argId, + argTypeInstance, + templateProps, + valueMissing, + label, + setLabel, + onValueRemove, + workpad, + assets, + renderError, + setRenderError, + resolvedArgValue, + } = props; + + const isMounted = useRef(); + + useEffect(() => { + isMounted.current = true; + return () => { + isMounted.current = false; + }; + }, []); + + if (isPending(argTypeInstance, resolvedArgValue)) { + return ; } - render() { - const { - argId, - argTypeInstance, - templateProps, - valueMissing, - label, - setLabel, - onValueRemove, - workpad, - assets, - renderError, - setRenderError, - resolvedArgValue, - } = this.props; - - return ( - - {({ error, resetErrorState }) => { - const { template, simpleTemplate } = argTypeInstance.argType; - const hasError = Boolean(error) || renderError; - - const argumentProps = { - ...templateProps, - resolvedArgValue, - defaultValue: argTypeInstance.default, - - renderError: () => { - // TODO: don't do this - // It's an ugly hack to avoid React's render cycle and ensure the error happens on the next tick - // This is important; Otherwise we end up updating state in the middle of a render cycle - Promise.resolve().then(() => { - // Provide templates with a renderError method, and wrap the error in a known error type - // to stop Kibana's window.error from being called - // see window_error_handler.js for details, - this._isMounted && setRenderError(true); - }); - }, - error: hasError, - setLabel: (label) => this._isMounted && setLabel(label), - resetErrorState: () => { - resetErrorState(); - this._isMounted && setRenderError(false); - }, - label, - workpad, - argId, - assets, - }; - - const expandableLabel = Boolean(hasError || template); - - const simpleArg = ( - + {({ error, resetErrorState }) => { + const { template, simpleTemplate } = argTypeInstance.argType; + const hasError = Boolean(error) || renderError; + + const argumentProps = { + ...templateProps, + resolvedArgValue, + defaultValue: argTypeInstance.default, + + renderError: () => { + // TODO: don't do this + // It's an ugly hack to avoid React's render cycle and ensure the error happens on the next tick + // This is important; Otherwise we end up updating state in the middle of a render cycle + Promise.resolve().then(() => { + // Provide templates with a renderError method, and wrap the error in a known error type + // to stop Kibana's window.error from being called + // see window_error_handler.js for details, + isMounted.current && setRenderError(true); + }); + }, + error: hasError, + setLabel: (label) => isMounted.current && setLabel(label), + resetErrorState: () => { + resetErrorState(); + isMounted.current && setRenderError(false); + }, + label, + workpad, + argId, + assets, + }; + + const expandableLabel = Boolean(hasError || template); + + const simpleArg = ( + + + + ); + + const extendedArg = ( +

+ +
+ ); + + return ( +
+ - - - ); - - const extendedArg = ( -
- -
- ); - - return ( -
- - {extendedArg} - -
- ); - }} - - ); - } -} + {extendedArg} +
+
+ ); + }} + + ); +}; -ArgFormComponent.propTypes = { +ArgForm.propTypes = { argId: PropTypes.string.isRequired, workpad: PropTypes.object.isRequired, argTypeInstance: PropTypes.shape({ @@ -161,5 +159,3 @@ ArgFormComponent.propTypes = { setRenderError: PropTypes.func.isRequired, resolvedArgValue: PropTypes.any, }; - -export const ArgForm = compose(...branches)(ArgFormComponent); diff --git a/x-pack/plugins/canvas/public/components/arg_form/arg_label.js b/x-pack/plugins/canvas/public/components/arg_form/arg_label.js index e199019bc27b6..58ad44b4cbf8a 100644 --- a/x-pack/plugins/canvas/public/components/arg_form/arg_label.js +++ b/x-pack/plugins/canvas/public/components/arg_form/arg_label.js @@ -30,21 +30,19 @@ export const ArgLabel = (props) => {
{children}
) : ( - simpleArg && ( - - - {label} - - - } - id={argId} - > - {simpleArg} - - ) + + + {label} + + + } + id={argId} + > + {simpleArg || children} + )}
); diff --git a/x-pack/plugins/canvas/public/components/arg_form/arg_template_form.js b/x-pack/plugins/canvas/public/components/arg_form/arg_template_form.js deleted file mode 100644 index 4b968c9dd4ee0..0000000000000 --- a/x-pack/plugins/canvas/public/components/arg_form/arg_template_form.js +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import PropTypes from 'prop-types'; -import { compose, withPropsOnChange, withProps } from 'recompose'; -import { RenderToDom } from '../render_to_dom'; -import { ExpressionFormHandlers } from '../../../common/lib/expression_form_handlers'; - -class ArgTemplateFormComponent extends React.Component { - static propTypes = { - template: PropTypes.func, - argumentProps: PropTypes.shape({ - valueMissing: PropTypes.bool, - label: PropTypes.string, - setLabel: PropTypes.func.isRequired, - expand: PropTypes.bool, - setExpand: PropTypes.func, - onValueRemove: PropTypes.func, - resetErrorState: PropTypes.func.isRequired, - renderError: PropTypes.func.isRequired, - }), - handlers: PropTypes.object.isRequired, - error: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]).isRequired, - errorTemplate: PropTypes.oneOfType([PropTypes.element, PropTypes.func]).isRequired, - }; - - UNSAFE_componentWillUpdate(prevProps) { - //see if error state changed - if (this.props.error !== prevProps.error) { - this.props.handlers.destroy(); - } - } - componentDidUpdate() { - if (this.props.error) { - return this._renderErrorTemplate(); - } - this._renderTemplate(this._domNode); - } - - componentWillUnmount() { - this.props.handlers.destroy(); - } - - _domNode = null; - - _renderTemplate = (domNode) => { - const { template, argumentProps, handlers } = this.props; - if (template) { - return template(domNode, argumentProps, handlers); - } - }; - - _renderErrorTemplate = () => { - const { errorTemplate, argumentProps } = this.props; - return React.createElement(errorTemplate, argumentProps); - }; - - render() { - const { template, error } = this.props; - - if (error) { - return this._renderErrorTemplate(); - } - - if (!template) { - return null; - } - - return ( - { - this._domNode = domNode; - this._renderTemplate(domNode); - }} - /> - ); - } -} - -export const ArgTemplateForm = compose( - withPropsOnChange( - () => false, - () => ({ - expressionFormHandlers: new ExpressionFormHandlers(), - }) - ), - withProps(({ handlers, expressionFormHandlers }) => ({ - handlers: Object.assign(expressionFormHandlers, handlers), - })) -)(ArgTemplateFormComponent); diff --git a/x-pack/plugins/canvas/public/components/arg_form/arg_template_form.tsx b/x-pack/plugins/canvas/public/components/arg_form/arg_template_form.tsx new file mode 100644 index 0000000000000..1d7227d65e536 --- /dev/null +++ b/x-pack/plugins/canvas/public/components/arg_form/arg_template_form.tsx @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState, useEffect, useCallback, useRef } from 'react'; +import usePrevious from 'react-use/lib/usePrevious'; +import { RenderToDom } from '../render_to_dom'; +import { ExpressionFormHandlers } from '../../../common/lib/expression_form_handlers'; + +interface ArgTemplateFormProps { + template?: ( + domNode: HTMLElement, + config: ArgTemplateFormProps['argumentProps'], + handlers: ArgTemplateFormProps['handlers'] + ) => void; + argumentProps: { + valueMissing?: boolean; + label?: string; + setLabel: (label: string) => void; + expand?: boolean; + setExpand?: (expand: boolean) => void; + onValueRemove?: (argName: string, argIndex: string) => void; + resetErrorState: () => void; + renderError: () => void; + }; + handlers?: { [key: string]: (...args: any[]) => any }; + error?: unknown; + errorTemplate: React.FunctionComponent; +} + +const mergeWithFormHandlers = (handlers: ArgTemplateFormProps['handlers']) => + Object.assign(new ExpressionFormHandlers(), handlers); + +export const ArgTemplateForm: React.FunctionComponent = ({ + template, + argumentProps, + handlers, + error, + errorTemplate, +}) => { + const [updatedHandlers, setHandlers] = useState(mergeWithFormHandlers(handlers)); + const previousError = usePrevious(error); + const domNodeRef = useRef(); + const renderTemplate = useCallback( + (domNode) => template && template(domNode, argumentProps, updatedHandlers), + [template, argumentProps, updatedHandlers] + ); + + const renderErrorTemplate = useCallback(() => React.createElement(errorTemplate, argumentProps), [ + errorTemplate, + argumentProps, + ]); + + useEffect(() => { + setHandlers(mergeWithFormHandlers(handlers)); + }, [handlers]); + + useEffect(() => { + if (previousError !== error) { + updatedHandlers.destroy(); + } + }, [previousError, error, updatedHandlers]); + + useEffect(() => { + if (!error) { + renderTemplate(domNodeRef.current); + } + }, [error, renderTemplate, domNodeRef]); + + if (error) { + return renderErrorTemplate(); + } + + if (!template) { + return null; + } + + return ( + { + domNodeRef.current = domNode; + renderTemplate(domNode); + }} + /> + ); +}; diff --git a/x-pack/plugins/canvas/public/components/arg_form/pending_arg_value.js b/x-pack/plugins/canvas/public/components/arg_form/pending_arg_value.js index f933230f39928..38b29c7d80091 100644 --- a/x-pack/plugins/canvas/public/components/arg_form/pending_arg_value.js +++ b/x-pack/plugins/canvas/public/components/arg_form/pending_arg_value.js @@ -47,7 +47,6 @@ export class PendingArgValue extends React.PureComponent { render() { const { label, argTypeInstance } = this.props; - return (
{ + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('contains a button to delete the domain', () => { + setMockValues(MOCK_VALUES); + setMockActions(MOCK_ACTIONS); + + const confirmSpy = jest.spyOn(window, 'confirm'); + confirmSpy.mockImplementation(jest.fn(() => true)); + + const wrapper = shallow(); + wrapper.find(EuiButton).simulate('click'); + + expect(MOCK_ACTIONS.deleteDomain).toHaveBeenCalledWith(MOCK_VALUES.domain); + }); + + it("doesn't throw if the users chooses not to confirm", () => { + setMockValues(MOCK_VALUES); + + const confirmSpy = jest.spyOn(window, 'confirm'); + confirmSpy.mockImplementation(jest.fn(() => false)); + + const wrapper = shallow(); + wrapper.find(EuiButton).simulate('click'); + }); + + // The user should never encounter this state, the containing AppSearchTemplate should be loading until + // the relevant domain has been loaded. However we must account for the possibility in this component. + it('is empty if domain has not yet been set', () => { + setMockValues({ + ...MOCK_VALUES, + domain: null, + }); + + const wrapper = shallow(); + + expect(wrapper.isEmptyRender()).toBe(true); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/delete_domain_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/delete_domain_panel.tsx new file mode 100644 index 0000000000000..084d9693fe279 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/delete_domain_panel.tsx @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useActions, useValues } from 'kea'; + +import { EuiButton, EuiSpacer, EuiText } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { CrawlerSingleDomainLogic } from '../crawler_single_domain_logic'; +import { getDeleteDomainSuccessMessage } from '../utils'; + +export const DeleteDomainPanel: React.FC = ({}) => { + const { domain } = useValues(CrawlerSingleDomainLogic); + const { deleteDomain } = useActions(CrawlerSingleDomainLogic); + + if (!domain) { + return null; + } + + return ( + <> + +

+ + {i18n.translate( + 'xpack.enterpriseSearch.appSearch.crawler.deleteDomainPanel.cannotUndoMessage', + { + defaultMessage: 'This cannot be undone', + } + )} + + ), + }} + /> +

+
+ + { + if (confirm(getDeleteDomainSuccessMessage(domain.url))) { + deleteDomain(domain); + } + }} + > + {i18n.translate( + 'xpack.enterpriseSearch.appSearch.crawler.deleteDomainPanel.deleteDomainButtonLabel', + { + defaultMessage: 'Delete domain', + } + )} + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.tsx index 0da3b8462cfcf..9dd0a518f233b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.tsx @@ -23,6 +23,8 @@ import { generateEnginePath } from '../../engine'; import { CrawlerOverviewLogic } from '../crawler_overview_logic'; import { CrawlerDomain } from '../types'; +import { getDeleteDomainConfirmationMessage } from '../utils'; + import { CustomFormattedTimestamp } from './custom_formatted_timestamp'; export const DomainsTable: React.FC = () => { @@ -101,20 +103,7 @@ export const DomainsTable: React.FC = () => { icon: 'trash', color: 'danger', onClick: (domain) => { - if ( - window.confirm( - i18n.translate( - 'xpack.enterpriseSearch.appSearch.crawler.domainsTable.action.delete.confirmationPopupMessage', - { - defaultMessage: - 'Are you sure you want to remove the domain "{domainUrl}" and all of its settings?', - values: { - domainUrl: domain.url, - }, - } - ) - ) - ) { + if (window.confirm(getDeleteDomainConfirmationMessage(domain.url))) { deleteDomain(domain); } }, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover.test.tsx new file mode 100644 index 0000000000000..e97d9a703b668 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover.test.tsx @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { + EuiButton, + EuiContextMenuItem, + EuiContextMenuPanel, + EuiPopover, + EuiResizeObserver, +} from '@elastic/eui'; + +import { mountWithIntl } from '../../../../../test_helpers'; +import { CrawlerDomain } from '../../types'; + +import { ManageCrawlsPopover } from './manage_crawls_popover'; + +const MOCK_ACTIONS = { + closePopover: jest.fn(), + reApplyCrawlRules: jest.fn(), + togglePopover: jest.fn(), +}; + +const MOCK_VALUES = { + isOpen: false, +}; + +const MOCK_DOMAIN = { url: 'https://elastic.co' } as CrawlerDomain; + +describe('ManageCrawlsPopover', () => { + beforeEach(() => { + jest.clearAllMocks(); + setMockActions(MOCK_ACTIONS); + setMockValues(MOCK_VALUES); + }); + + it('renders', () => { + const wrapper = shallow(); + + expect(wrapper.is(EuiPopover)).toBe(true); + expect(wrapper.prop('closePopover')).toEqual(MOCK_ACTIONS.closePopover); + expect(wrapper.dive().find(EuiButton).prop('onClick')).toEqual(MOCK_ACTIONS.togglePopover); + }); + + it('is closed by default', () => { + const wrapper = shallow(); + + expect(wrapper.find(EuiContextMenuPanel)).toHaveLength(0); + }); + + it('includes a context menu when open', () => { + setMockValues({ + ...MOCK_VALUES, + isOpen: true, + }); + + const wrapper = mountWithIntl(); + + const menuItems = wrapper + .find(EuiContextMenuPanel) + .find(EuiResizeObserver) + .find(EuiContextMenuItem); + + expect(menuItems).toHaveLength(1); + + menuItems.first().simulate('click'); + expect(MOCK_ACTIONS.reApplyCrawlRules).toHaveBeenCalledWith(MOCK_DOMAIN); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover.tsx new file mode 100644 index 0000000000000..a980ee73ebcd4 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover.tsx @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useActions, useValues } from 'kea'; + +import { EuiButton, EuiContextMenu, EuiPopover } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { CrawlerDomain } from '../../types'; + +// import { AutomaticCrawlScheduler } from './automatic_crawl_scheduler'; + +import { ManageCrawlsPopoverLogic } from './manage_crawls_popover_logic'; + +interface ManageCrawlsPopoverProps { + domain?: CrawlerDomain; +} + +export const ManageCrawlsPopover: React.FC = ({ domain }) => { + const { closePopover, reApplyCrawlRules, togglePopover } = useActions(ManageCrawlsPopoverLogic); + + const { isOpen } = useValues(ManageCrawlsPopoverLogic); + + const panels = [ + { + id: 0, + items: [ + { + name: i18n.translate( + 'xpack.enterpriseSearch.appSearch.crawler.manageCrawlsPopover.reApplyCrawlRulesButtonLabel', + { defaultMessage: 'Re-apply crawl rules' } + ), + icon: 'refresh', + onClick: () => reApplyCrawlRules(domain), + }, + // { + // name: 'Automatic Crawling', + // icon: 'gear', + // panel: 1, + // }, + ], + }, + // { + // id: 1, + // title: 'Automatic Crawling', + // width: 400, + // content: , + // }, + ]; + + return ( + + {i18n.translate( + 'xpack.enterpriseSearch.appSearch.crawler.manageCrawlsPopover.manageCrawlsButtonLabel', + { defaultMessage: 'Manage crawls' } + )} + + } + > + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover_logic.test.ts new file mode 100644 index 0000000000000..a804164a90dca --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover_logic.test.ts @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + LogicMounter, + mockHttpValues, + mockFlashMessageHelpers, +} from '../../../../../__mocks__/kea_logic'; +import '../../../../__mocks__/engine_logic.mock'; + +import { nextTick } from '@kbn/test/jest'; + +import { CrawlerDomain } from '../../types'; + +import { ManageCrawlsPopoverLogic } from './manage_crawls_popover_logic'; + +describe('ManageCrawlsPopoverLogic', () => { + const { mount } = new LogicMounter(ManageCrawlsPopoverLogic); + const { http } = mockHttpValues; + const { flashAPIErrors, flashSuccessToast } = mockFlashMessageHelpers; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('has expected default values', () => { + mount(); + + expect(ManageCrawlsPopoverLogic.values).toEqual({ + isOpen: false, + }); + }); + + describe('actions', () => { + describe('closePopover', () => { + it('closes the popover', () => { + mount({ + isOpen: true, + }); + + ManageCrawlsPopoverLogic.actions.closePopover(); + + expect(ManageCrawlsPopoverLogic.values.isOpen).toEqual(false); + }); + }); + + describe('togglePopover', () => { + it('toggles the visibility of the popover', () => { + mount({ + isOpen: false, + }); + + ManageCrawlsPopoverLogic.actions.togglePopover(); + + expect(ManageCrawlsPopoverLogic.values.isOpen).toEqual(true); + + ManageCrawlsPopoverLogic.actions.togglePopover(); + + expect(ManageCrawlsPopoverLogic.values.isOpen).toEqual(false); + }); + }); + }); + + describe('listeners', () => { + describe('reApplyCrawlRules', () => { + it('flashes a success toast on success', async () => { + jest.spyOn(ManageCrawlsPopoverLogic.actions, 'closePopover'); + http.post.mockReturnValueOnce(Promise.resolve()); + + ManageCrawlsPopoverLogic.actions.reApplyCrawlRules({ + url: 'https://elastic.co', + } as CrawlerDomain); + await nextTick(); + + expect(flashSuccessToast).toHaveBeenCalled(); + expect(ManageCrawlsPopoverLogic.actions.closePopover).toHaveBeenCalled(); + }); + + it('flashes an error callout if there is an error', async () => { + jest.spyOn(ManageCrawlsPopoverLogic.actions, 'closePopover'); + http.post.mockReturnValueOnce(Promise.reject('error')); + + ManageCrawlsPopoverLogic.actions.reApplyCrawlRules(); + await nextTick(); + + expect(flashAPIErrors).toHaveBeenCalledWith('error'); + expect(ManageCrawlsPopoverLogic.actions.closePopover).toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover_logic.ts new file mode 100644 index 0000000000000..c269a2ab595c2 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/manage_crawls_popover/manage_crawls_popover_logic.ts @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { kea, MakeLogicType } from 'kea'; + +import { flashAPIErrors, flashSuccessToast } from '../../../../../shared/flash_messages'; +import { HttpLogic } from '../../../../../shared/http'; +import { EngineLogic } from '../../../engine'; +import { CrawlerDomain } from '../../types'; + +export interface ManageCrawlsPopoverLogicValues { + isOpen: boolean; +} + +export interface ManageCrawlsPopoverLogicActions { + closePopover(): void; + reApplyCrawlRules(domain?: CrawlerDomain): { domain: CrawlerDomain }; + togglePopover(): void; +} + +export const ManageCrawlsPopoverLogic = kea< + MakeLogicType +>({ + path: ['enterprise_search', 'app_search', 'crawler', 'manage_crawls_popover'], + actions: () => ({ + closePopover: true, + reApplyCrawlRules: (domain) => ({ domain }), + togglePopover: true, + }), + reducers: () => ({ + isOpen: [ + false, + { + closePopover: () => false, + togglePopover: (currentIsOpen) => !currentIsOpen, + }, + ], + }), + listeners: ({ actions }) => ({ + reApplyCrawlRules: async ({ domain }) => { + const { engineName } = EngineLogic.values; + const { http } = HttpLogic.values; + const requestBody: { domains?: string[] } = {}; + + if (domain) { + requestBody.domains = [domain.url]; + } + + try { + await http.post(`/api/app_search/engines/${engineName}/crawler/process_crawls`, { + body: JSON.stringify(requestBody), + }); + + flashSuccessToast('Crawl Rules are being re-applied in the background'); + } catch (e) { + flashAPIErrors(e); + } finally { + actions.closePopover(); + } + }, + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx index ae4fc6b04b002..8e8ed0d4c9258 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.test.tsx @@ -22,6 +22,7 @@ import { CrawlRequestsTable } from './components/crawl_requests_table'; import { CrawlerStatusBanner } from './components/crawler_status_banner'; import { CrawlerStatusIndicator } from './components/crawler_status_indicator/crawler_status_indicator'; import { DomainsTable } from './components/domains_table'; +import { ManageCrawlsPopover } from './components/manage_crawls_popover/manage_crawls_popover'; import { CrawlerOverview } from './crawler_overview'; import { CrawlerDomainFromServer, @@ -115,6 +116,12 @@ describe('CrawlerOverview', () => { expect(getPageHeaderActions(wrapper).find(CrawlerStatusIndicator)).toHaveLength(1); }); + it('contains a popover to manage crawls', () => { + const wrapper = shallow(); + + expect(getPageHeaderActions(wrapper).find(ManageCrawlsPopover)).toHaveLength(1); + }); + it('hides the domain and crawl request tables when there are no domains, and no crawl requests', () => { setMockValues({ ...mockValues, domains: [], crawlRequests: [] }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx index c18c1a753d247..e268acbae5c90 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview.tsx @@ -24,6 +24,7 @@ import { CrawlRequestsTable } from './components/crawl_requests_table'; import { CrawlerStatusBanner } from './components/crawler_status_banner'; import { CrawlerStatusIndicator } from './components/crawler_status_indicator/crawler_status_indicator'; import { DomainsTable } from './components/domains_table'; +import { ManageCrawlsPopover } from './components/manage_crawls_popover/manage_crawls_popover'; import { CRAWLER_TITLE } from './constants'; import { CrawlerOverviewLogic } from './crawler_overview_logic'; @@ -42,7 +43,7 @@ export const CrawlerOverview: React.FC = () => { pageChrome={getEngineBreadcrumbs([CRAWLER_TITLE])} pageHeader={{ pageTitle: CRAWLER_TITLE, - rightSideItems: [], + rightSideItems: [, ], }} isLoading={dataLoading} > diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview_logic.ts index 35dd866c0453e..0506f4ba647f7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_overview_logic.ts @@ -7,8 +7,6 @@ import { kea, MakeLogicType } from 'kea'; -import { i18n } from '@kbn/i18n'; - import { flashAPIErrors, flashSuccessToast } from '../../../shared/flash_messages'; import { HttpLogic } from '../../../shared/http'; @@ -21,18 +19,11 @@ import { CrawlRequestFromServer, CrawlerStatus, } from './types'; -import { crawlerDataServerToClient, crawlRequestServerToClient } from './utils'; - -export const DELETE_DOMAIN_MESSAGE = (domainUrl: string) => - i18n.translate( - 'xpack.enterpriseSearch.appSearch.crawler.domainsTable.action.delete.successMessage', - { - defaultMessage: "Domain '{domainUrl}' was deleted", - values: { - domainUrl, - }, - } - ); +import { + crawlerDataServerToClient, + crawlRequestServerToClient, + getDeleteDomainSuccessMessage, +} from './utils'; const POLLING_DURATION = 1000; const POLLING_DURATION_ON_FAILURE = 5000; @@ -145,7 +136,7 @@ export const CrawlerOverviewLogic = kea< ); const crawlerData = crawlerDataServerToClient(response); actions.onReceiveCrawlerData(crawlerData); - flashSuccessToast(DELETE_DOMAIN_MESSAGE(domain.url)); + flashSuccessToast(getDeleteDomainSuccessMessage(domain.url)); } catch (e) { flashAPIErrors(e); } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain.test.tsx index e2b230041c810..52e3ca19e69e6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain.test.tsx @@ -19,6 +19,8 @@ import { getPageHeaderActions } from '../../../test_helpers'; import { CrawlerStatusBanner } from './components/crawler_status_banner'; import { CrawlerStatusIndicator } from './components/crawler_status_indicator/crawler_status_indicator'; +import { DeleteDomainPanel } from './components/delete_domain_panel'; +import { ManageCrawlsPopover } from './components/manage_crawls_popover/manage_crawls_popover'; import { CrawlerOverview } from './crawler_overview'; import { CrawlerSingleDomain } from './crawler_single_domain'; @@ -50,6 +52,7 @@ describe('CrawlerSingleDomain', () => { it('renders', () => { const wrapper = shallow(); + expect(wrapper.find(DeleteDomainPanel)).toHaveLength(1); expect(wrapper.find(EuiCode).render().text()).toContain('https://elastic.co'); expect(wrapper.prop('pageHeader').pageTitle).toEqual('https://elastic.co'); }); @@ -76,4 +79,10 @@ describe('CrawlerSingleDomain', () => { expect(getPageHeaderActions(wrapper).find(CrawlerStatusIndicator)).toHaveLength(1); }); + + it('contains a popover to manage crawls', () => { + const wrapper = shallow(); + + expect(getPageHeaderActions(wrapper).find(ManageCrawlsPopover)).toHaveLength(1); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain.tsx index 9f9ec288a690c..aaa5f0d553983 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain.tsx @@ -11,7 +11,7 @@ import { useParams } from 'react-router-dom'; import { useActions, useValues } from 'kea'; -import { EuiCode, EuiSpacer } from '@elastic/eui'; +import { EuiCode, EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -20,6 +20,8 @@ import { AppSearchPageTemplate } from '../layout'; import { CrawlerStatusBanner } from './components/crawler_status_banner'; import { CrawlerStatusIndicator } from './components/crawler_status_indicator/crawler_status_indicator'; +import { DeleteDomainPanel } from './components/delete_domain_panel'; +import { ManageCrawlsPopover } from './components/manage_crawls_popover/manage_crawls_popover'; import { CRAWLER_TITLE } from './constants'; import { CrawlerSingleDomainLogic } from './crawler_single_domain_logic'; @@ -43,11 +45,27 @@ export const CrawlerSingleDomain: React.FC = () => { return ( ] }} + pageHeader={{ + pageTitle: displayDomainUrl, + rightSideItems: [, ], + }} isLoading={dataLoading} > + +

+ {i18n.translate( + 'xpack.enterpriseSearch.appSearch.crawler.singleDomain.deleteDomainTitle', + { + defaultMessage: 'Delete domain', + } + )} +

+
+ + + {JSON.stringify(domain, null, 2)}
); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain_logic.test.ts index bb478a30ee5ef..f6c3b2c87ab8c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain_logic.test.ts @@ -9,6 +9,7 @@ import { LogicMounter, mockHttpValues, mockFlashMessageHelpers, + mockKibanaValues, } from '../../../__mocks__/kea_logic'; import '../../__mocks__/engine_logic.mock'; @@ -25,7 +26,7 @@ const DEFAULT_VALUES: CrawlerSingleDomainValues = { describe('CrawlerSingleDomainLogic', () => { const { mount } = new LogicMounter(CrawlerSingleDomainLogic); const { http } = mockHttpValues; - const { flashAPIErrors } = mockFlashMessageHelpers; + const { flashAPIErrors, flashSuccessToast } = mockFlashMessageHelpers; beforeEach(() => { jest.clearAllMocks(); @@ -53,6 +54,33 @@ describe('CrawlerSingleDomainLogic', () => { }); describe('listeners', () => { + describe('deleteDomain', () => { + it('flashes a success toast and redirects the user to the crawler overview on success', async () => { + const { navigateToUrl } = mockKibanaValues; + + http.delete.mockReturnValue(Promise.resolve()); + + CrawlerSingleDomainLogic.actions.deleteDomain({ id: '1234' } as CrawlerDomain); + await nextTick(); + + expect(http.delete).toHaveBeenCalledWith( + '/api/app_search/engines/some-engine/crawler/domains/1234' + ); + + expect(flashSuccessToast).toHaveBeenCalled(); + expect(navigateToUrl).toHaveBeenCalledWith('/engines/some-engine/crawler'); + }); + + it('calls flashApiErrors when there is an error', async () => { + http.delete.mockReturnValue(Promise.reject('error')); + + CrawlerSingleDomainLogic.actions.deleteDomain({ id: '1234' } as CrawlerDomain); + await nextTick(); + + expect(flashAPIErrors).toHaveBeenCalledWith('error'); + }); + }); + describe('fetchDomainData', () => { it('updates logic with data that has been converted from server to client', async () => { jest.spyOn(CrawlerSingleDomainLogic.actions, 'onReceiveDomainData'); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain_logic.ts index bccd67a4921d1..7b5ba6984f106 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawler_single_domain_logic.ts @@ -7,13 +7,15 @@ import { kea, MakeLogicType } from 'kea'; -import { flashAPIErrors } from '../../../shared/flash_messages'; +import { flashAPIErrors, flashSuccessToast } from '../../../shared/flash_messages'; import { HttpLogic } from '../../../shared/http'; -import { EngineLogic } from '../engine'; +import { KibanaLogic } from '../../../shared/kibana'; +import { ENGINE_CRAWLER_PATH } from '../../routes'; +import { EngineLogic, generateEnginePath } from '../engine'; import { CrawlerDomain } from './types'; -import { crawlerDomainServerToClient } from './utils'; +import { crawlerDomainServerToClient, getDeleteDomainSuccessMessage } from './utils'; export interface CrawlerSingleDomainValues { dataLoading: boolean; @@ -21,6 +23,7 @@ export interface CrawlerSingleDomainValues { } interface CrawlerSingleDomainActions { + deleteDomain(domain: CrawlerDomain): { domain: CrawlerDomain }; fetchDomainData(domainId: string): { domainId: string }; onReceiveDomainData(domain: CrawlerDomain): { domain: CrawlerDomain }; } @@ -30,6 +33,7 @@ export const CrawlerSingleDomainLogic = kea< >({ path: ['enterprise_search', 'app_search', 'crawler', 'crawler_single_domain'], actions: { + deleteDomain: (domain) => ({ domain }), fetchDomainData: (domainId) => ({ domainId }), onReceiveDomainData: (domain) => ({ domain }), }, @@ -48,6 +52,19 @@ export const CrawlerSingleDomainLogic = kea< ], }, listeners: ({ actions }) => ({ + deleteDomain: async ({ domain }) => { + const { http } = HttpLogic.values; + const { engineName } = EngineLogic.values; + + try { + await http.delete(`/api/app_search/engines/${engineName}/crawler/domains/${domain.id}`); + + flashSuccessToast(getDeleteDomainSuccessMessage(domain.url)); + KibanaLogic.values.navigateToUrl(generateEnginePath(ENGINE_CRAWLER_PATH)); + } catch (e) { + flashAPIErrors(e); + } + }, fetchDomainData: async ({ domainId }) => { const { http } = HttpLogic.values; const { engineName } = EngineLogic.values; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts index 95a7c714eba6a..e356fae46f30e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts @@ -23,6 +23,8 @@ import { crawlerDataServerToClient, crawlDomainValidationToResult, crawlRequestServerToClient, + getDeleteDomainConfirmationMessage, + getDeleteDomainSuccessMessage, } from './utils'; const DEFAULT_CRAWL_RULE: CrawlRule = { @@ -223,3 +225,17 @@ describe('crawlDomainValidationToResult', () => { } as CrawlerDomainValidationStep); }); }); + +describe('getDeleteDomainConfirmationMessage', () => { + it('includes the url', () => { + expect(getDeleteDomainConfirmationMessage('https://elastic.co/')).toContain( + 'https://elastic.co' + ); + }); +}); + +describe('getDeleteDomainSuccessMessage', () => { + it('includes the url', () => { + expect(getDeleteDomainSuccessMessage('https://elastic.co/')).toContain('https://elastic.co'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts index fe759044b3e1b..a25025dc08522 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { i18n } from '@kbn/i18n'; + import { CrawlerDomain, CrawlerDomainFromServer, @@ -101,3 +103,28 @@ export function crawlDomainValidationToResult( state: 'valid', }; } + +export const getDeleteDomainConfirmationMessage = (domainUrl: string) => { + return i18n.translate( + 'xpack.enterpriseSearch.appSearch.crawler.action.deleteDomain.confirmationPopupMessage', + { + defaultMessage: + 'Are you sure you want to remove the domain "{domainUrl}" and all of its settings?', + values: { + domainUrl, + }, + } + ); +}; + +export const getDeleteDomainSuccessMessage = (domainUrl: string) => { + return i18n.translate( + 'xpack.enterpriseSearch.appSearch.crawler.action.deleteDomain.successMessage', + { + defaultMessage: "Domain '{domainUrl}' was deleted", + values: { + domainUrl, + }, + } + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.scss b/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.scss index 677767c190f0e..adf2dc16d8327 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.scss +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.scss @@ -6,15 +6,18 @@ */ @include euiBreakpoint('m', 'l', 'xl') { - .kbnPageTemplateSolutionNav { - display: flex; - flex-direction: column; - } - .euiSideNav__content { - flex-grow: 1; - display: flex; - flex-direction: column; - justify-content: space-between; + .betaSidebarNotification { + .euiSideNav { + display: flex; + flex-direction: column; + + .euiSideNav__content { + flex-grow: 1; + display: flex; + flex-direction: column; + justify-content: space-between; + } + } } } diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx index 5da455283eceb..202c9b6a59e8d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx @@ -79,6 +79,7 @@ export const EnterpriseSearchPageTemplate: React.FC = ({ }} isEmptyState={isEmptyState && !isLoading} solutionNav={solutionNav ? { icon: 'logoEnterpriseSearch', ...solutionNav } : undefined} + pageSideBarProps={{ className: 'betaSidebarNotification' }} > {setPageChrome} {readOnlyMode && ( diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/crawler.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/crawler.test.ts index 3b790bf2696cb..3107afbf46cdd 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/crawler.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/crawler.test.ts @@ -318,4 +318,51 @@ describe('crawler routes', () => { mockRouter.shouldThrow(request); }); }); + + describe('POST /api/app_search/engines/{name}/crawler/process_crawls', () => { + let mockRouter: MockRouter; + + beforeEach(() => { + jest.clearAllMocks(); + mockRouter = new MockRouter({ + method: 'post', + path: '/api/app_search/engines/{name}/crawler/process_crawls', + }); + + registerCrawlerRoutes({ + ...mockDependencies, + router: mockRouter.router, + }); + }); + + it('creates a request to enterprise search', () => { + expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ + path: '/api/as/v0/engines/:name/crawler/process_crawls', + }); + }); + + it('validates correctly', () => { + const request = { + params: { name: 'some-engine' }, + body: { domains: ['https://elastic.co', 'https://swiftype.com'] }, + }; + mockRouter.shouldValidate(request); + }); + + it('validates correctly without body', () => { + const request = { + params: { name: 'some-engine' }, + body: {}, + }; + mockRouter.shouldValidate(request); + }); + + it('fails validation without a name param', () => { + const request = { + params: {}, + body: { domains: ['https://elastic.co', 'https://swiftype.com'] }, + }; + mockRouter.shouldThrow(request); + }); + }); }); diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/crawler.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/crawler.ts index 26a755a6d2b6c..6374b7c83de8f 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/crawler.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/crawler.ts @@ -141,4 +141,21 @@ export function registerCrawlerRoutes({ path: '/api/as/v0/crawler/validate_url', }) ); + + router.post( + { + path: '/api/app_search/engines/{name}/crawler/process_crawls', + validate: { + params: schema.object({ + name: schema.string(), + }), + body: schema.object({ + domains: schema.maybe(schema.arrayOf(schema.string())), + }), + }, + }, + enterpriseSearchRequestHandler.createRequest({ + path: '/api/as/v0/engines/:name/crawler/process_crawls', + }) + ); } diff --git a/x-pack/plugins/features/kibana.json b/x-pack/plugins/features/kibana.json index 92fdd08e93478..867f9ced7ed88 100644 --- a/x-pack/plugins/features/kibana.json +++ b/x-pack/plugins/features/kibana.json @@ -1,5 +1,9 @@ { "id": "features", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "8.0.0", "kibanaVersion": "kibana", "requiredPlugins": ["licensing"], diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index e3ecdcda20d2a..d3cccd4c07f3c 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -74,6 +74,7 @@ const MONITORING_DATASETS = [ 'elastic_agent.packetbeat', 'elastic_agent.endpoint_security', 'elastic_agent.auditbeat', + 'elastic_agent.heartbeat', ]; class AgentPolicyService { diff --git a/x-pack/plugins/global_search/common/types.ts b/x-pack/plugins/global_search/common/types.ts index a910cc5cd3ae7..fabae7ea01e8f 100644 --- a/x-pack/plugins/global_search/common/types.ts +++ b/x-pack/plugins/global_search/common/types.ts @@ -6,7 +6,7 @@ */ import { Observable } from 'rxjs'; -import { Serializable } from 'src/core/types'; +import { Serializable } from '@kbn/utility-types'; /** * Options provided to {@link GlobalSearchResultProvider | a result provider}'s `find` method. diff --git a/x-pack/plugins/global_search/kibana.json b/x-pack/plugins/global_search/kibana.json index c94e080a8c589..435b622a76d9a 100644 --- a/x-pack/plugins/global_search/kibana.json +++ b/x-pack/plugins/global_search/kibana.json @@ -1,5 +1,9 @@ { "id": "globalSearch", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "8.0.0", "kibanaVersion": "kibana", "server": true, diff --git a/x-pack/plugins/global_search_bar/kibana.json b/x-pack/plugins/global_search_bar/kibana.json index 85e091fe1abad..5c0a9999b8e3a 100644 --- a/x-pack/plugins/global_search_bar/kibana.json +++ b/x-pack/plugins/global_search_bar/kibana.json @@ -1,5 +1,9 @@ { "id": "globalSearchBar", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "8.0.0", "kibanaVersion": "kibana", "server": false, diff --git a/x-pack/plugins/global_search_providers/kibana.json b/x-pack/plugins/global_search_providers/kibana.json index 39eca87d0bf89..eb6b66648e681 100644 --- a/x-pack/plugins/global_search_providers/kibana.json +++ b/x-pack/plugins/global_search_providers/kibana.json @@ -1,5 +1,9 @@ { "id": "globalSearchProviders", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "8.0.0", "kibanaVersion": "kibana", "server": true, diff --git a/x-pack/plugins/graph/public/types/workspace_state.ts b/x-pack/plugins/graph/public/types/workspace_state.ts index e511a2eb5c779..86f05376b9526 100644 --- a/x-pack/plugins/graph/public/types/workspace_state.ts +++ b/x-pack/plugins/graph/public/types/workspace_state.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { FontawesomeIcon } from '../helpers/style_choices'; import { WorkspaceField, AdvancedSettings } from './app_state'; diff --git a/x-pack/plugins/index_lifecycle_management/public/locator.ts b/x-pack/plugins/index_lifecycle_management/public/locator.ts index 025946a095a6f..4df7cf85ddebb 100644 --- a/x-pack/plugins/index_lifecycle_management/public/locator.ts +++ b/x-pack/plugins/index_lifecycle_management/public/locator.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import { ManagementAppLocator } from 'src/plugins/management/common'; import { LocatorDefinition } from '../../../../src/plugins/share/public/'; import { @@ -17,7 +17,7 @@ import { PLUGIN } from '../common/constants'; export const ILM_LOCATOR_ID = 'ILM_LOCATOR_ID'; -export interface IlmLocatorParams extends SerializableState { +export interface IlmLocatorParams extends SerializableRecord { page: 'policies_list' | 'policy_edit' | 'policy_create'; policyName?: string; } diff --git a/x-pack/plugins/infra/common/typed_json.ts b/x-pack/plugins/infra/common/typed_json.ts index 44409ab433a60..fee846b437a7a 100644 --- a/x-pack/plugins/infra/common/typed_json.ts +++ b/x-pack/plugins/infra/common/typed_json.ts @@ -6,7 +6,7 @@ */ import * as rt from 'io-ts'; -import { JsonArray, JsonObject, JsonValue } from '@kbn/common-utils'; +import { JsonArray, JsonObject, JsonValue } from '@kbn/utility-types'; export { JsonArray, JsonObject, JsonValue }; diff --git a/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx b/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx index ff9b749911c84..b927505a42c8a 100644 --- a/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx +++ b/x-pack/plugins/infra/public/components/log_stream/log_stream.tsx @@ -7,7 +7,7 @@ import React, { useMemo, useCallback, useEffect } from 'react'; import { noop } from 'lodash'; -import { JsonValue } from '@kbn/common-utils'; +import { JsonValue } from '@kbn/utility-types'; import { DataPublicPluginStart, esQuery, Filter } from '../../../../../../src/plugins/data/public'; import { euiStyled } from '../../../../../../src/plugins/kibana_react/common'; import { LogEntryCursor } from '../../../common/log_entry'; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/field_value.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/field_value.tsx index 9cffef270219e..e52d302a9193f 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/field_value.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/field_value.tsx @@ -7,7 +7,7 @@ import stringify from 'json-stable-stringify'; import React from 'react'; -import { JsonArray, JsonValue } from '@kbn/common-utils'; +import { JsonArray, JsonValue } from '@kbn/utility-types'; import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common'; import { ActiveHighlightMarker, highlightFieldValue, HighlightMarker } from './highlighting'; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx index 33e81756552d8..d8021aa0279d5 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { JsonValue } from '@kbn/common-utils'; +import { JsonValue } from '@kbn/utility-types'; import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common'; import { LogColumn } from '../../../../common/log_entry'; import { isFieldColumn, isHighlightFieldColumn } from '../../../utils/log_entry'; diff --git a/x-pack/plugins/infra/public/utils/log_column_render_configuration.tsx b/x-pack/plugins/infra/public/utils/log_column_render_configuration.tsx index a6adc716e02fb..ff4a24f1498a6 100644 --- a/x-pack/plugins/infra/public/utils/log_column_render_configuration.tsx +++ b/x-pack/plugins/infra/public/utils/log_column_render_configuration.tsx @@ -6,7 +6,7 @@ */ import { ReactNode } from 'react'; -import { JsonValue } from '@kbn/common-utils'; +import { JsonValue } from '@kbn/utility-types'; /** * Interface for common configuration properties, regardless of the column type. diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts index f33bcd2fcab0c..3cd435ab0f6e8 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts @@ -8,7 +8,7 @@ import type { estypes } from '@elastic/elasticsearch'; import { Lifecycle } from '@hapi/hapi'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { JsonArray, JsonValue } from '@kbn/common-utils'; +import { JsonArray, JsonValue } from '@kbn/utility-types'; import { RouteConfig, RouteMethod } from '../../../../../../../src/core/server'; import { PluginSetup as DataPluginSetup, diff --git a/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts b/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts index 9f2e9e2713bbc..4ad2fa656f9b2 100644 --- a/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts +++ b/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts @@ -11,7 +11,7 @@ import { constant, identity } from 'fp-ts/lib/function'; import { pipe } from 'fp-ts/lib/pipeable'; import * as runtimeTypes from 'io-ts'; import { compact } from 'lodash'; -import { JsonArray } from '@kbn/common-utils'; +import { JsonArray } from '@kbn/utility-types'; import type { InfraPluginRequestHandlerContext } from '../../../types'; import { LogEntriesAdapter, diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts index f8268570710f2..f6be310d79ed2 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts @@ -6,7 +6,7 @@ */ import type { estypes } from '@elastic/elasticsearch'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import type { InfraPluginRequestHandlerContext } from '../../../types'; diff --git a/x-pack/plugins/infra/server/routes/snapshot/lib/get_metrics_aggregations.ts b/x-pack/plugins/infra/server/routes/snapshot/lib/get_metrics_aggregations.ts index 33060f428b7ff..1f8760993c867 100644 --- a/x-pack/plugins/infra/server/routes/snapshot/lib/get_metrics_aggregations.ts +++ b/x-pack/plugins/infra/server/routes/snapshot/lib/get_metrics_aggregations.ts @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { InventoryItemType, MetricsUIAggregation, diff --git a/x-pack/plugins/infra/server/services/log_entries/message/message.ts b/x-pack/plugins/infra/server/services/log_entries/message/message.ts index 2deee584f5187..fc547126b3b44 100644 --- a/x-pack/plugins/infra/server/services/log_entries/message/message.ts +++ b/x-pack/plugins/infra/server/services/log_entries/message/message.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonArray, JsonValue } from '@kbn/common-utils'; +import { JsonArray, JsonValue } from '@kbn/utility-types'; import { LogMessagePart } from '../../../../common/log_entry'; import { LogMessageFormattingCondition, diff --git a/x-pack/plugins/infra/server/services/log_entries/message/rule_types.ts b/x-pack/plugins/infra/server/services/log_entries/message/rule_types.ts index 56d1b38e7e390..65229a747e5ea 100644 --- a/x-pack/plugins/infra/server/services/log_entries/message/rule_types.ts +++ b/x-pack/plugins/infra/server/services/log_entries/message/rule_types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonValue } from '@kbn/common-utils'; +import { JsonValue } from '@kbn/utility-types'; export interface LogMessageFormattingRule { when: LogMessageFormattingCondition; diff --git a/x-pack/plugins/infra/server/utils/serialized_query.ts b/x-pack/plugins/infra/server/utils/serialized_query.ts index 4169e123d8532..b3b2569528aea 100644 --- a/x-pack/plugins/infra/server/utils/serialized_query.ts +++ b/x-pack/plugins/infra/server/utils/serialized_query.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; export const parseFilterQuery = ( filterQuery: string | null | undefined diff --git a/x-pack/plugins/infra/server/utils/typed_search_strategy.ts b/x-pack/plugins/infra/server/utils/typed_search_strategy.ts index 2482694474b0e..7dcda66e1bb98 100644 --- a/x-pack/plugins/infra/server/utils/typed_search_strategy.ts +++ b/x-pack/plugins/infra/server/utils/typed_search_strategy.ts @@ -7,7 +7,7 @@ import * as rt from 'io-ts'; import stringify from 'json-stable-stringify'; -import { JsonValue } from '@kbn/common-utils'; +import { JsonValue } from '@kbn/utility-types'; import { jsonValueRT } from '../../common/typed_json'; import { SearchStrategyError } from '../../common/search_strategies/common/errors'; import { ShardFailure } from './elasticsearch_runtime_types'; diff --git a/x-pack/plugins/ingest_pipelines/public/locator.ts b/x-pack/plugins/ingest_pipelines/public/locator.ts index bfcc2f0fc9ce2..e4d6bf3539492 100644 --- a/x-pack/plugins/ingest_pipelines/public/locator.ts +++ b/x-pack/plugins/ingest_pipelines/public/locator.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import { ManagementAppLocator } from 'src/plugins/management/common'; import { LocatorPublic, @@ -27,7 +27,7 @@ export enum INGEST_PIPELINES_PAGES { CLONE = 'pipeline_clone', } -interface IngestPipelinesBaseParams extends SerializableState { +interface IngestPipelinesBaseParams extends SerializableRecord { pipelineId: string; } export interface IngestPipelinesListParams extends Partial { diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx index 5cf2abf7b8d0f..56abf499aac88 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.test.tsx @@ -128,7 +128,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, { timeRange: { @@ -168,7 +167,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, { timeRange: { @@ -212,7 +210,6 @@ describe('embeddable', () => { }, errors: [{ shortMessage: '', longMessage: 'my validation error' }], }), - executionContext: coreMock.createStart().executionContext, }, {} as LensEmbeddableInput ); @@ -256,7 +253,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, {} as LensEmbeddableInput ); @@ -295,7 +291,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, { id: '123' } as LensEmbeddableInput ); @@ -337,7 +332,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, { id: '123' } as LensEmbeddableInput ); @@ -386,7 +380,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, { id: '123' } as LensEmbeddableInput ); @@ -433,7 +426,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, { id: '123' } as LensEmbeddableInput ); @@ -487,7 +479,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, input ); @@ -541,7 +532,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, input ); @@ -594,7 +584,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, input ); @@ -636,7 +625,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, { id: '123' } as LensEmbeddableInput ); @@ -678,7 +666,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, { id: '123' } as LensEmbeddableInput ); @@ -720,7 +707,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, { id: '123', timeRange, query, filters } as LensEmbeddableInput ); @@ -777,7 +763,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, ({ id: '123', onLoad } as unknown) as LensEmbeddableInput ); @@ -850,7 +835,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, ({ id: '123', onFilter } as unknown) as LensEmbeddableInput ); @@ -898,7 +882,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, ({ id: '123', onBrushEnd } as unknown) as LensEmbeddableInput ); @@ -946,7 +929,6 @@ describe('embeddable', () => { }, errors: undefined, }), - executionContext: coreMock.createStart().executionContext, }, ({ id: '123', onTableRowClick } as unknown) as LensEmbeddableInput ); diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index e26466be6f81b..4ecb86ac1069f 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -8,7 +8,6 @@ import { isEqual, uniqBy } from 'lodash'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; -import type { ExecutionContextServiceStart } from 'src/core/public'; import { ExecutionContextSearch, Filter, @@ -98,7 +97,6 @@ export interface LensEmbeddableDeps { getTriggerCompatibleActions?: UiActionsStart['getTriggerCompatibleActions']; capabilities: { canSaveVisualizations: boolean; canSaveDashboards: boolean }; usageCollection?: UsageCollectionSetup; - executionContext: ExecutionContextServiceStart; } export class Embeddable @@ -324,13 +322,16 @@ export class Embeddable if (this.input.onLoad) { this.input.onLoad(true); } - const executionContext = this.deps.executionContext.create({ + + const executionContext = { type: 'lens', name: this.savedVis.visualizationType ?? '', - description: this.savedVis.title ?? this.savedVis.description ?? '', id: this.id, + description: this.savedVis.title || this.input.title || '', url: this.output.editUrl, - }); + parent: this.input.executionContext, + }; + const input = this.getInput(); render( diff --git a/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts b/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts index ba4e4df849488..4cc074b5e830c 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts +++ b/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts @@ -5,12 +5,7 @@ * 2.0. */ -import type { - Capabilities, - HttpSetup, - SavedObjectReference, - ExecutionContextServiceStart, -} from 'kibana/public'; +import type { Capabilities, HttpSetup, SavedObjectReference } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { RecursiveReadonly } from '@kbn/utility-types'; import { Ast } from '@kbn/interpreter/target/common'; @@ -38,7 +33,6 @@ export interface LensEmbeddableStartServices { indexPatternService: IndexPatternsContract; uiActions?: UiActionsStart; usageCollection?: UsageCollectionSetup; - executionContext: ExecutionContextServiceStart; documentToExpression: ( doc: Document ) => Promise<{ ast: Ast | null; errors: ErrorMessage[] | undefined }>; @@ -93,7 +87,6 @@ export class EmbeddableFactory implements EmbeddableFactoryDefinition { indexPatternService, capabilities, usageCollection, - executionContext, } = await this.getStartServices(); const { Embeddable } = await import('../async_services'); @@ -113,7 +106,6 @@ export class EmbeddableFactory implements EmbeddableFactoryDefinition { canSaveVisualizations: Boolean(capabilities.visualize.save), }, usageCollection, - executionContext, }, input, parent diff --git a/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx b/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx index b61dba1623028..fc6fcee9428b0 100644 --- a/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx +++ b/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx @@ -14,7 +14,7 @@ import { ReactExpressionRendererType, ReactExpressionRendererProps, } from 'src/plugins/expressions/public'; -import type { IExecutionContextContainer } from 'src/core/public'; +import type { KibanaExecutionContext } from 'src/core/public'; import { ExecutionContextSearch } from 'src/plugins/data/public'; import { DefaultInspectorAdapters, RenderMode } from 'src/plugins/expressions'; import classNames from 'classnames'; @@ -40,7 +40,7 @@ export interface ExpressionWrapperProps { className?: string; canEdit: boolean; onRuntimeError: () => void; - executionContext?: IExecutionContextContainer; + executionContext?: KibanaExecutionContext; } interface VisualizationErrorProps { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx index 3f359f214fe40..0e53b0f3c8d44 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx @@ -347,23 +347,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ supportedFieldTypes.has(field.type) ); const sorted = allSupportedTypesFields.sort(sortFields); - let groupedFields; - // optimization before existingFields are synced - if (!hasSyncedExistingFields) { - groupedFields = { - ...defaultFieldGroups, - ...groupBy(sorted, (field) => { - if (field.type === 'document') { - return 'specialFields'; - } else if (field.meta) { - return 'metaFields'; - } else { - return 'emptyFields'; - } - }), - }; - } - groupedFields = { + const groupedFields = { ...defaultFieldGroups, ...groupBy(sorted, (field) => { if (field.type === 'document') { @@ -455,7 +439,6 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ return fieldGroupDefinitions; }, [ allFields, - hasSyncedExistingFields, fieldInfoUnavailable, filters.length, existenceFetchTimeout, diff --git a/x-pack/plugins/lens/public/plugin.ts b/x-pack/plugins/lens/public/plugin.ts index ae8aa268c0580..26608f9cc78be 100644 --- a/x-pack/plugins/lens/public/plugin.ts +++ b/x-pack/plugins/lens/public/plugin.ts @@ -177,7 +177,6 @@ export class LensPlugin { attributeService: await this.attributeService!(), capabilities: coreStart.application.capabilities, coreHttp: coreStart.http, - executionContext: coreStart.executionContext, timefilter: deps.data.query.timefilter.timefilter, expressionRenderer: deps.expressions.ReactExpressionRenderer, documentToExpression: this.editorFrameService!.documentToExpression, diff --git a/x-pack/plugins/lens/public/shared_components/coloring/utils.test.ts b/x-pack/plugins/lens/public/shared_components/coloring/utils.test.ts index 3564785aa570e..97dc2e45c96dc 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/utils.test.ts +++ b/x-pack/plugins/lens/public/shared_components/coloring/utils.test.ts @@ -405,4 +405,15 @@ describe('getContrastColor', () => { expect(getContrastColor('#fff', true)).toBe('#000000'); expect(getContrastColor('#fff', false)).toBe('#000000'); }); + + it('should take into account background color if the primary color is opaque', () => { + expect(getContrastColor('rgba(0,0,0,0)', true)).toBe('#ffffff'); + expect(getContrastColor('rgba(0,0,0,0)', false)).toBe('#000000'); + expect(getContrastColor('#00000000', true)).toBe('#ffffff'); + expect(getContrastColor('#00000000', false)).toBe('#000000'); + expect(getContrastColor('#ffffff00', true)).toBe('#ffffff'); + expect(getContrastColor('#ffffff00', false)).toBe('#000000'); + expect(getContrastColor('rgba(255,255,255,0)', true)).toBe('#ffffff'); + expect(getContrastColor('rgba(255,255,255,0)', false)).toBe('#000000'); + }); }); diff --git a/x-pack/plugins/lens/public/shared_components/coloring/utils.ts b/x-pack/plugins/lens/public/shared_components/coloring/utils.ts index 8cd0a6cf49001..b2969565f5390 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/utils.ts +++ b/x-pack/plugins/lens/public/shared_components/coloring/utils.ts @@ -294,7 +294,12 @@ export function getColorStops( export function getContrastColor(color: string, isDarkTheme: boolean) { const darkColor = isDarkTheme ? euiDarkVars.euiColorInk : euiLightVars.euiColorInk; const lightColor = isDarkTheme ? euiDarkVars.euiColorGhost : euiLightVars.euiColorGhost; - return isColorDark(...chroma(color).rgb()) ? lightColor : darkColor; + const backgroundColor = isDarkTheme + ? euiDarkVars.euiPageBackgroundColor + : euiLightVars.euiPageBackgroundColor; + const finalColor = + chroma(color).alpha() < 1 ? chroma.blend(backgroundColor, color, 'overlay') : chroma(color); + return isColorDark(...finalColor.rgb()) ? lightColor : darkColor; } /** diff --git a/x-pack/plugins/lens/server/embeddable/lens_embeddable_factory.ts b/x-pack/plugins/lens/server/embeddable/lens_embeddable_factory.ts index 4f21378cc8115..6f1ec38ea951a 100644 --- a/x-pack/plugins/lens/server/embeddable/lens_embeddable_factory.ts +++ b/x-pack/plugins/lens/server/embeddable/lens_embeddable_factory.ts @@ -6,7 +6,7 @@ */ import { EmbeddableRegistryDefinition } from 'src/plugins/embeddable/server'; -import { SerializableState } from '../../../../../src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import { DOC_TYPE } from '../../common'; import { commonRemoveTimezoneDateHistogramParam, @@ -25,7 +25,7 @@ export const lensEmbeddableFactory = (): EmbeddableRegistryDefinition => { return ({ ...lensState, attributes: migratedLensState, - } as unknown) as SerializableState; + } as unknown) as SerializableRecord; }, '7.14.0': (state) => { const lensState = (state as unknown) as { attributes: LensDocShape713 }; @@ -33,7 +33,7 @@ export const lensEmbeddableFactory = (): EmbeddableRegistryDefinition => { return ({ ...lensState, attributes: migratedLensState, - } as unknown) as SerializableState; + } as unknown) as SerializableRecord; }, }, }; diff --git a/x-pack/plugins/licensing/kibana.json b/x-pack/plugins/licensing/kibana.json index 2d38a82271eb0..c00d3149e73de 100644 --- a/x-pack/plugins/licensing/kibana.json +++ b/x-pack/plugins/licensing/kibana.json @@ -1,5 +1,9 @@ { "id": "licensing", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "0.0.1", "kibanaVersion": "kibana", "configPath": ["xpack", "licensing"], diff --git a/x-pack/plugins/maps/public/locators.test.ts b/x-pack/plugins/maps/public/locators.test.ts index d6e82d1cdb601..838d272120324 100644 --- a/x-pack/plugins/maps/public/locators.test.ts +++ b/x-pack/plugins/maps/public/locators.test.ts @@ -8,7 +8,7 @@ import { LAYER_TYPE, SOURCE_TYPES, SCALING_TYPES } from '../common/constants'; import { esFilters } from '../../../../src/plugins/data/public'; import { MapsAppLocatorDefinition } from './locators'; -import { SerializableState } from '../../../../src/plugins/kibana_utils/common'; +import { SerializableRecord } from '@kbn/utility-types'; import { LayerDescriptor } from '../common/descriptor_types'; const MAP_ID: string = '2c9c1f60-1909-11e9-919b-ffe5949a18d2'; @@ -65,7 +65,7 @@ describe('visualize url generator', () => { }, ]; const location = await locator.getLocation({ - initialLayers: (initialLayers as unknown) as LayerDescriptor[] & SerializableState, + initialLayers: (initialLayers as unknown) as LayerDescriptor[] & SerializableRecord, }); expect(location).toMatchObject({ diff --git a/x-pack/plugins/maps/public/locators.ts b/x-pack/plugins/maps/public/locators.ts index 7e2be7c6c7ec9..9689be8c133d4 100644 --- a/x-pack/plugins/maps/public/locators.ts +++ b/x-pack/plugins/maps/public/locators.ts @@ -8,6 +8,7 @@ /* eslint-disable max-classes-per-file */ import rison from 'rison-node'; +import type { SerializableRecord } from '@kbn/utility-types'; import type { TimeRange, Filter, @@ -17,13 +18,12 @@ import type { } from '../../../../src/plugins/data/public'; import { esFilters } from '../../../../src/plugins/data/public'; import { setStateToKbnUrl } from '../../../../src/plugins/kibana_utils/public'; -import { SerializableState } from '../../../../src/plugins/kibana_utils/common'; import type { LocatorDefinition, LocatorPublic } from '../../../../src/plugins/share/public'; import type { LayerDescriptor } from '../common/descriptor_types'; import { INITIAL_LAYERS_KEY, APP_ID } from '../common/constants'; import { lazyLoadMapModules } from './lazy_load_bundle'; -export interface MapsAppLocatorParams extends SerializableState { +export interface MapsAppLocatorParams extends SerializableRecord { /** * If given, it will load the given map else will load the create a new map page. */ @@ -37,12 +37,12 @@ export interface MapsAppLocatorParams extends SerializableState { /** * Optionally set the initial Layers. */ - initialLayers?: LayerDescriptor[] & SerializableState; + initialLayers?: LayerDescriptor[] & SerializableRecord; /** * Optionally set the refresh interval. */ - refreshInterval?: RefreshInterval & SerializableState; + refreshInterval?: RefreshInterval & SerializableRecord; /** * Optionally apply filers. NOTE: if given and used in conjunction with `mapId`, and the @@ -101,7 +101,7 @@ export class MapsAppLocatorDefinition implements LocatorDefinition string; }).encode_array(initialLayers); path = `${path}&${INITIAL_LAYERS_KEY}=${encodeURIComponent(risonEncodedInitialLayers)}`; @@ -115,7 +115,7 @@ export class MapsAppLocatorDefinition implements LocatorDefinition { const location = await locator.getLocation({ filters: getData().query.filterManager.getFilters(), query: getData().query.queryString.getQuery(), - initialLayers: (initialLayers as unknown) as LayerDescriptor[] & SerializableState, + initialLayers: (initialLayers as unknown) as LayerDescriptor[] & SerializableRecord, timeRange: getData().query.timefilter.timefilter.getTime(), }); diff --git a/x-pack/plugins/maps/server/embeddable_migrations.ts b/x-pack/plugins/maps/server/embeddable_migrations.ts index 4bf39dc1f999c..2a53198d8d247 100644 --- a/x-pack/plugins/maps/server/embeddable_migrations.ts +++ b/x-pack/plugins/maps/server/embeddable_migrations.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { SerializableState } from '../../../../src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import { MapSavedObjectAttributes } from '../common/map_saved_object_type'; import { moveAttribution } from '../common/migrations/move_attribution'; @@ -17,10 +17,10 @@ import { moveAttribution } from '../common/migrations/move_attribution'; * This is the embeddable migration registry. */ export const embeddableMigrations = { - '7.14.0': (state: SerializableState) => { + '7.14.0': (state: SerializableRecord) => { return { ...state, attributes: moveAttribution(state as { attributes: MapSavedObjectAttributes }), - } as SerializableState; + } as SerializableRecord; }, }; diff --git a/x-pack/plugins/maps/server/plugin.ts b/x-pack/plugins/maps/server/plugin.ts index 1119be32a04de..ecf89c8774c72 100644 --- a/x-pack/plugins/maps/server/plugin.ts +++ b/x-pack/plugins/maps/server/plugin.ts @@ -83,18 +83,6 @@ export class MapsPlugin implements Plugin { }, ]); - home.sampleData.replacePanelInSampleDatasetDashboard({ - sampleDataId: 'ecommerce', - dashboardId: '722b74f0-b882-11e8-a6d9-e546fe2bba5f', - oldEmbeddableId: '9c6f83f0-bb4d-11e8-9c84-77068524bcab', - embeddableId: '2c9c1f60-1909-11e9-919b-ffe5949a18d2', - // @ts-ignore - embeddableType: 'map', - embeddableConfig: { - isLayerTOCOpen: false, - }, - }); - home.sampleData.addSavedObjectsToSampleDataset('flights', getFlightsSavedObjects()); home.sampleData.addAppLinksToSampleDataset('flights', [ diff --git a/x-pack/plugins/maps/server/routes.js b/x-pack/plugins/maps/server/routes.js index 1b669a5bcdbee..f41e9a9d199b8 100644 --- a/x-pack/plugins/maps/server/routes.js +++ b/x-pack/plugins/maps/server/routes.js @@ -525,25 +525,23 @@ export async function initRoutes(core, getLicenseId, emsSettings, kbnVersion, lo }, }, (context, request, response) => { - return new Promise((resolve, reject) => { - const santizedRange = path.normalize(request.params.range); - const fontPath = path.join(__dirname, 'fonts', 'open_sans', `${santizedRange}.pbf`); - fs.readFile(fontPath, (error, data) => { - if (error) { - reject( - response.custom({ - statusCode: 404, - }) - ); - } else { - resolve( - response.ok({ - body: data, - }) - ); - } - }); - }); + const range = path.normalize(request.params.range); + return range.startsWith('..') + ? response.notFound() + : new Promise((resolve) => { + const fontPath = path.join(__dirname, 'fonts', 'open_sans', `${range}.pbf`); + fs.readFile(fontPath, (error, data) => { + if (error) { + resolve(response.notFound()); + } else { + resolve( + response.ok({ + body: data, + }) + ); + } + }); + }); } ); diff --git a/x-pack/plugins/ml/common/constants/usage_collection.ts b/x-pack/plugins/ml/common/constants/usage_collection.ts new file mode 100644 index 0000000000000..647999d1903af --- /dev/null +++ b/x-pack/plugins/ml/common/constants/usage_collection.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const ML_USAGE_EVENT = { + IMPORTED_ANOMALY_DETECTOR_JOBS: 'imported_anomaly_detector_jobs', + IMPORTED_DATA_FRAME_ANALYTICS_JOBS: 'imported_data_frame_analytics_jobs', + EXPORTED_ANOMALY_DETECTOR_JOBS: 'exported_anomaly_detector_jobs', + EXPORTED_DATA_FRAME_ANALYTICS_JOBS: 'exported_data_frame_analytics_jobs', +} as const; + +export type MlUsageEvent = typeof ML_USAGE_EVENT[keyof typeof ML_USAGE_EVENT]; diff --git a/x-pack/plugins/ml/common/types/es_client.ts b/x-pack/plugins/ml/common/types/es_client.ts index 433deac02bc9c..b3d36283b5d5e 100644 --- a/x-pack/plugins/ml/common/types/es_client.ts +++ b/x-pack/plugins/ml/common/types/es_client.ts @@ -7,7 +7,7 @@ import { estypes } from '@elastic/elasticsearch'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { buildEsQuery, DslQuery } from '@kbn/es-query'; import { isPopulatedObject } from '../util/object_utils'; diff --git a/x-pack/plugins/ml/common/types/locator.ts b/x-pack/plugins/ml/common/types/locator.ts index 9d294e1323f72..bfb953777d857 100644 --- a/x-pack/plugins/ml/common/types/locator.ts +++ b/x-pack/plugins/ml/common/types/locator.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import type { LocatorPublic } from 'src/plugins/share/public'; import type { RefreshInterval, TimeRange } from '../../../../../src/plugins/data/common/query'; import type { JobId } from './anomaly_detection_jobs/job'; @@ -253,6 +253,6 @@ export type MlLocatorState = | FilterEditUrlState | MlGenericUrlState; -export type MlLocatorParams = MlLocatorState & SerializableState; +export type MlLocatorParams = MlLocatorState & SerializableRecord; export type MlLocator = LocatorPublic; diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx index fd1703e907ee1..c7e457c0b5e00 100644 --- a/x-pack/plugins/ml/public/application/app.tsx +++ b/x-pack/plugins/ml/public/application/app.tsx @@ -11,6 +11,7 @@ import ReactDOM from 'react-dom'; import { AppMountParameters, CoreStart, HttpStart } from 'kibana/public'; +import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; import { Storage } from '../../../../../src/plugins/kibana_utils/public'; import { @@ -19,7 +20,8 @@ import { } from '../../../../../src/plugins/kibana_react/public'; import { setDependencyCache, clearCache } from './util/dependency_cache'; import { setLicenseCache } from './license'; -import { MlSetupDependencies, MlStartDependencies } from '../plugin'; +import type { MlSetupDependencies, MlStartDependencies } from '../plugin'; +import { mlUsageCollectionProvider } from './services/usage_collection'; import { MlRouter } from './routing'; import { mlApiServicesProvider } from './services/ml_api_service'; @@ -39,11 +41,12 @@ const localStorage = new Storage(window.localStorage); /** * Provides global services available across the entire ML app. */ -export function getMlGlobalServices(httpStart: HttpStart) { +export function getMlGlobalServices(httpStart: HttpStart, usageCollection?: UsageCollectionSetup) { const httpService = new HttpService(httpStart); return { httpService, mlApiServices: mlApiServicesProvider(httpService), + mlUsageCollection: mlUsageCollectionProvider(usageCollection), }; } @@ -68,8 +71,8 @@ const App: FC = ({ coreStart, deps, appMountParams }) => { setBreadcrumbs: coreStart.chrome!.setBreadcrumbs, redirectToMlAccessDeniedPage, }; + const services = { - appName: 'ML', kibanaVersion: deps.kibanaVersion, share: deps.share, data: deps.data, @@ -80,6 +83,7 @@ const App: FC = ({ coreStart, deps, appMountParams }) => { maps: deps.maps, triggersActionsUi: deps.triggersActionsUi, dataVisualizer: deps.dataVisualizer, + usageCollection: deps.usageCollection, ...coreStart, }; @@ -94,7 +98,10 @@ const App: FC = ({ coreStart, deps, appMountParams }) => { diff --git a/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/export_jobs_flyout.tsx b/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/export_jobs_flyout.tsx index cd9ecc70e553a..5ae6159f806ba 100644 --- a/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/export_jobs_flyout.tsx +++ b/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/export_jobs_flyout.tsx @@ -46,6 +46,7 @@ export const ExportJobsFlyout: FC = ({ isDisabled, currentTab }) => { const { services: { notifications: { toasts }, + mlServices: { mlUsageCollection }, }, } = useMlKibana(); @@ -121,6 +122,13 @@ export const ExportJobsFlyout: FC = ({ isDisabled, currentTab }) => { await jobsExportService.exportDataframeAnalyticsJobs(selectedJobIds); } + mlUsageCollection.count( + selectedJobType === 'anomaly-detector' + ? 'exported_anomaly_detector_jobs' + : 'exported_data_frame_analytics_jobs', + selectedJobIds.length + ); + setExporting(false); setShowFlyout(false); } catch (error) { diff --git a/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/import_jobs_flyout.tsx b/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/import_jobs_flyout.tsx index c156a41150420..68f70d05ccc8f 100644 --- a/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/import_jobs_flyout.tsx +++ b/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/import_jobs_flyout.tsx @@ -54,6 +54,7 @@ export const ImportJobsFlyout: FC = ({ isDisabled }) => { indexPatterns: { getTitles: getIndexPatternTitles }, }, notifications: { toasts }, + mlServices: { mlUsageCollection }, }, } = useMlKibana(); @@ -175,6 +176,7 @@ export const ImportJobsFlyout: FC = ({ isDisabled }) => { const renamedJobs = jobImportService.renameAdJobs(jobIdObjects, adJobs); try { await bulkCreateADJobs(renamedJobs); + mlUsageCollection.count('imported_anomaly_detector_jobs', renamedJobs.length); } catch (error) { // display unexpected error displayErrorToast(error); @@ -182,6 +184,7 @@ export const ImportJobsFlyout: FC = ({ isDisabled }) => { } else if (jobType === 'data-frame-analytics') { const renamedJobs = jobImportService.renameDfaJobs(jobIdObjects, dfaJobs); await bulkCreateDfaJobs(renamedJobs); + mlUsageCollection.count('imported_data_frame_analytics_jobs', renamedJobs.length); } setImporting(false); diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts b/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts index 1ade617fa60a5..e69d75a24d423 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/kibana_context.ts @@ -5,21 +5,22 @@ * 2.0. */ -import { DataPublicPluginStart } from 'src/plugins/data/public'; -import { CoreStart } from 'kibana/public'; +import type { DataPublicPluginStart } from 'src/plugins/data/public'; +import type { CoreStart } from 'kibana/public'; +import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; import { useKibana, KibanaReactContextValue, } from '../../../../../../../src/plugins/kibana_react/public'; -import { SecurityPluginSetup } from '../../../../../security/public'; -import { LicenseManagementUIPluginSetup } from '../../../../../license_management/public'; -import { SharePluginStart } from '../../../../../../../src/plugins/share/public'; -import { MlServicesContext } from '../../app'; -import { IStorageWrapper } from '../../../../../../../src/plugins/kibana_utils/public'; +import type { SecurityPluginSetup } from '../../../../../security/public'; +import type { LicenseManagementUIPluginSetup } from '../../../../../license_management/public'; +import type { SharePluginStart } from '../../../../../../../src/plugins/share/public'; +import type { MlServicesContext } from '../../app'; +import type { IStorageWrapper } from '../../../../../../../src/plugins/kibana_utils/public'; import type { EmbeddableStart } from '../../../../../../../src/plugins/embeddable/public'; import type { MapsStartApi } from '../../../../../maps/public'; import type { DataVisualizerPluginStart } from '../../../../../data_visualizer/public'; -import { TriggersAndActionsUIPublicPluginStart } from '../../../../../triggers_actions_ui/public'; +import type { TriggersAndActionsUIPublicPluginStart } from '../../../../../triggers_actions_ui/public'; interface StartPlugins { data: DataPublicPluginStart; @@ -30,10 +31,10 @@ interface StartPlugins { maps?: MapsStartApi; triggersActionsUi?: TriggersAndActionsUIPublicPluginStart; dataVisualizer?: DataVisualizerPluginStart; + usageCollection?: UsageCollectionSetup; } export type StartServices = CoreStart & StartPlugins & { - appName: string; kibanaVersion: string; storage: IStorageWrapper; } & MlServicesContext; diff --git a/x-pack/plugins/ml/public/application/management/index.ts b/x-pack/plugins/ml/public/application/management/index.ts index 648a1ef7759a3..9d6376a668c1d 100644 --- a/x-pack/plugins/ml/public/application/management/index.ts +++ b/x-pack/plugins/ml/public/application/management/index.ts @@ -9,13 +9,15 @@ import { i18n } from '@kbn/i18n'; import type { CoreSetup } from 'kibana/public'; import type { ManagementSetup } from 'src/plugins/management/public'; +import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; import type { MlStartDependencies } from '../../plugin'; import type { ManagementAppMountParams } from '../../../../../../src/plugins/management/public'; export function registerManagementSection( management: ManagementSetup, - core: CoreSetup + core: CoreSetup, + deps: { usageCollection?: UsageCollectionSetup } ) { return management.sections.section.insightsAndAlerting.registerApp({ id: 'jobsListLink', @@ -25,7 +27,7 @@ export function registerManagementSection( order: 2, async mount(params: ManagementAppMountParams) { const { mountApp } = await import('./jobs_list'); - return mountApp(core, params); + return mountApp(core, params, deps); }, }); } diff --git a/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx b/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx index 6a76b1e207ec5..e1ed8ee75767e 100644 --- a/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx +++ b/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx @@ -23,9 +23,10 @@ import { } from '@elastic/eui'; import type { SpacesContextProps } from 'src/plugins/spaces_oss/public'; +import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; import type { DataPublicPluginStart } from 'src/plugins/data/public'; import { PLUGIN_ID } from '../../../../../../common/constants/app'; -import { ManagementAppMountParams } from '../../../../../../../../../src/plugins/management/public/'; +import type { ManagementAppMountParams } from '../../../../../../../../../src/plugins/management/public'; import { checkGetManagementMlJobsResolver } from '../../../../capabilities/check_capabilities'; import { @@ -39,7 +40,7 @@ import { JobsListView } from '../../../../jobs/jobs_list/components/jobs_list_vi import { DataFrameAnalyticsList } from '../../../../data_frame_analytics/pages/analytics_management/components/analytics_list'; import { AccessDeniedPage } from '../access_denied_page'; import { InsufficientLicensePage } from '../insufficient_license_page'; -import { SharePluginStart } from '../../../../../../../../../src/plugins/share/public'; +import type { SharePluginStart } from '../../../../../../../../../src/plugins/share/public'; import type { SpacesPluginStart } from '../../../../../../../spaces/public'; import { JobSpacesSyncFlyout } from '../../../../components/job_spaces_sync'; import { getDefaultAnomalyDetectionJobsListState } from '../../../../jobs/jobs_list/jobs'; @@ -47,7 +48,7 @@ import { getMlGlobalServices } from '../../../../app'; import { ListingPageUrlState } from '../../../../../../common/types/common'; import { getDefaultDFAListState } from '../../../../data_frame_analytics/pages/analytics_management/page'; import { ExportJobsFlyout, ImportJobsFlyout } from '../../../../components/import_export_jobs'; -import { JobType } from '../../../../../../common/types/saved_objects'; +import type { JobType } from '../../../../../../common/types/saved_objects'; interface Tab extends EuiTabbedContentTab { 'data-test-subj': string; @@ -128,7 +129,8 @@ export const JobsListPage: FC<{ history: ManagementAppMountParams['history']; spacesApi?: SpacesPluginStart; data: DataPublicPluginStart; -}> = ({ coreStart, share, history, spacesApi, data }) => { + usageCollection?: UsageCollectionSetup; +}> = ({ coreStart, share, history, spacesApi, data, usageCollection }) => { const spacesEnabled = spacesApi !== undefined; const [initialized, setInitialized] = useState(false); const [accessDenied, setAccessDenied] = useState(false); @@ -219,7 +221,13 @@ export const JobsListPage: FC<{ diff --git a/x-pack/plugins/ml/public/application/management/jobs_list/index.ts b/x-pack/plugins/ml/public/application/management/jobs_list/index.ts index 039653af0d095..b1dd8344b86fd 100644 --- a/x-pack/plugins/ml/public/application/management/jobs_list/index.ts +++ b/x-pack/plugins/ml/public/application/management/jobs_list/index.ts @@ -7,16 +7,17 @@ import ReactDOM, { unmountComponentAtNode } from 'react-dom'; import React from 'react'; -import { CoreSetup, CoreStart } from 'kibana/public'; +import type { CoreSetup, CoreStart } from 'kibana/public'; import type { DataPublicPluginStart } from 'src/plugins/data/public'; -import { ManagementAppMountParams } from '../../../../../../../src/plugins/management/public/'; -import { MlStartDependencies } from '../../../plugin'; +import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; +import type { ManagementAppMountParams } from '../../../../../../../src/plugins/management/public/'; +import type { MlStartDependencies } from '../../../plugin'; import { JobsListPage } from './components'; import { getJobsListBreadcrumbs } from '../breadcrumbs'; import { setDependencyCache, clearCache } from '../../util/dependency_cache'; import './_index.scss'; -import { SharePluginStart } from '../../../../../../../src/plugins/share/public'; -import { SpacesPluginStart } from '../../../../../spaces/public'; +import type { SharePluginStart } from '../../../../../../../src/plugins/share/public'; +import type { SpacesPluginStart } from '../../../../../spaces/public'; const renderApp = ( element: HTMLElement, @@ -24,10 +25,18 @@ const renderApp = ( coreStart: CoreStart, share: SharePluginStart, data: DataPublicPluginStart, - spacesApi?: SpacesPluginStart + spacesApi?: SpacesPluginStart, + usageCollection?: UsageCollectionSetup ) => { ReactDOM.render( - React.createElement(JobsListPage, { coreStart, history, share, data, spacesApi }), + React.createElement(JobsListPage, { + coreStart, + history, + share, + data, + spacesApi, + usageCollection, + }), element ); return () => { @@ -38,7 +47,8 @@ const renderApp = ( export async function mountApp( core: CoreSetup, - params: ManagementAppMountParams + params: ManagementAppMountParams, + deps: { usageCollection?: UsageCollectionSetup } ) { const [coreStart, pluginsStart] = await core.getStartServices(); @@ -56,6 +66,7 @@ export async function mountApp( coreStart, pluginsStart.share, pluginsStart.data, - pluginsStart.spaces + pluginsStart.spaces, + deps.usageCollection ); } diff --git a/x-pack/plugins/ml/public/application/services/usage_collection.test.ts b/x-pack/plugins/ml/public/application/services/usage_collection.test.ts new file mode 100644 index 0000000000000..5262b67136b71 --- /dev/null +++ b/x-pack/plugins/ml/public/application/services/usage_collection.test.ts @@ -0,0 +1,64 @@ +/* + * 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 { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; + +import { mlUsageCollectionProvider } from './usage_collection'; + +describe('usage_collection', () => { + let usageCollection: jest.Mocked; + + beforeEach(() => { + usageCollection = ({ + reportUiCounter: jest.fn(), + } as unknown) as jest.Mocked; + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test('should use usageCollection for usage events', () => { + const mlUsageCollection = mlUsageCollectionProvider(usageCollection); + + mlUsageCollection.click('exported_anomaly_detector_jobs'); + mlUsageCollection.count('exported_data_frame_analytics_jobs'); + expect(usageCollection.reportUiCounter).toHaveBeenCalledTimes(2); + expect(usageCollection.reportUiCounter).toHaveBeenCalledWith( + 'ml', + 'click', + 'exported_anomaly_detector_jobs', + undefined + ); + expect(usageCollection.reportUiCounter).toHaveBeenCalledWith( + 'ml', + 'count', + 'exported_data_frame_analytics_jobs', + undefined + ); + }); + + test('should not use usageCollection if usageCollection is disabled', () => { + const mlUsageCollection = mlUsageCollectionProvider(undefined); + mlUsageCollection.click('imported_anomaly_detector_jobs', 1); + mlUsageCollection.count('imported_data_frame_analytics_jobs', 2); + expect(usageCollection.reportUiCounter).toHaveBeenCalledTimes(0); + + expect(usageCollection.reportUiCounter).not.toHaveBeenCalledWith( + 'ml', + 'click', + 'imported_anomaly_detector_jobs', + undefined + ); + expect(usageCollection.reportUiCounter).not.toHaveBeenCalledWith( + 'ml', + 'count', + 'imported_data_frame_analytics_jobs', + undefined + ); + }); +}); diff --git a/x-pack/plugins/ml/public/application/services/usage_collection.ts b/x-pack/plugins/ml/public/application/services/usage_collection.ts new file mode 100644 index 0000000000000..3ec70b1995c0f --- /dev/null +++ b/x-pack/plugins/ml/public/application/services/usage_collection.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; +import { METRIC_TYPE } from '@kbn/analytics'; +import { PLUGIN_ID } from '../../../common/constants/app'; +import { MlUsageEvent } from '../../../common/constants/usage_collection'; + +export function mlUsageCollectionProvider(usageCollection?: UsageCollectionSetup) { + if (usageCollection === undefined) { + // if usageCollection is disabled, swallow the clicks and counts + const noop = (eventNames: string | string[], count?: number) => undefined; + return { + click: noop, + count: noop, + }; + } + + return { + click: (eventNames: MlUsageEvent | MlUsageEvent[], count?: number) => + usageCollection.reportUiCounter(PLUGIN_ID, METRIC_TYPE.CLICK, eventNames, count), + count: (eventNames: MlUsageEvent | MlUsageEvent[], count?: number) => + usageCollection.reportUiCounter(PLUGIN_ID, METRIC_TYPE.COUNT, eventNames, count), + }; +} diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index 1c2cc32063e88..3316bdd5011ef 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -42,10 +42,10 @@ import { TriggersAndActionsUIPublicPluginSetup, TriggersAndActionsUIPublicPluginStart, } from '../../triggers_actions_ui/public'; -import { DataVisualizerPluginStart } from '../../data_visualizer/public'; -import { PluginSetupContract as AlertingSetup } from '../../alerting/public'; +import type { DataVisualizerPluginStart } from '../../data_visualizer/public'; +import type { PluginSetupContract as AlertingSetup } from '../../alerting/public'; import { registerManagementSection } from './application/management'; -import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public'; +import type { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public'; export interface MlStartDependencies { data: DataPublicPluginStart; @@ -127,7 +127,9 @@ export class MlPlugin implements Plugin { } if (pluginsSetup.management) { - registerManagementSection(pluginsSetup.management, core).enable(); + registerManagementSection(pluginsSetup.management, core, { + usageCollection: pluginsSetup.usageCollection, + }).enable(); } const licensing = pluginsSetup.licensing.license$.pipe(take(1)); diff --git a/x-pack/plugins/monitoring/public/angular/app_modules.ts b/x-pack/plugins/monitoring/public/angular/app_modules.ts index e7b2f7a537000..20989e080edbf 100644 --- a/x-pack/plugins/monitoring/public/angular/app_modules.ts +++ b/x-pack/plugins/monitoring/public/angular/app_modules.ts @@ -52,7 +52,7 @@ export const appModuleName = 'monitoring'; type IPrivate = (provider: (...injectable: unknown[]) => T) => T; -const thirdPartyAngularDependencies = ['ngSanitize', 'ngRoute', 'react', 'ui.bootstrap']; +const thirdPartyAngularDependencies = ['ngSanitize', 'ngRoute', 'react']; export const localAppModule = ({ core, diff --git a/x-pack/plugins/monitoring/public/plugin.ts b/x-pack/plugins/monitoring/public/plugin.ts index f1a9c2708d5d6..15b7290fbeaf7 100644 --- a/x-pack/plugins/monitoring/public/plugin.ts +++ b/x-pack/plugins/monitoring/public/plugin.ts @@ -93,10 +93,7 @@ export class MonitoringPlugin category: DEFAULT_APP_CATEGORIES.management, mount: async (params: AppMountParameters) => { const [coreStart, pluginsStart] = await core.getStartServices(); - const [, { AngularApp }] = await Promise.all([ - pluginsStart.kibanaLegacy.loadAngularBootstrap(), - import('./angular'), - ]); + const { AngularApp } = await import('./angular'); const deps: MonitoringStartPluginDependencies = { navigation: pluginsStart.navigation, kibanaLegacy: pluginsStart.kibanaLegacy, diff --git a/x-pack/plugins/monitoring/server/config.test.ts b/x-pack/plugins/monitoring/server/config.test.ts index 45b3e07200680..9a5699189241f 100644 --- a/x-pack/plugins/monitoring/server/config.test.ts +++ b/x-pack/plugins/monitoring/server/config.test.ts @@ -7,8 +7,7 @@ import fs from 'fs'; import { when } from 'jest-when'; - -import { createConfig, configSchema } from './config'; +import { configSchema, createConfig } from './config'; const MOCKED_PATHS = [ '/proc/self/cgroup', @@ -71,6 +70,8 @@ describe('config schema', () => { "enabled": false, }, }, + "debug_log_path": "", + "debug_mode": false, "elasticsearch": Object { "apiVersion": "master", "customHeaders": Object {}, diff --git a/x-pack/plugins/monitoring/server/config.ts b/x-pack/plugins/monitoring/server/config.ts index 8c411fb5c28a8..98fd02b03539c 100644 --- a/x-pack/plugins/monitoring/server/config.ts +++ b/x-pack/plugins/monitoring/server/config.ts @@ -25,6 +25,8 @@ export const configSchema = schema.object({ enabled: schema.boolean({ defaultValue: true }), ui: schema.object({ enabled: schema.boolean({ defaultValue: true }), + debug_mode: schema.boolean({ defaultValue: false }), + debug_log_path: schema.string({ defaultValue: '' }), ccs: schema.object({ enabled: schema.boolean({ defaultValue: true }), }), diff --git a/x-pack/plugins/monitoring/server/debug_logger.ts b/x-pack/plugins/monitoring/server/debug_logger.ts new file mode 100644 index 0000000000000..0add1f12f0304 --- /dev/null +++ b/x-pack/plugins/monitoring/server/debug_logger.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import fs from 'fs'; +import { MonitoringConfig } from './config'; +import { RouteDependencies } from './types'; + +export function decorateDebugServer( + _server: any, + config: MonitoringConfig, + logger: RouteDependencies['logger'] +) { + // bail if the proper config value is not set (extra protection) + if (!config.ui.debug_mode) { + return _server; + } + + // create a debug logger that will either write to file (if debug_log_path exists) or log out via logger + const debugLog = createDebugLogger({ path: config.ui.debug_log_path, logger }); + + return { + // maintain the rest of _server untouched + ..._server, + // TODO: replace any + route: (options: any) => { + const apiPath = options.path; + return _server.route({ + ...options, + // TODO: replace any + handler: async (req: any) => { + const { elasticsearch: cached } = req.server.plugins; + const apiRequestHeaders = req.headers; + req.server.plugins.elasticsearch = { + ...req.server.plugins.elasticsearch, + getCluster: (name: string) => { + const cluster = cached.getCluster(name); + return { + ...cluster, + // TODO: better types? + callWithRequest: async (_req: typeof req, type: string, params: any) => { + const result = await cluster.callWithRequest(_req, type, params); + + // log everything about this request -> query -> result + debugLog({ + api_path: apiPath, + referer_url: apiRequestHeaders.referer, + query: { + params, + result, + }, + }); + + return result; + }, + }; + }, + }; + return options.handler(req); + }, + }); + }, + }; +} + +function createDebugLogger({ + path, + logger, +}: { + path: string; + logger: RouteDependencies['logger']; +}) { + if (path.length > 0) { + const stream = fs.createWriteStream('./stack_monitoring_debug_log.ndjson', { flags: 'a' }); + return function logToFile(line: any) { + stream.write(JSON.stringify(line)); + }; + } else { + return function logToStdOut(line: any) { + logger.info(JSON.stringify(line)); + }; + } +} diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index aed48b7391529..6bfa052a6fe8f 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -6,53 +6,52 @@ */ import Boom from '@hapi/boom'; -import { i18n } from '@kbn/i18n'; -import { has, get } from 'lodash'; import { TypeOf } from '@kbn/config-schema'; +import { i18n } from '@kbn/i18n'; import { - Logger, - PluginInitializerContext, - KibanaRequest, - KibanaResponseFactory, CoreSetup, - ICustomClusterClient, CoreStart, CustomHttpResponseOptions, - ResponseError, + ICustomClusterClient, + KibanaRequest, + KibanaResponseFactory, + Logger, Plugin, + PluginInitializerContext, + ResponseError, SharedGlobalConfig, } from 'kibana/server'; +import { get, has } from 'lodash'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server'; import { - LOGGING_TAG, + ALERTS, KIBANA_MONITORING_LOGGING_TAG, KIBANA_STATS_TYPE_MONITORING, - ALERTS, + LOGGING_TAG, SAVED_OBJECT_TELEMETRY, } from '../common/constants'; -import { MonitoringConfig, createConfig, configSchema } from './config'; -import { requireUIRoutes } from './routes'; +import { AlertsFactory } from './alerts'; +import { configSchema, createConfig, MonitoringConfig } from './config'; +import { instantiateClient } from './es_client/instantiate_client'; import { initBulkUploader } from './kibana_monitoring'; -import { initInfraSource } from './lib/logs/init_infra_source'; import { registerCollectors } from './kibana_monitoring/collectors'; -import { registerMonitoringTelemetryCollection } from './telemetry_collection'; +import { initInfraSource } from './lib/logs/init_infra_source'; import { LicenseService } from './license_service'; -import { AlertsFactory } from './alerts'; +import { requireUIRoutes } from './routes'; +import { EndpointTypes, Globals } from './static_globals'; +import { registerMonitoringTelemetryCollection } from './telemetry_collection'; import { + IBulkUploader, + LegacyRequest, + LegacyShimDependencies, MonitoringCore, MonitoringLicenseService, MonitoringPluginSetup, - LegacyShimDependencies, - IBulkUploader, PluginsSetup, PluginsStart, - LegacyRequest, RequestHandlerContextMonitoringPlugin, } from './types'; -import { Globals, EndpointTypes } from './static_globals'; -import { instantiateClient } from './es_client/instantiate_client'; - // This is used to test the version of kibana const snapshotRegex = /-snapshot/i; @@ -192,7 +191,11 @@ export class MonitoringPlugin plugins ); - requireUIRoutes(this.monitoringCore, { + if (config.ui.debug_mode) { + this.log.info('MONITORING DEBUG MODE: ON'); + } + + requireUIRoutes(this.monitoringCore, config, { cluster, router, licenseService: this.licenseService, diff --git a/x-pack/plugins/monitoring/server/routes/index.ts b/x-pack/plugins/monitoring/server/routes/index.ts index 0f65fde1b2966..05a8de96b4c07 100644 --- a/x-pack/plugins/monitoring/server/routes/index.ts +++ b/x-pack/plugins/monitoring/server/routes/index.ts @@ -4,14 +4,23 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - /* eslint import/namespace: ['error', { allowComputed: true }]*/ + +import { MonitoringConfig } from '../config'; +import { decorateDebugServer } from '../debug_logger'; +import { RouteDependencies } from '../types'; // @ts-ignore import * as uiRoutes from './api/v1/ui'; // namespace import -import { RouteDependencies } from '../types'; -export function requireUIRoutes(server: any, npRoute: RouteDependencies) { +export function requireUIRoutes( + _server: any, + config: MonitoringConfig, + npRoute: RouteDependencies +) { const routes = Object.keys(uiRoutes); + const server = config.ui.debug_mode + ? decorateDebugServer(_server, config, npRoute.logger) + : _server; routes.forEach((route) => { const registerRoute = uiRoutes[route]; // computed reference to module objects imported via namespace diff --git a/x-pack/plugins/observability/public/pages/alerts/severity_badge.tsx b/x-pack/plugins/observability/public/pages/alerts/severity_badge.tsx index 931b9396f912a..34cab3ec7abeb 100644 --- a/x-pack/plugins/observability/public/pages/alerts/severity_badge.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/severity_badge.tsx @@ -6,7 +6,6 @@ */ import { EuiBadge } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import React from 'react'; export interface SeverityBadgeProps { @@ -19,12 +18,11 @@ const colorMap: { [key: string]: string } = { }; export function SeverityBadge({ severityLevel }: SeverityBadgeProps) { + if (!severityLevel) { + return null; + } + return ( - - {severityLevel ?? - i18n.translate('xpack.observability.severityBadge.unknownDescription', { - defaultMessage: 'unknown', - })} - + {severityLevel} ); } diff --git a/x-pack/plugins/osquery/common/typed_json.ts b/x-pack/plugins/osquery/common/typed_json.ts index 7ef7469a5ebe7..3735778b87491 100644 --- a/x-pack/plugins/osquery/common/typed_json.ts +++ b/x-pack/plugins/osquery/common/typed_json.ts @@ -6,7 +6,7 @@ */ import { DslQuery, Filter } from '@kbn/es-query'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; export type ESQuery = | ESRangeQuery diff --git a/x-pack/plugins/reporting/public/management/ilm_policy_link.tsx b/x-pack/plugins/reporting/public/management/ilm_policy_link.tsx index a40f167de5bc3..1dccb11dbbbc5 100644 --- a/x-pack/plugins/reporting/public/management/ilm_policy_link.tsx +++ b/x-pack/plugins/reporting/public/management/ilm_policy_link.tsx @@ -12,11 +12,11 @@ import { EuiButtonEmpty } from '@elastic/eui'; import type { ApplicationStart } from 'src/core/public'; import { ILM_POLICY_NAME } from '../../common/constants'; -import { LocatorPublic, SerializableState } from '../shared_imports'; +import { LocatorPublic, SerializableRecord } from '../shared_imports'; interface Props { navigateToUrl: ApplicationStart['navigateToUrl']; - locator: LocatorPublic; + locator: LocatorPublic; } const i18nTexts = { diff --git a/x-pack/plugins/reporting/public/shared_imports.ts b/x-pack/plugins/reporting/public/shared_imports.ts index 02717351e315f..a18ceaf151c7d 100644 --- a/x-pack/plugins/reporting/public/shared_imports.ts +++ b/x-pack/plugins/reporting/public/shared_imports.ts @@ -19,7 +19,7 @@ import { useKibana as _useKibana } from '../../../../src/plugins/kibana_react/pu import { KibanaContext } from './types'; export const useKibana = () => _useKibana(); -export type { SerializableState } from 'src/plugins/kibana_utils/common'; +export type { SerializableRecord } from '@kbn/utility-types'; export type { UiActionsSetup, UiActionsStart } from 'src/plugins/ui_actions/public'; diff --git a/x-pack/plugins/rule_registry/docs/alerts_client/alerts_client_api.md b/x-pack/plugins/rule_registry/docs/alerts_client/alerts_client_api.md index b94a19f8e3f38..9a317a995d718 100644 --- a/x-pack/plugins/rule_registry/docs/alerts_client/alerts_client_api.md +++ b/x-pack/plugins/rule_registry/docs/alerts_client/alerts_client_api.md @@ -10,5 +10,6 @@ Alerts as data client API Interface ### Interfaces +- [BulkUpdateOptions](interfaces/bulkupdateoptions.md) - [ConstructorOptions](interfaces/constructoroptions.md) - [UpdateOptions](interfaces/updateoptions.md) diff --git a/x-pack/plugins/rule_registry/docs/alerts_client/classes/alertsclient.md b/x-pack/plugins/rule_registry/docs/alerts_client/classes/alertsclient.md index 6b18ad0206797..7c79e0a5e4c0f 100644 --- a/x-pack/plugins/rule_registry/docs/alerts_client/classes/alertsclient.md +++ b/x-pack/plugins/rule_registry/docs/alerts_client/classes/alertsclient.md @@ -22,10 +22,14 @@ on alerts as data. ### Methods -- [fetchAlert](alertsclient.md#fetchalert) +- [buildEsQueryWithAuthz](alertsclient.md#buildesquerywithauthz) +- [bulkUpdate](alertsclient.md#bulkupdate) +- [ensureAllAuthorized](alertsclient.md#ensureallauthorized) - [get](alertsclient.md#get) -- [getAlertsIndex](alertsclient.md#getalertsindex) - [getAuthorizedAlertsIndices](alertsclient.md#getauthorizedalertsindices) +- [mgetAlertsAuditOperate](alertsclient.md#mgetalertsauditoperate) +- [queryAndAuditAllAlerts](alertsclient.md#queryandauditallalerts) +- [singleSearchAfterAndAudit](alertsclient.md#singlesearchafterandaudit) - [update](alertsclient.md#update) ## Constructors @@ -42,7 +46,7 @@ on alerts as data. #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:66](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L66) +[alerts_client.ts:93](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L93) ## Properties @@ -52,7 +56,7 @@ on alerts as data. #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:63](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L63) +[alerts_client.ts:90](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L90) ___ @@ -62,7 +66,7 @@ ___ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:64](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L64) +[alerts_client.ts:91](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L91) ___ @@ -72,7 +76,7 @@ ___ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:65](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L65) +[alerts_client.ts:92](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L92) ___ @@ -82,78 +86,110 @@ ___ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:62](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L62) +[alerts_client.ts:89](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L89) ___ ### spaceId -• `Private` `Readonly` **spaceId**: `Promise` +• `Private` `Readonly` **spaceId**: `undefined` \| `string` #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:66](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L66) +[alerts_client.ts:93](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L93) ## Methods -### fetchAlert +### buildEsQueryWithAuthz -▸ `Private` **fetchAlert**(`__namedParameters`): `Promise`\>, ``"kibana.alert.owner"`` \| ``"rule.id"``\> & { `kibana.alert.owner`: `string` ; `rule.id`: `string` } & { `_version`: `undefined` \| `string` }\> +▸ `Private` **buildEsQueryWithAuthz**(`query`, `id`, `alertSpaceId`, `operation`, `config`): `Promise`<`Object`\> #### Parameters | Name | Type | | :------ | :------ | -| `__namedParameters` | `GetAlertParams` | +| `query` | `undefined` \| ``null`` \| `string` | +| `id` | `undefined` \| ``null`` \| `string` | +| `alertSpaceId` | `string` | +| `operation` | `Get` \| `Find` \| `Update` | +| `config` | `EsQueryConfig` | #### Returns -`Promise`\>, ``"kibana.alert.owner"`` \| ``"rule.id"``\> & { `kibana.alert.owner`: `string` ; `rule.id`: `string` } & { `_version`: `undefined` \| `string` }\> +`Promise`<`Object`\> #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:87](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L87) +[alerts_client.ts:305](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L305) ___ -### get +### bulkUpdate + +▸ **bulkUpdate**(`__namedParameters`): `Promise` \| ApiResponse\> + +#### Type parameters -▸ **get**(`__namedParameters`): `Promise`\>\> +| Name | Type | +| :------ | :------ | +| `Params` | `Params`: `AlertTypeParams` = `never` | #### Parameters | Name | Type | | :------ | :------ | -| `__namedParameters` | `GetAlertParams` | +| `__namedParameters` | [BulkUpdateOptions](../interfaces/bulkupdateoptions.md) | #### Returns -`Promise`\>\> +`Promise` \| ApiResponse\> #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:134](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L134) +[alerts_client.ts:475](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L475) ___ -### getAlertsIndex +### ensureAllAuthorized -▸ **getAlertsIndex**(`featureIds`, `operations`): `Promise`<`Object`\> +▸ `Private` **ensureAllAuthorized**(`items`, `operation`): `Promise`<(undefined \| void)[]\> + +Accepts an array of ES documents and executes ensureAuthorized for the given operation #### Parameters | Name | Type | | :------ | :------ | -| `featureIds` | `string`[] | -| `operations` | (`ReadOperations` \| `WriteOperations`)[] | +| `items` | { `_id`: `string` ; `_source?`: ``null`` \| { `kibana.alert.owner?`: ``null`` \| `string` ; `rule.id?`: ``null`` \| `string` } }[] | +| `operation` | `Get` \| `Find` \| `Update` | #### Returns -`Promise`<`Object`\> +`Promise`<(undefined \| void)[]\> + +#### Defined in + +[alerts_client.ts:111](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L111) + +___ + +### get + +▸ **get**(`__namedParameters`): `Promise`\>\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `__namedParameters` | `GetAlertParams` | + +#### Returns + +`Promise`\>\> #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:76](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L76) +[alerts_client.ts:407](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L407) ___ @@ -173,13 +209,87 @@ ___ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:238](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L238) +[alerts_client.ts:533](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L533) + +___ + +### mgetAlertsAuditOperate + +▸ `Private` **mgetAlertsAuditOperate**(`__namedParameters`): `Promise`\> + +When an update by ids is requested, do a multi-get, ensure authz and audit alerts, then execute bulk update + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `__namedParameters` | `Object` | +| `__namedParameters.ids` | `string`[] | +| `__namedParameters.indexName` | `string` | +| `__namedParameters.operation` | `Get` \| `Find` \| `Update` | +| `__namedParameters.status` | `STATUS\_VALUES` | + +#### Returns + +`Promise`\> + +#### Defined in + +[alerts_client.ts:252](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L252) + +___ + +### queryAndAuditAllAlerts + +▸ `Private` **queryAndAuditAllAlerts**(`__namedParameters`): `Promise` + +executes a search after to find alerts with query (+ authz filter) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `__namedParameters` | `Object` | +| `__namedParameters.index` | `string` | +| `__namedParameters.operation` | `Get` \| `Find` \| `Update` | +| `__namedParameters.query` | `string` | + +#### Returns + +`Promise` + +#### Defined in + +[alerts_client.ts:343](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L343) + +___ + +### singleSearchAfterAndAudit + +▸ `Private` **singleSearchAfterAndAudit**(`__namedParameters`): `Promise`\>\>\> + +This will be used as a part of the "find" api +In the future we will add an "aggs" param + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `__namedParameters` | `SingleSearchAfterAndAudit` | + +#### Returns + +`Promise`\>\>\> + +#### Defined in + +[alerts_client.ts:176](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L176) ___ ### update -▸ **update**(`__namedParameters`): `Promise` +▸ **update**(`__namedParameters`): `Promise`<`Object`\> #### Type parameters @@ -195,8 +305,8 @@ ___ #### Returns -`Promise` +`Promise`<`Object`\> #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:179](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L179) +[alerts_client.ts:432](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L432) diff --git a/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/bulkupdateoptions.md b/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/bulkupdateoptions.md new file mode 100644 index 0000000000000..28c49c3519f6e --- /dev/null +++ b/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/bulkupdateoptions.md @@ -0,0 +1,58 @@ +[Alerts as data client API Interface](../alerts_client_api.md) / BulkUpdateOptions + +# Interface: BulkUpdateOptions + +## Type parameters + +| Name | Type | +| :------ | :------ | +| `Params` | `Params`: `AlertTypeParams` | + +## Table of contents + +### Properties + +- [ids](bulkupdateoptions.md#ids) +- [index](bulkupdateoptions.md#index) +- [query](bulkupdateoptions.md#query) +- [status](bulkupdateoptions.md#status) + +## Properties + +### ids + +• **ids**: `undefined` \| ``null`` \| `string`[] + +#### Defined in + +[alerts_client.ts:64](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L64) + +___ + +### index + +• **index**: `string` + +#### Defined in + +[alerts_client.ts:66](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L66) + +___ + +### query + +• **query**: `undefined` \| ``null`` \| `string` + +#### Defined in + +[alerts_client.ts:67](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L67) + +___ + +### status + +• **status**: `STATUS\_VALUES` + +#### Defined in + +[alerts_client.ts:65](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L65) diff --git a/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/constructoroptions.md b/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/constructoroptions.md index 23c5b94ad0d52..c371719dbced3 100644 --- a/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/constructoroptions.md +++ b/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/constructoroptions.md @@ -19,7 +19,7 @@ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:40](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L40) +[alerts_client.ts:52](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L52) ___ @@ -29,7 +29,7 @@ ___ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:39](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L39) +[alerts_client.ts:51](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L51) ___ @@ -39,7 +39,7 @@ ___ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:41](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L41) +[alerts_client.ts:53](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L53) ___ @@ -49,4 +49,4 @@ ___ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:38](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L38) +[alerts_client.ts:50](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L50) diff --git a/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/updateoptions.md b/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/updateoptions.md index a8bff815c250f..f05a061b279d9 100644 --- a/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/updateoptions.md +++ b/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/updateoptions.md @@ -25,7 +25,7 @@ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:47](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L47) +[alerts_client.ts:59](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L59) ___ @@ -35,7 +35,7 @@ ___ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:45](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L45) +[alerts_client.ts:57](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L57) ___ @@ -45,7 +45,7 @@ ___ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:48](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L48) +[alerts_client.ts:60](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L60) ___ @@ -55,4 +55,4 @@ ___ #### Defined in -[rule_registry/server/alert_data_client/alerts_client.ts:46](https://github.com/elastic/kibana/blob/48e1b91d751/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L46) +[alerts_client.ts:58](https://github.com/elastic/kibana/blob/daf6871ba4b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L58) diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.mock.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.mock.ts index 73c6b4dd40526..ee81a39052522 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.mock.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.mock.ts @@ -14,9 +14,9 @@ export type AlertsClientMock = jest.Mocked; const createAlertsClientMock = () => { const mocked: AlertsClientMock = { get: jest.fn(), - getAlertsIndex: jest.fn(), update: jest.fn(), getAuthorizedAlertsIndices: jest.fn(), + bulkUpdate: jest.fn(), }; return mocked; }; diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts index 91282edf3778a..2a7419b20570e 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts @@ -4,23 +4,28 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import Boom from '@hapi/boom'; import { PublicMethodsOf } from '@kbn/utility-types'; +import { Filter, buildEsQuery, EsQueryConfig } from '@kbn/es-query'; import { decodeVersion, encodeHitVersion } from '@kbn/securitysolution-es-utils'; import { mapConsumerToIndexName, - validFeatureIds, isValidFeatureId, + getSafeSortIds, + STATUS_VALUES, + getEsQueryConfig, } from '@kbn/rule-data-utils/target/alerts_as_data_rbac'; -import { AlertTypeParams } from '../../../alerting/server'; +import { InlineScript, QueryDslQueryContainer } from '@elastic/elasticsearch/api/types'; +import { AlertTypeParams, AlertingAuthorizationFilterType } from '../../../alerting/server'; import { ReadOperations, AlertingAuthorization, WriteOperations, AlertingAuthorizationEntity, } from '../../../alerting/server'; -import { Logger, ElasticsearchClient } from '../../../../../src/core/server'; -import { alertAuditEvent, AlertAuditAction } from './audit_events'; +import { Logger, ElasticsearchClient, EcsEventOutcome } from '../../../../../src/core/server'; +import { alertAuditEvent, operationAlertAuditActionMap } from './audit_events'; import { AuditLogger } from '../../../security/server'; import { ALERT_STATUS, @@ -33,10 +38,13 @@ import { ParsedTechnicalFields } from '../../common/parse_technical_fields'; // TODO: Fix typings https://github.com/elastic/kibana/issues/101776 type NonNullableProps = Omit & { [K in Props]-?: NonNullable }; -type AlertType = NonNullableProps; +type AlertType = NonNullableProps< + ParsedTechnicalFields, + typeof RULE_ID | typeof ALERT_OWNER | typeof SPACE_IDS +>; const isValidAlert = (source?: ParsedTechnicalFields): source is AlertType => { - return source?.[RULE_ID] != null && source?.[ALERT_OWNER] != null; + return source?.[RULE_ID] != null && source?.[ALERT_OWNER] != null && source?.[SPACE_IDS] != null; }; export interface ConstructorOptions { logger: Logger; @@ -52,11 +60,26 @@ export interface UpdateOptions { index: string; } +export interface BulkUpdateOptions { + ids: string[] | undefined | null; + status: STATUS_VALUES; + index: string; + query: string | undefined | null; +} + interface GetAlertParams { id: string; index?: string; } +interface SingleSearchAfterAndAudit { + id: string | null | undefined; + query: string | null | undefined; + index?: string; + operation: WriteOperations.Update | ReadOperations.Find | ReadOperations.Get; + lastSortIds: Array | undefined; +} + /** * Provides apis to interact with alerts as data * ensures the request is authorized to perform read / write actions @@ -79,105 +102,337 @@ export class AlertsClient { this.spaceId = this.authorization.getSpaceId(); } - public async getAlertsIndex( - featureIds: string[], - operations: Array + private getOutcome( + operation: WriteOperations.Update | ReadOperations.Find | ReadOperations.Get + ): { outcome: EcsEventOutcome } { + return { + outcome: operation === WriteOperations.Update ? 'unknown' : 'success', + }; + } + + /** + * Accepts an array of ES documents and executes ensureAuthorized for the given operation + * @param items + * @param operation + * @returns + */ + private async ensureAllAuthorized( + items: Array<{ + _id: string; + // this is typed kind of crazy to fit the output of es api response to this + _source?: + | { [RULE_ID]?: string | null | undefined; [ALERT_OWNER]?: string | null | undefined } + | null + | undefined; + }>, + operation: ReadOperations.Find | ReadOperations.Get | WriteOperations.Update ) { - return this.authorization.getAugmentedRuleTypesWithAuthorization( - featureIds.length !== 0 ? featureIds : validFeatureIds, - operations, - AlertingAuthorizationEntity.Alert + const { hitIds, ownersAndRuleTypeIds } = items.reduce( + (acc, hit) => ({ + hitIds: [hit._id, ...acc.hitIds], + ownersAndRuleTypeIds: [ + { + [RULE_ID]: hit?._source?.[RULE_ID], + [ALERT_OWNER]: hit?._source?.[ALERT_OWNER], + }, + ], + }), + { hitIds: [], ownersAndRuleTypeIds: [] } as { + hitIds: string[]; + ownersAndRuleTypeIds: Array<{ + [RULE_ID]: string | null | undefined; + [ALERT_OWNER]: string | null | undefined; + }>; + } ); + + const assertString = (hit: unknown): hit is string => hit !== null && hit !== undefined; + + return Promise.all( + ownersAndRuleTypeIds.map((hit) => { + const alertOwner = hit?.[ALERT_OWNER]; + const ruleId = hit?.[RULE_ID]; + if (hit != null && assertString(alertOwner) && assertString(ruleId)) { + return this.authorization.ensureAuthorized({ + ruleTypeId: ruleId, + consumer: alertOwner, + operation, + entity: AlertingAuthorizationEntity.Alert, + }); + } + }) + ).catch((error) => { + for (const hitId of hitIds) { + this.auditLogger?.log( + alertAuditEvent({ + action: operationAlertAuditActionMap[operation], + id: hitId, + error, + }) + ); + } + throw error; + }); } - private async fetchAlert({ + /** + * This will be used as a part of the "find" api + * In the future we will add an "aggs" param + * @param param0 + * @returns + */ + private async singleSearchAfterAndAudit({ id, + query, index, - }: GetAlertParams): Promise<(AlertType & { _version: string | undefined }) | null | undefined> { + operation, + lastSortIds = [], + }: SingleSearchAfterAndAudit) { try { const alertSpaceId = this.spaceId; if (alertSpaceId == null) { - this.logger.error('Failed to acquire spaceId from authorization client'); - return; + const errorMessage = 'Failed to acquire spaceId from authorization client'; + this.logger.error(`fetchAlertAndAudit threw an error: ${errorMessage}`); + throw Boom.failedDependency(`fetchAlertAndAudit threw an error: ${errorMessage}`); } + + const config = getEsQueryConfig(); + + let queryBody = { + query: await this.buildEsQueryWithAuthz(query, id, alertSpaceId, operation, config), + sort: [ + { + '@timestamp': { + order: 'asc', + unmapped_type: 'date', + }, + }, + ], + }; + + if (lastSortIds.length > 0) { + queryBody = { + ...queryBody, + // @ts-expect-error + search_after: lastSortIds, + }; + } + const result = await this.esClient.search({ - // Context: Originally thought of always just searching `.alerts-*` but that could - // result in a big performance hit. If the client already knows which index the alert - // belongs to, passing in the index will speed things up index: index ?? '.alerts-*', ignore_unavailable: true, - body: { - query: { - bool: { - filter: [{ term: { _id: id } }, { term: { [SPACE_IDS]: alertSpaceId } }], - }, - }, - }, + // @ts-expect-error + body: queryBody, seq_no_primary_term: true, }); - if (result == null || result.body == null || result.body.hits.hits.length === 0) { - return; + if (!result?.body.hits.hits.every((hit) => isValidAlert(hit._source))) { + const errorMessage = `Invalid alert found with id of "${id}" or with query "${query}" and operation ${operation}`; + this.logger.error(errorMessage); + throw Boom.badData(errorMessage); } - if (!isValidAlert(result.body.hits.hits[0]._source)) { - const errorMessage = `Unable to retrieve alert details for alert with id of "${id}".`; - this.logger.debug(errorMessage); - throw new Error(errorMessage); - } + await this.ensureAllAuthorized(result.body.hits.hits, operation); - return { - ...result.body.hits.hits[0]._source, - _version: encodeHitVersion(result.body.hits.hits[0]), - }; + result?.body.hits.hits.map((item) => + this.auditLogger?.log( + alertAuditEvent({ + action: operationAlertAuditActionMap[operation], + id: item._id, + ...this.getOutcome(operation), + }) + ) + ); + + return result.body; } catch (error) { - const errorMessage = `Unable to retrieve alert with id of "${id}".`; - this.logger.debug(errorMessage); - throw error; + const errorMessage = `Unable to retrieve alert details for alert with id of "${id}" or with query "${query}" and operation ${operation} \nError: ${error}`; + this.logger.error(errorMessage); + throw Boom.notFound(errorMessage); } } - public async get({ - id, - index, - }: GetAlertParams): Promise { + /** + * When an update by ids is requested, do a multi-get, ensure authz and audit alerts, then execute bulk update + * @param param0 + * @returns + */ + private async mgetAlertsAuditOperate({ + ids, + status, + indexName, + operation, + }: { + ids: string[]; + status: STATUS_VALUES; + indexName: string; + operation: ReadOperations.Find | ReadOperations.Get | WriteOperations.Update; + }) { try { - // first search for the alert by id, then use the alert info to check if user has access to it - const alert = await this.fetchAlert({ - id, - index, + const mgetRes = await this.esClient.mget({ + index: indexName, + body: { + ids, + }, }); - if (alert == null) { - return; + await this.ensureAllAuthorized(mgetRes.body.docs, operation); + + for (const id of ids) { + this.auditLogger?.log( + alertAuditEvent({ + action: operationAlertAuditActionMap[operation], + id, + ...this.getOutcome(operation), + }) + ); } - // this.authorization leverages the alerting plugin's authorization - // client exposed to us for reuse - await this.authorization.ensureAuthorized({ - ruleTypeId: alert[RULE_ID], - consumer: alert[ALERT_OWNER], - operation: ReadOperations.Get, - entity: AlertingAuthorizationEntity.Alert, + const bulkUpdateRequest = mgetRes.body.docs.flatMap((item) => [ + { + update: { + _index: item._index, + _id: item._id, + }, + }, + { + doc: { [ALERT_STATUS]: status }, + }, + ]); + + const bulkUpdateResponse = await this.esClient.bulk({ + body: bulkUpdateRequest, }); + return bulkUpdateResponse; + } catch (exc) { + this.logger.error(`error in mgetAlertsAuditOperate ${exc}`); + throw exc; + } + } - this.auditLogger?.log( - alertAuditEvent({ - action: AlertAuditAction.GET, - id, - }) + private async buildEsQueryWithAuthz( + query: string | null | undefined, + id: string | null | undefined, + alertSpaceId: string, + operation: WriteOperations.Update | ReadOperations.Get | ReadOperations.Find, + config: EsQueryConfig + ) { + try { + const { filter: authzFilter } = await this.authorization.getAuthorizationFilter( + AlertingAuthorizationEntity.Alert, + { + type: AlertingAuthorizationFilterType.ESDSL, + fieldNames: { consumer: ALERT_OWNER, ruleTypeId: RULE_ID }, + }, + operation ); + return buildEsQuery( + undefined, + { query: query == null ? `_id:${id}` : query, language: 'kuery' }, + [ + (authzFilter as unknown) as Filter, + ({ term: { [SPACE_IDS]: alertSpaceId } } as unknown) as Filter, + ], + config + ); + } catch (exc) { + this.logger.error(exc); + throw Boom.expectationFailed( + `buildEsQueryWithAuthz threw an error: unable to get authorization filter \n ${exc}` + ); + } + } + + /** + * executes a search after to find alerts with query (+ authz filter) + * @param param0 + * @returns + */ + private async queryAndAuditAllAlerts({ + index, + query, + operation, + }: { + index: string; + query: string; + operation: WriteOperations.Update | ReadOperations.Find | ReadOperations.Get; + }) { + let lastSortIds; + let hasSortIds = true; + const alertSpaceId = this.spaceId; + if (alertSpaceId == null) { + this.logger.error('Failed to acquire spaceId from authorization client'); + return; + } + + const config = getEsQueryConfig(); + + const authorizedQuery = await this.buildEsQueryWithAuthz( + query, + null, + alertSpaceId, + operation, + config + ); + + while (hasSortIds) { + try { + const result = await this.singleSearchAfterAndAudit({ + id: null, + query, + index, + operation, + lastSortIds, + }); + + if (lastSortIds != null && result?.hits.hits.length === 0) { + return { auditedAlerts: true, authorizedQuery }; + } + if (result == null) { + this.logger.error('RESULT WAS EMPTY'); + return { auditedAlerts: false, authorizedQuery }; + } + if (result.hits.hits.length === 0) { + this.logger.error('Search resulted in no hits'); + return { auditedAlerts: true, authorizedQuery }; + } + + lastSortIds = getSafeSortIds(result.hits.hits[result.hits.hits.length - 1]?.sort); + if (lastSortIds != null && lastSortIds.length !== 0) { + hasSortIds = true; + } else { + hasSortIds = false; + return { auditedAlerts: true, authorizedQuery }; + } + } catch (error) { + const errorMessage = `queryAndAuditAllAlerts threw an error: Unable to retrieve alerts with query "${query}" and operation ${operation} \n ${error}`; + this.logger.error(errorMessage); + throw Boom.notFound(errorMessage); + } + } + } - return alert; + public async get({ id, index }: GetAlertParams) { + try { + // first search for the alert by id, then use the alert info to check if user has access to it + const alert = await this.singleSearchAfterAndAudit({ + id, + query: null, + index, + operation: ReadOperations.Get, + lastSortIds: undefined, + }); + + if (alert == null || alert.hits.hits.length === 0) { + const errorMessage = `Unable to retrieve alert details for alert with id of "${id}" and operation ${ReadOperations.Get}`; + this.logger.error(errorMessage); + throw Boom.notFound(errorMessage); + } + + // move away from pulling data from _source in the future + return alert.hits.hits[0]._source; } catch (error) { - this.logger.debug(`Error fetching alert with id of "${id}"`); - this.auditLogger?.log( - alertAuditEvent({ - action: AlertAuditAction.GET, - id, - error, - }) - ); + this.logger.error(`get threw an error: ${error}`); throw error; } } @@ -189,29 +444,19 @@ export class AlertsClient { index, }: UpdateOptions) { try { - const alert = await this.fetchAlert({ + const alert = await this.singleSearchAfterAndAudit({ id, + query: null, index, - }); - - if (alert == null) { - return; - } - - await this.authorization.ensureAuthorized({ - ruleTypeId: alert[RULE_ID], - consumer: alert[ALERT_OWNER], operation: WriteOperations.Update, - entity: AlertingAuthorizationEntity.Alert, + lastSortIds: undefined, }); - this.auditLogger?.log( - alertAuditEvent({ - action: AlertAuditAction.UPDATE, - id, - outcome: 'unknown', - }) - ); + if (alert == null || alert.hits.hits.length === 0) { + const errorMessage = `Unable to retrieve alert details for alert with id of "${id}" and operation ${ReadOperations.Get}`; + this.logger.error(errorMessage); + throw Boom.notFound(errorMessage); + } const { body: response } = await this.esClient.update({ ...decodeVersion(_version), @@ -230,39 +475,97 @@ export class AlertsClient { _version: encodeHitVersion(response), }; } catch (error) { - this.auditLogger?.log( - alertAuditEvent({ - action: AlertAuditAction.UPDATE, - id, - error, - }) - ); + this.logger.error(`update threw an error: ${error}`); throw error; } } - public async getAuthorizedAlertsIndices(featureIds: string[]): Promise { - const augmentedRuleTypes = await this.authorization.getAugmentedRuleTypesWithAuthorization( - featureIds, - [ReadOperations.Find, ReadOperations.Get, WriteOperations.Update], - AlertingAuthorizationEntity.Alert - ); + public async bulkUpdate({ + ids, + query, + index, + status, + }: BulkUpdateOptions) { + // rejects at the route level if more than 1000 id's are passed in + if (ids != null) { + return this.mgetAlertsAuditOperate({ + ids, + status, + indexName: index, + operation: WriteOperations.Update, + }); + } else if (query != null) { + try { + // execute search after with query + authorization filter + // audit results of that query + const fetchAndAuditResponse = await this.queryAndAuditAllAlerts({ + query, + index, + operation: WriteOperations.Update, + }); - // As long as the user can read a minimum of one type of rule type produced by the provided feature, - // the user should be provided that features' alerts index. - // Limiting which alerts that user can read on that index will be done via the findAuthorizationFilter - const authorizedFeatures = new Set(); - for (const ruleType of augmentedRuleTypes.authorizedRuleTypes) { - authorizedFeatures.add(ruleType.producer); + if (!fetchAndAuditResponse?.auditedAlerts) { + throw Boom.unauthorized('Failed to audit alerts'); + } + + // executes updateByQuery with query + authorization filter + // used in the queryAndAuditAllAlerts function + const result = await this.esClient.updateByQuery({ + index, + conflicts: 'proceed', + refresh: true, + body: { + script: { + source: `if (ctx._source['${ALERT_STATUS}'] != null) { + ctx._source['${ALERT_STATUS}'] = '${status}' + } + if (ctx._source['signal.status'] != null) { + ctx._source['signal.status'] = '${status}' + }`, + lang: 'painless', + } as InlineScript, + query: fetchAndAuditResponse.authorizedQuery as Omit, + }, + ignore_unavailable: true, + }); + return result; + } catch (err) { + this.logger.error(`bulkUpdate threw an error: ${err}`); + throw err; + } + } else { + throw Boom.badRequest('no ids or query were provided for updating'); } + } + + public async getAuthorizedAlertsIndices(featureIds: string[]): Promise { + try { + const augmentedRuleTypes = await this.authorization.getAugmentedRuleTypesWithAuthorization( + featureIds, + [ReadOperations.Find, ReadOperations.Get, WriteOperations.Update], + AlertingAuthorizationEntity.Alert + ); - const toReturn = Array.from(authorizedFeatures).flatMap((feature) => { - if (isValidFeatureId(feature)) { - return mapConsumerToIndexName[feature]; + // As long as the user can read a minimum of one type of rule type produced by the provided feature, + // the user should be provided that features' alerts index. + // Limiting which alerts that user can read on that index will be done via the findAuthorizationFilter + const authorizedFeatures = new Set(); + for (const ruleType of augmentedRuleTypes.authorizedRuleTypes) { + authorizedFeatures.add(ruleType.producer); } - return []; - }); - return toReturn; + const toReturn = Array.from(authorizedFeatures).flatMap((feature) => { + if (isValidFeatureId(feature)) { + return mapConsumerToIndexName[feature]; + } + return []; + }); + + return toReturn; + } catch (exc) { + const errMessage = `getAuthorizedAlertsIndices failed to get authorized rule types: ${exc}`; + this.logger.error(errMessage); + throw Boom.failedDependency(errMessage); + } } } diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/audit_events.ts b/x-pack/plugins/rule_registry/server/alert_data_client/audit_events.ts index d07c23c7fbe9f..4b983e986f859 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/audit_events.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/audit_events.ts @@ -7,6 +7,7 @@ import { EcsEventOutcome, EcsEventType } from 'src/core/server'; import { AuditEvent } from '../../../security/server'; +import { ReadOperations, WriteOperations } from '../../../alerting/server'; export enum AlertAuditAction { GET = 'alert_get', @@ -14,6 +15,12 @@ export enum AlertAuditAction { FIND = 'alert_find', } +export const operationAlertAuditActionMap = { + [WriteOperations.Update]: AlertAuditAction.UPDATE, + [ReadOperations.Find]: AlertAuditAction.FIND, + [ReadOperations.Get]: AlertAuditAction.GET, +}; + type VerbsTuple = [string, string, string]; const eventVerbs: Record = { diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts new file mode 100644 index 0000000000000..97a19935fa787 --- /dev/null +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts @@ -0,0 +1,458 @@ +/* + * 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 { ALERT_OWNER, ALERT_STATUS, SPACE_IDS, RULE_ID } from '@kbn/rule-data-utils'; +import { AlertsClient, ConstructorOptions } from '../alerts_client'; +import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; +import { alertingAuthorizationMock } from '../../../../alerting/server/authorization/alerting_authorization.mock'; +import { AuditLogger } from '../../../../security/server'; +import { AlertingAuthorizationEntity } from '../../../../alerting/server'; + +const alertingAuthMock = alertingAuthorizationMock.create(); +const esClientMock = elasticsearchClientMock.createElasticsearchClient(); +const auditLogger = { + log: jest.fn(), +} as jest.Mocked; + +const alertsClientParams: jest.Mocked = { + logger: loggingSystemMock.create().get(), + authorization: alertingAuthMock, + esClient: esClientMock, + auditLogger, +}; + +const DEFAULT_SPACE = 'test_default_space_id'; + +beforeEach(() => { + jest.resetAllMocks(); + alertingAuthMock.getSpaceId.mockImplementation(() => 'test_default_space_id'); + // @ts-expect-error + alertingAuthMock.getAuthorizationFilter.mockImplementation(async () => + Promise.resolve({ filter: [] }) + ); + alertingAuthMock.ensureAuthorized.mockImplementation( + // @ts-expect-error + async ({ + ruleTypeId, + consumer, + operation, + entity, + }: { + ruleTypeId: string; + consumer: string; + operation: string; + entity: typeof AlertingAuthorizationEntity.Alert; + }) => { + if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { + return Promise.resolve(); + } + return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + } + ); +}); + +const fakeAlertId = 'myfakeid1'; +const successfulAuthzHit = 'successfulAuthzHit'; +const unsuccessfulAuthzHit = 'unsuccessfulAuthzHit'; +// fakeRuleTypeId will cause authz to fail +const fakeRuleTypeId = 'fake.rule'; + +describe('bulkUpdate()', () => { + describe('ids', () => { + describe('audit log', () => { + test('logs successful event in audit logger', async () => { + const indexName = '.alerts-observability-apm.alerts'; + const alertsClient = new AlertsClient(alertsClientParams); + esClientMock.mget.mockResolvedValueOnce( + elasticsearchClientMock.createApiResponse({ + body: { + docs: [ + { + _id: fakeAlertId, + _index: indexName, + _source: { + [RULE_ID]: 'apm.error_rate', + [ALERT_OWNER]: 'apm', + [ALERT_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + ], + }, + }) + ); + esClientMock.bulk.mockResolvedValueOnce( + elasticsearchClientMock.createApiResponse({ + body: { + errors: false, + took: 1, + items: [ + { + update: { + _id: fakeAlertId, + _index: '.alerts-observability-apm.alerts', + result: 'updated', + status: 200, + }, + }, + ], + }, + }) + ); + await alertsClient.bulkUpdate({ + ids: [fakeAlertId], + query: undefined, + index: indexName, + status: 'closed', + }); + expect(auditLogger.log).toHaveBeenNthCalledWith(1, { + message: `User is updating alert [id=${fakeAlertId}]`, + event: { + action: 'alert_update', + category: ['database'], + outcome: 'unknown', + type: ['change'], + }, + error: undefined, + }); + }); + + test('audit error access if user is unauthorized for given alert', async () => { + const indexName = '.alerts-observability-apm.alerts'; + const alertsClient = new AlertsClient(alertsClientParams); + esClientMock.mget.mockResolvedValueOnce( + elasticsearchClientMock.createApiResponse({ + body: { + docs: [ + { + _id: fakeAlertId, + _index: indexName, + _source: { + [RULE_ID]: fakeRuleTypeId, + [ALERT_OWNER]: 'apm', + [ALERT_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + ], + }, + }) + ); + + await expect( + alertsClient.bulkUpdate({ + ids: [fakeAlertId], + query: undefined, + index: indexName, + status: 'closed', + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Unauthorized for fake.rule and apm"`); + + expect(auditLogger.log).toHaveBeenNthCalledWith(1, { + message: `Failed attempt to update alert [id=${fakeAlertId}]`, + event: { + action: 'alert_update', + category: ['database'], + outcome: 'failure', + type: ['change'], + }, + error: { + code: 'Error', + message: 'Unauthorized for fake.rule and apm', + }, + }); + }); + + test('logs multiple error events in audit logger', async () => { + const indexName = '.alerts-observability-apm.alerts'; + const alertsClient = new AlertsClient(alertsClientParams); + esClientMock.mget.mockResolvedValueOnce( + elasticsearchClientMock.createApiResponse({ + body: { + docs: [ + { + _id: successfulAuthzHit, + _index: indexName, + _source: { + [RULE_ID]: 'apm.error_rate', + [ALERT_OWNER]: 'apm', + [ALERT_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + { + _id: unsuccessfulAuthzHit, + _index: indexName, + _source: { + [RULE_ID]: fakeRuleTypeId, + [ALERT_OWNER]: 'apm', + [ALERT_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + ], + }, + }) + ); + + await expect( + alertsClient.bulkUpdate({ + ids: [successfulAuthzHit, unsuccessfulAuthzHit], + query: undefined, + index: indexName, + status: 'closed', + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Unauthorized for fake.rule and apm"`); + expect(auditLogger.log).toHaveBeenCalledTimes(2); + expect(auditLogger.log).toHaveBeenNthCalledWith(1, { + message: `Failed attempt to update alert [id=${unsuccessfulAuthzHit}]`, + event: { + action: 'alert_update', + category: ['database'], + outcome: 'failure', + type: ['change'], + }, + error: { + code: 'Error', + message: 'Unauthorized for fake.rule and apm', + }, + }); + expect(auditLogger.log).toHaveBeenNthCalledWith(2, { + message: `Failed attempt to update alert [id=${successfulAuthzHit}]`, + event: { + action: 'alert_update', + category: ['database'], + outcome: 'failure', + type: ['change'], + }, + error: { + code: 'Error', + message: 'Unauthorized for fake.rule and apm', + }, + }); + }); + }); + + // test('throws an error if ES client fetch fails', async () => {}); + // test('throws an error if ES client bulk update fails', async () => {}); + // test('throws an error if ES client updateByQuery fails', async () => {}); + }); + describe('query', () => { + describe('audit log', () => { + test('logs successful event in audit logger', async () => { + const indexName = '.alerts-observability-apm.alerts'; + const alertsClient = new AlertsClient(alertsClientParams); + esClientMock.search.mockResolvedValueOnce( + elasticsearchClientMock.createApiResponse({ + body: { + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + _id: fakeAlertId, + _index: '.alerts-observability-apm.alerts', + _source: { + [RULE_ID]: 'apm.error_rate', + [ALERT_OWNER]: 'apm', + [ALERT_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + ], + }, + }, + }) + ); + + esClientMock.updateByQuery.mockResolvedValueOnce( + elasticsearchClientMock.createApiResponse({ + body: { + updated: 1, + }, + }) + ); + + await alertsClient.bulkUpdate({ + ids: undefined, + query: `${ALERT_STATUS}: open`, + index: indexName, + status: 'closed', + }); + expect(auditLogger.log).toHaveBeenCalledWith({ + message: `User is updating alert [id=${fakeAlertId}]`, + event: { + action: 'alert_update', + category: ['database'], + outcome: 'unknown', + type: ['change'], + }, + error: undefined, + }); + }); + + test('audit error access if user is unauthorized for given alert', async () => { + const indexName = '.alerts-observability-apm.alerts'; + const alertsClient = new AlertsClient(alertsClientParams); + esClientMock.search.mockResolvedValueOnce( + elasticsearchClientMock.createApiResponse({ + body: { + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + _id: fakeAlertId, + _index: '.alerts-observability-apm.alerts', + _source: { + [RULE_ID]: fakeRuleTypeId, + [ALERT_OWNER]: 'apm', + [ALERT_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + ], + }, + }, + }) + ); + await expect( + alertsClient.bulkUpdate({ + ids: undefined, + query: `${ALERT_STATUS}: open`, + index: indexName, + status: 'closed', + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(` + "queryAndAuditAllAlerts threw an error: Unable to retrieve alerts with query \\"kibana.alert.status: open\\" and operation update + Error: Unable to retrieve alert details for alert with id of \\"null\\" or with query \\"kibana.alert.status: open\\" and operation update + Error: Error: Unauthorized for fake.rule and apm" + `); + + expect(auditLogger.log).toHaveBeenNthCalledWith(1, { + message: `Failed attempt to update alert [id=${fakeAlertId}]`, + event: { + action: 'alert_update', + category: ['database'], + outcome: 'failure', + type: ['change'], + }, + error: { + code: 'Error', + message: 'Unauthorized for fake.rule and apm', + }, + }); + }); + + test('logs multiple error events in audit logger', async () => { + const indexName = '.alerts-observability-apm.alerts'; + const alertsClient = new AlertsClient(alertsClientParams); + esClientMock.search.mockResolvedValueOnce( + elasticsearchClientMock.createApiResponse({ + body: { + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 2, + max_score: 999, + hits: [ + { + _id: successfulAuthzHit, + _index: '.alerts-observability-apm.alerts', + _source: { + [RULE_ID]: 'apm.error_rate', + [ALERT_OWNER]: 'apm', + [ALERT_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + { + _id: unsuccessfulAuthzHit, + _index: '.alerts-observability-apm.alerts', + _source: { + [RULE_ID]: fakeRuleTypeId, + [ALERT_OWNER]: 'apm', + [ALERT_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + ], + }, + }, + }) + ); + await expect( + alertsClient.bulkUpdate({ + ids: undefined, + query: `${ALERT_STATUS}: open`, + index: indexName, + status: 'closed', + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(` + "queryAndAuditAllAlerts threw an error: Unable to retrieve alerts with query \\"kibana.alert.status: open\\" and operation update + Error: Unable to retrieve alert details for alert with id of \\"null\\" or with query \\"kibana.alert.status: open\\" and operation update + Error: Error: Unauthorized for fake.rule and apm" + `); + + expect(auditLogger.log).toHaveBeenCalledTimes(2); + expect(auditLogger.log).toHaveBeenNthCalledWith(1, { + message: `Failed attempt to update alert [id=${unsuccessfulAuthzHit}]`, + event: { + action: 'alert_update', + category: ['database'], + outcome: 'failure', + type: ['change'], + }, + error: { + code: 'Error', + message: 'Unauthorized for fake.rule and apm', + }, + }); + expect(auditLogger.log).toHaveBeenNthCalledWith(2, { + message: `Failed attempt to update alert [id=${successfulAuthzHit}]`, + event: { + action: 'alert_update', + category: ['database'], + outcome: 'failure', + type: ['change'], + }, + error: { + code: 'Error', + message: 'Unauthorized for fake.rule and apm', + }, + }); + }); + }); + // test('throws an error if ES client fetch fails', async () => {}); + // test('throws an error if ES client bulk update fails', async () => {}); + // test('throws an error if ES client updateByQuery fails', async () => {}); + }); +}); diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts index 51789a09234e2..651d728b1983c 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts @@ -5,13 +5,14 @@ * 2.0. */ -import { ALERT_OWNER, ALERT_STATUS, SPACE_IDS } from '@kbn/rule-data-utils'; +import { ALERT_OWNER, ALERT_STATUS, RULE_ID, SPACE_IDS } from '@kbn/rule-data-utils'; import { AlertsClient, ConstructorOptions } from '../alerts_client'; import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { alertingAuthorizationMock } from '../../../../alerting/server/authorization/alerting_authorization.mock'; import { AuditLogger } from '../../../../security/server'; +import { AlertingAuthorizationEntity } from '../../../../alerting/server'; const alertingAuthMock = alertingAuthorizationMock.create(); const esClientMock = elasticsearchClientMock.createElasticsearchClient(); @@ -26,9 +27,35 @@ const alertsClientParams: jest.Mocked = { auditLogger, }; +const DEFAULT_SPACE = 'test_default_space_id'; + beforeEach(() => { jest.resetAllMocks(); - alertingAuthMock.getSpaceId.mockImplementation(() => 'test_default_space_id'); + alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); + // @ts-expect-error + alertingAuthMock.getAuthorizationFilter.mockImplementation(async () => + Promise.resolve({ filter: [] }) + ); + + alertingAuthMock.ensureAuthorized.mockImplementation( + // @ts-expect-error + async ({ + ruleTypeId, + consumer, + operation, + entity, + }: { + ruleTypeId: string; + consumer: string; + operation: string; + entity: typeof AlertingAuthorizationEntity.Alert; + }) => { + if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { + return Promise.resolve(); + } + return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + } + ); }); describe('get()', () => { @@ -73,10 +100,9 @@ describe('get()', () => { const result = await alertsClient.get({ id: '1', index: '.alerts-observability-apm' }); expect(result).toMatchInlineSnapshot(` Object { - "_version": "WzM2MiwyXQ==", - "${ALERT_OWNER}": "apm", - "${ALERT_STATUS}": "open", - "${SPACE_IDS}": Array [ + "kibana.alert.owner": "apm", + "kibana.alert.status": "open", + "kibana.space_ids": Array [ "test_default_space_id", ], "message": "hello world 1", @@ -92,18 +118,37 @@ describe('get()', () => { "bool": Object { "filter": Array [ Object { - "term": Object { - "_id": "1", + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "_id": "1", + }, + }, + ], }, }, + Object {}, Object { "term": Object { "kibana.space_ids": "test_default_space_id", }, }, ], + "must": Array [], + "must_not": Array [], + "should": Array [], }, }, + "sort": Array [ + Object { + "@timestamp": Object { + "order": "asc", + "unmapped_type": "date", + }, + }, + ], }, "ignore_unavailable": true, "index": ".alerts-observability-apm", @@ -151,12 +196,75 @@ describe('get()', () => { }, }) ); - await alertsClient.get({ id: '1', index: '.alerts-observability-apm' }); + await alertsClient.get({ id: 'NoxgpHkBqbdrfX07MqXV', index: '.alerts-observability-apm' }); expect(auditLogger.log).toHaveBeenCalledWith({ error: undefined, event: { action: 'alert_get', category: ['database'], outcome: 'success', type: ['access'] }, - message: 'User has accessed alert [id=1]', + message: 'User has accessed alert [id=NoxgpHkBqbdrfX07MqXV]', + }); + }); + + test('audit error access if user is unauthorized for given alert', async () => { + const indexName = '.alerts-observability-apm.alerts'; + const fakeAlertId = 'myfakeid1'; + // fakeRuleTypeId will cause authz to fail + const fakeRuleTypeId = 'fake.rule'; + const alertsClient = new AlertsClient(alertsClientParams); + esClientMock.search.mockResolvedValueOnce( + elasticsearchClientMock.createApiResponse({ + body: { + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + found: true, + _type: 'alert', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _id: fakeAlertId, + _index: indexName, + _source: { + [RULE_ID]: fakeRuleTypeId, + [ALERT_OWNER]: 'apm', + [ALERT_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + ], + }, + }, + }) + ); + + await expect(alertsClient.get({ id: fakeAlertId, index: '.alerts-observability-apm' })).rejects + .toThrowErrorMatchingInlineSnapshot(` + "Unable to retrieve alert details for alert with id of \\"myfakeid1\\" or with query \\"null\\" and operation get + Error: Error: Unauthorized for fake.rule and apm" + `); + + expect(auditLogger.log).toHaveBeenNthCalledWith(1, { + message: `Failed attempt to access alert [id=${fakeAlertId}]`, + event: { + action: 'alert_get', + category: ['database'], + outcome: 'failure', + type: ['access'], + }, + error: { + code: 'Error', + message: 'Unauthorized for fake.rule and apm', + }, }); }); @@ -166,13 +274,11 @@ describe('get()', () => { esClientMock.search.mockRejectedValue(error); await expect( - alertsClient.get({ id: '1', index: '.alerts-observability-apm' }) - ).rejects.toThrowErrorMatchingInlineSnapshot(`"something went wrong"`); - expect(auditLogger.log).toHaveBeenCalledWith({ - error: { code: 'Error', message: 'something went wrong' }, - event: { action: 'alert_get', category: ['database'], outcome: 'failure', type: ['access'] }, - message: 'Failed attempt to access alert [id=1]', - }); + alertsClient.get({ id: 'NoxgpHkBqbdrfX07MqXV', index: '.alerts-observability-apm' }) + ).rejects.toThrowErrorMatchingInlineSnapshot(` + "Unable to retrieve alert details for alert with id of \\"NoxgpHkBqbdrfX07MqXV\\" or with query \\"null\\" and operation get + Error: Error: something went wrong" + `); }); describe('authorization', () => { @@ -217,20 +323,16 @@ describe('get()', () => { test('returns alert if user is authorized to read alert under the consumer', async () => { const alertsClient = new AlertsClient(alertsClientParams); - const result = await alertsClient.get({ id: '1', index: '.alerts-observability-apm' }); - - expect(alertingAuthMock.ensureAuthorized).toHaveBeenCalledWith({ - entity: 'alert', - consumer: 'apm', - operation: 'get', - ruleTypeId: 'apm.error_rate', + const result = await alertsClient.get({ + id: 'NoxgpHkBqbdrfX07MqXV', + index: '.alerts-observability-apm', }); + expect(result).toMatchInlineSnapshot(` Object { - "_version": "WzM2MiwyXQ==", - "${ALERT_OWNER}": "apm", - "${ALERT_STATUS}": "open", - "${SPACE_IDS}": Array [ + "kibana.alert.owner": "apm", + "kibana.alert.status": "open", + "kibana.space_ids": Array [ "test_default_space_id", ], "message": "hello world 1", @@ -238,25 +340,5 @@ describe('get()', () => { } `); }); - - test('throws when user is not authorized to get this type of alert', async () => { - const alertsClient = new AlertsClient(alertsClientParams); - alertingAuthMock.ensureAuthorized.mockRejectedValue( - new Error(`Unauthorized to get a "apm.error_rate" alert for "apm"`) - ); - - await expect( - alertsClient.get({ id: '1', index: '.alerts-observability-apm' }) - ).rejects.toMatchInlineSnapshot( - `[Error: Unauthorized to get a "apm.error_rate" alert for "apm"]` - ); - - expect(alertingAuthMock.ensureAuthorized).toHaveBeenCalledWith({ - entity: 'alert', - consumer: 'apm', - operation: 'get', - ruleTypeId: 'apm.error_rate', - }); - }); }); }); diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts index 47a86c718d8de..435b6e310ffdf 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts @@ -5,13 +5,14 @@ * 2.0. */ -import { ALERT_OWNER, ALERT_STATUS, SPACE_IDS } from '@kbn/rule-data-utils'; +import { ALERT_OWNER, ALERT_STATUS, SPACE_IDS, RULE_ID } from '@kbn/rule-data-utils'; import { AlertsClient, ConstructorOptions } from '../alerts_client'; import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { alertingAuthorizationMock } from '../../../../alerting/server/authorization/alerting_authorization.mock'; import { AuditLogger } from '../../../../security/server'; +import { AlertingAuthorizationEntity } from '../../../../alerting/server'; const alertingAuthMock = alertingAuthorizationMock.create(); const esClientMock = elasticsearchClientMock.createElasticsearchClient(); @@ -26,9 +27,35 @@ const alertsClientParams: jest.Mocked = { auditLogger, }; +const DEFAULT_SPACE = 'test_default_space_id'; + beforeEach(() => { jest.resetAllMocks(); - alertingAuthMock.getSpaceId.mockImplementation(() => 'test_default_space_id'); + alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); + // @ts-expect-error + alertingAuthMock.getAuthorizationFilter.mockImplementation(async () => + Promise.resolve({ filter: [] }) + ); + + alertingAuthMock.ensureAuthorized.mockImplementation( + // @ts-expect-error + async ({ + ruleTypeId, + consumer, + operation, + entity, + }: { + ruleTypeId: string; + consumer: string; + operation: string; + entity: typeof AlertingAuthorizationEntity.Alert; + }) => { + if (ruleTypeId === 'apm.error_rate' && consumer === 'apm') { + return Promise.resolve(); + } + return Promise.reject(new Error(`Unauthorized for ${ruleTypeId} and ${consumer}`)); + } + ); }); describe('update()', () => { @@ -55,11 +82,11 @@ describe('update()', () => { _index: '.alerts-observability-apm', _id: 'NoxgpHkBqbdrfX07MqXV', _source: { - 'rule.id': 'apm.error_rate', + [RULE_ID]: 'apm.error_rate', message: 'hello world 1', [ALERT_OWNER]: 'apm', [ALERT_STATUS]: 'open', - [SPACE_IDS]: ['test_default_space_id'], + [SPACE_IDS]: [DEFAULT_SPACE], }, }, ], @@ -145,7 +172,7 @@ describe('update()', () => { message: 'hello world 1', [ALERT_OWNER]: 'apm', [ALERT_STATUS]: 'open', - [SPACE_IDS]: ['test_default_space_id'], + [SPACE_IDS]: [DEFAULT_SPACE], }, }, ], @@ -167,7 +194,7 @@ describe('update()', () => { }) ); await alertsClient.update({ - id: '1', + id: 'NoxgpHkBqbdrfX07MqXV', status: 'closed', _version: undefined, index: '.alerts-observability-apm', @@ -181,35 +208,97 @@ describe('update()', () => { outcome: 'unknown', type: ['change'], }, - message: 'User is updating alert [id=1]', + message: 'User is updating alert [id=NoxgpHkBqbdrfX07MqXV]', }); }); - test(`throws an error if ES client get fails`, async () => { - const error = new Error('something went wrong on get'); + test('audit error update if user is unauthorized for given alert', async () => { + const indexName = '.alerts-observability-apm.alerts'; + const fakeAlertId = 'myfakeid1'; + // fakeRuleTypeId will cause authz to fail + const fakeRuleTypeId = 'fake.rule'; const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockRejectedValue(error); + esClientMock.search.mockResolvedValueOnce( + elasticsearchClientMock.createApiResponse({ + body: { + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + found: true, + _type: 'alert', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _id: fakeAlertId, + _index: indexName, + _source: { + [RULE_ID]: fakeRuleTypeId, + [ALERT_OWNER]: 'apm', + [ALERT_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + ], + }, + }, + }) + ); await expect( alertsClient.update({ - id: '1', + id: fakeAlertId, status: 'closed', - _version: undefined, + _version: '1', index: '.alerts-observability-apm', }) - ).rejects.toThrowErrorMatchingInlineSnapshot(`"something went wrong on get"`); - expect(auditLogger.log).toHaveBeenCalledWith({ - error: { code: 'Error', message: 'something went wrong on get' }, + ).rejects.toThrowErrorMatchingInlineSnapshot(` + "Unable to retrieve alert details for alert with id of \\"myfakeid1\\" or with query \\"null\\" and operation update + Error: Error: Unauthorized for fake.rule and apm" + `); + + expect(auditLogger.log).toHaveBeenNthCalledWith(1, { + message: `Failed attempt to update alert [id=${fakeAlertId}]`, event: { action: 'alert_update', category: ['database'], outcome: 'failure', type: ['change'], }, - message: 'Failed attempt to update alert [id=1]', + error: { + code: 'Error', + message: 'Unauthorized for fake.rule and apm', + }, }); }); + test(`throws an error if ES client get fails`, async () => { + const error = new Error('something went wrong on update'); + const alertsClient = new AlertsClient(alertsClientParams); + esClientMock.search.mockRejectedValue(error); + + await expect( + alertsClient.update({ + id: 'NoxgpHkBqbdrfX07MqXV', + status: 'closed', + _version: undefined, + index: '.alerts-observability-apm', + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(` + "Unable to retrieve alert details for alert with id of \\"NoxgpHkBqbdrfX07MqXV\\" or with query \\"null\\" and operation update + Error: Error: something went wrong on update" + `); + }); + test(`throws an error if ES client update fails`, async () => { const error = new Error('something went wrong on update'); const alertsClient = new AlertsClient(alertsClientParams); @@ -238,7 +327,7 @@ describe('update()', () => { message: 'hello world 1', [ALERT_OWNER]: 'apm', [ALERT_STATUS]: 'open', - [SPACE_IDS]: ['test_default_space_id'], + [SPACE_IDS]: [DEFAULT_SPACE], }, }, ], @@ -250,21 +339,21 @@ describe('update()', () => { await expect( alertsClient.update({ - id: '1', + id: 'NoxgpHkBqbdrfX07MqXV', status: 'closed', _version: undefined, index: '.alerts-observability-apm', }) ).rejects.toThrowErrorMatchingInlineSnapshot(`"something went wrong on update"`); expect(auditLogger.log).toHaveBeenCalledWith({ - error: { code: 'Error', message: 'something went wrong on update' }, + error: undefined, event: { action: 'alert_update', category: ['database'], - outcome: 'failure', + outcome: 'unknown', type: ['change'], }, - message: 'Failed attempt to update alert [id=1]', + message: 'User is updating alert [id=NoxgpHkBqbdrfX07MqXV]', }); }); @@ -298,7 +387,7 @@ describe('update()', () => { message: 'hello world 1', [ALERT_OWNER]: 'apm', [ALERT_STATUS]: 'open', - [SPACE_IDS]: ['test_default_space_id'], + [SPACE_IDS]: [DEFAULT_SPACE], }, }, ], @@ -325,18 +414,12 @@ describe('update()', () => { test('returns alert if user is authorized to update alert under the consumer', async () => { const alertsClient = new AlertsClient(alertsClientParams); const result = await alertsClient.update({ - id: '1', + id: 'NoxgpHkBqbdrfX07MqXV', status: 'closed', _version: undefined, index: '.alerts-observability-apm', }); - expect(alertingAuthMock.ensureAuthorized).toHaveBeenCalledWith({ - entity: 'alert', - consumer: 'apm', - operation: 'update', - ruleTypeId: 'apm.error_rate', - }); expect(result).toMatchInlineSnapshot(` Object { "_id": "NoxgpHkBqbdrfX07MqXV", @@ -353,30 +436,5 @@ describe('update()', () => { } `); }); - - test('throws when user is not authorized to update this type of alert', async () => { - const alertsClient = new AlertsClient(alertsClientParams); - alertingAuthMock.ensureAuthorized.mockRejectedValue( - new Error(`Unauthorized to get a "apm.error_rate" alert for "apm"`) - ); - - await expect( - alertsClient.update({ - id: '1', - status: 'closed', - _version: undefined, - index: '.alerts-observability-apm', - }) - ).rejects.toMatchInlineSnapshot( - `[Error: Unauthorized to get a "apm.error_rate" alert for "apm"]` - ); - - expect(alertingAuthMock.ensureAuthorized).toHaveBeenCalledWith({ - entity: 'alert', - consumer: 'apm', - operation: 'update', - ruleTypeId: 'apm.error_rate', - }); - }); }); }); diff --git a/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts b/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts new file mode 100644 index 0000000000000..40f27f7eb7e23 --- /dev/null +++ b/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts @@ -0,0 +1,93 @@ +/* + * 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 'kibana/server'; +import * as t from 'io-ts'; +import { id as _id } from '@kbn/securitysolution-io-ts-list-types'; +import { transformError } from '@kbn/securitysolution-es-utils'; + +import { buildRouteValidation } from './utils/route_validation'; +import { RacRequestHandlerContext } from '../types'; +import { BASE_RAC_ALERTS_API_PATH } from '../../common/constants'; + +export const bulkUpdateAlertsRoute = (router: IRouter) => { + router.post( + { + path: `${BASE_RAC_ALERTS_API_PATH}/bulk_update`, + validate: { + body: buildRouteValidation( + t.union([ + t.strict({ + status: t.union([t.literal('open'), t.literal('closed')]), + index: t.string, + ids: t.array(t.string), + query: t.undefined, + }), + t.strict({ + status: t.union([t.literal('open'), t.literal('closed')]), + index: t.string, + ids: t.undefined, + query: t.string, + }), + ]) + ), + }, + options: { + tags: ['access:rac'], + }, + }, + async (context, req, response) => { + try { + const alertsClient = await context.rac.getAlertsClient(); + const { status, ids, index, query } = req.body; + + if (ids != null && ids.length > 1000) { + return response.badRequest({ + body: { + message: 'cannot use more than 1000 ids', + }, + }); + } + + const updatedAlert = await alertsClient.bulkUpdate({ + ids, + status, + query, + index, + }); + + if (updatedAlert == null) { + return response.notFound({ + body: { message: `alerts with ids ${ids} and index ${index} not found` }, + }); + } + + return response.ok({ body: { success: true, ...updatedAlert } }); + } catch (exc) { + const err = transformError(exc); + + const contentType = { + 'content-type': 'application/json', + }; + const defaultedHeaders = { + ...contentType, + }; + + return response.customError({ + headers: defaultedHeaders, + statusCode: err.statusCode, + body: { + message: err.message, + attributes: { + success: false, + }, + }, + }); + } + } + ); +}; diff --git a/x-pack/plugins/rule_registry/server/routes/index.ts b/x-pack/plugins/rule_registry/server/routes/index.ts index 6698cd7717268..0b900f26e56e6 100644 --- a/x-pack/plugins/rule_registry/server/routes/index.ts +++ b/x-pack/plugins/rule_registry/server/routes/index.ts @@ -10,9 +10,11 @@ import { RacRequestHandlerContext } from '../types'; import { getAlertByIdRoute } from './get_alert_by_id'; import { updateAlertByIdRoute } from './update_alert_by_id'; import { getAlertsIndexRoute } from './get_alert_index'; +import { bulkUpdateAlertsRoute } from './bulk_update_alerts'; export function defineRoutes(router: IRouter) { getAlertByIdRoute(router); updateAlertByIdRoute(router); getAlertsIndexRoute(router); + bulkUpdateAlertsRoute(router); } diff --git a/x-pack/plugins/rule_registry/server/scripts/bulk_update_observability_alert_by_ids.sh b/x-pack/plugins/rule_registry/server/scripts/bulk_update_observability_alert_by_ids.sh new file mode 100755 index 0000000000000..7c7c7d0ab679b --- /dev/null +++ b/x-pack/plugins/rule_registry/server/scripts/bulk_update_observability_alert_by_ids.sh @@ -0,0 +1,30 @@ +#!/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 + +IDS=${1:-[\"Do4JnHoBqkRSppNZ6vre\"]} +STATUS=${2} + +echo $IDS +echo "'"$STATUS"'" + +cd ./hunter && sh ./post_detections_role.sh && sh ./post_detections_user.sh +cd ../observer && sh ./post_detections_role.sh && sh ./post_detections_user.sh +cd .. + +# Example: ./update_observability_alert.sh [\"my-alert-id\",\"another-alert-id\"] +curl -s -k \ + -H 'Content-Type: application/json' \ + -H 'kbn-xsrf: 123' \ + -u observer:changeme \ + -X POST ${KIBANA_URL}${SPACE_URL}/internal/rac/alerts/bulk_update \ +-d "{\"ids\": $IDS, \"status\":\"$STATUS\", \"index\":\".alerts-observability-apm\"}" | jq . +# -d "{\"ids\": $IDS, \"query\": \"kibana.rac.alert.status: open\", \"status\":\"$STATUS\", \"index\":\".alerts-observability-apm\"}" | jq . +# -d "{\"ids\": $IDS, \"status\":\"$STATUS\", \"index\":\".alerts-observability-apm\"}" | jq . diff --git a/x-pack/plugins/rule_registry/server/scripts/bulk_update_observability_alert_by_query.sh b/x-pack/plugins/rule_registry/server/scripts/bulk_update_observability_alert_by_query.sh new file mode 100755 index 0000000000000..4bcfd53b12299 --- /dev/null +++ b/x-pack/plugins/rule_registry/server/scripts/bulk_update_observability_alert_by_query.sh @@ -0,0 +1,28 @@ +#!/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 + +QUERY=${1:-"kibana.rac.alert.status: open"} +STATUS=${2} + +echo $IDS +echo "'"$STATUS"'" + +cd ./hunter && sh ./post_detections_role.sh && sh ./post_detections_user.sh +cd ../observer && sh ./post_detections_role.sh && sh ./post_detections_user.sh +cd .. + +# Example: ./update_observability_alert.sh "kibana.rac.alert.stats: open" +curl -s -k \ + -H 'Content-Type: application/json' \ + -H 'kbn-xsrf: 123' \ + -u observer:changeme \ + -X POST ${KIBANA_URL}${SPACE_URL}/internal/rac/alerts/bulk_update \ +-d "{\"query\": \"$QUERY\", \"status\":\"$STATUS\", \"index\":\".alerts-observability-apm\"}" | jq . diff --git a/x-pack/plugins/rule_registry/server/scripts/bulk_update_old_security_solution_alert_by_query.sh b/x-pack/plugins/rule_registry/server/scripts/bulk_update_old_security_solution_alert_by_query.sh new file mode 100755 index 0000000000000..8725e791d8efa --- /dev/null +++ b/x-pack/plugins/rule_registry/server/scripts/bulk_update_old_security_solution_alert_by_query.sh @@ -0,0 +1,28 @@ +#!/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 + +QUERY=${1:-"signal.status: open"} +STATUS=${2} + +echo $IDS +echo "'"$STATUS"'" + +cd ./hunter && sh ./post_detections_role.sh && sh ./post_detections_user.sh +cd ../observer && sh ./post_detections_role.sh && sh ./post_detections_user.sh +cd .. + +# Example: ./update_observability_alert.sh "kibana.rac.alert.stats: open" +curl -s -k \ + -H 'Content-Type: application/json' \ + -H 'kbn-xsrf: 123' \ + -u hunter:changeme \ + -X POST ${KIBANA_URL}${SPACE_URL}/internal/rac/alerts/bulk_update \ +-d "{\"query\": \"$QUERY\", \"status\":\"$STATUS\", \"index\":\".siem-signals*\"}" | jq . diff --git a/x-pack/plugins/rule_registry/server/scripts/get_observability_alert.sh b/x-pack/plugins/rule_registry/server/scripts/get_observability_alert.sh index 6fbd0eb3dc816..1b34910c2b737 100755 --- a/x-pack/plugins/rule_registry/server/scripts/get_observability_alert.sh +++ b/x-pack/plugins/rule_registry/server/scripts/get_observability_alert.sh @@ -10,7 +10,7 @@ set -e USER=${1:-'observer'} -ID=${2:-'DHEnOXoB8br9Z2X1fq_l'} +ID=${2:-'Do4JnHoBqkRSppNZ6vre'} cd ./hunter && sh ./post_detections_role.sh && sh ./post_detections_user.sh cd ../observer && sh ./post_detections_role.sh && sh ./post_detections_user.sh diff --git a/x-pack/plugins/rule_registry/server/scripts/hunter/detections_role.json b/x-pack/plugins/rule_registry/server/scripts/hunter/detections_role.json index 80f63f80b849c..c1d5572672b8f 100644 --- a/x-pack/plugins/rule_registry/server/scripts/hunter/detections_role.json +++ b/x-pack/plugins/rule_registry/server/scripts/hunter/detections_role.json @@ -6,12 +6,7 @@ "kibana": [ { "feature": { - "ml": ["read"], - "siem": ["all"], - "actions": ["read"], - "ruleRegistry": ["all"], - "builtInAlerts": ["all"], - "alerting": ["all"] + "siem": ["all"] }, "spaces": ["*"] } diff --git a/x-pack/plugins/rule_registry/server/scripts/observer/detections_role.json b/x-pack/plugins/rule_registry/server/scripts/observer/detections_role.json index ee4a1d84f0b7e..4df9097a4f82d 100644 --- a/x-pack/plugins/rule_registry/server/scripts/observer/detections_role.json +++ b/x-pack/plugins/rule_registry/server/scripts/observer/detections_role.json @@ -6,7 +6,7 @@ "kibana": [ { "feature": { - "apm": ["read", "alerts_all"] + "apm": ["all"] }, "spaces": ["*"] } diff --git a/x-pack/plugins/saved_objects_tagging/kibana.json b/x-pack/plugins/saved_objects_tagging/kibana.json index 5e8bb47bbc3a2..ced7d149f5ad9 100644 --- a/x-pack/plugins/saved_objects_tagging/kibana.json +++ b/x-pack/plugins/saved_objects_tagging/kibana.json @@ -1,5 +1,9 @@ { "id": "savedObjectsTagging", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "version": "8.0.0", "kibanaVersion": "kibana", "server": true, diff --git a/x-pack/plugins/saved_objects_tagging/server/saved_objects/tag.ts b/x-pack/plugins/saved_objects_tagging/server/saved_objects/tag.ts index 36f02fe2235c4..c6dacbd81a0e9 100644 --- a/x-pack/plugins/saved_objects_tagging/server/saved_objects/tag.ts +++ b/x-pack/plugins/saved_objects_tagging/server/saved_objects/tag.ts @@ -11,7 +11,8 @@ import { tagSavedObjectTypeName, TagAttributes } from '../../common'; export const tagType: SavedObjectsType = { name: tagSavedObjectTypeName, hidden: false, - namespaceType: 'single', + namespaceType: 'multiple-isolated', + convertToMultiNamespaceTypeVersion: '8.0.0', mappings: { properties: { name: { diff --git a/x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/rule_editor_panel/json_rule_editor.test.tsx b/x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/rule_editor_panel/json_rule_editor.test.tsx index 1cfc57323da1d..5a1122a88ac80 100644 --- a/x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/rule_editor_panel/json_rule_editor.test.tsx +++ b/x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/rule_editor_panel/json_rule_editor.test.tsx @@ -12,25 +12,27 @@ import 'brace/mode/json'; // warnings in the console which adds unnecessary noise to the test output. import '@kbn/test/target_node/jest/utils/stub_web_worker'; -import { EuiCodeEditor } from '@elastic/eui'; import React from 'react'; import { act } from 'react-dom/test-utils'; -import { mountWithIntl } from '@kbn/test/jest'; -import { coreMock } from 'src/core/public/mocks'; -import { KibanaContextProvider } from 'src/plugins/kibana_react/public'; +import type { monaco } from '@kbn/monaco'; +import { shallowWithIntl } from '@kbn/test/jest'; +import { CodeEditorField } from 'src/plugins/kibana_react/public'; import { AllRule, AnyRule, ExceptAllRule, ExceptAnyRule, FieldRule } from '../../model'; import { JSONRuleEditor } from './json_rule_editor'; +jest.mock('../../../../../../../../src/plugins/kibana_react/public', () => ({ + ...jest.requireActual('../../../../../../../../src/plugins/kibana_react/public'), + useKibana: jest.fn().mockReturnValue({ + services: { docLinks: { links: { apis: { createRoleMapping: 'createRoleMappingLink' } } } }, + }), +})); + describe('JSONRuleEditor', () => { + const mockChangeEvent = {} as monaco.editor.IModelContentChangedEvent; const renderView = (props: React.ComponentProps) => { - const coreStart = coreMock.createStart(); - return mountWithIntl( - - - - ); + return shallowWithIntl(); }; it('renders an empty rule set', () => { @@ -40,7 +42,8 @@ describe('JSONRuleEditor', () => { expect(props.onChange).not.toHaveBeenCalled(); expect(props.onValidityChange).not.toHaveBeenCalled(); - expect(wrapper.find(EuiCodeEditor).props().value).toMatchInlineSnapshot(`"{}"`); + wrapper.update(); + expect(wrapper.find(CodeEditorField).props().value).toMatchInlineSnapshot(`"{}"`); }); it('renders a rule set', () => { @@ -58,7 +61,7 @@ describe('JSONRuleEditor', () => { }; const wrapper = renderView(props); - const { value } = wrapper.find(EuiCodeEditor).props(); + const { value } = wrapper.find(CodeEditorField).props(); expect(JSON.parse(value as string)).toEqual({ all: [ { @@ -89,7 +92,10 @@ describe('JSONRuleEditor', () => { const allRule = JSON.stringify(new AllRule().toRaw()); act(() => { - wrapper.find(EuiCodeEditor).props().onChange!(allRule + ', this makes invalid JSON'); + wrapper.find(CodeEditorField).props().onChange!( + allRule + ', this makes invalid JSON', + mockChangeEvent + ); }); expect(props.onValidityChange).toHaveBeenCalledTimes(1); @@ -112,7 +118,7 @@ describe('JSONRuleEditor', () => { }); act(() => { - wrapper.find(EuiCodeEditor).props().onChange!(invalidRule); + wrapper.find(CodeEditorField).props().onChange!(invalidRule, mockChangeEvent); }); expect(props.onValidityChange).toHaveBeenCalledTimes(1); @@ -126,7 +132,10 @@ describe('JSONRuleEditor', () => { const allRule = JSON.stringify(new AllRule().toRaw()); act(() => { - wrapper.find(EuiCodeEditor).props().onChange!(allRule + ', this makes invalid JSON'); + wrapper.find(CodeEditorField).props().onChange!( + allRule + ', this makes invalid JSON', + mockChangeEvent + ); }); expect(props.onValidityChange).toHaveBeenCalledTimes(1); @@ -136,7 +145,7 @@ describe('JSONRuleEditor', () => { props.onValidityChange.mockReset(); act(() => { - wrapper.find(EuiCodeEditor).props().onChange!(allRule); + wrapper.find(CodeEditorField).props().onChange!(allRule, mockChangeEvent); }); expect(props.onValidityChange).toHaveBeenCalledTimes(1); diff --git a/x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/rule_editor_panel/json_rule_editor.tsx b/x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/rule_editor_panel/json_rule_editor.tsx index ecbc71f295a94..86f7892e49d24 100644 --- a/x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/rule_editor_panel/json_rule_editor.tsx +++ b/x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/rule_editor_panel/json_rule_editor.tsx @@ -8,13 +8,17 @@ import 'brace/mode/json'; import 'brace/theme/github'; -import { EuiButton, EuiCodeEditor, EuiFormRow, EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; +import { EuiButton, EuiFormRow, EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; import React, { Fragment, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { XJsonLang } from '@kbn/monaco'; -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; +import { + CodeEditorField, + useKibana, +} from '../../../../../../../../src/plugins/kibana_react/public'; import type { Rule } from '../../model'; import { generateRulesFromRaw, RuleBuilderError } from '../../model'; @@ -76,25 +80,26 @@ export const JSONRuleEditor = (props: Props) => { data-test-subj="roleMappingsJSONEditor" > - diff --git a/x-pack/plugins/security_solution/common/endpoint/constants.ts b/x-pack/plugins/security_solution/common/endpoint/constants.ts index 9dcee10db62e7..4aebae0b15c95 100644 --- a/x-pack/plugins/security_solution/common/endpoint/constants.ts +++ b/x-pack/plugins/security_solution/common/endpoint/constants.ts @@ -7,10 +7,19 @@ export const eventsIndexPattern = 'logs-endpoint.events.*'; export const alertsIndexPattern = 'logs-endpoint.alerts-*'; + +/** index pattern for the data source index (data stream) that the Endpoint streams documents to */ export const metadataIndexPattern = 'metrics-endpoint.metadata-*'; + +/** index that the metadata transform writes to (destination) and that is used by endpoint APIs */ export const metadataCurrentIndexPattern = 'metrics-endpoint.metadata_current_*'; + +/** The metadata Transform Name prefix with NO (package) version) */ export const metadataTransformPrefix = 'endpoint.metadata_current-default'; + +/** The metadata Transform Name prefix with NO namespace and NO (package) version) */ export const metadataTransformPattern = 'endpoint.metadata_current-*'; + export const policyIndexPattern = 'metrics-endpoint.policy-*'; export const telemetryIndexPattern = 'metrics-endpoint.telemetry-*'; export const LIMITED_CONCURRENCY_ENDPOINT_ROUTE_TAG = 'endpoint:limited-concurrency'; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_alerts.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_alerts.ts new file mode 100644 index 0000000000000..c8678960ed3b9 --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_alerts.ts @@ -0,0 +1,74 @@ +/* + * 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 { Client } from '@elastic/elasticsearch'; +import { EndpointDocGenerator, Event, TreeOptions } from '../generate_data'; +import { firstNonNullValue } from '../models/ecs_safety_helpers'; + +function delay(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +/** + * Indexes Alerts/Events into elasticsarch + * + * @param client + * @param eventIndex + * @param alertIndex + * @param generator + * @param numAlerts + * @param options + */ +export async function indexAlerts({ + client, + eventIndex, + alertIndex, + generator, + numAlerts, + options = {}, +}: { + client: Client; + eventIndex: string; + alertIndex: string; + generator: EndpointDocGenerator; + numAlerts: number; + options: TreeOptions; +}) { + const alertGenerator = generator.alertsGenerator(numAlerts, options); + let result = alertGenerator.next(); + while (!result.done) { + let k = 0; + const resolverDocs: Event[] = []; + while (k < 1000 && !result.done) { + resolverDocs.push(result.value); + result = alertGenerator.next(); + k++; + } + const body = resolverDocs.reduce( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (array: Array>, doc) => { + let index = eventIndex; + if (firstNonNullValue(doc.event?.kind) === 'alert') { + index = alertIndex; + } + array.push({ create: { _index: index } }, doc); + return array; + }, + [] + ); + await client.bulk({ body, refresh: true }); + } + + await client.indices.refresh({ + index: eventIndex, + }); + + // TODO: Unclear why the documents are not showing up after the call to refresh. + // Waiting 5 seconds allows the indices to refresh automatically and + // the documents become available in API/integration tests. + await delay(5000); +} diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts new file mode 100644 index 0000000000000..7e647b2a2ec5e --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_endpoint_hosts.ts @@ -0,0 +1,310 @@ +/* + * 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 { Client } from '@elastic/elasticsearch'; +import { cloneDeep, merge } from 'lodash'; +import { AxiosResponse } from 'axios'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { KbnClient } from '@kbn/test'; +import { DeleteByQueryResponse } from '@elastic/elasticsearch/api/types'; +import { Agent, CreatePackagePolicyResponse, GetPackagesResponse } from '../../../../fleet/common'; +import { EndpointDocGenerator } from '../generate_data'; +import { HostMetadata, HostPolicyResponse } from '../types'; +import { + deleteIndexedFleetAgents, + DeleteIndexedFleetAgentsResponse, + IndexedFleetAgentResponse, + indexFleetAgentForHost, +} from './index_fleet_agent'; +import { + deleteIndexedFleetActions, + DeleteIndexedFleetActionsResponse, + IndexedFleetActionsForHostResponse, + indexFleetActionsForHost, +} from './index_fleet_actions'; +import { + deleteIndexedFleetEndpointPolicies, + DeleteIndexedFleetEndpointPoliciesResponse, + IndexedFleetEndpointPolicyResponse, + indexFleetEndpointPolicy, +} from './index_fleet_endpoint_policy'; +import { metadataCurrentIndexPattern } from '../constants'; +import { EndpointDataLoadingError, wrapErrorAndRejectPromise } from './utils'; + +export interface IndexedHostsResponse + extends IndexedFleetAgentResponse, + IndexedFleetActionsForHostResponse, + IndexedFleetEndpointPolicyResponse { + /** + * The documents (1 or more) that were generated for the (single) endpoint host. + * If consuming this data and wanting only the last one created, just access the + * last item in the array + */ + hosts: HostMetadata[]; + + /** + * The list of Endpoint Policy Response documents (1 or more) that was created. + */ + policyResponses: HostPolicyResponse[]; + + metadataIndex: string; + policyResponseIndex: string; +} + +/** + * Indexes the requested number of documents for the endpoint host metadata currently being output by the generator. + * Endpoint Host metadata documents are added to an index that is set as "append only", thus one Endpoint host could + * have multiple documents in that index. + * + * + * + * @param numDocs + * @param client + * @param kbnClient + * @param realPolicies + * @param epmEndpointPackage + * @param metadataIndex + * @param policyResponseIndex + * @param enrollFleet + * @param generator + */ +export async function indexEndpointHostDocs({ + numDocs, + client, + kbnClient, + realPolicies, + epmEndpointPackage, + metadataIndex, + policyResponseIndex, + enrollFleet, + generator, +}: { + numDocs: number; + client: Client; + kbnClient: KbnClient; + realPolicies: Record; + epmEndpointPackage: GetPackagesResponse['response'][0]; + metadataIndex: string; + policyResponseIndex: string; + enrollFleet: boolean; + generator: EndpointDocGenerator; +}): Promise { + const timeBetweenDocs = 6 * 3600 * 1000; // 6 hours between metadata documents + const timestamp = new Date().getTime(); + const kibanaVersion = await fetchKibanaVersion(kbnClient); + const response: IndexedHostsResponse = { + hosts: [], + agents: [], + policyResponses: [], + metadataIndex, + policyResponseIndex, + fleetAgentsIndex: '', + actionResponses: [], + responsesIndex: '', + actions: [], + actionsIndex: '', + integrationPolicies: [], + agentPolicies: [], + }; + let hostMetadata: HostMetadata; + let wasAgentEnrolled = false; + let enrolledAgent: undefined | Agent; + + for (let j = 0; j < numDocs; j++) { + generator.updateHostData(); + generator.updateHostPolicyData(); + + hostMetadata = generator.generateHostMetadata( + timestamp - timeBetweenDocs * (numDocs - j - 1), + EndpointDocGenerator.createDataStreamFromIndex(metadataIndex) + ); + + if (enrollFleet) { + const { id: appliedPolicyId, name: appliedPolicyName } = hostMetadata.Endpoint.policy.applied; + + // If we don't yet have a "real" policy record, then create it now in ingest (package config) + if (!realPolicies[appliedPolicyId]) { + const createdPolicies = await indexFleetEndpointPolicy( + kbnClient, + appliedPolicyName, + epmEndpointPackage.version + ); + + merge(response, createdPolicies); + + // eslint-disable-next-line require-atomic-updates + realPolicies[appliedPolicyId] = createdPolicies.integrationPolicies[0]; + } + + // If we did not yet enroll an agent for this Host, do it now that we have good policy id + if (!wasAgentEnrolled) { + wasAgentEnrolled = true; + + const indexedAgentResponse = await indexFleetAgentForHost( + client, + kbnClient, + hostMetadata!, + realPolicies[appliedPolicyId].policy_id, + kibanaVersion + ); + + enrolledAgent = indexedAgentResponse.agents[0]; + merge(response, indexedAgentResponse); + } + // Update the Host metadata record with the ID of the "real" policy along with the enrolled agent id + hostMetadata = { + ...hostMetadata, + elastic: { + ...hostMetadata.elastic, + agent: { + ...hostMetadata.elastic.agent, + id: enrolledAgent?.id ?? hostMetadata.elastic.agent.id, + }, + }, + Endpoint: { + ...hostMetadata.Endpoint, + policy: { + ...hostMetadata.Endpoint.policy, + applied: { + ...hostMetadata.Endpoint.policy.applied, + id: realPolicies[appliedPolicyId].id, + }, + }, + }, + }; + + // Create some actions for this Host + await indexFleetActionsForHost(client, hostMetadata); + } + + await client + .index({ + index: metadataIndex, + body: hostMetadata, + op_type: 'create', + }) + .catch(wrapErrorAndRejectPromise); + + const hostPolicyResponse = generator.generatePolicyResponse({ + ts: timestamp - timeBetweenDocs * (numDocs - j - 1), + policyDataStream: EndpointDocGenerator.createDataStreamFromIndex(policyResponseIndex), + }); + + await client + .index({ + index: policyResponseIndex, + body: hostPolicyResponse, + op_type: 'create', + }) + .catch(wrapErrorAndRejectPromise); + + // Clone the hostMetadata and policyResponse document to ensure that no shared state + // (as a result of using the generator) is returned across docs. + response.hosts.push(cloneDeep(hostMetadata)); + response.policyResponses.push(cloneDeep(hostPolicyResponse)); + } + + return response; +} + +const fetchKibanaVersion = async (kbnClient: KbnClient) => { + const version = ((await kbnClient.request({ + path: '/api/status', + method: 'GET', + })) as AxiosResponse).data.version.number; + + if (!version) { + throw new EndpointDataLoadingError('failed to get kibana version via `/api/status` api'); + } + + return version; +}; + +export interface DeleteIndexedEndpointHostsResponse + extends DeleteIndexedFleetAgentsResponse, + DeleteIndexedFleetActionsResponse, + DeleteIndexedFleetEndpointPoliciesResponse { + hosts: DeleteByQueryResponse | undefined; + policyResponses: DeleteByQueryResponse | undefined; +} + +export const deleteIndexedEndpointHosts = async ( + esClient: Client, + kbnClient: KbnClient, + indexedData: IndexedHostsResponse +): Promise => { + const response: DeleteIndexedEndpointHostsResponse = { + hosts: undefined, + policyResponses: undefined, + agents: undefined, + responses: undefined, + actions: undefined, + integrationPolicies: undefined, + agentPolicies: undefined, + }; + + if (indexedData.hosts.length) { + const body = { + query: { + bool: { + filter: [{ terms: { 'agent.id': indexedData.hosts.map((host) => host.agent.id) } }], + }, + }, + }; + + response.hosts = ( + await esClient + .deleteByQuery({ + index: indexedData.metadataIndex, + wait_for_completion: true, + body, + }) + .catch(wrapErrorAndRejectPromise) + ).body; + + // Delete from the transform destination index + await esClient + .deleteByQuery({ + index: metadataCurrentIndexPattern, + wait_for_completion: true, + body, + }) + .catch(wrapErrorAndRejectPromise); + } + + if (indexedData.policyResponses.length) { + response.policyResponses = ( + await esClient + .deleteByQuery({ + index: indexedData.policyResponseIndex, + wait_for_completion: true, + body: { + query: { + bool: { + filter: [ + { + terms: { + 'agent.id': indexedData.policyResponses.map( + (policyResponse) => policyResponse.agent.id + ), + }, + }, + ], + }, + }, + }, + }) + .catch(wrapErrorAndRejectPromise) + ).body; + } + + merge(response, await deleteIndexedFleetAgents(esClient, indexedData)); + merge(response, await deleteIndexedFleetActions(esClient, indexedData)); + merge(response, await deleteIndexedFleetEndpointPolicies(kbnClient, indexedData)); + + return response; +}; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_actions.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_actions.ts new file mode 100644 index 0000000000000..246cf059f4cbd --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_actions.ts @@ -0,0 +1,218 @@ +/* + * 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 { Client } from '@elastic/elasticsearch'; +import { DeleteByQueryResponse } from '@elastic/elasticsearch/api/types'; +import { EndpointAction, EndpointActionResponse, HostMetadata } from '../types'; +import { AGENT_ACTIONS_INDEX, AGENT_ACTIONS_RESULTS_INDEX } from '../../../../fleet/common'; +import { FleetActionGenerator } from '../data_generators/fleet_action_generator'; +import { wrapErrorAndRejectPromise } from './utils'; + +const defaultFleetActionGenerator = new FleetActionGenerator(); + +export interface IndexedFleetActionsForHostResponse { + actions: EndpointAction[]; + actionResponses: EndpointActionResponse[]; + actionsIndex: string; + responsesIndex: string; +} + +/** + * Indexes a randome number of Endpoint (via Fleet) Actions for a given host + * (NOTE: ensure that fleet is setup first before calling this loading function) + * + * @param esClient + * @param endpointHost + * @param [fleetActionGenerator] + */ +export const indexFleetActionsForHost = async ( + esClient: Client, + endpointHost: HostMetadata, + fleetActionGenerator: FleetActionGenerator = defaultFleetActionGenerator +): Promise => { + const ES_INDEX_OPTIONS = { headers: { 'X-elastic-product-origin': 'fleet' } }; + const agentId = endpointHost.elastic.agent.id; + const total = fleetActionGenerator.randomN(5); + const response: IndexedFleetActionsForHostResponse = { + actions: [], + actionResponses: [], + actionsIndex: AGENT_ACTIONS_INDEX, + responsesIndex: AGENT_ACTIONS_RESULTS_INDEX, + }; + + for (let i = 0; i < total; i++) { + // create an action + const action = fleetActionGenerator.generate({ + data: { comment: 'data generator: this host is bad' }, + }); + + action.agents = [agentId]; + + esClient + .index( + { + index: AGENT_ACTIONS_INDEX, + body: action, + }, + ES_INDEX_OPTIONS + ) + .catch(wrapErrorAndRejectPromise); + + // Create an action response for the above + const actionResponse = fleetActionGenerator.generateResponse({ + action_id: action.action_id, + agent_id: agentId, + action_data: action.data, + }); + + esClient + .index( + { + index: AGENT_ACTIONS_RESULTS_INDEX, + body: actionResponse, + }, + ES_INDEX_OPTIONS + ) + .catch(wrapErrorAndRejectPromise); + + response.actions.push(action); + response.actionResponses.push(actionResponse); + } + + // Add edge cases (maybe) + if (fleetActionGenerator.randomFloat() < 0.3) { + const randomFloat = fleetActionGenerator.randomFloat(); + + // 60% of the time just add either an Isolate -OR- an UnIsolate action + if (randomFloat < 0.6) { + let action: EndpointAction; + + if (randomFloat < 0.3) { + // add a pending isolation + action = fleetActionGenerator.generateIsolateAction({ + '@timestamp': new Date().toISOString(), + }); + } else { + // add a pending UN-isolation + action = fleetActionGenerator.generateUnIsolateAction({ + '@timestamp': new Date().toISOString(), + }); + } + + action.agents = [agentId]; + + await esClient + .index( + { + index: AGENT_ACTIONS_INDEX, + body: action, + }, + ES_INDEX_OPTIONS + ) + .catch(wrapErrorAndRejectPromise); + + response.actions.push(action); + } else { + // Else (40% of the time) add a pending isolate AND pending un-isolate + const action1 = fleetActionGenerator.generateIsolateAction({ + '@timestamp': new Date().toISOString(), + }); + const action2 = fleetActionGenerator.generateUnIsolateAction({ + '@timestamp': new Date().toISOString(), + }); + + action1.agents = [agentId]; + action2.agents = [agentId]; + + await Promise.all([ + esClient + .index( + { + index: AGENT_ACTIONS_INDEX, + body: action1, + }, + ES_INDEX_OPTIONS + ) + .catch(wrapErrorAndRejectPromise), + esClient + .index( + { + index: AGENT_ACTIONS_INDEX, + body: action2, + }, + ES_INDEX_OPTIONS + ) + .catch(wrapErrorAndRejectPromise), + ]); + + response.actions.push(action1, action2); + } + } + + return response; +}; + +export interface DeleteIndexedFleetActionsResponse { + actions: DeleteByQueryResponse | undefined; + responses: DeleteByQueryResponse | undefined; +} + +export const deleteIndexedFleetActions = async ( + esClient: Client, + indexedData: IndexedFleetActionsForHostResponse +): Promise => { + const response: DeleteIndexedFleetActionsResponse = { + actions: undefined, + responses: undefined, + }; + + if (indexedData.actions.length) { + response.actions = ( + await esClient + .deleteByQuery({ + index: `${indexedData.actionsIndex}-*`, + wait_for_completion: true, + body: { + query: { + bool: { + filter: [ + { terms: { action_id: indexedData.actions.map((action) => action.action_id) } }, + ], + }, + }, + }, + }) + .catch(wrapErrorAndRejectPromise) + ).body; + } + + if (indexedData.actionResponses) { + response.responses = ( + await esClient + .deleteByQuery({ + index: `${indexedData.responsesIndex}-*`, + wait_for_completion: true, + body: { + query: { + bool: { + filter: [ + { + terms: { + action_id: indexedData.actionResponses.map((action) => action.action_id), + }, + }, + ], + }, + }, + }, + }) + .catch(wrapErrorAndRejectPromise) + ).body; + } + + return response; +}; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts new file mode 100644 index 0000000000000..52998b090e3b6 --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_agent.ts @@ -0,0 +1,133 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Client } from '@elastic/elasticsearch'; +import { AxiosResponse } from 'axios'; +import { DeleteByQueryResponse } from '@elastic/elasticsearch/api/types'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { KbnClient } from '@kbn/test'; +import { HostMetadata } from '../types'; +import { + Agent, + AGENT_API_ROUTES, + FleetServerAgent, + GetOneAgentResponse, +} from '../../../../fleet/common'; +import { FleetAgentGenerator } from '../data_generators/fleet_agent_generator'; +import { wrapErrorAndRejectPromise } from './utils'; + +const defaultFleetAgentGenerator = new FleetAgentGenerator(); + +export interface IndexedFleetAgentResponse { + agents: Agent[]; + fleetAgentsIndex: string; +} + +/** + * Indexes a Fleet Agent + * (NOTE: ensure that fleet is setup first before calling this loading function) + * + * @param esClient + * @param kbnClient + * @param endpointHost + * @param agentPolicyId + * @param [kibanaVersion] + * @param [fleetAgentGenerator] + */ +export const indexFleetAgentForHost = async ( + esClient: Client, + kbnClient: KbnClient, + endpointHost: HostMetadata, + agentPolicyId: string, + kibanaVersion: string = '8.0.0', + fleetAgentGenerator: FleetAgentGenerator = defaultFleetAgentGenerator +): Promise => { + const agentDoc = fleetAgentGenerator.generateEsHit({ + _source: { + local_metadata: { + elastic: { + agent: { + version: kibanaVersion, + }, + }, + host: { + ...endpointHost.host, + }, + os: { + ...endpointHost.host.os, + }, + }, + policy_id: agentPolicyId, + }, + }); + + const createdFleetAgent = await esClient + .index({ + index: agentDoc._index, + id: agentDoc._id, + body: agentDoc._source!, + op_type: 'create', + }) + .catch(wrapErrorAndRejectPromise); + + return { + fleetAgentsIndex: agentDoc._index, + agents: [ + await fetchFleetAgent(kbnClient, createdFleetAgent.body._id).catch(wrapErrorAndRejectPromise), + ], + }; +}; + +const fetchFleetAgent = async (kbnClient: KbnClient, agentId: string): Promise => { + return ((await kbnClient + .request({ + path: AGENT_API_ROUTES.INFO_PATTERN.replace('{agentId}', agentId), + method: 'GET', + }) + .catch(wrapErrorAndRejectPromise)) as AxiosResponse).data.item; +}; + +export interface DeleteIndexedFleetAgentsResponse { + agents: DeleteByQueryResponse | undefined; +} + +export const deleteIndexedFleetAgents = async ( + esClient: Client, + indexedData: IndexedFleetAgentResponse +): Promise => { + const response: DeleteIndexedFleetAgentsResponse = { + agents: undefined, + }; + + if (indexedData.agents.length) { + response.agents = ( + await esClient + .deleteByQuery({ + index: `${indexedData.fleetAgentsIndex}-*`, + wait_for_completion: true, + body: { + query: { + bool: { + filter: [ + { + terms: { + 'local_metadata.elastic.agent.id': indexedData.agents.map( + (agent) => agent.local_metadata.elastic.agent.id + ), + }, + }, + ], + }, + }, + }, + }) + .catch(wrapErrorAndRejectPromise) + ).body; + } + + return response; +}; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_endpoint_policy.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_endpoint_policy.ts new file mode 100644 index 0000000000000..05e81e2645281 --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_endpoint_policy.ts @@ -0,0 +1,159 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// eslint-disable-next-line import/no-extraneous-dependencies +import { KbnClient } from '@kbn/test'; +import { AxiosResponse } from 'axios'; +import { + AGENT_POLICY_API_ROUTES, + AgentPolicy, + CreateAgentPolicyRequest, + CreateAgentPolicyResponse, + CreatePackagePolicyRequest, + CreatePackagePolicyResponse, + DeleteAgentPolicyResponse, + DeletePackagePoliciesResponse, + PACKAGE_POLICY_API_ROUTES, +} from '../../../../fleet/common'; +import { PolicyData } from '../types'; +import { policyFactory as policyConfigFactory } from '../models/policy_config'; +import { wrapErrorAndRejectPromise } from './utils'; + +export interface IndexedFleetEndpointPolicyResponse { + integrationPolicies: PolicyData[]; + agentPolicies: AgentPolicy[]; +} + +/** + * Create an endpoint Integration Policy (and associated Agent Policy) via Fleet + * (NOTE: ensure that fleet is setup first before calling this loading function) + */ +export const indexFleetEndpointPolicy = async ( + kbnClient: KbnClient, + policyName: string, + endpointPackageVersion: string = '8.0.0' +): Promise => { + const response: IndexedFleetEndpointPolicyResponse = { + integrationPolicies: [], + agentPolicies: [], + }; + + // Create Agent Policy first + const newAgentPolicyData: CreateAgentPolicyRequest['body'] = { + name: `Policy for ${policyName} (${Math.random().toString(36).substr(2, 5)})`, + description: `Policy created with endpoint data generator (${policyName})`, + namespace: 'default', + }; + + let agentPolicy: AxiosResponse; + + try { + agentPolicy = (await kbnClient + .request({ + path: AGENT_POLICY_API_ROUTES.CREATE_PATTERN, + method: 'POST', + body: newAgentPolicyData, + }) + .catch(wrapErrorAndRejectPromise)) as AxiosResponse; + } catch (error) { + throw new Error(`create fleet agent policy failed ${error}`); + } + + response.agentPolicies.push(agentPolicy.data.item); + + // Create integration (package) policy + const newPackagePolicyData: CreatePackagePolicyRequest['body'] = { + name: policyName, + description: 'Protect the worlds data', + policy_id: agentPolicy.data.item.id, + enabled: true, + output_id: '', + inputs: [ + { + type: 'endpoint', + enabled: true, + streams: [], + config: { + policy: { + value: policyConfigFactory(), + }, + }, + }, + ], + namespace: 'default', + package: { + name: 'endpoint', + title: 'endpoint', + version: endpointPackageVersion, + }, + }; + const packagePolicy = (await kbnClient + .request({ + path: PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN, + method: 'POST', + body: newPackagePolicyData, + }) + .catch(wrapErrorAndRejectPromise)) as AxiosResponse; + + response.integrationPolicies.push(packagePolicy.data.item as PolicyData); + + return response; +}; + +export interface DeleteIndexedFleetEndpointPoliciesResponse { + integrationPolicies: DeletePackagePoliciesResponse | undefined; + agentPolicies: DeleteAgentPolicyResponse[] | undefined; +} + +/** + * Delete indexed Fleet Endpoint integration policies along with their respective Agent Policies. + * Prior to calling this function, ensure that no agents are associated with the Agent Policy. + * (NOTE: ensure that fleet is setup first before calling this loading function) + * @param kbnClient + * @param indexData + */ +export const deleteIndexedFleetEndpointPolicies = async ( + kbnClient: KbnClient, + indexData: IndexedFleetEndpointPolicyResponse +): Promise => { + const response: DeleteIndexedFleetEndpointPoliciesResponse = { + integrationPolicies: undefined, + agentPolicies: undefined, + }; + + if (indexData.integrationPolicies.length) { + response.integrationPolicies = ((await kbnClient + .request({ + path: PACKAGE_POLICY_API_ROUTES.DELETE_PATTERN, + method: 'POST', + body: { + packagePolicyIds: indexData.integrationPolicies.map((policy) => policy.id), + }, + }) + .catch(wrapErrorAndRejectPromise)) as AxiosResponse).data; + } + + if (indexData.agentPolicies.length) { + response.agentPolicies = []; + + for (const agentPolicy of indexData.agentPolicies) { + response.agentPolicies.push( + ((await kbnClient + .request({ + path: AGENT_POLICY_API_ROUTES.DELETE_PATTERN, + method: 'POST', + body: { + agentPolicyId: agentPolicy.id, + }, + }) + .catch(wrapErrorAndRejectPromise)) as AxiosResponse).data + ); + } + } + + return response; +}; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_server.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_server.ts new file mode 100644 index 0000000000000..7ef827b8ea1f1 --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/index_fleet_server.ts @@ -0,0 +1,53 @@ +/* + * 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 { Client } from '@elastic/elasticsearch'; +import { FLEET_SERVER_SERVERS_INDEX } from '../../../../fleet/common'; +import { wrapErrorAndRejectPromise } from './utils'; + +/** + * Will ensure that at least one fleet server is present in the `.fleet-servers` index. This will + * enable the `Agent` section of kibana Fleet to be displayed + * + * @param esClient + * @param version + */ +export const enableFleetServerIfNecessary = async (esClient: Client, version: string = '8.0.0') => { + const res = await esClient.search<{}, {}>({ + index: FLEET_SERVER_SERVERS_INDEX, + ignore_unavailable: true, + rest_total_hits_as_int: true, + }); + + if (res.body.hits.total > 0) { + return; + } + + // Create a Fake fleet-server in this kibana instance + await esClient + .index({ + index: FLEET_SERVER_SERVERS_INDEX, + body: { + agent: { + id: '12988155-475c-430d-ac89-84dc84b67cd1', + version, + }, + host: { + architecture: 'linux', + id: 'c3e5f4f690b4a3ff23e54900701a9513', + ip: ['127.0.0.1', '::1', '10.201.0.213', 'fe80::4001:aff:fec9:d5'], + name: 'endpoint-data-generator', + }, + server: { + id: '12988155-475c-430d-ac89-84dc84b67cd1', + version, + }, + '@timestamp': '2021-05-12T18:42:52.009482058Z', + }, + }) + .catch(wrapErrorAndRejectPromise); +}; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/setup_fleet_for_endpoint.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/setup_fleet_for_endpoint.ts new file mode 100644 index 0000000000000..401a1b70dec4f --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/setup_fleet_for_endpoint.ts @@ -0,0 +1,117 @@ +/* + * 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 { AxiosResponse } from 'axios'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { KbnClient } from '@kbn/test'; +import { + AGENTS_SETUP_API_ROUTES, + BulkInstallPackageInfo, + BulkInstallPackagesResponse, + EPM_API_ROUTES, + IBulkInstallPackageHTTPError, + PostFleetSetupResponse, + SETUP_API_ROUTE, +} from '../../../../fleet/common'; +import { EndpointDataLoadingError, wrapErrorAndRejectPromise } from './utils'; + +/** + * Calls the fleet setup APIs and then installs the latest Endpoint package + * @param kbnClient + */ +export const setupFleetForEndpoint = async (kbnClient: KbnClient) => { + // We try to use the kbnClient **private** logger, bug if unable to access it, then just use console + // @ts-ignore + const log = kbnClient.log ? kbnClient.log : console; + + // Setup Fleet + try { + const setupResponse = (await kbnClient + .request({ + path: SETUP_API_ROUTE, + method: 'POST', + }) + .catch(wrapErrorAndRejectPromise)) as AxiosResponse; + + if (!setupResponse.data.isInitialized) { + log.error(setupResponse.data); + throw new Error('Initializing the ingest manager failed, existing'); + } + } catch (error) { + log.error(error); + throw error; + } + + // Setup Agents + try { + const setupResponse = (await kbnClient + .request({ + path: AGENTS_SETUP_API_ROUTES.CREATE_PATTERN, + method: 'POST', + }) + .catch(wrapErrorAndRejectPromise)) as AxiosResponse; + + if (!setupResponse.data.isInitialized) { + log.error(setupResponse.data); + throw new Error('Initializing Fleet failed, existing'); + } + } catch (error) { + log.error(error); + throw error; + } + + // Install/upgrade the endpoint package + try { + await installOrUpgradeEndpointFleetPackage(kbnClient); + } catch (error) { + log.error(error); + throw error; + } +}; + +/** + * Installs the Endpoint package (or upgrades it) in Fleet to the latest available in the registry + * + * @param kbnClient + */ +export const installOrUpgradeEndpointFleetPackage = async (kbnClient: KbnClient): Promise => { + const installEndpointPackageResp = (await kbnClient + .request({ + path: EPM_API_ROUTES.BULK_INSTALL_PATTERN, + method: 'POST', + body: { + packages: ['endpoint'], + }, + }) + .catch(wrapErrorAndRejectPromise)) as AxiosResponse; + + const bulkResp = installEndpointPackageResp.data.response; + + if (bulkResp.length <= 0) { + throw new EndpointDataLoadingError( + 'Installing the Endpoint package failed, response was empty, existing', + bulkResp + ); + } + + if (isFleetBulkInstallError(bulkResp[0])) { + if (bulkResp[0].error instanceof Error) { + throw new EndpointDataLoadingError( + `Installing the Endpoint package failed: ${bulkResp[0].error.message}, exiting`, + bulkResp + ); + } + + throw new EndpointDataLoadingError(bulkResp[0].error, bulkResp); + } +}; + +function isFleetBulkInstallError( + installResponse: BulkInstallPackageInfo | IBulkInstallPackageHTTPError +): installResponse is IBulkInstallPackageHTTPError { + return 'error' in installResponse && installResponse.error !== undefined; +} diff --git a/x-pack/plugins/security_solution/common/endpoint/data_loaders/utils.ts b/x-pack/plugins/security_solution/common/endpoint/data_loaders/utils.ts new file mode 100644 index 0000000000000..80a7699e51cf8 --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/data_loaders/utils.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export class EndpointDataLoadingError extends Error { + constructor(message: string, public meta?: unknown) { + super(message); + } +} + +export const wrapErrorIfNeeded = (error: Error): EndpointDataLoadingError => + error instanceof EndpointDataLoadingError + ? error + : new EndpointDataLoadingError(error.message, error); + +// Use it in Promise's `.catch()` as `.catch(wrapErrorAndRejectPromise)` +export const wrapErrorAndRejectPromise = (error: Error) => Promise.reject(wrapErrorIfNeeded(error)); diff --git a/x-pack/plugins/security_solution/common/endpoint/index_data.ts b/x-pack/plugins/security_solution/common/endpoint/index_data.ts index 66a3efa82347e..37dcc1e831b94 100644 --- a/x-pack/plugins/security_solution/common/endpoint/index_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/index_data.ts @@ -5,39 +5,49 @@ * 2.0. */ -import { Client, estypes } from '@elastic/elasticsearch'; +import { Client } from '@elastic/elasticsearch'; import seedrandom from 'seedrandom'; // eslint-disable-next-line import/no-extraneous-dependencies import { KbnClient } from '@kbn/test'; import { AxiosResponse } from 'axios'; -import { EndpointDocGenerator, Event, TreeOptions } from './generate_data'; -import { firstNonNullValue } from './models/ecs_safety_helpers'; +import { merge } from 'lodash'; +import { EndpointDocGenerator, TreeOptions } from './generate_data'; import { - AGENT_ACTIONS_INDEX, - AGENT_ACTIONS_RESULTS_INDEX, - AGENT_POLICY_API_ROUTES, - CreateAgentPolicyRequest, - CreateAgentPolicyResponse, - CreatePackagePolicyRequest, CreatePackagePolicyResponse, EPM_API_ROUTES, - FLEET_SERVER_SERVERS_INDEX, - FleetServerAgent, GetPackagesResponse, - PACKAGE_POLICY_API_ROUTES, } from '../../../fleet/common'; -import { policyFactory as policyConfigFactory } from './models/policy_config'; -import { EndpointAction, HostMetadata } from './types'; -import { KbnClientWithApiKeySupport } from '../../scripts/endpoint/kbn_client_with_api_key_support'; -import { FleetAgentGenerator } from './data_generators/fleet_agent_generator'; -import { FleetActionGenerator } from './data_generators/fleet_action_generator'; +import { + deleteIndexedEndpointHosts, + DeleteIndexedEndpointHostsResponse, + IndexedHostsResponse, + indexEndpointHostDocs, +} from './data_loaders/index_endpoint_hosts'; +import { enableFleetServerIfNecessary } from './data_loaders/index_fleet_server'; +import { indexAlerts } from './data_loaders/index_alerts'; +import { setupFleetForEndpoint } from './data_loaders/setup_fleet_for_endpoint'; -const fleetAgentGenerator = new FleetAgentGenerator(); -const fleetActionGenerator = new FleetActionGenerator(); +export type IndexedHostsAndAlertsResponse = IndexedHostsResponse; +/** + * Indexes Endpoint Hosts (with optional Fleet counterparts) along with alerts + * + * @param client + * @param kbnClient + * @param seed + * @param numHosts + * @param numDocs + * @param metadataIndex + * @param policyResponseIndex + * @param eventIndex + * @param alertIndex + * @param alertsPerHost + * @param fleet + * @param options + */ export async function indexHostsAndAlerts( client: Client, - kbnClient: KbnClientWithApiKeySupport, + kbnClient: KbnClient, seed: string, numHosts: number, numDocs: number, @@ -48,9 +58,26 @@ export async function indexHostsAndAlerts( alertsPerHost: number, fleet: boolean, options: TreeOptions = {} -) { +): Promise { const random = seedrandom(seed); const epmEndpointPackage = await getEndpointPackageInfo(kbnClient); + const response: IndexedHostsAndAlertsResponse = { + hosts: [], + policyResponses: [], + agents: [], + fleetAgentsIndex: '', + metadataIndex, + policyResponseIndex, + actionResponses: [], + responsesIndex: '', + actions: [], + actionsIndex: '', + integrationPolicies: [], + agentPolicies: [], + }; + + // Ensure fleet is setup and endpint package installed + await setupFleetForEndpoint(kbnClient); // If `fleet` integration is true, then ensure a (fake) fleet-server is connected if (fleet) { @@ -62,7 +89,7 @@ export async function indexHostsAndAlerts( for (let i = 0; i < numHosts; i++) { const generator = new EndpointDocGenerator(random); - await indexHostDocs({ + const indexedHosts = await indexEndpointHostDocs({ numDocs, client, kbnClient, @@ -73,6 +100,9 @@ export async function indexHostsAndAlerts( enrollFleet: fleet, generator, }); + + merge(response, indexedHosts); + await indexAlerts({ client, eventIndex, @@ -83,220 +113,9 @@ export async function indexHostsAndAlerts( }); } - await client.indices.refresh({ - index: eventIndex, - }); - - // TODO: Unclear why the documents are not showing up after the call to refresh. - // Waiting 5 seconds allows the indices to refresh automatically and - // the documents become available in API/integration tests. - await delay(5000); -} - -function delay(ms: number) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -async function indexHostDocs({ - numDocs, - client, - kbnClient, - realPolicies, - epmEndpointPackage, - metadataIndex, - policyResponseIndex, - enrollFleet, - generator, -}: { - numDocs: number; - client: Client; - kbnClient: KbnClientWithApiKeySupport; - realPolicies: Record; - epmEndpointPackage: GetPackagesResponse['response'][0]; - metadataIndex: string; - policyResponseIndex: string; - enrollFleet: boolean; - generator: EndpointDocGenerator; -}) { - const timeBetweenDocs = 6 * 3600 * 1000; // 6 hours between metadata documents - const timestamp = new Date().getTime(); - const kibanaVersion = await fetchKibanaVersion(kbnClient); - let hostMetadata: HostMetadata; - let wasAgentEnrolled = false; - let enrolledAgent: undefined | estypes.SearchHit; - - for (let j = 0; j < numDocs; j++) { - generator.updateHostData(); - generator.updateHostPolicyData(); - - hostMetadata = generator.generateHostMetadata( - timestamp - timeBetweenDocs * (numDocs - j - 1), - EndpointDocGenerator.createDataStreamFromIndex(metadataIndex) - ); - - if (enrollFleet) { - const { id: appliedPolicyId, name: appliedPolicyName } = hostMetadata.Endpoint.policy.applied; - - // If we don't yet have a "real" policy record, then create it now in ingest (package config) - if (!realPolicies[appliedPolicyId]) { - // eslint-disable-next-line require-atomic-updates - realPolicies[appliedPolicyId] = await createPolicy( - kbnClient, - appliedPolicyName, - epmEndpointPackage.version - ); - } - - // If we did not yet enroll an agent for this Host, do it now that we have good policy id - if (!wasAgentEnrolled) { - wasAgentEnrolled = true; - - enrolledAgent = await indexFleetAgentForHost( - client, - hostMetadata!, - realPolicies[appliedPolicyId].policy_id, - kibanaVersion - ); - } - // Update the Host metadata record with the ID of the "real" policy along with the enrolled agent id - hostMetadata = { - ...hostMetadata, - elastic: { - ...hostMetadata.elastic, - agent: { - ...hostMetadata.elastic.agent, - id: enrolledAgent?._id ?? hostMetadata.elastic.agent.id, - }, - }, - Endpoint: { - ...hostMetadata.Endpoint, - policy: { - ...hostMetadata.Endpoint.policy, - applied: { - ...hostMetadata.Endpoint.policy.applied, - id: realPolicies[appliedPolicyId].id, - }, - }, - }, - }; - - // Create some actions for this Host - await indexFleetActionsForHost(client, hostMetadata); - } - - await client.index({ - index: metadataIndex, - body: hostMetadata, - op_type: 'create', - }); - await client.index({ - index: policyResponseIndex, - body: generator.generatePolicyResponse({ - ts: timestamp - timeBetweenDocs * (numDocs - j - 1), - policyDataStream: EndpointDocGenerator.createDataStreamFromIndex(policyResponseIndex), - }), - op_type: 'create', - }); - } -} - -async function indexAlerts({ - client, - eventIndex, - alertIndex, - generator, - numAlerts, - options = {}, -}: { - client: Client; - eventIndex: string; - alertIndex: string; - generator: EndpointDocGenerator; - numAlerts: number; - options: TreeOptions; -}) { - const alertGenerator = generator.alertsGenerator(numAlerts, options); - let result = alertGenerator.next(); - while (!result.done) { - let k = 0; - const resolverDocs: Event[] = []; - while (k < 1000 && !result.done) { - resolverDocs.push(result.value); - result = alertGenerator.next(); - k++; - } - const body = resolverDocs.reduce( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (array: Array>, doc) => { - let index = eventIndex; - if (firstNonNullValue(doc.event?.kind) === 'alert') { - index = alertIndex; - } - array.push({ create: { _index: index } }, doc); - return array; - }, - [] - ); - await client.bulk({ body, refresh: true }); - } + return response; } -const createPolicy = async ( - kbnClient: KbnClient, - policyName: string, - endpointPackageVersion: string -): Promise => { - // Create Agent Policy first - const newAgentPolicyData: CreateAgentPolicyRequest['body'] = { - name: `Policy for ${policyName} (${Math.random().toString(36).substr(2, 5)})`, - description: `Policy created with endpoint data generator (${policyName})`, - namespace: 'default', - }; - let agentPolicy; - try { - agentPolicy = (await kbnClient.request({ - path: AGENT_POLICY_API_ROUTES.CREATE_PATTERN, - method: 'POST', - body: newAgentPolicyData, - })) as AxiosResponse; - } catch (error) { - throw new Error(`create policy ${error}`); - } - - // Create Package Configuration - const newPackagePolicyData: CreatePackagePolicyRequest['body'] = { - name: policyName, - description: 'Protect the worlds data', - policy_id: agentPolicy.data.item.id, - enabled: true, - output_id: '', - inputs: [ - { - type: 'endpoint', - enabled: true, - streams: [], - config: { - policy: { - value: policyConfigFactory(), - }, - }, - }, - ], - namespace: 'default', - package: { - name: 'endpoint', - title: 'endpoint', - version: endpointPackageVersion, - }, - }; - const packagePolicy = (await kbnClient.request({ - path: PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN, - method: 'POST', - body: newPackagePolicyData, - })) as AxiosResponse; - return packagePolicy.data.item; -}; - const getEndpointPackageInfo = async ( kbnClient: KbnClient ): Promise => { @@ -314,194 +133,14 @@ const getEndpointPackageInfo = async ( return endpointPackage; }; -const fetchKibanaVersion = async (kbnClient: KbnClientWithApiKeySupport) => { - const version = ((await kbnClient.request({ - path: '/api/status', - method: 'GET', - })) as AxiosResponse).data.version.number; +export type DeleteIndexedHostsAndAlertsResponse = DeleteIndexedEndpointHostsResponse; - if (!version) { - // eslint-disable-next-line no-console - console.log('failed to retrieve kibana version'); - return '8.0.0'; - } - - return version; -}; - -/** - * Will ensure that at least one fleet server is present in the `.fleet-servers` index. This will - * enable the `Agent` section of kibana Fleet to be displayed - * - * @param esClient - * @param version - */ -const enableFleetServerIfNecessary = async (esClient: Client, version: string = '8.0.0') => { - const res = await esClient.search<{}, {}>({ - index: FLEET_SERVER_SERVERS_INDEX, - ignore_unavailable: true, - }); - - // @ts-expect-error value is number | TotalHits - if (res.body.hits.total.value > 0) { - return; - } - - // Create a Fake fleet-server in this kibana instance - await esClient.index({ - index: FLEET_SERVER_SERVERS_INDEX, - body: { - agent: { - id: '12988155-475c-430d-ac89-84dc84b67cd1', - version: '', - }, - host: { - architecture: 'linux', - id: 'c3e5f4f690b4a3ff23e54900701a9513', - ip: ['127.0.0.1', '::1', '10.201.0.213', 'fe80::4001:aff:fec9:d5'], - name: 'endpoint-data-generator', - }, - server: { - id: '12988155-475c-430d-ac89-84dc84b67cd1', - version: '8.0.0-SNAPSHOT', - }, - '@timestamp': '2021-05-12T18:42:52.009482058Z', - }, - }); -}; - -const indexFleetAgentForHost = async ( +export const deleteIndexedHostsAndAlerts = async ( esClient: Client, - endpointHost: HostMetadata, - agentPolicyId: string, - kibanaVersion: string = '8.0.0' -): Promise> => { - const agentDoc = fleetAgentGenerator.generateEsHit({ - _source: { - local_metadata: { - elastic: { - agent: { - version: kibanaVersion, - }, - }, - host: { - ...endpointHost.host, - }, - os: { - ...endpointHost.host.os, - }, - }, - policy_id: agentPolicyId, - }, - }); - - await esClient.index({ - index: agentDoc._index, - id: agentDoc._id, - body: agentDoc._source!, - op_type: 'create', - }); - - return agentDoc; -}; - -const indexFleetActionsForHost = async ( - esClient: Client, - endpointHost: HostMetadata -): Promise => { - const ES_INDEX_OPTIONS = { headers: { 'X-elastic-product-origin': 'fleet' } }; - const agentId = endpointHost.elastic.agent.id; - const total = fleetActionGenerator.randomN(5); - - for (let i = 0; i < total; i++) { - // create an action - const action = fleetActionGenerator.generate({ - data: { comment: 'data generator: this host is bad' }, - }); - - action.agents = [agentId]; - - esClient.index( - { - index: AGENT_ACTIONS_INDEX, - body: action, - }, - ES_INDEX_OPTIONS - ); - - // Create an action response for the above - const actionResponse = fleetActionGenerator.generateResponse({ - action_id: action.action_id, - agent_id: agentId, - action_data: action.data, - }); - - esClient.index( - { - index: AGENT_ACTIONS_RESULTS_INDEX, - body: actionResponse, - }, - ES_INDEX_OPTIONS - ); - } - - // Add edge cases (maybe) - if (fleetActionGenerator.randomFloat() < 0.3) { - const randomFloat = fleetActionGenerator.randomFloat(); - - // 60% of the time just add either an Isolate -OR- an UnIsolate action - if (randomFloat < 0.6) { - let action: EndpointAction; - - if (randomFloat < 0.3) { - // add a pending isolation - action = fleetActionGenerator.generateIsolateAction({ - '@timestamp': new Date().toISOString(), - }); - } else { - // add a pending UN-isolation - action = fleetActionGenerator.generateUnIsolateAction({ - '@timestamp': new Date().toISOString(), - }); - } - - action.agents = [agentId]; - - await esClient.index( - { - index: AGENT_ACTIONS_INDEX, - body: action, - }, - ES_INDEX_OPTIONS - ); - } else { - // Else (40% of the time) add a pending isolate AND pending un-isolate - const action1 = fleetActionGenerator.generateIsolateAction({ - '@timestamp': new Date().toISOString(), - }); - const action2 = fleetActionGenerator.generateUnIsolateAction({ - '@timestamp': new Date().toISOString(), - }); - - action1.agents = [agentId]; - action2.agents = [agentId]; - - await Promise.all([ - esClient.index( - { - index: AGENT_ACTIONS_INDEX, - body: action1, - }, - ES_INDEX_OPTIONS - ), - esClient.index( - { - index: AGENT_ACTIONS_INDEX, - body: action2, - }, - ES_INDEX_OPTIONS - ), - ]); - } - } + kbnClient: KbnClient, + indexedData: IndexedHostsAndAlertsResponse +): Promise => { + return { + ...(await deleteIndexedEndpointHosts(esClient, kbnClient, indexedData)), + }; }; diff --git a/x-pack/plugins/security_solution/common/typed_json.ts b/x-pack/plugins/security_solution/common/typed_json.ts index 1c42ab3a6fd24..c1d281eccb1fa 100644 --- a/x-pack/plugins/security_solution/common/typed_json.ts +++ b/x-pack/plugins/security_solution/common/typed_json.ts @@ -7,7 +7,7 @@ import { DslQuery, Filter } from '@kbn/es-query'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; export type ESQuery = | ESRangeQuery diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index 8a8ebd18174be..fe6c7e85e175d 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -62,6 +62,7 @@ export interface OwnProps { renderCellValue: (props: CellValueElementProps) => React.ReactNode; rowRenderers: RowRenderer[]; utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode; + additionalFilters?: React.ReactNode; } type Props = OwnProps & PropsFromRedux; @@ -98,6 +99,7 @@ const StatefulEventsViewerComponent: React.FC = ({ showCheckboxes, sort, utilityBar, + additionalFilters, // If truthy, the graph viewer (Resolver) is showing graphEventId, }) => { @@ -165,7 +167,7 @@ const StatefulEventsViewerComponent: React.FC = ({ setGlobalFullScreen, start, sort, - utilityBar, + additionalFilters, graphEventId, filterStatus: currentFilter, leadingControlColumns, @@ -291,6 +293,7 @@ export const StatefulEventsViewer = connector( prevProps.showCheckboxes === nextProps.showCheckboxes && prevProps.start === nextProps.start && prevProps.utilityBar === nextProps.utilityBar && + prevProps.additionalFilters === nextProps.additionalFilters && prevProps.graphEventId === nextProps.graphEventId ) ); diff --git a/x-pack/plugins/security_solution/public/common/lib/keury/index.ts b/x-pack/plugins/security_solution/public/common/lib/keury/index.ts index 13db6e94d2eea..1e286931bf799 100644 --- a/x-pack/plugins/security_solution/public/common/lib/keury/index.ts +++ b/x-pack/plugins/security_solution/public/common/lib/keury/index.ts @@ -7,7 +7,7 @@ import { isEmpty, isString, flow } from 'lodash/fp'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { EsQueryConfig, Query, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx index 0d6793eb2b886..484cd66575005 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { waitFor, act } from '@testing-library/react'; import { mount } from 'enzyme'; -import { esQuery } from '../../../../../../../../src/plugins/data/public'; +import { esQuery, Filter } from '../../../../../../../../src/plugins/data/public'; import { TestProviders } from '../../../../common/mock'; import { SecurityPageName } from '../../../../app/types'; @@ -78,6 +78,11 @@ describe('AlertsHistogramPanel', () => { updateDateRange: jest.fn(), }; + afterEach(() => { + jest.clearAllMocks(); + jest.restoreAllMocks(); + }); + it('renders correctly', () => { const wrapper = mount( @@ -157,7 +162,7 @@ describe('AlertsHistogramPanel', () => { combinedQueries: '{"bool":{"must":[],"filter":[{"match_all":{}},{"exists":{"field":"process.name"}}],"should":[],"must_not":[]}}', }; - mount( + const wrapper = mount( @@ -180,6 +185,60 @@ describe('AlertsHistogramPanel', () => { ], ]); }); + wrapper.unmount(); + }); + }); + + describe('Filters', () => { + it('filters props is valid, alerts query include filter', async () => { + const mockGetAlertsHistogramQuery = jest.spyOn(helpers, 'getAlertsHistogramQuery'); + const statusFilter: Filter = { + meta: { + alias: null, + disabled: false, + key: 'signal.status', + negate: false, + params: { + query: 'open', + }, + type: 'phrase', + }, + query: { + term: { + 'signal.status': 'open', + }, + }, + }; + + const props = { + ...defaultProps, + query: { query: '', language: 'kql' }, + filters: [statusFilter], + }; + const wrapper = mount( + + + + ); + + await waitFor(() => { + expect(mockGetAlertsHistogramQuery.mock.calls[1]).toEqual([ + 'signal.rule.name', + '2020-07-07T08:20:18.966Z', + '2020-07-08T08:20:18.966Z', + [ + { + bool: { + filter: [{ term: { 'signal.status': 'open' } }], + must: [], + must_not: [], + should: [], + }, + }, + ], + ]); + }); + wrapper.unmount(); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx index db918951b8555..82f58b5b1c723 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx @@ -6,7 +6,9 @@ */ import { EuiFilterButton, EuiFilterGroup } from '@elastic/eui'; +import { rgba } from 'polished'; import React, { useCallback, useState } from 'react'; +import styled from 'styled-components'; import { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; import * as i18n from '../translations'; @@ -14,6 +16,17 @@ export const FILTER_OPEN: Status = 'open'; export const FILTER_CLOSED: Status = 'closed'; export const FILTER_IN_PROGRESS: Status = 'in-progress'; +const StatusFilterButton = styled(EuiFilterButton)<{ isActive: boolean }>` + background: ${({ isActive, theme }) => (isActive ? theme.eui.euiColorPrimary : '')}; +`; + +const StatusFilterGroup = styled(EuiFilterGroup)` + background: ${({ theme }) => rgba(theme.eui.euiColorPrimary, 0.2)}; + .euiButtonEmpty--ghost:enabled:focus { + background-color: ${({ theme }) => theme.eui.euiColorPrimary}; + } +`; + interface Props { onFilterGroupChanged: (filterGroup: Status) => void; } @@ -37,33 +50,39 @@ const AlertsTableFilterGroupComponent: React.FC = ({ onFilterGroupChanged }, [setFilterGroup, onFilterGroupChanged]); return ( - - + {i18n.OPEN_ALERTS} - + - {i18n.IN_PROGRESS_ALERTS} - + - {i18n.CLOSED_ALERTS} - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx index 1ef79a64f831e..8a88c430b03e9 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx @@ -50,14 +50,12 @@ const UtilityBarFlexGroup = styled(EuiFlexGroup)` min-width: 175px; `; -const BuildingBlockContainer = styled(EuiFlexItem)` - background: repeating-linear-gradient( - 127deg, - rgba(245, 167, 0, 0.2), - rgba(245, 167, 0, 0.2) 1px, - rgba(245, 167, 0, 0.05) 2px, - rgba(245, 167, 0, 0.05) 10px - ); +const AdditionalFiltersItem = styled(EuiFlexItem)` + padding: ${({ theme }) => theme.eui.paddingSizes.s}; +`; + +const BuildingBlockContainer = styled(AdditionalFiltersItem)` + background: ${({ theme }) => theme.eui.euiColorHighlight}; `; const AlertsUtilityBarComponent: React.FC = ({ @@ -146,39 +144,6 @@ const AlertsUtilityBarComponent: React.FC = ({ ); - const UtilityBarAdditionalFiltersContent = (closePopover: () => void) => ( - - - ) => { - closePopover(); - onShowBuildingBlockAlertsChanged(e.target.checked); - }} - checked={showBuildingBlockAlerts} - color="text" - data-test-subj="showBuildingBlockAlertsCheckbox" - label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK} - /> - - - ) => { - closePopover(); - onShowOnlyThreatIndicatorAlertsChanged(e.target.checked); - }} - checked={showOnlyThreatIndicatorAlerts} - color="text" - data-test-subj="showOnlyThreatIndicatorAlertsCheckbox" - label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS} - /> - - - ); - const handleSelectAllAlertsClick = useCallback(() => { if (!showClearSelection) { selectAll(); @@ -233,16 +198,13 @@ const AlertsUtilityBarComponent: React.FC = ({ )} - - {i18n.ADDITIONAL_FILTERS_ACTIONS} - + @@ -260,3 +222,63 @@ export const AlertsUtilityBar = React.memo( prevProps.showBuildingBlockAlerts === nextProps.showBuildingBlockAlerts && prevProps.showOnlyThreatIndicatorAlerts === nextProps.showOnlyThreatIndicatorAlerts ); + +export const AditionalFiltersAction = ({ + areEventsLoading, + onShowBuildingBlockAlertsChanged, + showBuildingBlockAlerts, + onShowOnlyThreatIndicatorAlertsChanged, + showOnlyThreatIndicatorAlerts, +}: { + areEventsLoading: boolean; + onShowBuildingBlockAlertsChanged: (showBuildingBlockAlerts: boolean) => void; + showBuildingBlockAlerts: boolean; + onShowOnlyThreatIndicatorAlertsChanged: (showOnlyThreatIndicatorAlerts: boolean) => void; + showOnlyThreatIndicatorAlerts: boolean; +}) => { + const UtilityBarAdditionalFiltersContent = (closePopover: () => void) => ( + + + ) => { + closePopover(); + onShowBuildingBlockAlertsChanged(e.target.checked); + }} + checked={showBuildingBlockAlerts} + color="text" + data-test-subj="showBuildingBlockAlertsCheckbox" + label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_BUILDING_BLOCK} + /> + + + ) => { + closePopover(); + onShowOnlyThreatIndicatorAlertsChanged(e.target.checked); + }} + checked={showOnlyThreatIndicatorAlerts} + color="text" + data-test-subj="showOnlyThreatIndicatorAlertsCheckbox" + label={i18n.ADDITIONAL_FILTERS_ACTIONS_SHOW_ONLY_THREAT_INDICATOR_ALERTS} + /> + + + ); + + return ( + + {i18n.ADDITIONAL_FILTERS_ACTIONS} + + ); +}; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx index be11aecfe47dd..dba7915460ada 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx @@ -35,9 +35,7 @@ describe('AlertsTableComponent', () => { isSelectAllChecked={false} clearSelected={jest.fn()} setEventsLoading={jest.fn()} - clearEventsLoading={jest.fn()} setEventsDeleted={jest.fn()} - clearEventsDeleted={jest.fn()} showBuildingBlockAlerts={false} onShowBuildingBlockAlertsChanged={jest.fn()} showOnlyThreatIndicatorAlerts={false} diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index a1f2025c6c0d5..d8d6424ef2a73 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -31,8 +31,7 @@ import { alertsDefaultModelRuleRegistry, buildAlertStatusFilterRuleRegistry, } from './default_config'; -import { FILTER_OPEN, AlertsTableFilterGroup } from './alerts_filter_group'; -import { AlertsUtilityBar } from './alerts_utility_bar'; +import { AditionalFiltersAction, AlertsUtilityBar } from './alerts_utility_bar'; import * as i18nCommon from '../../../common/translations'; import * as i18n from './translations'; import { @@ -68,13 +67,12 @@ interface OwnProps { showOnlyThreatIndicatorAlerts: boolean; timelineId: TimelineIdLiteral; to: string; + filterGroup?: Status; } type AlertsTableComponentProps = OwnProps & PropsFromRedux; export const AlertsTableComponent: React.FC = ({ - clearEventsDeleted, - clearEventsLoading, clearSelected, defaultFilters, from, @@ -95,10 +93,10 @@ export const AlertsTableComponent: React.FC = ({ showOnlyThreatIndicatorAlerts, timelineId, to, + filterGroup = 'open', }) => { const dispatch = useDispatch(); const [showClearSelectionAction, setShowClearSelectionAction] = useState(false); - const [filterGroup, setFilterGroup] = useState(FILTER_OPEN); const { browserFields, indexPattern: indexPatterns, @@ -216,17 +214,6 @@ export const AlertsTableComponent: React.FC = ({ } }, [dispatch, isSelectAllChecked, timelineId]); - // Callback for when open/closed filter changes - const onFilterGroupChangedCallback = useCallback( - (newFilterGroup: Status) => { - clearEventsLoading!({ id: timelineId }); - clearEventsDeleted!({ id: timelineId }); - clearSelected!({ id: timelineId }); - setFilterGroup(newFilterGroup); - }, - [clearEventsLoading, clearEventsDeleted, clearSelected, setFilterGroup, timelineId] - ); - // Callback for clearing entire selection from utility bar const clearSelectionCallback = useCallback(() => { clearSelected!({ id: timelineId }); @@ -326,6 +313,16 @@ export const AlertsTableComponent: React.FC = ({ ] ); + const additionalFiltersComponent = ( + 0} + onShowBuildingBlockAlertsChanged={onShowBuildingBlockAlertsChanged} + showBuildingBlockAlerts={showBuildingBlockAlerts} + onShowOnlyThreatIndicatorAlertsChanged={onShowOnlyThreatIndicatorAlertsChanged} + showOnlyThreatIndicatorAlerts={showOnlyThreatIndicatorAlerts} + /> + ); + const defaultFiltersMemo = useMemo(() => { // TODO: Once we are past experimental phase this code should be removed const alertStatusFilter = ruleRegistryEnabled @@ -372,11 +369,6 @@ export const AlertsTableComponent: React.FC = ({ ); }, [dispatch, defaultTimelineModel, filterManager, tGridEnabled, timelineId]); - const headerFilterGroup = useMemo( - () => , - [onFilterGroupChangedCallback] - ); - if (loading || indexPatternsLoading || isEmpty(selectedPatterns)) { return ( @@ -393,7 +385,6 @@ export const AlertsTableComponent: React.FC = ({ defaultModel={defaultTimelineModel} end={to} currentFilter={filterGroup} - headerFilterGroup={headerFilterGroup} id={timelineId} onRuleChange={onRuleChange} renderCellValue={RenderCellValue} @@ -401,6 +392,7 @@ export const AlertsTableComponent: React.FC = ({ scopeId={SourcererScopeName.detections} start={from} utilityBar={utilityBarCallback} + additionalFilters={additionalFiltersComponent} /> ); }; @@ -438,8 +430,6 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ eventIds: string[]; isLoading: boolean; }) => dispatch(timelineActions.setEventsLoading({ id, eventIds, isLoading })), - clearEventsLoading: ({ id }: { id: string }) => - dispatch(timelineActions.clearEventsLoading({ id })), setEventsDeleted: ({ id, eventIds, @@ -449,8 +439,6 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ eventIds: string[]; isDeleted: boolean; }) => dispatch(timelineActions.setEventsDeleted({ id, eventIds, isDeleted })), - clearEventsDeleted: ({ id }: { id: string }) => - dispatch(timelineActions.clearEventsDeleted({ id })), }); const connector = connect(makeMapStateToProps, mapDispatchToProps); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_endpoint_exception.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_endpoint_exception.tsx index 23709269a4c13..7be51c4eaa41a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_endpoint_exception.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_endpoint_exception.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiContextMenuItem, EuiText } from '@elastic/eui'; +import { EuiContextMenuItem } from '@elastic/eui'; import React from 'react'; import * as i18n from '../translations'; @@ -27,7 +27,7 @@ const AddEndpointExceptionComponent: React.FC = ({ onClick={onClick} disabled={disabled} > - {i18n.ACTION_ADD_ENDPOINT_EXCEPTION} + {i18n.ACTION_ADD_ENDPOINT_EXCEPTION} ); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_event_filter.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_event_filter.tsx index 1104b3eb83081..9b14c01371c9b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_event_filter.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_event_filter.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiContextMenuItem, EuiText } from '@elastic/eui'; +import { EuiContextMenuItem } from '@elastic/eui'; import React from 'react'; import * as i18n from '../translations'; @@ -24,9 +24,7 @@ const AddEventFilterComponent: React.FC = ({ onClick, disab onClick={onClick} disabled={disabled} > - - {i18n.ACTION_ADD_EVENT_FILTER} - + {i18n.ACTION_ADD_EVENT_FILTER} ); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_exception.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_exception.tsx index 030f67c9e708c..99eef3aefd42c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_exception.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/add_exception.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiContextMenuItem, EuiText } from '@elastic/eui'; +import { EuiContextMenuItem } from '@elastic/eui'; import React from 'react'; import * as i18n from '../translations'; @@ -24,9 +24,7 @@ const AddExceptionComponent: React.FC = ({ disabled, onClick onClick={onClick} disabled={disabled} > - - {i18n.ACTION_ADD_EXCEPTION} - + {i18n.ACTION_ADD_EXCEPTION} ); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index 3a9a4e875369e..2dae69fec43e1 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -7,8 +7,7 @@ import React, { useCallback, useMemo, useState } from 'react'; -import { EuiButtonIcon, EuiContextMenu, EuiPopover, EuiToolTip } from '@elastic/eui'; -import styled from 'styled-components'; +import { EuiButtonIcon, EuiContextMenuPanel, EuiPopover, EuiToolTip } from '@elastic/eui'; import { indexOf } from 'lodash'; import { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; @@ -31,8 +30,10 @@ import { useAlertsActions } from './use_alerts_actions'; import { useExceptionModal } from './use_add_exception_modal'; import { useExceptionActions } from './use_add_exception_actions'; import { useEventFilterModal } from './use_event_filter_modal'; -import { useEventFilterAction } from './use_event_filter_action'; import { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; +import { AddEventFilter } from './add_event_filter'; +import { AddException } from './add_exception'; +import { AddEndpointException } from './add_endpoint_exception'; interface AlertContextMenuProps { ariaLabel?: string; @@ -112,7 +113,7 @@ const AlertContextMenuComponent: React.FC = ({ onAddEventFilterClick, } = useEventFilterModal(); - const { statusActions } = useAlertsActions({ + const { actionItems } = useAlertsActions({ alertStatus, eventId: ecsRowData?._id, timelineId, @@ -132,23 +133,41 @@ const AlertContextMenuComponent: React.FC = ({ closePopover(); }, [closePopover, onAddEventFilterClick]); - const exceptionActions = useExceptionActions({ + const { + disabledAddEndpointException, + disabledAddException, + handleEndpointExceptionModal, + handleDetectionExceptionModal, + } = useExceptionActions({ isEndpointAlert, onAddExceptionTypeClick: handleOnAddExceptionTypeClick, }); - const eventFilterActions = useEventFilterAction({ - onAddEventFilterClick: handleOnAddEventFilterClick, - }); - - const panels = useMemo( - () => [ - { - id: 0, - items: !isEvent && ruleId ? [...statusActions, ...exceptionActions] : [eventFilterActions], - }, - ], - [eventFilterActions, exceptionActions, isEvent, ruleId, statusActions] + const items = useMemo( + () => + !isEvent && ruleId + ? [ + ...actionItems, + , + , + ] + : [], + [ + actionItems, + disabledAddEndpointException, + disabledAddException, + handleDetectionExceptionModal, + handleEndpointExceptionModal, + handleOnAddEventFilterClick, + isEvent, + ruleId, + ] ); return ( @@ -164,7 +183,7 @@ const AlertContextMenuComponent: React.FC = ({ anchorPosition="downLeft" repositionOnScroll > - +
@@ -191,12 +210,6 @@ const AlertContextMenuComponent: React.FC = ({ ); }; -const ContextMenuPanel = styled(EuiContextMenu)` - font-size: ${({ theme }) => theme.eui.euiFontSizeS}; -`; - -ContextMenuPanel.displayName = 'ContextMenuPanel'; - export const AlertContextMenu = React.memo(AlertContextMenuComponent); type AddExceptionModalWrapperProps = Omit< diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/close_status.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/close_status.tsx index 038d58c38a013..28a34c549ef16 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/close_status.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/close_status.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiContextMenuItem, EuiText } from '@elastic/eui'; +import { EuiContextMenuItem } from '@elastic/eui'; import React from 'react'; import { FILTER_CLOSED } from '../../alerts_filter_group'; import * as i18n from '../../translations'; @@ -25,7 +25,7 @@ const CloseAlertActionComponent: React.FC = ({ onClick, d onClick={onClick} disabled={disabled} > - {i18n.ACTION_CLOSE_ALERT} + {i18n.ACTION_CLOSE_ALERT} ); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/in_progress_alert_status.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/in_progress_alert_status.tsx index 2bca569032827..f273833c1c1b3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/in_progress_alert_status.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/in_progress_alert_status.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiContextMenuItem, EuiText } from '@elastic/eui'; +import { EuiContextMenuItem } from '@elastic/eui'; import React from 'react'; import { FILTER_IN_PROGRESS } from '../../alerts_filter_group'; import * as i18n from '../../translations'; @@ -28,7 +28,7 @@ const InProgressAlertStatusComponent: React.FC = ({ onClick={onClick} disabled={disabled} > - {i18n.ACTION_IN_PROGRESS_ALERT} + {i18n.ACTION_IN_PROGRESS_ALERT} ); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/open_alert_status.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/open_alert_status.tsx index 34832ee07ea75..2042acea4d604 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/open_alert_status.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/open_alert_status.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiContextMenuItem, EuiText } from '@elastic/eui'; +import { EuiContextMenuItem } from '@elastic/eui'; import React from 'react'; import { FILTER_OPEN } from '../../alerts_filter_group'; import * as i18n from '../../translations'; @@ -25,7 +25,7 @@ const OpenAlertStatusComponent: React.FC = ({ onClick, dis onClick={onClick} disabled={disabled} > - {i18n.ACTION_OPEN_ALERT} + {i18n.ACTION_OPEN_ALERT} ); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx index 0f8fa00a3ac40..9f1f699241e21 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx @@ -11,12 +11,20 @@ import type { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { useUserData } from '../../user_info'; import { ACTION_ADD_ENDPOINT_EXCEPTION, ACTION_ADD_EXCEPTION } from '../translations'; -interface UseExceptionActions { +interface ExceptionActions { name: string; onClick: () => void; disabled: boolean; } +interface UseExceptionActions { + disabledAddEndpointException: boolean; + disabledAddException: boolean; + exceptionActions: ExceptionActions[]; + handleEndpointExceptionModal: () => void; + handleDetectionExceptionModal: () => void; +} + interface UseExceptionActionProps { isEndpointAlert: boolean; onAddExceptionTypeClick: (type: ExceptionListType) => void; @@ -25,7 +33,7 @@ interface UseExceptionActionProps { export const useExceptionActions = ({ isEndpointAlert, onAddExceptionTypeClick, -}: UseExceptionActionProps): UseExceptionActions[] => { +}: UseExceptionActionProps): UseExceptionActions => { const [{ canUserCRUD, hasIndexWrite }] = useUserData(); const handleDetectionExceptionModal = useCallback(() => { @@ -62,5 +70,11 @@ export const useExceptionActions = ({ ] ); - return exceptionActions; + return { + disabledAddEndpointException, + disabledAddException, + exceptionActions, + handleEndpointExceptionModal, + handleDetectionExceptionModal, + }; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx index 855eb2dd5fef4..4fdebee6e1f4d 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx @@ -5,14 +5,12 @@ * 2.0. */ -import { useCallback, useMemo } from 'react'; +import { useCallback } from 'react'; import { useDispatch } from 'react-redux'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; import { timelineActions } from '../../../../timelines/store/timeline'; -import { FILTER_OPEN, FILTER_CLOSED, FILTER_IN_PROGRESS } from '../alerts_filter_group'; -import { updateAlertStatusAction } from '../actions'; import { SetEventsDeletedProps, SetEventsLoadingProps } from '../types'; import * as i18nCommon from '../../../../common/translations'; import * as i18n from '../translations'; @@ -22,12 +20,12 @@ import { displaySuccessToast, displayErrorToast, } from '../../../../common/components/toasters'; -import { useUserData } from '../../user_info'; +import { useStatusBulkActionItems } from '../../../../../../timelines/public'; interface Props { - alertStatus?: string; + alertStatus?: Status; closePopover: () => void; - eventId: string | null | undefined; + eventId: string; timelineId: string; } @@ -37,10 +35,9 @@ export const useAlertsActions = ({ alertStatus, closePopover, eventId, timelineI const { addWarning } = useAppToasts(); - const [{ canUserCRUD, hasIndexMaintenance, hasIndexUpdateDelete }] = useUserData(); - const onAlertStatusUpdateSuccess = useCallback( (updated: number, conflicts: number, newStatus: Status) => { + closePopover(); if (conflicts > 0) { // Partial failure addWarning({ @@ -63,12 +60,14 @@ export const useAlertsActions = ({ alertStatus, closePopover, eventId, timelineI displaySuccessToast(title, dispatchToaster); } }, - [addWarning, dispatchToaster] + [addWarning, closePopover, dispatchToaster] ); const onAlertStatusUpdateFailure = useCallback( (newStatus: Status, error: Error) => { let title: string; + closePopover(); + switch (newStatus) { case 'closed': title = i18n.CLOSED_ALERT_FAILED_TOAST; @@ -81,7 +80,7 @@ export const useAlertsActions = ({ alertStatus, closePopover, eventId, timelineI } displayErrorToast(title, [error.message], dispatchToaster); }, - [dispatchToaster] + [closePopover, dispatchToaster] ); const setEventsLoading = useCallback( @@ -98,120 +97,16 @@ export const useAlertsActions = ({ alertStatus, closePopover, eventId, timelineI [dispatch, timelineId] ); - const openAlertActionOnClick = useCallback(() => { - if (eventId) { - updateAlertStatusAction({ - alertIds: [eventId], - onAlertStatusUpdateFailure, - onAlertStatusUpdateSuccess, - setEventsDeleted, - setEventsLoading, - selectedStatus: FILTER_OPEN, - }); - } - closePopover(); - }, [ - closePopover, - eventId, - onAlertStatusUpdateFailure, - onAlertStatusUpdateSuccess, - setEventsDeleted, - setEventsLoading, - ]); - - const closeAlertActionClick = useCallback(() => { - if (eventId) { - updateAlertStatusAction({ - alertIds: [eventId], - onAlertStatusUpdateFailure, - onAlertStatusUpdateSuccess, - setEventsDeleted, - setEventsLoading, - selectedStatus: FILTER_CLOSED, - }); - } - - closePopover(); - }, [ - closePopover, - eventId, - onAlertStatusUpdateFailure, - onAlertStatusUpdateSuccess, - setEventsDeleted, + const actionItems = useStatusBulkActionItems({ + eventIds: [eventId], + currentStatus: alertStatus, setEventsLoading, - ]); - - const inProgressAlertActionClick = useCallback(() => { - if (eventId) { - updateAlertStatusAction({ - alertIds: [eventId], - onAlertStatusUpdateFailure, - onAlertStatusUpdateSuccess, - setEventsDeleted, - setEventsLoading, - selectedStatus: FILTER_IN_PROGRESS, - }); - } - - closePopover(); - }, [ - closePopover, - eventId, - onAlertStatusUpdateFailure, - onAlertStatusUpdateSuccess, setEventsDeleted, - setEventsLoading, - ]); - - const disabledInProgressAlertAction = !canUserCRUD || !hasIndexUpdateDelete; - - const inProgressAlertAction = useMemo(() => { - return { - name: i18n.ACTION_IN_PROGRESS_ALERT, - disabled: disabledInProgressAlertAction, - onClick: inProgressAlertActionClick, - [`data-test-subj`]: 'in-progress-alert-status', - }; - }, [disabledInProgressAlertAction, inProgressAlertActionClick]); - - const disabledCloseAlertAction = !hasIndexUpdateDelete && !hasIndexMaintenance; - const closeAlertAction = useMemo(() => { - return { - name: i18n.ACTION_CLOSE_ALERT, - disabled: disabledCloseAlertAction, - onClick: closeAlertActionClick, - [`data-test-subj`]: 'close-alert-status', - }; - }, [disabledCloseAlertAction, closeAlertActionClick]); - - const disabledOpenAlertAction = !hasIndexUpdateDelete && !hasIndexMaintenance; - const openAlertAction = useMemo(() => { - return { - name: i18n.ACTION_OPEN_ALERT, - disabled: disabledOpenAlertAction, - onClick: openAlertActionOnClick, - [`data-test-subj`]: 'open-alert-status', - }; - }, [disabledOpenAlertAction, openAlertActionOnClick]); - - const statusActions = useMemo(() => { - if (!alertStatus) { - return []; - } - - switch (alertStatus) { - case 'open': - return [inProgressAlertAction, closeAlertAction]; - case 'in-progress': - return [openAlertAction, closeAlertAction]; - case 'closed': - return [openAlertAction, inProgressAlertAction]; - default: - return []; - } - }, [alertStatus, inProgressAlertAction, closeAlertAction, openAlertAction]); + onUpdateSuccess: onAlertStatusUpdateSuccess, + onUpdateFailure: onAlertStatusUpdateFailure, + }); return { - statusActions, + actionItems, }; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx index d0f26894bf7d2..ffaea216f3fe3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx @@ -6,7 +6,7 @@ */ import React, { useState, useCallback, useMemo } from 'react'; -import { EuiContextMenu, EuiButton, EuiPopover } from '@elastic/eui'; +import { EuiContextMenu, EuiContextMenuPanel, EuiButton, EuiPopover } from '@elastic/eui'; import type { ExceptionListType } from '@kbn/securitysolution-io-ts-list-types'; import { TAKE_ACTION } from '../alerts_table/alerts_utility_bar/translations'; @@ -135,7 +135,7 @@ export const TakeActionDropdown = React.memo( [onAddExceptionTypeClick] ); - const exceptionActions = useExceptionActions({ + const { exceptionActions } = useExceptionActions({ isEndpointAlert, onAddExceptionTypeClick: handleOnAddExceptionTypeClick, }); @@ -149,7 +149,7 @@ export const TakeActionDropdown = React.memo( onAddEventFilterClick: handleOnAddEventFilterClick, }); - const { statusActions } = useAlertsActions({ + const { actionItems } = useAlertsActions({ alertStatus: actionsData.alertStatus, eventId: actionsData.eventId, timelineId, @@ -191,7 +191,7 @@ export const TakeActionDropdown = React.memo( { id: 1, title: CHANGE_ALERT_STATUS, - items: statusActions, + content: , }, /* Todo: Uncomment case action after getAddToCaseAction is split into action and modal { @@ -210,7 +210,7 @@ export const TakeActionDropdown = React.memo( ), },*/ ], - [alertsActionItems, hostIsolationAction, investigateInTimelineAction, statusActions] + [actionItems, alertsActionItems, hostIsolationAction, investigateInTimelineAction] ); const takeActionButton = useMemo(() => { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index 035784b2e27a4..323ef93133e24 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -5,11 +5,19 @@ * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiWindowEvent } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiWindowEvent, + EuiHorizontalRule, +} from '@elastic/eui'; import styled from 'styled-components'; import { noop } from 'lodash/fp'; import React, { useCallback, useMemo, useRef, useState } from 'react'; -import { useDispatch } from 'react-redux'; +import { connect, ConnectedProps, useDispatch } from 'react-redux'; +import { Dispatch } from 'redux'; +import { Status } from '../../../../common/detection_engine/schemas/common/schemas'; import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; import { isTab } from '../../../../../timelines/public'; import { useDeepEqualSelector, useShallowEqualSelector } from '../../../common/hooks/use_selector'; @@ -44,9 +52,11 @@ import { resetKeyboardFocus, showGlobalFilters, } from '../../../timelines/components/timeline/helpers'; -import { timelineSelectors } from '../../../timelines/store/timeline'; +import { timelineActions, timelineSelectors } from '../../../timelines/store/timeline'; import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; import { + buildAlertStatusFilter, + buildAlertStatusFilterRuleRegistry, buildShowBuildingBlockFilter, buildShowBuildingBlockFilterRuleRegistry, buildThreatMatchFilter, @@ -58,6 +68,10 @@ import { MissingPrivilegesCallOut } from '../../components/callouts/missing_priv import { useKibana } from '../../../common/lib/kibana'; import { AlertsCountPanel } from '../../components/alerts_kpis/alerts_count_panel'; import { CHART_HEIGHT } from '../../components/alerts_kpis/common/config'; +import { + AlertsTableFilterGroup, + FILTER_OPEN, +} from '../../components/alerts_table/alerts_filter_group'; /** * Need a 100% height here to account for the graph/analyze tool, which sets no explicit height parameters, but fills the available space. @@ -68,7 +82,13 @@ const StyledFullHeightContainer = styled.div` flex: 1 1 auto; `; -const DetectionEnginePageComponent = () => { +type DetectionEngineComponentProps = PropsFromRedux; + +const DetectionEnginePageComponent: React.FC = ({ + clearEventsDeleted, + clearEventsLoading, + clearSelected, +}) => { const dispatch = useDispatch(); const containerElement = useRef(null); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); @@ -108,6 +128,7 @@ const DetectionEnginePageComponent = () => { const [showOnlyThreatIndicatorAlerts, setShowOnlyThreatIndicatorAlerts] = useState(false); const loading = userInfoLoading || listsConfigLoading; const { navigateToUrl } = useKibana().services.application; + const [filterGroup, setFilterGroup] = useState(FILTER_OPEN); const updateDateRangeCallback = useCallback( ({ x }) => { @@ -134,23 +155,51 @@ const DetectionEnginePageComponent = () => { [formatUrl, navigateToUrl] ); + // Callback for when open/closed filter changes + const onFilterGroupChangedCallback = useCallback( + (newFilterGroup: Status) => { + const timelineId = TimelineId.detectionsPage; + clearEventsLoading!({ id: timelineId }); + clearEventsDeleted!({ id: timelineId }); + clearSelected!({ id: timelineId }); + setFilterGroup(newFilterGroup); + }, + [clearEventsLoading, clearEventsDeleted, clearSelected, setFilterGroup] + ); + const alertsHistogramDefaultFilters = useMemo( () => [ ...filters, ...(ruleRegistryEnabled - ? buildShowBuildingBlockFilterRuleRegistry(showBuildingBlockAlerts) // TODO: Once we are past experimental phase this code should be removed - : buildShowBuildingBlockFilter(showBuildingBlockAlerts)), + ? [ + // TODO: Once we are past experimental phase this code should be removed + ...buildShowBuildingBlockFilterRuleRegistry(showBuildingBlockAlerts), + ...buildAlertStatusFilterRuleRegistry(filterGroup), + ] + : [ + ...buildShowBuildingBlockFilter(showBuildingBlockAlerts), + ...buildAlertStatusFilter(filterGroup), + ]), ...buildThreatMatchFilter(showOnlyThreatIndicatorAlerts), ], - [filters, ruleRegistryEnabled, showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts] + [ + filters, + ruleRegistryEnabled, + showBuildingBlockAlerts, + showOnlyThreatIndicatorAlerts, + filterGroup, + ] ); // AlertsTable manages global filters itself, so not including `filters` const alertsTableDefaultFilters = useMemo( () => [ ...(ruleRegistryEnabled - ? buildShowBuildingBlockFilterRuleRegistry(showBuildingBlockAlerts) // TODO: Once we are past experimental phase this code should be removed - : buildShowBuildingBlockFilter(showBuildingBlockAlerts)), + ? [ + // TODO: Once we are past experimental phase this code should be removed + ...buildShowBuildingBlockFilterRuleRegistry(showBuildingBlockAlerts), + ] + : [...buildShowBuildingBlockFilter(showBuildingBlockAlerts)]), ...buildThreatMatchFilter(showOnlyThreatIndicatorAlerts), ], [ruleRegistryEnabled, showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts] @@ -227,7 +276,10 @@ const DetectionEnginePageComponent = () => { - + { {i18n.BUTTON_MANAGE_RULES} + + + { showOnlyThreatIndicatorAlerts={showOnlyThreatIndicatorAlerts} onShowOnlyThreatIndicatorAlertsChanged={onShowOnlyThreatIndicatorAlertsCallback} to={to} + filterGroup={filterGroup} /> @@ -301,4 +357,16 @@ const DetectionEnginePageComponent = () => { ); }; -export const DetectionEnginePage = React.memo(DetectionEnginePageComponent); +const mapDispatchToProps = (dispatch: Dispatch) => ({ + clearSelected: ({ id }: { id: string }) => dispatch(timelineActions.clearSelected({ id })), + clearEventsLoading: ({ id }: { id: string }) => + dispatch(timelineActions.clearEventsLoading({ id })), + clearEventsDeleted: ({ id }: { id: string }) => + dispatch(timelineActions.clearEventsDeleted({ id })), +}); + +const connector = connect(null, mapDispatchToProps); + +type PropsFromRedux = ConnectedProps; + +export const DetectionEnginePage = connector(React.memo(DetectionEnginePageComponent)); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx index 233189a3e8be9..230eaeb10939d 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx @@ -23,7 +23,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { noop } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useParams } from 'react-router-dom'; -import { useDispatch } from 'react-redux'; +import { connect, ConnectedProps, useDispatch } from 'react-redux'; import styled from 'styled-components'; import deepEqual from 'fast-deep-equal'; import { @@ -31,6 +31,7 @@ import { ExceptionListIdentifiers, } from '@kbn/securitysolution-io-ts-list-types'; +import { Dispatch } from 'redux'; import { isTab } from '../../../../../../../timelines/public'; import { useDeepEqualSelector, @@ -63,6 +64,8 @@ import { StepDefineRule } from '../../../../components/rules/step_define_rule'; import { StepScheduleRule } from '../../../../components/rules/step_schedule_rule'; import { buildAlertsRuleIdFilter, + buildAlertStatusFilter, + buildAlertStatusFilterRuleRegistry, buildShowBuildingBlockFilter, buildShowBuildingBlockFilterRuleRegistry, buildThreatMatchFilter, @@ -98,7 +101,7 @@ import { resetKeyboardFocus, showGlobalFilters, } from '../../../../../timelines/components/timeline/helpers'; -import { timelineSelectors } from '../../../../../timelines/store/timeline'; +import { timelineActions, timelineSelectors } from '../../../../../timelines/store/timeline'; import { timelineDefaults } from '../../../../../timelines/store/timeline/defaults'; import { useSourcererScope } from '../../../../../common/containers/sourcerer'; import { SourcererScopeName } from '../../../../../common/store/sourcerer/model'; @@ -118,6 +121,11 @@ import { MissingPrivilegesCallOut } from '../../../../components/callouts/missin import { useRuleWithFallback } from '../../../../containers/detection_engine/rules/use_rule_with_fallback'; import { BadgeOptions } from '../../../../../common/components/header_page/types'; import { AlertsStackByField } from '../../../../components/alerts_kpis/common/types'; +import { Status } from '../../../../../../common/detection_engine/schemas/common/schemas'; +import { + AlertsTableFilterGroup, + FILTER_OPEN, +} from '../../../../components/alerts_table/alerts_filter_group'; /** * Need a 100% height here to account for the graph/analyze tool, which sets no explicit height parameters, but fills the available space. @@ -155,7 +163,13 @@ const ruleDetailTabs = [ }, ]; -const RuleDetailsPageComponent = () => { +type DetectionEngineComponentProps = PropsFromRedux; + +const RuleDetailsPageComponent: React.FC = ({ + clearEventsDeleted, + clearEventsLoading, + clearSelected, +}) => { const { navigateToApp } = useKibana().services.application; const dispatch = useDispatch(); const containerElement = useRef(null); @@ -226,6 +240,7 @@ const RuleDetailsPageComponent = () => { const mlCapabilities = useMlCapabilities(); const { formatUrl } = useFormatUrl(SecurityPageName.rules); const { globalFullScreen } = useGlobalFullScreen(); + const [filterGroup, setFilterGroup] = useState(FILTER_OPEN); // TODO: Once we are past experimental phase this code should be removed const ruleRegistryEnabled = useIsExperimentalFeatureEnabled('ruleRegistryEnabled'); @@ -315,6 +330,18 @@ const RuleDetailsPageComponent = () => { [rule, ruleLoading] ); + // Callback for when open/closed filter changes + const onFilterGroupChangedCallback = useCallback( + (newFilterGroup: Status) => { + const timelineId = TimelineId.detectionsPage; + clearEventsLoading!({ id: timelineId }); + clearEventsDeleted!({ id: timelineId }); + clearSelected!({ id: timelineId }); + setFilterGroup(newFilterGroup); + }, + [clearEventsLoading, clearEventsDeleted, clearSelected, setFilterGroup] + ); + // Set showBuildingBlockAlerts if rule is a Building Block Rule otherwise we won't show alerts useEffect(() => { setShowBuildingBlockAlerts(rule?.building_block_type != null); @@ -324,11 +351,38 @@ const RuleDetailsPageComponent = () => { () => [ ...buildAlertsRuleIdFilter(ruleId), ...(ruleRegistryEnabled - ? buildShowBuildingBlockFilterRuleRegistry(showBuildingBlockAlerts) // TODO: Once we are past experimental phase this code should be removed - : buildShowBuildingBlockFilter(showBuildingBlockAlerts)), + ? [ + ...buildShowBuildingBlockFilterRuleRegistry(showBuildingBlockAlerts), // TODO: Once we are past experimental phase this code should be removed + ...buildAlertStatusFilterRuleRegistry(filterGroup), + ] + : [ + ...buildShowBuildingBlockFilter(showBuildingBlockAlerts), + ...buildAlertStatusFilter(filterGroup), + ]), ...buildThreatMatchFilter(showOnlyThreatIndicatorAlerts), ], - [ruleId, ruleRegistryEnabled, showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts] + [ + ruleId, + ruleRegistryEnabled, + showBuildingBlockAlerts, + showOnlyThreatIndicatorAlerts, + filterGroup, + ] + ); + + const alertsTableDefaultFilters = useMemo( + () => [ + ...buildAlertsRuleIdFilter(ruleId), + ...filters, + ...(ruleRegistryEnabled + ? [ + // TODO: Once we are past experimental phase this code should be removed + ...buildShowBuildingBlockFilterRuleRegistry(showBuildingBlockAlerts), + ] + : [...buildShowBuildingBlockFilter(showBuildingBlockAlerts)]), + ...buildThreatMatchFilter(showOnlyThreatIndicatorAlerts), + ], + [ruleId, filters, ruleRegistryEnabled, showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts] ); const alertMergedFilters = useMemo(() => [...alertDefaultFilters, ...filters], [ @@ -705,6 +759,8 @@ const RuleDetailsPageComponent = () => { {ruleDetailTab === RuleDetailTabs.alerts && ( <> + + { {ruleId != null && ( { ); }; +const mapDispatchToProps = (dispatch: Dispatch) => ({ + clearSelected: ({ id }: { id: string }) => dispatch(timelineActions.clearSelected({ id })), + clearEventsLoading: ({ id }: { id: string }) => + dispatch(timelineActions.clearEventsLoading({ id })), + clearEventsDeleted: ({ id }: { id: string }) => + dispatch(timelineActions.clearEventsDeleted({ id })), +}); + +const connector = connect(null, mapDispatchToProps); + +type PropsFromRedux = ConnectedProps; + RuleDetailsPageComponent.displayName = 'RuleDetailsPageComponent'; -export const RuleDetailsPage = React.memo(RuleDetailsPageComponent); +export const RuleDetailsPage = connector(React.memo(RuleDetailsPageComponent)); RuleDetailsPage.displayName = 'RuleDetailsPage'; diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx index 7c34e6f30b910..c07df41225d40 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx @@ -126,7 +126,10 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta - + (next) => async (action) => { next(action); @@ -108,270 +107,12 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory(HOST_METADATA_LIST_ROUTE, { - body: JSON.stringify({ - paging_properties: [{ page_index: pageIndex }, { page_size: pageSize }], - filters: { kql: decodedQuery.query }, - }), - }); - endpointResponse.request_page_index = Number(pageIndex); - - dispatch({ - type: 'serverReturnedEndpointList', - payload: endpointResponse, - }); - - loadEndpointsPendingActions(store); - - try { - const endpointsTotalCount = await endpointsTotal(coreStart.http); - dispatch({ - type: 'serverReturnedEndpointsTotal', - payload: endpointsTotalCount, - }); - } catch (error) { - dispatch({ - type: 'serverFailedToReturnEndpointsTotal', - payload: error, - }); - } - - try { - const agentsWithEndpoint = await sendGetFleetAgentsWithEndpoint(coreStart.http); - dispatch({ - type: 'serverReturnedAgenstWithEndpointsTotal', - payload: agentsWithEndpoint.total, - }); - } catch (error) { - dispatch({ - type: 'serverFailedToReturnAgenstWithEndpointsTotal', - payload: error, - }); - } - - try { - const ingestPolicies = await getAgentAndPoliciesForEndpointsList( - coreStart.http, - endpointResponse.hosts, - nonExistingPolicies(getState()) - ); - if (ingestPolicies?.packagePolicy !== undefined) { - dispatch({ - type: 'serverReturnedEndpointNonExistingPolicies', - payload: ingestPolicies.packagePolicy, - }); - } - if (ingestPolicies?.agentPolicy !== undefined) { - dispatch({ - type: 'serverReturnedEndpointAgentPolicies', - payload: ingestPolicies.agentPolicy, - }); - } - } catch (error) { - // TODO should handle the error instead of logging it to the browser - // Also this is an anti-pattern we shouldn't use - // Ignore Errors, since this should not hinder the user's ability to use the UI - logError(error); - } - } catch (error) { - dispatch({ - type: 'serverFailedToReturnEndpointList', - payload: error, - }); - } - - // get index pattern and fields for search bar - if (patterns(getState()).length === 0) { - try { - const indexPatterns = await fetchIndexPatterns(); - if (indexPatterns !== undefined) { - dispatch({ - type: 'serverReturnedMetadataPatterns', - payload: indexPatterns, - }); - } - } catch (error) { - dispatch({ - type: 'serverFailedToReturnMetadataPatterns', - payload: error, - }); - } - } - - // No endpoints, so we should check to see if there are policies for onboarding - if (endpointResponse && endpointResponse.hosts.length === 0) { - const http = coreStart.http; - - // The original query to the list could have had an invalid param (ex. invalid page_size), - // so we check first if endpoints actually do exist before pulling in data for the onboarding - // messages. - if (await doEndpointsExist(http)) { - return; - } - - dispatch({ - type: 'serverReturnedEndpointExistValue', - payload: false, - }); - - try { - const policyDataResponse: GetPolicyListResponse = await sendGetEndpointSpecificPackagePolicies( - http, - { - query: { - perPage: 50, // Since this is an oboarding flow, we'll cap at 50 policies. - page: 1, - }, - } - ); - - dispatch({ - type: 'serverReturnedPoliciesForOnboarding', - payload: { - policyItems: policyDataResponse.items, - }, - }); - } catch (error) { - dispatch({ - type: 'serverFailedToReturnPoliciesForOnboarding', - payload: error.body ?? error, - }); - return; - } - } else { - dispatch({ - type: 'serverCancelledPolicyItemsLoading', - }); - - dispatch({ - type: 'serverReturnedEndpointExistValue', - payload: true, - }); - } + endpointDetailsListMiddleware({ coreStart, store, fetchIndexPatterns }); } // Endpoint Details if (action.type === 'userChangedUrl' && hasSelectedEndpoint(getState()) === true) { - dispatch({ - type: 'serverCancelledPolicyItemsLoading', - }); - - // If user navigated directly to a endpoint details page, load the endpoint list - if (listData(getState()).length === 0) { - const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(getState()); - try { - const response = await coreStart.http.post(HOST_METADATA_LIST_ROUTE, { - body: JSON.stringify({ - paging_properties: [{ page_index: pageIndex }, { page_size: pageSize }], - }), - }); - response.request_page_index = Number(pageIndex); - dispatch({ - type: 'serverReturnedEndpointList', - payload: response, - }); - - try { - const ingestPolicies = await getAgentAndPoliciesForEndpointsList( - coreStart.http, - response.hosts, - nonExistingPolicies(getState()) - ); - if (ingestPolicies?.packagePolicy !== undefined) { - dispatch({ - type: 'serverReturnedEndpointNonExistingPolicies', - payload: ingestPolicies.packagePolicy, - }); - } - if (ingestPolicies?.agentPolicy !== undefined) { - dispatch({ - type: 'serverReturnedEndpointAgentPolicies', - payload: ingestPolicies.agentPolicy, - }); - } - } catch (error) { - // TODO should handle the error instead of logging it to the browser - // Also this is an anti-pattern we shouldn't use - // Ignore Errors, since this should not hinder the user's ability to use the UI - logError(error); - } - } catch (error) { - dispatch({ - type: 'serverFailedToReturnEndpointList', - payload: error, - }); - } - } else { - dispatch({ - type: 'serverCancelledEndpointListLoading', - }); - } - - // call the endpoint details api - const { selected_endpoint: selectedEndpoint } = uiQueryParams(getState()); - try { - const response = await coreStart.http.get( - resolvePathVariables(HOST_METADATA_GET_ROUTE, { id: selectedEndpoint as string }) - ); - dispatch({ - type: 'serverReturnedEndpointDetails', - payload: response, - }); - - try { - const ingestPolicies = await getAgentAndPoliciesForEndpointsList( - coreStart.http, - [response], - nonExistingPolicies(getState()) - ); - if (ingestPolicies !== undefined) { - dispatch({ - type: 'serverReturnedEndpointNonExistingPolicies', - payload: ingestPolicies.packagePolicy, - }); - } - if (ingestPolicies?.agentPolicy !== undefined) { - dispatch({ - type: 'serverReturnedEndpointAgentPolicies', - payload: ingestPolicies.agentPolicy, - }); - } - } catch (error) { - // TODO should handle the error instead of logging it to the browser - // Also this is an anti-pattern we shouldn't use - // Ignore Errors, since this should not hinder the user's ability to use the UI - logError(error); - } - } catch (error) { - dispatch({ - type: 'serverFailedToReturnEndpointDetails', - payload: error, - }); - } - - loadEndpointsPendingActions(store); - - // call the policy response api - try { - const policyResponse = await coreStart.http.get(BASE_POLICY_RESPONSE_ROUTE, { - query: { agentId: selectedEndpoint }, - }); - dispatch({ - type: 'serverReturnedEndpointPolicyResponse', - payload: policyResponse, - }); - } catch (error) { - dispatch({ - type: 'serverFailedToReturnEndpointPolicyResponse', - payload: error, - }); - } + endpointDetailsMiddleware({ store, coreStart }); } if ( @@ -379,32 +120,7 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory(getActivityLogData(getState())), - }); - - try { - const { page, pageSize } = getActivityLogDataPaging(getState()); - const route = resolvePathVariables(ENDPOINT_ACTION_LOG_ROUTE, { - agent_id: selectedAgent(getState()), - }); - const activityLog = await coreStart.http.get(route, { - query: { page, page_size: pageSize }, - }); - dispatch({ - type: 'endpointDetailsActivityLogChanged', - payload: createLoadedResourceState(activityLog), - }); - } catch (error) { - dispatch({ - type: 'endpointDetailsActivityLogChanged', - payload: createFailedResourceState(error.body ?? error), - }); - } + endpointDetailsActivityLogChangedMiddleware({ store, coreStart }); } // page activity log API @@ -412,91 +128,7 @@ export const endpointMiddlewareFactory: ImmutableMiddlewareFactory(getActivityLogData(getState())), - }); - const route = resolvePathVariables(ENDPOINT_ACTION_LOG_ROUTE, { - agent_id: selectedAgent(getState()), - }); - const activityLog = await coreStart.http.get(route, { - query: { - page, - page_size: pageSize, - start_date: startDate, - end_date: endDate, - }, - }); - - const lastLoadedLogData = getLastLoadedActivityLogData(getState()); - if (lastLoadedLogData !== undefined) { - const updatedLogDataItems = ([ - ...new Set([...lastLoadedLogData.data, ...activityLog.data]), - ] as ActivityLog['data']).sort((a, b) => - new Date(b.item.data['@timestamp']) > new Date(a.item.data['@timestamp']) ? 1 : -1 - ); - - const updatedLogData = { - page: activityLog.page, - pageSize: activityLog.pageSize, - startDate: activityLog.startDate, - endDate: activityLog.endDate, - data: activityLog.page === 1 ? activityLog.data : updatedLogDataItems, - }; - dispatch({ - type: 'endpointDetailsActivityLogChanged', - payload: createLoadedResourceState(updatedLogData), - }); - if (!activityLog.data.length) { - dispatch({ - type: 'endpointDetailsActivityLogUpdatePaging', - payload: { - disabled: true, - page: activityLog.page > 1 ? activityLog.page - 1 : 1, - pageSize: activityLog.pageSize, - startDate: activityLog.startDate, - endDate: activityLog.endDate, - }, - }); - } - } else { - dispatch({ - type: 'endpointDetailsActivityLogChanged', - payload: createLoadedResourceState(activityLog), - }); - } - } catch (error) { - dispatch({ - type: 'endpointDetailsActivityLogChanged', - payload: createFailedResourceState(error.body ?? error), - }); - } + endpointDetailsActivityLogPagingMiddleware({ store, coreStart }); } // Isolate Host @@ -730,6 +362,416 @@ const loadEndpointsPendingActions = async ({ } }; +async function endpointDetailsListMiddleware({ + store, + coreStart, + fetchIndexPatterns, +}: { + store: ImmutableMiddlewareAPI; + coreStart: CoreStart; + fetchIndexPatterns: () => Promise; +}) { + const { getState, dispatch } = store; + + const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(getState()); + let endpointResponse; + + try { + const decodedQuery: Query = searchBarQuery(getState()); + + endpointResponse = await coreStart.http.post(HOST_METADATA_LIST_ROUTE, { + body: JSON.stringify({ + paging_properties: [{ page_index: pageIndex }, { page_size: pageSize }], + filters: { kql: decodedQuery.query }, + }), + }); + endpointResponse.request_page_index = Number(pageIndex); + + dispatch({ + type: 'serverReturnedEndpointList', + payload: endpointResponse, + }); + + loadEndpointsPendingActions(store); + + try { + const endpointsTotalCount = await endpointsTotal(coreStart.http); + dispatch({ + type: 'serverReturnedEndpointsTotal', + payload: endpointsTotalCount, + }); + } catch (error) { + dispatch({ + type: 'serverFailedToReturnEndpointsTotal', + payload: error, + }); + } + + try { + const agentsWithEndpoint = await sendGetFleetAgentsWithEndpoint(coreStart.http); + dispatch({ + type: 'serverReturnedAgenstWithEndpointsTotal', + payload: agentsWithEndpoint.total, + }); + } catch (error) { + dispatch({ + type: 'serverFailedToReturnAgenstWithEndpointsTotal', + payload: error, + }); + } + + try { + const ingestPolicies = await getAgentAndPoliciesForEndpointsList( + coreStart.http, + endpointResponse.hosts, + nonExistingPolicies(getState()) + ); + if (ingestPolicies?.packagePolicy !== undefined) { + dispatch({ + type: 'serverReturnedEndpointNonExistingPolicies', + payload: ingestPolicies.packagePolicy, + }); + } + if (ingestPolicies?.agentPolicy !== undefined) { + dispatch({ + type: 'serverReturnedEndpointAgentPolicies', + payload: ingestPolicies.agentPolicy, + }); + } + } catch (error) { + // TODO should handle the error instead of logging it to the browser + // Also this is an anti-pattern we shouldn't use + // Ignore Errors, since this should not hinder the user's ability to use the UI + logError(error); + } + } catch (error) { + dispatch({ + type: 'serverFailedToReturnEndpointList', + payload: error, + }); + } + + // get index pattern and fields for search bar + if (patterns(getState()).length === 0) { + try { + const indexPatterns = await fetchIndexPatterns(); + if (indexPatterns !== undefined) { + dispatch({ + type: 'serverReturnedMetadataPatterns', + payload: indexPatterns, + }); + } + } catch (error) { + dispatch({ + type: 'serverFailedToReturnMetadataPatterns', + payload: error, + }); + } + } + + // No endpoints, so we should check to see if there are policies for onboarding + if (endpointResponse && endpointResponse.hosts.length === 0) { + const http = coreStart.http; + + // The original query to the list could have had an invalid param (ex. invalid page_size), + // so we check first if endpoints actually do exist before pulling in data for the onboarding + // messages. + if (await doEndpointsExist(http)) { + return; + } + + dispatch({ + type: 'serverReturnedEndpointExistValue', + payload: false, + }); + + try { + const policyDataResponse: GetPolicyListResponse = await sendGetEndpointSpecificPackagePolicies( + http, + { + query: { + perPage: 50, // Since this is an oboarding flow, we'll cap at 50 policies. + page: 1, + }, + } + ); + + dispatch({ + type: 'serverReturnedPoliciesForOnboarding', + payload: { + policyItems: policyDataResponse.items, + }, + }); + } catch (error) { + dispatch({ + type: 'serverFailedToReturnPoliciesForOnboarding', + payload: error.body ?? error, + }); + } + } else { + dispatch({ + type: 'serverCancelledPolicyItemsLoading', + }); + + dispatch({ + type: 'serverReturnedEndpointExistValue', + payload: true, + }); + } +} + +async function endpointDetailsActivityLogPagingMiddleware({ + store, + coreStart, +}: { + store: ImmutableMiddlewareAPI; + coreStart: CoreStart; +}) { + const { getState, dispatch } = store; + try { + const { disabled, page, pageSize, startDate, endDate } = getActivityLogDataPaging(getState()); + // don't page when paging is disabled or when date ranges are invalid + if (disabled) { + return; + } + if (getIsInvalidDateRange({ startDate, endDate })) { + dispatch({ + type: 'endpointDetailsActivityLogUpdateIsInvalidDateRange', + payload: { + isInvalidDateRange: true, + }, + }); + return; + } + + dispatch({ + type: 'endpointDetailsActivityLogUpdateIsInvalidDateRange', + payload: { + isInvalidDateRange: false, + }, + }); + dispatch({ + type: 'endpointDetailsActivityLogChanged', + // ts error to be fixed when AsyncResourceState is refactored (#830) + // @ts-expect-error + payload: createLoadingResourceState(getActivityLogData(getState())), + }); + const route = resolvePathVariables(ENDPOINT_ACTION_LOG_ROUTE, { + agent_id: selectedAgent(getState()), + }); + const activityLog = await coreStart.http.get(route, { + query: { + page, + page_size: pageSize, + start_date: startDate, + end_date: endDate, + }, + }); + + const lastLoadedLogData = getLastLoadedActivityLogData(getState()); + if (lastLoadedLogData !== undefined) { + const updatedLogDataItems = ([ + ...new Set([...lastLoadedLogData.data, ...activityLog.data]), + ] as ActivityLog['data']).sort((a, b) => + new Date(b.item.data['@timestamp']) > new Date(a.item.data['@timestamp']) ? 1 : -1 + ); + + const updatedLogData = { + page: activityLog.page, + pageSize: activityLog.pageSize, + startDate: activityLog.startDate, + endDate: activityLog.endDate, + data: activityLog.page === 1 ? activityLog.data : updatedLogDataItems, + }; + dispatch({ + type: 'endpointDetailsActivityLogChanged', + payload: createLoadedResourceState(updatedLogData), + }); + if (!activityLog.data.length) { + dispatch({ + type: 'endpointDetailsActivityLogUpdatePaging', + payload: { + disabled: true, + page: activityLog.page > 1 ? activityLog.page - 1 : 1, + pageSize: activityLog.pageSize, + startDate: activityLog.startDate, + endDate: activityLog.endDate, + }, + }); + } + } else { + dispatch({ + type: 'endpointDetailsActivityLogChanged', + payload: createLoadedResourceState(activityLog), + }); + } + } catch (error) { + dispatch({ + type: 'endpointDetailsActivityLogChanged', + payload: createFailedResourceState(error.body ?? error), + }); + } +} + +async function endpointDetailsMiddleware({ + store, + coreStart, +}: { + store: ImmutableMiddlewareAPI; + coreStart: CoreStart; +}) { + const { getState, dispatch } = store; + dispatch({ + type: 'serverCancelledPolicyItemsLoading', + }); + + // If user navigated directly to a endpoint details page, load the endpoint list + if (listData(getState()).length === 0) { + const { page_index: pageIndex, page_size: pageSize } = uiQueryParams(getState()); + try { + const response = await coreStart.http.post(HOST_METADATA_LIST_ROUTE, { + body: JSON.stringify({ + paging_properties: [{ page_index: pageIndex }, { page_size: pageSize }], + }), + }); + response.request_page_index = Number(pageIndex); + dispatch({ + type: 'serverReturnedEndpointList', + payload: response, + }); + + try { + const ingestPolicies = await getAgentAndPoliciesForEndpointsList( + coreStart.http, + response.hosts, + nonExistingPolicies(getState()) + ); + if (ingestPolicies?.packagePolicy !== undefined) { + dispatch({ + type: 'serverReturnedEndpointNonExistingPolicies', + payload: ingestPolicies.packagePolicy, + }); + } + if (ingestPolicies?.agentPolicy !== undefined) { + dispatch({ + type: 'serverReturnedEndpointAgentPolicies', + payload: ingestPolicies.agentPolicy, + }); + } + } catch (error) { + // TODO should handle the error instead of logging it to the browser + // Also this is an anti-pattern we shouldn't use + // Ignore Errors, since this should not hinder the user's ability to use the UI + logError(error); + } + } catch (error) { + dispatch({ + type: 'serverFailedToReturnEndpointList', + payload: error, + }); + } + } else { + dispatch({ + type: 'serverCancelledEndpointListLoading', + }); + } + + // call the endpoint details api + const { selected_endpoint: selectedEndpoint } = uiQueryParams(getState()); + try { + const response = await coreStart.http.get( + resolvePathVariables(HOST_METADATA_GET_ROUTE, { id: selectedEndpoint as string }) + ); + dispatch({ + type: 'serverReturnedEndpointDetails', + payload: response, + }); + + try { + const ingestPolicies = await getAgentAndPoliciesForEndpointsList( + coreStart.http, + [response], + nonExistingPolicies(getState()) + ); + if (ingestPolicies !== undefined) { + dispatch({ + type: 'serverReturnedEndpointNonExistingPolicies', + payload: ingestPolicies.packagePolicy, + }); + } + if (ingestPolicies?.agentPolicy !== undefined) { + dispatch({ + type: 'serverReturnedEndpointAgentPolicies', + payload: ingestPolicies.agentPolicy, + }); + } + } catch (error) { + // TODO should handle the error instead of logging it to the browser + // Also this is an anti-pattern we shouldn't use + // Ignore Errors, since this should not hinder the user's ability to use the UI + logError(error); + } + } catch (error) { + dispatch({ + type: 'serverFailedToReturnEndpointDetails', + payload: error, + }); + } + + loadEndpointsPendingActions(store); + + // call the policy response api + try { + const policyResponse = await coreStart.http.get(BASE_POLICY_RESPONSE_ROUTE, { + query: { agentId: selectedEndpoint }, + }); + dispatch({ + type: 'serverReturnedEndpointPolicyResponse', + payload: policyResponse, + }); + } catch (error) { + dispatch({ + type: 'serverFailedToReturnEndpointPolicyResponse', + payload: error, + }); + } +} +async function endpointDetailsActivityLogChangedMiddleware({ + store, + coreStart, +}: { + store: ImmutableMiddlewareAPI; + coreStart: CoreStart; +}) { + const { getState, dispatch } = store; + // call the activity log api + dispatch({ + type: 'endpointDetailsActivityLogChanged', + // ts error to be fixed when AsyncResourceState is refactored (#830) + // @ts-expect-error + payload: createLoadingResourceState(getActivityLogData(getState())), + }); + + try { + const { page, pageSize } = getActivityLogDataPaging(getState()); + const route = resolvePathVariables(ENDPOINT_ACTION_LOG_ROUTE, { + agent_id: selectedAgent(getState()), + }); + const activityLog = await coreStart.http.get(route, { + query: { page, page_size: pageSize }, + }); + dispatch({ + type: 'endpointDetailsActivityLogChanged', + payload: createLoadedResourceState(activityLog), + }); + } catch (error) { + dispatch({ + type: 'endpointDetailsActivityLogChanged', + payload: createFailedResourceState(error.body ?? error), + }); + } +} + export async function handleLoadMetadataTransformStats(http: HttpStart, store: EndpointPageStore) { const { getState, dispatch } = store; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx index eaa5a66e4e375..85db83bf0ada6 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx @@ -24,9 +24,11 @@ import { PolicyProtection, MacPolicyProtection, LinuxPolicyProtection } from '.. export const ProtectionSwitch = React.memo( ({ protection, + protectionLabel, osList, }: { protection: PolicyProtection; + protectionLabel?: string; osList: ImmutableArray>; }) => { const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); @@ -93,10 +95,9 @@ export const ProtectionSwitch = React.memo( return ( { const OSes: Immutable = [OS.windows, OS.mac, OS.linux]; const protection = 'behavior_protection'; + const protectionLabel = i18n.translate( + 'xpack.securitySolution.endpoint.policy.protections.behavior', + { + defaultMessage: 'Behaviour protections', + } + ); return ( { })} supportedOss={[OperatingSystem.WINDOWS, OperatingSystem.MAC, OperatingSystem.LINUX]} dataTestSubj="behaviorProtectionsForm" - rightCorner={} + rightCorner={ + + } > diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx index 6374ba3bc4f5f..5056cd2feb101 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx @@ -26,6 +26,12 @@ import { ProtectionSwitch } from '../components/protection_switch'; export const MalwareProtections = React.memo(() => { const OSes: Immutable = [OS.windows, OS.mac, OS.linux]; const protection = 'malware'; + const protectionLabel = i18n.translate( + 'xpack.securitySolution.endpoint.policy.protections.malware', + { + defaultMessage: 'Malware protections', + } + ); const isPlatinumPlus = useLicense().isPlatinumPlus(); return ( @@ -35,7 +41,9 @@ export const MalwareProtections = React.memo(() => { })} supportedOss={[OperatingSystem.WINDOWS, OperatingSystem.MAC, OperatingSystem.LINUX]} dataTestSubj="malwareProtectionsForm" - rightCorner={} + rightCorner={ + + } > {isPlatinumPlus && } diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/memory.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/memory.tsx index 45d472a00f31e..f12449fccbe2b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/memory.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/memory.tsx @@ -25,6 +25,12 @@ import { ProtectionSwitch } from '../components/protection_switch'; export const MemoryProtection = React.memo(() => { const OSes: Immutable = [OS.windows]; const protection = 'memory_protection'; + const protectionLabel = i18n.translate( + 'xpack.securitySolution.endpoint.policy.protections.memory', + { + defaultMessage: 'Memory protections', + } + ); return ( { })} supportedOss={[OperatingSystem.WINDOWS]} dataTestSubj="memoryProtectionsForm" - rightCorner={} + rightCorner={ + + } > diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/ransomware.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/ransomware.tsx index 70f41015bc257..96635482f4b61 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/ransomware.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/ransomware.tsx @@ -25,6 +25,12 @@ import { ProtectionSwitch } from '../components/protection_switch'; export const Ransomware = React.memo(() => { const OSes: Immutable = [OS.windows]; const protection = 'ransomware'; + const protectionLabel = i18n.translate( + 'xpack.securitySolution.endpoint.policy.protections.ransomware', + { + defaultMessage: 'Ransomware protections', + } + ); return ( { })} supportedOss={[OperatingSystem.WINDOWS]} dataTestSubj="ransomwareProtectionsForm" - rightCorner={} + rightCorner={ + + } > diff --git a/x-pack/plugins/security_solution/scripts/endpoint/kbn_client_with_api_key_support.ts b/x-pack/plugins/security_solution/scripts/endpoint/kbn_client_with_api_key_support.ts deleted file mode 100644 index a8ed7b77a5d9e..0000000000000 --- a/x-pack/plugins/security_solution/scripts/endpoint/kbn_client_with_api_key_support.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 { URL } from 'url'; - -import { KbnClient, KbnClientOptions } from '@kbn/test'; -import fetch, { RequestInit } from 'node-fetch'; - -export class KbnClientWithApiKeySupport extends KbnClient { - private kibanaUrlNoAuth: URL; - - constructor(options: KbnClientOptions) { - super(options); - - // strip auth from url - const url = new URL(this.resolveUrl('/')); - url.username = ''; - url.password = ''; - - this.kibanaUrlNoAuth = url; - } - - /** - * The fleet api to enroll and agent requires an api key when you make - * the request, however KbnClient currently does not support sending - * an api key with the request. This function allows you to send an - * api key with a request. - */ - requestWithApiKey(path: string, init?: RequestInit) { - return fetch(new URL(path, this.kibanaUrlNoAuth), init); - } -} diff --git a/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts b/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts index 9071351ab541a..a9ad30adc994c 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts @@ -12,21 +12,8 @@ import { Client, ClientOptions } from '@elastic/elasticsearch'; import { ResponseError } from '@elastic/elasticsearch/lib/errors'; import { ToolingLog, CA_CERT_PATH } from '@kbn/dev-utils'; import { KbnClient } from '@kbn/test'; -import { AxiosResponse } from 'axios'; import { indexHostsAndAlerts } from '../../common/endpoint/index_data'; import { ANCESTRY_LIMIT, EndpointDocGenerator } from '../../common/endpoint/generate_data'; -import { - AGENTS_SETUP_API_ROUTES, - EPM_API_ROUTES, - SETUP_API_ROUTE, -} from '../../../fleet/common/constants'; -import { - BulkInstallPackageInfo, - BulkInstallPackagesResponse, - IBulkInstallPackageHTTPError, - PostFleetSetupResponse, -} from '../../../fleet/common/types/rest_spec'; -import { KbnClientWithApiKeySupport } from './kbn_client_with_api_key_support'; main(); @@ -50,75 +37,6 @@ async function deleteIndices(indices: string[], client: Client) { } } -function isFleetBulkInstallError( - installResponse: BulkInstallPackageInfo | IBulkInstallPackageHTTPError -): installResponse is IBulkInstallPackageHTTPError { - return 'error' in installResponse && installResponse.error !== undefined; -} - -async function doIngestSetup(kbnClient: KbnClient) { - // Setup Ingest - try { - const setupResponse = (await kbnClient.request({ - path: SETUP_API_ROUTE, - method: 'POST', - })) as AxiosResponse; - - if (!setupResponse.data.isInitialized) { - console.error(setupResponse.data); - throw new Error('Initializing the ingest manager failed, existing'); - } - } catch (error) { - console.error(error); - throw error; - } - - // Setup Fleet - try { - const setupResponse = (await kbnClient.request({ - path: AGENTS_SETUP_API_ROUTES.CREATE_PATTERN, - method: 'POST', - })) as AxiosResponse; - - if (!setupResponse.data.isInitialized) { - console.error(setupResponse.data); - throw new Error('Initializing Fleet failed, existing'); - } - } catch (error) { - console.error(error); - throw error; - } - - // Install/upgrade the endpoint package - try { - const installEndpointPackageResp = (await kbnClient.request({ - path: EPM_API_ROUTES.BULK_INSTALL_PATTERN, - method: 'POST', - body: { - packages: ['endpoint'], - }, - })) as AxiosResponse; - - const bulkResp = installEndpointPackageResp.data.response; - if (bulkResp.length <= 0) { - throw new Error('Installing the Endpoint package failed, response was empty, existing'); - } - - if (isFleetBulkInstallError(bulkResp[0])) { - if (bulkResp[0].error instanceof Error) { - throw new Error( - `Installing the Endpoint package failed: ${bulkResp[0].error.message}, exiting` - ); - } - - throw new Error(bulkResp[0].error); - } - } catch (error) { - console.error(error); - throw error; - } -} - async function main() { const argv = yargs.help().options({ seed: { @@ -255,14 +173,14 @@ async function main() { }, }).argv; let ca: Buffer; - let kbnClient: KbnClientWithApiKeySupport; + let kbnClient: KbnClient; let clientOptions: ClientOptions; if (argv.ssl) { ca = fs.readFileSync(CA_CERT_PATH); const url = argv.kibana.replace('http:', 'https:'); const node = argv.node.replace('http:', 'https:'); - kbnClient = new KbnClientWithApiKeySupport({ + kbnClient = new KbnClient({ log: new ToolingLog({ level: 'info', writeTo: process.stdout, @@ -272,7 +190,7 @@ async function main() { }); clientOptions = { node, ssl: { ca: [ca] } }; } else { - kbnClient = new KbnClientWithApiKeySupport({ + kbnClient = new KbnClient({ log: new ToolingLog({ level: 'info', writeTo: process.stdout, @@ -283,13 +201,6 @@ async function main() { } const client = new Client(clientOptions); - try { - await doIngestSetup(kbnClient); - } catch (error) { - // eslint-disable-next-line no-process-exit - process.exit(1); - } - if (argv.delete) { await deleteIndices( [argv.eventIndex, argv.metadataIndex, argv.policyIndex, argv.alertIndex], diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.ts index 70e74356188c7..424be81e6e56a 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.ts @@ -6,7 +6,7 @@ */ import type { IScopedClusterClient } from 'kibana/server'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { parseFilterQuery } from '../../../../utils/serialized_query'; import { SafeResolverEvent } from '../../../../../common/endpoint/types'; import { PaginationBuilder } from '../utils/pagination'; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/descendants.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/descendants.ts index 331f622951515..ba9ac98cbffe4 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/descendants.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/descendants.ts @@ -7,7 +7,7 @@ import type { ApiResponse, estypes } from '@elastic/elasticsearch'; import { IScopedClusterClient } from 'src/core/server'; -import { JsonObject, JsonValue } from '@kbn/common-utils'; +import { JsonObject, JsonValue } from '@kbn/utility-types'; import { FieldsObject, ResolverSchema } from '../../../../../../common/endpoint/types'; import { NodeID, TimeRange, docValueFields, validIDs } from '../utils/index'; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/lifecycle.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/lifecycle.ts index 7de038ccc9ae4..0ea8f672aad64 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/lifecycle.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/lifecycle.ts @@ -6,7 +6,7 @@ */ import { IScopedClusterClient } from 'src/core/server'; -import { JsonObject, JsonValue } from '@kbn/common-utils'; +import { JsonObject, JsonValue } from '@kbn/utility-types'; import { FieldsObject, ResolverSchema } from '../../../../../../common/endpoint/types'; import { NodeID, TimeRange, docValueFields, validIDs } from '../utils/index'; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/stats.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/stats.ts index b64390f4e382f..5365fddbd436b 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/stats.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/stats.ts @@ -6,7 +6,7 @@ */ import { IScopedClusterClient } from 'src/core/server'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { EventStats, ResolverSchema } from '../../../../../../common/endpoint/types'; import { NodeID, TimeRange } from '../utils/index'; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/pagination.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/pagination.ts index 24fc447173ba6..caa28abe1abfd 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/pagination.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/pagination.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { SafeResolverEvent } from '../../../../../common/endpoint/types'; import { eventIDSafeVersion, diff --git a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts index 6745759727f07..92a0391492a3f 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts @@ -26,7 +26,12 @@ import { } from './errors'; import { getESQueryHostMetadataByID } from '../../routes/metadata/query_builders'; import { queryResponseToHostResult } from '../../routes/metadata/support/query_strategies'; -import { DEFAULT_ENDPOINT_HOST_STATUS, fleetAgentStatusToEndpointHostStatus } from '../../utils'; +import { + catchAndWrapError, + DEFAULT_ENDPOINT_HOST_STATUS, + fleetAgentStatusToEndpointHostStatus, + wrapErrorIfNeeded, +} from '../../utils'; import { EndpointError } from '../../errors'; import { createInternalReadonlySoClient } from '../../utils/create_internal_readonly_so_client'; @@ -34,15 +39,6 @@ type AgentPolicyWithPackagePolicies = Omit & { package_policies: PackagePolicy[]; }; -// Will wrap the given Error with `EndpointError`, which will -// help getting a good picture of where in our code the error originated from. -const wrapErrorIfNeeded = (error: Error): EndpointError => - error instanceof EndpointError ? error : new EndpointError(error.message, error); - -// used as the callback to `Promise#catch()` to ensure errors -// (especially those from kibana/elasticsearch clients) are wrapped -const catchAndWrapError = (error: E) => Promise.reject(wrapErrorIfNeeded(error)); - export class EndpointMetadataService { /** * For internal use only by the `this.DANGEROUS_INTERNAL_SO_CLIENT` diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/index.ts b/x-pack/plugins/security_solution/server/endpoint/utils/index.ts index 5cf23db57be12..34cabf79aff0e 100644 --- a/x-pack/plugins/security_solution/server/endpoint/utils/index.ts +++ b/x-pack/plugins/security_solution/server/endpoint/utils/index.ts @@ -6,3 +6,4 @@ */ export * from './fleet_agent_status_to_endpoint_host_status'; +export * from './wrap_errors'; diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/wrap_errors.ts b/x-pack/plugins/security_solution/server/endpoint/utils/wrap_errors.ts new file mode 100644 index 0000000000000..475cd42bc802c --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/utils/wrap_errors.ts @@ -0,0 +1,24 @@ +/* + * 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 { EndpointError } from '../errors'; + +/** + * Will wrap the given Error with `EndpointError`, which will help getting a good picture of where in + * our code the error originated (better stack trace). + */ +export const wrapErrorIfNeeded = (error: Error): EndpointError => + error instanceof EndpointError ? error : new EndpointError(error.message, error); + +/** + * used as the callback to `Promise#catch()` to ensure errors + * (especially those from kibana/elasticsearch clients) are wrapped + * + * @param error + */ +export const catchAndWrapError = (error: E) => + Promise.reject(wrapErrorIfNeeded(error)); diff --git a/x-pack/plugins/security_solution/server/index.ts b/x-pack/plugins/security_solution/server/index.ts index 5b95ddf13e033..7e3da726f6ebe 100644 --- a/x-pack/plugins/security_solution/server/index.ts +++ b/x-pack/plugins/security_solution/server/index.ts @@ -47,5 +47,5 @@ export const config: PluginConfigDescriptor = { export { ConfigType, Plugin, PluginSetup, PluginStart }; export { AppClient }; - export type { AppRequestContext } from './types'; +export { EndpointError } from './endpoint/errors'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_registry_log_client/rule_execution_field_map.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_registry_log_client/rule_execution_field_map.ts index b3c70cd56d9e6..700ce66e2770f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_registry_log_client/rule_execution_field_map.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_registry_log_client/rule_execution_field_map.ts @@ -18,6 +18,9 @@ import { * @deprecated ruleExecutionFieldMap is kept here only as a reference. It will be superseded with EventLog implementation */ export const ruleExecutionFieldMap = { + // [ALERT_OWNER]: { type: 'keyword', required: true }, + // [SPACE_IDS]: { type: 'keyword', array: true, required: true }, + // [RULE_ID]: { type: 'keyword', required: true }, [MESSAGE]: { type: 'keyword' }, [EVENT_SEQUENCE]: { type: 'long' }, [EVENT_END]: { type: 'date' }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_registry_log_client/rule_registry_log_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_registry_log_client/rule_registry_log_client.ts index e2c5c98702f12..f5971475e2b16 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_registry_log_client/rule_registry_log_client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_execution_log/rule_registry_log_client/rule_registry_log_client.ts @@ -213,6 +213,14 @@ export class RuleRegistryLogClient implements IRuleRegistryLogClient { ); } + // { [x: string]: string | string[] | ExecutionMetricValue; + // [x: number]: string; + // "kibana.space_ids": string[]; + // "event.action": T; + // "event.kind": string; + // "rule.id": string; + // "@timestamp": string; } + public async logExecutionMetric({ ruleId, namespace, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/detections_admin/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/detections_admin/detections_role.json index 82ef8cc6687b4..1291c9274271e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/detections_admin/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/detections_admin/detections_role.json @@ -17,6 +17,14 @@ "winlogbeat-*" ], "privileges": ["manage", "write", "read"] + }, + { + "names": [ + "metrics-endpoint.metadata_current_*", + ".fleet-agents*", + ".fleet-actions*" + ], + "privileges": ["read"] } ] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/hunter/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/hunter/detections_role.json index ba9adfda82bea..62d0343e57afb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/hunter/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/hunter/detections_role.json @@ -22,6 +22,14 @@ { "names": [".lists*", ".items*"], "privileges": ["read", "write"] + }, + { + "names": [ + "metrics-endpoint.metadata_current_*", + ".fleet-agents*", + ".fleet-actions*" + ], + "privileges": ["read"] } ] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/platform_engineer/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/platform_engineer/detections_role.json index 73a9559389b4e..d5c84dc5811de 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/platform_engineer/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/platform_engineer/detections_role.json @@ -15,7 +15,10 @@ "filebeat-*", "logs-*", "packetbeat-*", - "winlogbeat-*" + "winlogbeat-*", + "metrics-endpoint.metadata_current_*", + ".fleet-agents*", + ".fleet-actions*" ], "privileges": ["all"] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/reader/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/reader/detections_role.json index 289aeca24d45e..72c9369b31ae8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/reader/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/reader/detections_role.json @@ -6,7 +6,10 @@ "names" : [ ".siem-signals*", ".lists*", - ".items*" + ".items*", + "metrics-endpoint.metadata_current_*", + ".fleet-agents*", + ".fleet-actions*" ], "privileges" : ["read"] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/rule_author/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/rule_author/detections_role.json index bb606616d1bd5..1f3b8ceaf7b36 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/rule_author/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/rule_author/detections_role.json @@ -20,6 +20,14 @@ { "names": [".siem-signals-*"], "privileges": ["read", "write", "maintenance", "view_index_metadata"] + }, + { + "names": [ + "metrics-endpoint.metadata_current_*", + ".fleet-agents*", + ".fleet-actions*" + ], + "privileges": ["read"] } ] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/soc_manager/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/soc_manager/detections_role.json index 92a62034afcef..ae18fb7d3f1b5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/soc_manager/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/soc_manager/detections_role.json @@ -20,6 +20,14 @@ { "names": [".siem-signals-*"], "privileges": ["read", "write", "manage"] + }, + { + "names": [ + "metrics-endpoint.metadata_current_*", + ".fleet-agents*", + ".fleet-actions*" + ], + "privileges": ["read"] } ] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t1_analyst/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t1_analyst/detections_role.json index be082e380211a..fad86e4a3572a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t1_analyst/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t1_analyst/detections_role.json @@ -12,7 +12,10 @@ "filebeat-*", "logs-*", "packetbeat-*", - "winlogbeat-*" + "winlogbeat-*", + "metrics-endpoint.metadata_current_*", + ".fleet-agents*", + ".fleet-actions*" ], "privileges": ["read"] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t2_analyst/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t2_analyst/detections_role.json index f9e069f174a91..af3ba06a97d6a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t2_analyst/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t2_analyst/detections_role.json @@ -14,7 +14,10 @@ "filebeat-*", "logs-*", "packetbeat-*", - "winlogbeat-*" + "winlogbeat-*", + "metrics-endpoint.metadata_current_*", + ".fleet-agents*", + ".fleet-actions*" ], "privileges": ["read"] } diff --git a/x-pack/plugins/security_solution/server/utils/serialized_query.ts b/x-pack/plugins/security_solution/server/utils/serialized_query.ts index 7f8603ccab4b7..0c53de4b37f8a 100644 --- a/x-pack/plugins/security_solution/server/utils/serialized_query.ts +++ b/x-pack/plugins/security_solution/server/utils/serialized_query.ts @@ -7,7 +7,7 @@ import { isEmpty, isPlainObject, isString } from 'lodash/fp'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; export const parseFilterQuery = (filterQuery: string): JsonObject => { try { diff --git a/x-pack/plugins/task_manager/server/lib/calculate_health_status.ts b/x-pack/plugins/task_manager/server/lib/calculate_health_status.ts index 7a6bc59862100..d0e99690066dd 100644 --- a/x-pack/plugins/task_manager/server/lib/calculate_health_status.ts +++ b/x-pack/plugins/task_manager/server/lib/calculate_health_status.ts @@ -6,7 +6,7 @@ */ import { isString } from 'lodash'; -import { JsonValue } from '@kbn/common-utils'; +import { JsonValue } from '@kbn/utility-types'; import { HealthStatus, RawMonitoringStats } from '../monitoring'; import { TaskManagerConfig } from '../config'; diff --git a/x-pack/plugins/task_manager/server/monitoring/capacity_estimation.ts b/x-pack/plugins/task_manager/server/monitoring/capacity_estimation.ts index 03efcff10eb63..9cc223f63b196 100644 --- a/x-pack/plugins/task_manager/server/monitoring/capacity_estimation.ts +++ b/x-pack/plugins/task_manager/server/monitoring/capacity_estimation.ts @@ -7,7 +7,7 @@ import { mapValues } from 'lodash'; import stats from 'stats-lite'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { RawMonitoringStats, RawMonitoredStat, HealthStatus } from './monitoring_stats_stream'; import { AveragedStat } from './task_run_calcultors'; import { TaskPersistenceTypes } from './task_run_statistics'; diff --git a/x-pack/plugins/task_manager/server/monitoring/ephemeral_task_statistics.ts b/x-pack/plugins/task_manager/server/monitoring/ephemeral_task_statistics.ts index d1f3ef9c14055..2378c7f4606a6 100644 --- a/x-pack/plugins/task_manager/server/monitoring/ephemeral_task_statistics.ts +++ b/x-pack/plugins/task_manager/server/monitoring/ephemeral_task_statistics.ts @@ -6,7 +6,7 @@ */ import { map, filter, startWith, buffer, share } from 'rxjs/operators'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { combineLatest, Observable, zip } from 'rxjs'; import { isOk, Ok } from '../lib/result_type'; import { AggregatedStat, AggregatedStatProvider } from './runtime_statistics_aggregator'; diff --git a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts index 8e615fb861717..50d4b6af9a4cf 100644 --- a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts +++ b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts @@ -9,7 +9,7 @@ import { TaskManagerConfig } from '../config'; import { of, Subject } from 'rxjs'; import { take, bufferCount } from 'rxjs/operators'; import { createMonitoringStatsStream, AggregatedStat } from './monitoring_stats_stream'; -import { JsonValue } from '@kbn/common-utils'; +import { JsonValue } from '@kbn/utility-types'; beforeEach(() => { jest.resetAllMocks(); diff --git a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts index b187faf9e9648..fdddfc41e590a 100644 --- a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts +++ b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.ts @@ -9,7 +9,7 @@ import { merge, of, Observable } from 'rxjs'; import { map, scan } from 'rxjs/operators'; import { set } from '@elastic/safer-lodash-set'; import { Logger } from 'src/core/server'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { TaskStore } from '../task_store'; import { TaskPollingLifecycle } from '../polling_lifecycle'; import { diff --git a/x-pack/plugins/task_manager/server/monitoring/runtime_statistics_aggregator.ts b/x-pack/plugins/task_manager/server/monitoring/runtime_statistics_aggregator.ts index 799ea054596c0..872da8e0cbd50 100644 --- a/x-pack/plugins/task_manager/server/monitoring/runtime_statistics_aggregator.ts +++ b/x-pack/plugins/task_manager/server/monitoring/runtime_statistics_aggregator.ts @@ -6,7 +6,7 @@ */ import { Observable } from 'rxjs'; -import { JsonValue } from '@kbn/common-utils'; +import { JsonValue } from '@kbn/utility-types'; export interface AggregatedStat { key: string; diff --git a/x-pack/plugins/task_manager/server/monitoring/task_run_calcultors.ts b/x-pack/plugins/task_manager/server/monitoring/task_run_calcultors.ts index b0611437d87be..f65c28562d2b4 100644 --- a/x-pack/plugins/task_manager/server/monitoring/task_run_calcultors.ts +++ b/x-pack/plugins/task_manager/server/monitoring/task_run_calcultors.ts @@ -6,7 +6,7 @@ */ import stats from 'stats-lite'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { isUndefined, countBy, mapValues } from 'lodash'; export interface AveragedStat extends JsonObject { diff --git a/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.ts b/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.ts index d43137d237a99..3946827827fee 100644 --- a/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.ts +++ b/x-pack/plugins/task_manager/server/monitoring/task_run_statistics.ts @@ -7,7 +7,7 @@ import { combineLatest, Observable } from 'rxjs'; import { filter, startWith, map } from 'rxjs/operators'; -import { JsonObject, JsonValue } from '@kbn/common-utils'; +import { JsonObject, JsonValue } from '@kbn/utility-types'; import { isNumber, mapValues } from 'lodash'; import { AggregatedStatProvider, AggregatedStat } from './runtime_statistics_aggregator'; import { TaskLifecycleEvent } from '../polling_lifecycle'; diff --git a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts index 5c4e7d6cbe2cf..6f70df4b8c5c4 100644 --- a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts +++ b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts @@ -8,7 +8,7 @@ import { combineLatest, Observable, timer } from 'rxjs'; import { mergeMap, map, filter, switchMap, catchError } from 'rxjs/operators'; import { Logger } from 'src/core/server'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { keyBy, mapValues } from 'lodash'; import { estypes } from '@elastic/elasticsearch'; import { AggregatedStatProvider } from './runtime_statistics_aggregator'; diff --git a/x-pack/plugins/telemetry_collection_xpack/kibana.json b/x-pack/plugins/telemetry_collection_xpack/kibana.json index 8499e0258f8ff..decd1a02f13dd 100644 --- a/x-pack/plugins/telemetry_collection_xpack/kibana.json +++ b/x-pack/plugins/telemetry_collection_xpack/kibana.json @@ -1,5 +1,9 @@ { "id": "telemetryCollectionXpack", + "owner": { + "name": "Kibana Telemetry", + "githubTeam": "kibana-telemetry" + }, "version": "kibana", "server": true, "ui": false, diff --git a/x-pack/plugins/timelines/common/search_strategy/timeline/events/all/index.ts b/x-pack/plugins/timelines/common/search_strategy/timeline/events/all/index.ts index 4f4d21484267b..c585d93330b20 100644 --- a/x-pack/plugins/timelines/common/search_strategy/timeline/events/all/index.ts +++ b/x-pack/plugins/timelines/common/search_strategy/timeline/events/all/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import type { IEsSearchResponse } from '../../../../../../../../src/plugins/data/common'; import type { Ecs } from '../../../../ecs'; diff --git a/x-pack/plugins/timelines/common/search_strategy/timeline/events/details/index.ts b/x-pack/plugins/timelines/common/search_strategy/timeline/events/details/index.ts index 7a344a163ebac..5bceb31081687 100644 --- a/x-pack/plugins/timelines/common/search_strategy/timeline/events/details/index.ts +++ b/x-pack/plugins/timelines/common/search_strategy/timeline/events/details/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { IEsSearchResponse } from '../../../../../../../../src/plugins/data/common'; import { Inspect, Maybe } from '../../../common'; diff --git a/x-pack/plugins/timelines/common/typed_json.ts b/x-pack/plugins/timelines/common/typed_json.ts index c639c1c0322dc..679a68a16f700 100644 --- a/x-pack/plugins/timelines/common/typed_json.ts +++ b/x-pack/plugins/timelines/common/typed_json.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { DslQuery, Filter } from '@kbn/es-query'; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/helpers.test.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/helpers.test.tsx index fe9c5ea2bc332..2b58487fce53a 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/body/helpers.test.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/body/helpers.test.tsx @@ -14,8 +14,12 @@ import { mapSortDirectionToDirection, mapSortingColumns, stringifyEvent, + addBuildingBlockStyle, } from './helpers'; +import { euiThemeVars } from '@kbn/ui-shared-deps/theme'; +import { mockDnsEvent } from '../../../mock'; + describe('helpers', () => { describe('stringifyEvent', () => { test('it omits __typename when it appears at arbitrary levels', () => { @@ -388,4 +392,32 @@ describe('helpers', () => { ).toBe(false); }); }); + + describe('addBuildingBlockStyle', () => { + const THEME = { eui: euiThemeVars, darkMode: false }; + + test('it calls `setCellProps` with background color when event is a building block', () => { + const mockedSetCellProps = jest.fn(); + const ecs = { + ...mockDnsEvent, + ...{ signal: { rule: { building_block_type: ['default'] } } }, + }; + + addBuildingBlockStyle(ecs, THEME, mockedSetCellProps); + + expect(mockedSetCellProps).toBeCalledWith({ + style: { + backgroundColor: euiThemeVars.euiColorHighlight, + }, + }); + }); + + test('it call `setCellProps` reseting the background color when event is not a building block', () => { + const mockedSetCellProps = jest.fn(); + + addBuildingBlockStyle(mockDnsEvent, THEME, mockedSetCellProps); + + expect(mockedSetCellProps).toBeCalledWith({ style: { backgroundColor: 'inherit' } }); + }); + }); }); diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/helpers.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/helpers.tsx index fb50d5ebabb8c..790414314ecdd 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/body/helpers.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/body/helpers.tsx @@ -7,6 +7,7 @@ import { isEmpty } from 'lodash/fp'; +import { EuiDataGridCellValueElementProps } from '@elastic/eui'; import type { Ecs } from '../../../../common/ecs'; import type { BrowserField, @@ -20,6 +21,8 @@ import type { TimelineEventsType, } from '../../../../common/types/timeline'; +import type { EuiTheme } from '../../../../../../../src/plugins/kibana_react/common'; + // eslint-disable-next-line @typescript-eslint/no-explicit-any export const omitTypenameAndEmpty = (k: string, v: any): any | undefined => k !== '__typename' && v != null ? v : undefined; @@ -185,3 +188,23 @@ export const allowSorting = ({ return isAllowlistedNonBrowserField || isAggregatable; }; +export const addBuildingBlockStyle = ( + ecs: Ecs, + theme: EuiTheme, + setCellProps: EuiDataGridCellValueElementProps['setCellProps'] +) => { + if (isEventBuildingBlockType(ecs)) { + setCellProps({ + style: { + backgroundColor: `${theme.eui.euiColorHighlight}`, + }, + }); + } else { + // reset cell style + setCellProps({ + style: { + backgroundColor: 'inherit', + }, + }); + } +}; diff --git a/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx index 00f9d513a1a16..cc94f901446a7 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx @@ -24,28 +24,34 @@ import React, { useEffect, useMemo, useState, + useContext, } from 'react'; + import { connect, ConnectedProps, useDispatch } from 'react-redux'; +import { ThemeContext } from 'styled-components'; import { TGridCellAction, - TimelineId, - TimelineTabs, BulkActionsProp, - SortColumnTimeline, -} from '../../../../common/types/timeline'; - -import type { CellValueElementProps, ColumnHeaderOptions, ControlColumnProps, RowRenderer, AlertStatus, + SortColumnTimeline, + TimelineId, + TimelineTabs, } from '../../../../common/types/timeline'; + import type { TimelineItem, TimelineNonEcsData } from '../../../../common/search_strategy/timeline'; import { getActionsColumnWidth, getColumnHeaders } from './column_headers/helpers'; -import { getEventIdToDataMapping, mapSortDirectionToDirection, mapSortingColumns } from './helpers'; +import { + addBuildingBlockStyle, + getEventIdToDataMapping, + mapSortDirectionToDirection, + mapSortingColumns, +} from './helpers'; import { DEFAULT_ICON_BUTTON_WIDTH } from '../helpers'; import type { BrowserFields } from '../../../../common/search_strategy/index_fields'; @@ -58,6 +64,7 @@ import { RowAction } from './row_action'; import * as i18n from './translations'; import { AlertCount } from '../styles'; import { checkBoxControlColumn } from './control_columns'; +import type { EuiTheme } from '../../../../../../../src/plugins/kibana_react/common'; const StatefulAlertStatusBulkActions = lazy( () => import('../toolbar/bulk_actions/alert_status_bulk_actions') @@ -121,6 +128,7 @@ const transformControlColumns = ({ onSelectPage, browserFields, sort, + theme, }: { actionColumnsWidth: number; columnHeaders: ColumnHeaderOptions[]; @@ -138,6 +146,7 @@ const transformControlColumns = ({ browserFields: BrowserFields; onSelectPage: OnSelectAll; sort: SortColumnTimeline[]; + theme: EuiTheme; }): EuiDataGridControlColumn[] => controlColumns.map( ({ id: columnId, headerCellRender = EmptyHeaderCellRender, rowCellRender, width }, i) => ({ @@ -173,29 +182,33 @@ const transformControlColumns = ({ isExpanded, rowIndex, setCellProps, - }: EuiDataGridCellValueElementProps) => ( - - ), + }: EuiDataGridCellValueElementProps) => { + addBuildingBlockStyle(data[rowIndex].ecs, theme, setCellProps); + + return ( + + ); + }, width: width ?? actionColumnsWidth, }) ); @@ -252,6 +265,7 @@ export const BodyComponent = React.memo( const selectedCount = useMemo(() => Object.keys(selectedEventIds).length, [selectedEventIds]); + const theme: EuiTheme = useContext(ThemeContext); const onRowSelected: OnRowSelected = useCallback( ({ eventIds, isSelected }: { eventIds: string[]; isSelected: boolean }) => { setSelected({ @@ -444,6 +458,7 @@ export const BodyComponent = React.memo( sort, browserFields, onSelectPage, + theme, }) ); }, [ @@ -463,6 +478,7 @@ export const BodyComponent = React.memo( browserFields, onSelectPage, sort, + theme, ]); const columnsWithCellActions: EuiDataGridColumn[] = useMemo( @@ -483,34 +499,37 @@ export const BodyComponent = React.memo( [browserFields, columnHeaders, data, defaultCellActions] ); - const renderTGridCellValue: (x: EuiDataGridCellValueElementProps) => React.ReactNode = ({ - columnId, - rowIndex, - setCellProps, - }) => { - const rowData = rowIndex < data.length ? data[rowIndex].data : null; - const header = columnHeaders.find((h) => h.id === columnId); - const eventId = rowIndex < data.length ? data[rowIndex]._id : null; - - if (rowData == null || header == null || eventId == null) { - return null; - } - - return renderCellValue({ - columnId: header.id, - eventId, - data: rowData, - header, - isDraggable: false, - isExpandable: true, - isExpanded: false, - isDetails: false, - linkValues: getOr([], header.linkField ?? '', data[rowIndex].ecs), - rowIndex, - setCellProps, - timelineId: tabType != null ? `${id}-${tabType}` : id, - }); - }; + const renderTGridCellValue: ( + x: EuiDataGridCellValueElementProps + ) => React.ReactNode = useCallback( + ({ columnId, rowIndex, setCellProps }) => { + const rowData = rowIndex < data.length ? data[rowIndex].data : null; + const header = columnHeaders.find((h) => h.id === columnId); + const eventId = rowIndex < data.length ? data[rowIndex]._id : null; + + addBuildingBlockStyle(data[rowIndex].ecs, theme, setCellProps); + + if (rowData == null || header == null || eventId == null) { + return null; + } + + return renderCellValue({ + columnId: header.id, + eventId, + data: rowData, + header, + isDraggable: false, + isExpandable: true, + isExpanded: false, + isDetails: false, + linkValues: getOr([], header.linkField ?? '', data[rowIndex].ecs), + rowIndex, + setCellProps, + timelineId: tabType != null ? `${id}-${tabType}` : id, + }); + }, + [columnHeaders, data, id, renderCellValue, tabType, theme] + ); return ( void; start: string; sort: Sort[]; - utilityBar?: (refetch: Refetch, totalCount: number) => React.ReactNode; + additionalFilters: React.ReactNode; // If truthy, the graph viewer (Resolver) is showing graphEventId: string | undefined; leadingControlColumns?: ControlColumnProps[]; @@ -167,7 +165,7 @@ const TGridIntegratedComponent: React.FC = ({ setGlobalFullScreen, start, sort, - utilityBar, + additionalFilters, graphEventId, leadingControlColumns, trailingControlColumns, @@ -239,7 +237,7 @@ const TGridIntegratedComponent: React.FC = ({ const [ loading, - { events, updatedAt, loadPage, pageInfo, refetch, totalCount = 0, inspect }, + { events, loadPage, pageInfo, refetch, totalCount = 0, inspect }, ] = useTimelineEvents({ alertConsumers: SECURITY_ALERTS_CONSUMERS, docValueFields, @@ -294,19 +292,17 @@ const TGridIntegratedComponent: React.FC = ({ height={ headerFilterGroup == null ? COMPACT_HEADER_HEIGHT : EVENTS_VIEWER_HEADER_HEIGHT } - subtitle={utilityBar} title={globalFullScreen ? titleWithExitFullScreen : justTitle} > {HeaderSectionContent} - - + {!resolverIsShowing(graphEventId) && additionalFilters} diff --git a/x-pack/plugins/timelines/public/components/utils/keury/index.ts b/x-pack/plugins/timelines/public/components/utils/keury/index.ts index 391b15e8fdbac..fe3d8c4bf2e24 100644 --- a/x-pack/plugins/timelines/public/components/utils/keury/index.ts +++ b/x-pack/plugins/timelines/public/components/utils/keury/index.ts @@ -6,7 +6,7 @@ */ import { isEmpty, isString, flow } from 'lodash/fp'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { EsQueryConfig, Filter, Query } from '@kbn/es-query'; import { esQuery, esKuery, IIndexPattern } from '../../../../../../../src/plugins/data/public'; diff --git a/x-pack/plugins/timelines/public/hooks/use_status_bulk_action_items.tsx b/x-pack/plugins/timelines/public/hooks/use_status_bulk_action_items.tsx index 335953e7ee43e..69d7ad36324de 100644 --- a/x-pack/plugins/timelines/public/hooks/use_status_bulk_action_items.tsx +++ b/x-pack/plugins/timelines/public/hooks/use_status_bulk_action_items.tsx @@ -83,21 +83,33 @@ export const useStatusBulkActionItems = ({ const actionItems = []; if (currentStatus !== FILTER_OPEN) { actionItems.push( - onClickUpdate(FILTER_OPEN)}> + onClickUpdate(FILTER_OPEN)} + > {i18n.BULK_ACTION_OPEN_SELECTED} ); } if (currentStatus !== FILTER_IN_PROGRESS) { actionItems.push( - onClickUpdate(FILTER_IN_PROGRESS)}> + onClickUpdate(FILTER_IN_PROGRESS)} + > {i18n.BULK_ACTION_IN_PROGRESS_SELECTED} ); } if (currentStatus !== FILTER_CLOSED) { actionItems.push( - onClickUpdate(FILTER_CLOSED)}> + onClickUpdate(FILTER_CLOSED)} + > {i18n.BULK_ACTION_CLOSE_SELECTED} ); diff --git a/x-pack/plugins/timelines/public/index.ts b/x-pack/plugins/timelines/public/index.ts index 6f4de1dd2559e..d31e80de7d285 100644 --- a/x-pack/plugins/timelines/public/index.ts +++ b/x-pack/plugins/timelines/public/index.ts @@ -52,7 +52,7 @@ export { getTimelineIdFromColumnDroppableId, } from './components/drag_and_drop/helpers'; export { StatefulFieldsBrowser } from './components/t_grid/toolbar/fields_browser'; - +export { useStatusBulkActionItems } from './hooks/use_status_bulk_action_items'; // This exports static code and TypeScript types, // as well as, Kibana Platform `plugin()` initializer. export function plugin(initializerContext: PluginInitializerContext) { diff --git a/x-pack/plugins/timelines/public/plugin.ts b/x-pack/plugins/timelines/public/plugin.ts index 24bc99e59aaf0..2ec35ef1a51f3 100644 --- a/x-pack/plugins/timelines/public/plugin.ts +++ b/x-pack/plugins/timelines/public/plugin.ts @@ -27,6 +27,7 @@ import { tGridReducer } from './store/t_grid/reducer'; import { useDraggableKeyboardWrapper } from './components/drag_and_drop/draggable_keyboard_wrapper_hook'; import { useAddToTimeline, useAddToTimelineSensor } from './hooks/use_add_to_timeline'; import { getHoverActions } from './components/hover_actions'; + export class TimelinesPlugin implements Plugin { constructor(private readonly initializerContext: PluginInitializerContext) {} private _store: Store | undefined; diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts index 0517dcfb64901..4297cd595e261 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { DocValueFields } from '../../../../../../common/search_strategy'; export const buildTimelineDetailsQuery = ( diff --git a/x-pack/plugins/translations/kibana.json b/x-pack/plugins/translations/kibana.json index b227fdf11f08a..7e919e8a651ce 100644 --- a/x-pack/plugins/translations/kibana.json +++ b/x-pack/plugins/translations/kibana.json @@ -1,5 +1,9 @@ { "id": "translations", + "owner": { + "name": "Kibana Localization", + "githubTeam": "kibana-localization" + }, "version": "0.0.1", "kibanaVersion": "kibana", "configPath": ["x-pack", "translations"], diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 34cef30b2c3a7..1d81b0ed7785d 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1993,7 +1993,6 @@ "home.sampleData.ecommerceSpec.promotionTrackingTitle": "[e コマース] プロモーショントラッキング", "home.sampleData.ecommerceSpec.revenueDashboardDescription": "サンプルの e コマースの注文と収益を分析します", "home.sampleData.ecommerceSpec.revenueDashboardTitle": "[e コマース] 収益ダッシュボード", - "home.sampleData.ecommerceSpec.salesCountMapTitle": "[eコマース] 売上カウントマップ", "home.sampleData.ecommerceSpec.soldProductsPerDayTitle": "[e コマース] 1 日の販売製品", "home.sampleData.ecommerceSpecDescription": "e コマースの注文をトラッキングするサンプルデータ、ビジュアライゼーション、ダッシュボードです。", "home.sampleData.ecommerceSpecTitle": "サンプル e コマース注文", @@ -18600,7 +18599,6 @@ "xpack.observability.section.apps.uptime.description": "サイトとサービスの可用性をアクティブに監視するアラートを受信し、問題をより迅速に解決して、ユーザーエクスペリエンスを最適化します。", "xpack.observability.section.apps.uptime.title": "アップタイム", "xpack.observability.section.errorPanel": "データの取得時にエラーが発生しました。再試行してください", - "xpack.observability.severityBadge.unknownDescription": "不明", "xpack.observability.transactionRateLabel": "{value} tpm", "xpack.observability.ux.coreVitals.average": "平均", "xpack.observability.ux.coreVitals.averageMessage": " {bad}未満", @@ -21528,7 +21526,6 @@ "xpack.securitySolution.endpoint.policy.details.platinum": "プラチナ", "xpack.securitySolution.endpoint.policy.details.prevent": "防御", "xpack.securitySolution.endpoint.policy.details.protections": "保護", - "xpack.securitySolution.endpoint.policy.details.protectionsEnabled": "{protectionName}保護は{mode, select, true {有効です} false {無効です}}", "xpack.securitySolution.endpoint.policy.details.ransomware": "ランサムウェア", "xpack.securitySolution.endpoint.policy.details.save": "保存", "xpack.securitySolution.endpoint.policy.details.settings": "設定", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 8f140ddff43a4..244b3dee8f0d4 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1886,6 +1886,25 @@ "expressions.functions.varset.val.help": "指定变量的值。如果未指定,则使用输入上下文。", "expressions.types.number.fromStringConversionErrorMessage": "无法将“{string}”字符串的类型转换为数字", "flot.pie.unableToDrawLabelsInsideCanvasErrorMessage": "无法用画布内包含的标签绘制饼图", + "flot.time.aprLabel": "四月", + "flot.time.augLabel": "八月", + "flot.time.decLabel": "十二月", + "flot.time.febLabel": "二月", + "flot.time.friLabel": "周五", + "flot.time.janLabel": "一月", + "flot.time.julLabel": "七月", + "flot.time.junLabel": "六月", + "flot.time.marLabel": "三月", + "flot.time.mayLabel": "五月", + "flot.time.monLabel": "周一", + "flot.time.novLabel": "十一月", + "flot.time.octLabel": "十月", + "flot.time.satLabel": "周六", + "flot.time.sepLabel": "九月", + "flot.time.sunLabel": "周日", + "flot.time.thuLabel": "周四", + "flot.time.tueLabel": "周二", + "flot.time.wedLabel": "周三", "fieldFormats.advancedSettings.shortenFieldsText": "缩短长字段,例如,不显示 foo.bar.baz,而显示 f.b.baz", "fieldFormats.advancedSettings.shortenFieldsTitle": "缩短字段", "fieldFormats.advancedSettings.format.bytesFormat.numeralFormatLinkText": "数值格式", @@ -1961,25 +1980,6 @@ "fieldFormats.url.types.audio": "音频", "fieldFormats.url.types.img": "图像", "fieldFormats.url.types.link": "链接", - "flot.time.aprLabel": "四月", - "flot.time.augLabel": "八月", - "flot.time.decLabel": "十二月", - "flot.time.febLabel": "二月", - "flot.time.friLabel": "周五", - "flot.time.janLabel": "一月", - "flot.time.julLabel": "七月", - "flot.time.junLabel": "六月", - "flot.time.marLabel": "三月", - "flot.time.mayLabel": "五月", - "flot.time.monLabel": "周一", - "flot.time.novLabel": "十一月", - "flot.time.octLabel": "十月", - "flot.time.satLabel": "周六", - "flot.time.sepLabel": "九月", - "flot.time.sunLabel": "周日", - "flot.time.thuLabel": "周四", - "flot.time.tueLabel": "周二", - "flot.time.wedLabel": "周三", "home.addData.sampleDataButtonLabel": "试用我们的样例数据", "home.addData.sectionTitle": "采集您的数据", "home.breadcrumbs.addDataTitle": "添加数据", @@ -2004,7 +2004,6 @@ "home.sampleData.ecommerceSpec.promotionTrackingTitle": "[电子商务] 促销追踪", "home.sampleData.ecommerceSpec.revenueDashboardDescription": "分析模拟的电子商务订单和收入", "home.sampleData.ecommerceSpec.revenueDashboardTitle": "[电子商务] 收入仪表板", - "home.sampleData.ecommerceSpec.salesCountMapTitle": "[电子商务] 销售计数地图", "home.sampleData.ecommerceSpecDescription": "用于追踪电子商务订单的样例数据、可视化和仪表板。", "home.sampleData.ecommerceSpecTitle": "样例电子商务订单", "home.sampleData.flightsSpec.airportConnectionsTitle": "[航班] 机场航线(将鼠标悬停在机场上)", @@ -19016,7 +19015,6 @@ "xpack.observability.section.apps.uptime.description": "主动监测站点和服务的可用性。接收告警并更快地解决问题,从而优化用户体验。", "xpack.observability.section.apps.uptime.title": "运行时间", "xpack.observability.section.errorPanel": "尝试提取数据时发生错误。请重试", - "xpack.observability.severityBadge.unknownDescription": "未知", "xpack.observability.transactionRateLabel": "{value} tpm", "xpack.observability.ux.coreVitals.average": "平均值", "xpack.observability.ux.coreVitals.averageMessage": " 且小于 {bad}", @@ -22014,7 +22012,6 @@ "xpack.securitySolution.endpoint.policy.details.platinum": "白金级", "xpack.securitySolution.endpoint.policy.details.prevent": "防御", "xpack.securitySolution.endpoint.policy.details.protections": "防护", - "xpack.securitySolution.endpoint.policy.details.protectionsEnabled": "{protectionName}防护{mode, select, true {已启用} false {已禁用}}", "xpack.securitySolution.endpoint.policy.details.ransomware": "勒索软件", "xpack.securitySolution.endpoint.policy.details.save": "保存", "xpack.securitySolution.endpoint.policy.details.settings": "设置", diff --git a/x-pack/plugins/ui_actions_enhanced/common/types.ts b/x-pack/plugins/ui_actions_enhanced/common/types.ts index f26134a236570..02cab5d17c0b2 100644 --- a/x-pack/plugins/ui_actions_enhanced/common/types.ts +++ b/x-pack/plugins/ui_actions_enhanced/common/types.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { SerializableState } from '../../../../src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; -export type BaseActionConfig = SerializableState; +export type BaseActionConfig = SerializableRecord; export type SerializedAction = { readonly factoryId: string; diff --git a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/state/drilldown_manager_state.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/state/drilldown_manager_state.ts index 0e374010139f0..5a34a002bf4c3 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/state/drilldown_manager_state.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/drilldown_manager/state/drilldown_manager_state.ts @@ -8,7 +8,7 @@ import useObservable from 'react-use/lib/useObservable'; import { BehaviorSubject } from 'rxjs'; import { map } from 'rxjs/operators'; -import { SerializableState } from 'src/plugins/kibana_utils/common'; +import type { SerializableRecord } from '@kbn/utility-types'; import { PublicDrilldownManagerProps, DrilldownManagerDependencies, @@ -352,7 +352,7 @@ export class DrilldownManagerState { const action: SerializedAction = { factoryId: template.factoryId, name, - config: (template.config || {}) as SerializableState, + config: (template.config || {}) as SerializableRecord, }; await dynamicActionManager.createEvent(action, template.triggers); } @@ -395,7 +395,7 @@ export class DrilldownManagerState { if (drilldownState) { drilldownState.setName(this.pickName(template.name)); drilldownState.setTriggers(template.triggers); - drilldownState.setConfig(template.config as SerializableState); + drilldownState.setConfig(template.config as SerializableRecord); } }; diff --git a/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_enhancement.ts b/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_enhancement.ts index 26134b7e17bec..71ae3cfcc19e3 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_enhancement.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/dynamic_actions/dynamic_action_enhancement.ts @@ -5,9 +5,9 @@ * 2.0. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { EnhancementRegistryDefinition } from '../../../../../src/plugins/embeddable/public'; import { SavedObjectReference } from '../../../../../src/core/types'; -import { SerializableState } from '../../../../../src/plugins/kibana_utils/common'; import { DynamicActionsState } from '../../../ui_actions_enhanced/public'; import { UiActionsServiceEnhancements } from '../services'; @@ -16,14 +16,14 @@ export const dynamicActionEnhancement = ( ): EnhancementRegistryDefinition => { return { id: 'dynamicActions', - telemetry: (state: SerializableState, telemetryData: Record) => { + telemetry: (state: SerializableRecord, telemetryData: Record) => { return uiActionsEnhanced.telemetry(state as DynamicActionsState, telemetryData); }, - extract: (state: SerializableState) => { + extract: (state: SerializableRecord) => { return uiActionsEnhanced.extract(state as DynamicActionsState); }, - inject: (state: SerializableState, references: SavedObjectReference[]) => { + inject: (state: SerializableRecord, references: SavedObjectReference[]) => { return uiActionsEnhanced.inject(state as DynamicActionsState, references); }, - } as EnhancementRegistryDefinition; + } as EnhancementRegistryDefinition; }; diff --git a/x-pack/plugins/ui_actions_enhanced/server/dynamic_action_enhancement.ts b/x-pack/plugins/ui_actions_enhanced/server/dynamic_action_enhancement.ts index 88e4809a70fa8..07cafef084a61 100644 --- a/x-pack/plugins/ui_actions_enhanced/server/dynamic_action_enhancement.ts +++ b/x-pack/plugins/ui_actions_enhanced/server/dynamic_action_enhancement.ts @@ -5,10 +5,10 @@ * 2.0. */ +import type { SerializableRecord } from '@kbn/utility-types'; import { EnhancementRegistryDefinition } from '../../../../src/plugins/embeddable/server'; import { SavedObjectReference } from '../../../../src/core/types'; import { ActionFactory, DynamicActionsState, SerializedEvent } from './types'; -import { SerializableState } from '../../../../src/plugins/kibana_utils/common'; import { dynamicActionsCollector } from './telemetry/dynamic_actions_collector'; import { dynamicActionFactoriesCollector } from './telemetry/dynamic_action_factories_collector'; @@ -17,14 +17,14 @@ export const dynamicActionEnhancement = ( ): EnhancementRegistryDefinition => { return { id: 'dynamicActions', - telemetry: (serializableState: SerializableState, stats: Record) => { + telemetry: (serializableState: SerializableRecord, stats: Record) => { const state = serializableState as DynamicActionsState; stats = dynamicActionsCollector(state, stats); stats = dynamicActionFactoriesCollector(getActionFactory, state, stats); return stats; }, - extract: (state: SerializableState) => { + extract: (state: SerializableRecord) => { const references: SavedObjectReference[] = []; const newState: DynamicActionsState = { events: (state as DynamicActionsState).events.map((event: SerializedEvent) => { @@ -41,7 +41,7 @@ export const dynamicActionEnhancement = ( }; return { state: newState, references }; }, - inject: (state: SerializableState, references: SavedObjectReference[]) => { + inject: (state: SerializableRecord, references: SavedObjectReference[]) => { return { events: (state as DynamicActionsState).events.map((event: SerializedEvent) => { const factory = getActionFactory(event.action.factoryId); diff --git a/x-pack/plugins/uptime/server/lib/alerts/status_check.ts b/x-pack/plugins/uptime/server/lib/alerts/status_check.ts index 249eaa33ec24e..8fe11000725a7 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/status_check.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/status_check.ts @@ -8,7 +8,7 @@ import { min } from 'lodash'; import datemath from '@elastic/datemath'; import { schema } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { UptimeAlertTypeFactory } from './types'; import { esKuery } from '../../../../../../src/plugins/data/server'; import { diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts index 15e6fe30db186..5227b8ca7dcc2 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/api/types'; import { asMutableArray } from '../../../common/utils/as_mutable_array'; import { UMElasticsearchQueryFn } from '../adapters'; diff --git a/x-pack/scripts/functional_tests.js b/x-pack/scripts/functional_tests.js index 9e527835231b4..2ef5004726eb2 100644 --- a/x-pack/scripts/functional_tests.js +++ b/x-pack/scripts/functional_tests.js @@ -88,6 +88,7 @@ const onlyNotInCoverageTests = [ require.resolve('../test/saved_object_tagging/api_integration/security_and_spaces/config.ts'), require.resolve('../test/saved_object_tagging/api_integration/tagging_api/config.ts'), require.resolve('../test/examples/config.ts'), + require.resolve('../test/performance/config.ts'), ]; require('../../src/setup_node_env'); diff --git a/x-pack/test/api_integration/apis/maps/fonts_api.js b/x-pack/test/api_integration/apis/maps/fonts_api.js index a9d4a2e10f6d9..afde003b05f2d 100644 --- a/x-pack/test/api_integration/apis/maps/fonts_api.js +++ b/x-pack/test/api_integration/apis/maps/fonts_api.js @@ -18,5 +18,19 @@ export default function ({ getService }) { expect(resp.body.length).to.be(74696); }); + + it('should return 404 when file not found', async () => { + await supertest + .get(`/api/maps/fonts/Open%20Sans%20Regular,Arial%20Unicode%20MS%20Regular/noGonaFindMe`) + .expect(404); + }); + + it('should return 404 when file is not in font folder (../)', async () => { + await supertest.get(`/api/maps/fonts/open_sans/..%2fopen_sans%2f0-255`).expect(404); + }); + + it('should return 404 when file is not in font folder (./../)', async () => { + await supertest.get(`/api/maps/fonts/open_sans/.%2f..%2fopen_sans%2f0-255`).expect(404); + }); }); } diff --git a/x-pack/test/api_integration/apis/security_solution/events.ts b/x-pack/test/api_integration/apis/security_solution/events.ts index c99e41e011a9a..f6a668679b11d 100644 --- a/x-pack/test/api_integration/apis/security_solution/events.ts +++ b/x-pack/test/api_integration/apis/security_solution/events.ts @@ -6,7 +6,7 @@ */ import expect from '@kbn/expect'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { Direction, diff --git a/x-pack/test/api_integration/apis/security_solution/utils.ts b/x-pack/test/api_integration/apis/security_solution/utils.ts index 9265a0066d208..c17a6abca27f1 100644 --- a/x-pack/test/api_integration/apis/security_solution/utils.ts +++ b/x-pack/test/api_integration/apis/security_solution/utils.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { JsonObject, JsonArray } from '@kbn/common-utils'; +import { JsonObject, JsonArray } from '@kbn/utility-types'; export const getFilterValue = (hostName: string, from: string, to: string): JsonObject => ({ bool: { diff --git a/x-pack/test/apm_api_integration/tests/services/annotations.ts b/x-pack/test/apm_api_integration/tests/services/annotations.ts index 34eadbe3c609c..a91fb59ce998c 100644 --- a/x-pack/test/apm_api_integration/tests/services/annotations.ts +++ b/x-pack/test/apm_api_integration/tests/services/annotations.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; import { merge, cloneDeep, isPlainObject } from 'lodash'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { registry } from '../../common/registry'; diff --git a/x-pack/test/common/services/security_solution/index.ts b/x-pack/test/common/services/security_solution/index.ts new file mode 100644 index 0000000000000..657f336155cbd --- /dev/null +++ b/x-pack/test/common/services/security_solution/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './roles_users_utils'; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/roles_users_utils/index.ts b/x-pack/test/common/services/security_solution/roles_users_utils.ts similarity index 93% rename from x-pack/test/detection_engine_api_integration/security_and_spaces/roles_users_utils/index.ts rename to x-pack/test/common/services/security_solution/roles_users_utils.ts index b320446cbe05f..dd184c6a94b46 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/roles_users_utils/index.ts +++ b/x-pack/test/common/services/security_solution/roles_users_utils.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { assertUnreachable } from '../../../../plugins/security_solution/common/utility_types'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { assertUnreachable } from '../../../../plugins/security_solution/common'; +import { FtrProviderContext } from '../../ftr_provider_context'; import { t1AnalystUser, t2AnalystUser, @@ -28,6 +28,13 @@ import { import { ROLES } from '../../../../plugins/security_solution/common/test'; +export { ROLES }; + +/** + * creates a security solution centric role and a user (both having the same name) + * @param getService + * @param role + */ export const createUserAndRole = async ( getService: FtrProviderContext['getService'], role: ROLES diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_exceptions.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_exceptions.ts index e2251b0b8af08..4f764533e7578 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_exceptions.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_exceptions.ts @@ -53,7 +53,7 @@ import { getThresholdRuleForSignalTesting, } from '../../utils'; import { ROLES } from '../../../../plugins/security_solution/common/test'; -import { createUserAndRole, deleteUserAndRole } from '../roles_users_utils'; +import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_index.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_index.ts index 2ee68f9dee91d..4748e39cd3a46 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_index.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_index.ts @@ -14,7 +14,7 @@ import { import { FtrProviderContext } from '../../common/ftr_provider_context'; import { deleteSignalsIndex } from '../../utils'; import { ROLES } from '../../../../plugins/security_solution/common/test'; -import { createUserAndRole, deleteUserAndRole } from '../roles_users_utils'; +import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_rules.ts index cd63ee36da801..fff871493dfda 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_rules.ts @@ -32,7 +32,7 @@ import { getRuleForSignalTestingWithTimestampOverride, } from '../../utils'; import { ROLES } from '../../../../plugins/security_solution/common/test'; -import { createUserAndRole, deleteUserAndRole } from '../roles_users_utils'; +import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution'; import { RuleStatusResponse } from '../../../../plugins/security_solution/server/lib/detection_engine/rules/types'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_signals_migrations.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_signals_migrations.ts index ed1cd4e82ef20..8d18b98e40c59 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_signals_migrations.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_signals_migrations.ts @@ -22,7 +22,7 @@ import { getIndexNameFromLoad, waitForIndexToPopulate, } from '../../utils'; -import { createUserAndRole, deleteUserAndRole } from '../roles_users_utils'; +import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution'; interface CreateResponse { index: string; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_signals_migrations.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_signals_migrations.ts index 4539b8de8e6dc..5f373ceedcf7d 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_signals_migrations.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_signals_migrations.ts @@ -15,7 +15,7 @@ import { import { ROLES } from '../../../../plugins/security_solution/common/test'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, deleteSignalsIndex, getIndexNameFromLoad, waitFor } from '../../utils'; -import { createUserAndRole } from '../roles_users_utils'; +import { createUserAndRole } from '../../../common/services/security_solution'; interface CreateResponse { index: string; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/finalize_signals_migrations.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/finalize_signals_migrations.ts index d5f287e78268e..e3842781eecf3 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/finalize_signals_migrations.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/finalize_signals_migrations.ts @@ -21,7 +21,7 @@ import { getIndexNameFromLoad, waitFor, } from '../../utils'; -import { createUserAndRole, deleteUserAndRole } from '../roles_users_utils'; +import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution'; interface StatusResponse { index: string; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/get_signals_migration_status.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/get_signals_migration_status.ts index 5c726a177bb60..bbc0b105d8a6b 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/get_signals_migration_status.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/get_signals_migration_status.ts @@ -11,7 +11,7 @@ import { DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL } from '../../../../plugi import { ROLES } from '../../../../plugins/security_solution/common/test'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, deleteSignalsIndex, getIndexNameFromLoad } from '../../utils'; -import { createUserAndRole, deleteUserAndRole } from '../roles_users_utils'; +import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext): void => { diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/open_close_signals.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/open_close_signals.ts index 6768a76d85d45..4ecfeab80546e 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/open_close_signals.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/open_close_signals.ts @@ -27,7 +27,7 @@ import { waitForRuleSuccessOrStatus, getRuleForSignalTesting, } from '../../utils'; -import { createUserAndRole, deleteUserAndRole } from '../roles_users_utils'; +import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution'; import { ROLES } from '../../../../plugins/security_solution/common/test'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/read_privileges.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/read_privileges.ts index f8949daea831e..ec1f8d7208f10 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/read_privileges.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/read_privileges.ts @@ -10,7 +10,7 @@ import { DETECTION_ENGINE_PRIVILEGES_URL } from '../../../../plugins/security_so import { FtrProviderContext } from '../../common/ftr_provider_context'; import { ROLES } from '../../../../plugins/security_solution/common/test'; -import { createUserAndRole, deleteUserAndRole } from '../roles_users_utils'; +import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { diff --git a/x-pack/test/functional/apps/discover/index.ts b/x-pack/test/functional/apps/discover/index.ts index 82f53929ada31..af117a2182034 100644 --- a/x-pack/test/functional/apps/discover/index.ts +++ b/x-pack/test/functional/apps/discover/index.ts @@ -19,5 +19,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./saved_searches')); loadTestFile(require.resolve('./visualize_field')); loadTestFile(require.resolve('./value_suggestions')); + loadTestFile(require.resolve('./value_suggestions_non_timebased')); }); } diff --git a/x-pack/test/functional/apps/discover/reporting.ts b/x-pack/test/functional/apps/discover/reporting.ts index 3eb66204df564..cb05a59f07917 100644 --- a/x-pack/test/functional/apps/discover/reporting.ts +++ b/x-pack/test/functional/apps/discover/reporting.ts @@ -56,6 +56,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('remains available regardless of the saved search state', async () => { // create new search, csv export is not available await PageObjects.discover.clickNewSearchButton(); + await PageObjects.reporting.setTimepickerInDataRange(); await PageObjects.reporting.openCsvReportingPanel(); expect(await PageObjects.reporting.isGenerateReportButtonDisabled()).to.be(null); // save search, csv export is available diff --git a/x-pack/test/functional/apps/discover/value_suggestions.ts b/x-pack/test/functional/apps/discover/value_suggestions.ts index 7d5f500992eb7..6d0047a27c7e3 100644 --- a/x-pack/test/functional/apps/discover/value_suggestions.ts +++ b/x-pack/test/functional/apps/discover/value_suggestions.ts @@ -7,29 +7,127 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; +import { UI_SETTINGS } from '../../../../../src/plugins/data/common'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const queryBar = getService('queryBar'); - const PageObjects = getPageObjects(['common', 'timePicker']); + const filterBar = getService('filterBar'); + const docTable = getService('docTable'); + const PageObjects = getPageObjects(['common', 'timePicker', 'settings', 'context']); + + async function setAutocompleteUseTimeRange(value: boolean) { + await PageObjects.settings.navigateTo(); + await PageObjects.settings.clickKibanaSettings(); + await PageObjects.settings.toggleAdvancedSettingCheckbox( + UI_SETTINGS.AUTOCOMPLETE_USE_TIMERANGE, + value + ); + } describe('value suggestions', function describeIndexTests() { before(async function () { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); await esArchiver.load('x-pack/test/functional/es_archives/dashboard/drilldowns'); - await PageObjects.common.navigateToApp('discover'); - await PageObjects.timePicker.setDefaultAbsoluteRange(); }); after(async () => { await esArchiver.unload('x-pack/test/functional/es_archives/dashboard/drilldowns'); }); - it('show up', async () => { - await queryBar.setQuery('extension.raw : '); - const suggestions = await queryBar.getSuggestions(); - expect(suggestions.length).to.be(5); - expect(suggestions).to.contain('"jpg"'); + describe('useTimeRange enabled', () => { + before(async () => { + await setAutocompleteUseTimeRange(true); + }); + + beforeEach(async () => { + await PageObjects.common.navigateToApp('discover'); + }); + + describe('discover', () => { + afterEach(async () => { + await queryBar.clearQuery(); + }); + + it('dont show up if outside of range', async () => { + await PageObjects.timePicker.setAbsoluteRange( + 'Mar 1, 2020 @ 00:00:00.000', + 'Nov 1, 2020 @ 00:00:00.000' + ); + + await queryBar.setQuery('extension.raw : '); + const suggestions = await queryBar.getSuggestions(); + expect(suggestions.length).to.be(0); + }); + + it('show up if in range', async () => { + await PageObjects.timePicker.setDefaultAbsoluteRange(); + await queryBar.setQuery('extension.raw : '); + const suggestions = await queryBar.getSuggestions(); + expect(suggestions.length).to.be(5); + expect(suggestions).to.contain('"jpg"'); + }); + }); + + describe('context', () => { + after(async () => { + await filterBar.removeFilter('geo.dest'); + }); + + it('shows all autosuggest options for a filter in discover context app', async () => { + // Set a good time range + await PageObjects.timePicker.setDefaultAbsoluteRange(); + + // navigate to context + await docTable.clickRowToggle({ rowIndex: 0 }); + const rowActions = await docTable.getRowActions({ rowIndex: 0 }); + await rowActions[0].click(); + await PageObjects.context.waitUntilContextLoadingHasFinished(); + + // Apply filter in context view + await filterBar.addFilter('geo.dest', 'is', 'US'); + }); + }); + }); + + describe('useTimeRange disabled', () => { + before(async () => { + await setAutocompleteUseTimeRange(false); + }); + + beforeEach(async () => { + await PageObjects.common.navigateToApp('discover'); + }); + + afterEach(async () => { + await queryBar.clearQuery(); + }); + + after(async () => { + await PageObjects.settings.navigateTo(); + await PageObjects.settings.clickKibanaSettings(); + await PageObjects.settings.clearAdvancedSettings(UI_SETTINGS.AUTOCOMPLETE_USE_TIMERANGE); + }); + + it('DO show up if outside of range', async () => { + await PageObjects.timePicker.setAbsoluteRange( + 'Mar 1, 2020 @ 00:00:00.000', + 'Nov 1, 2020 @ 00:00:00.000' + ); + + await queryBar.setQuery('extension.raw : '); + const suggestions = await queryBar.getSuggestions(); + expect(suggestions.length).to.be(5); + expect(suggestions).to.contain('"jpg"'); + }); + + it('show up', async () => { + await PageObjects.timePicker.setDefaultAbsoluteRange(); + await queryBar.setQuery('extension.raw : '); + const suggestions = await queryBar.getSuggestions(); + expect(suggestions.length).to.be(5); + expect(suggestions).to.contain('"jpg"'); + }); }); }); } diff --git a/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts b/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts new file mode 100644 index 0000000000000..cfddd33f4197e --- /dev/null +++ b/x-pack/test/functional/apps/discover/value_suggestions_non_timebased.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const esArchiver = getService('esArchiver'); + const queryBar = getService('queryBar'); + const PageObjects = getPageObjects(['common', 'settings', 'context']); + + describe('value suggestions non time based', function describeIndexTests() { + before(async function () { + await esArchiver.loadIfNeeded( + 'test/functional/fixtures/es_archiver/index_pattern_without_timefield' + ); + }); + + after(async () => { + await esArchiver.unload( + 'test/functional/fixtures/es_archiver/index_pattern_without_timefield' + ); + }); + + it('shows all autosuggest options for a filter in discover context app', async () => { + await PageObjects.common.navigateToApp('discover'); + + await queryBar.setQuery('type.keyword : '); + const suggestions = await queryBar.getSuggestions(); + expect(suggestions.length).to.be(1); + expect(suggestions).to.contain('"apache"'); + }); + }); +} diff --git a/x-pack/test/functional/apps/lens/dashboard.ts b/x-pack/test/functional/apps/lens/dashboard.ts index 095b1ae7c2f0f..a2654563c546d 100644 --- a/x-pack/test/functional/apps/lens/dashboard.ts +++ b/x-pack/test/functional/apps/lens/dashboard.ts @@ -132,6 +132,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should not carry over filters if creating a new lens visualization from within dashboard', async () => { await PageObjects.common.navigateToApp('dashboard'); await PageObjects.dashboard.clickNewDashboard(); + await PageObjects.timePicker.setDefaultAbsoluteRange(); await filterBar.addFilter('geo.src', 'is', 'US'); await filterBar.toggleFilterPinned('geo.src'); await filterBar.addFilter('geo.dest', 'is', 'LS'); diff --git a/x-pack/test/functional/apps/rollup_job/hybrid_index_pattern.js b/x-pack/test/functional/apps/rollup_job/hybrid_index_pattern.js index e479c6729d8c3..4fe957dac7b6d 100644 --- a/x-pack/test/functional/apps/rollup_job/hybrid_index_pattern.js +++ b/x-pack/test/functional/apps/rollup_job/hybrid_index_pattern.js @@ -11,8 +11,9 @@ import mockRolledUpData, { mockIndices } from './hybrid_index_helper'; export default function ({ getService, getPageObjects }) { const es = getService('es'); - const esArchiver = getService('esArchiver'); const retry = getService('retry'); + const security = getService('security'); + const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects(['common', 'settings']); const esDeleteAllIndices = getService('esDeleteAllIndices'); @@ -31,6 +32,20 @@ export default function ({ getService, getPageObjects }) { datemath.parse('now-3d', { forceNow: now }), ]; + before(async () => { + // load visualize to have an index pattern ready, otherwise visualize will redirect + await security.testUser.setRoles([ + 'global_index_pattern_management_all', + 'test_rollup_reader', + ]); + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup_hybrid' + ); + await kibanaServer.uiSettings.replace({ + defaultIndex: 'rollup', + }); + }); + it('create hybrid index pattern', async () => { //Create data for rollup job to recognize. //Index past data to be used in the test. @@ -105,8 +120,9 @@ export default function ({ getService, getPageObjects }) { `${regularIndexPrefix}*`, `${rollupSourceIndexPrefix}*`, ]); - - await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'); + await kibanaServer.importExport.unload( + 'x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup_hybrid' + ); }); }); } diff --git a/x-pack/test/functional/apps/rollup_job/tsvb.js b/x-pack/test/functional/apps/rollup_job/tsvb.js index ba39a8aaa436b..3b216bfb34b9b 100644 --- a/x-pack/test/functional/apps/rollup_job/tsvb.js +++ b/x-pack/test/functional/apps/rollup_job/tsvb.js @@ -10,8 +10,9 @@ import mockRolledUpData from './hybrid_index_helper'; export default function ({ getService, getPageObjects }) { const es = getService('es'); - const esArchiver = getService('esArchiver'); const retry = getService('retry'); + const security = getService('security'); + const kibanaServer = getService('kibanaServer'); const esDeleteAllIndices = getService('esDeleteAllIndices'); const PageObjects = getPageObjects([ 'common', @@ -26,7 +27,7 @@ export default function ({ getService, getPageObjects }) { //we add the Date.now() to avoid name collision if you run the tests locally back to back. const rollupJobName = `tsvb-test-rollup-job-${Date.now()}`; const rollupSourceIndexName = 'rollup-source-data'; - const rollupTargetIndexName = `rollup-target-data`; + const rollupTargetIndexName = 'rollup-target-data'; const pastDates = [ new Date('October 15, 2019 05:35:32'), new Date('October 15, 2019 05:34:32'), @@ -35,7 +36,13 @@ export default function ({ getService, getPageObjects }) { before(async () => { // load visualize to have an index pattern ready, otherwise visualize will redirect - await esArchiver.load('x-pack/test/functional/es_archives/visualize/default'); + await security.testUser.setRoles(['global_visualize_all', 'test_rollup_reader']); + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup.json' + ); + await kibanaServer.uiSettings.replace({ + defaultIndex: 'rollup', + }); }); it('create rollup tsvb', async () => { @@ -100,7 +107,10 @@ export default function ({ getService, getPageObjects }) { }); await esDeleteAllIndices([rollupTargetIndexName, rollupSourceIndexName]); - await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'); + await kibanaServer.importExport.unload( + 'x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup.json' + ); + await security.testUser.restoreDefaults(); }); }); } diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index a79e51057c90e..06e58638922d4 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -465,6 +465,17 @@ export default async function ({ readConfigFile }) { ], }, + test_rollup_reader: { + elasticsearch: { + indices: [ + { + names: ['rollup-*'], + privileges: ['read', 'view_index_metadata'], + }, + ], + }, + }, + //Kibana feature privilege isn't specific to advancedSetting. It can be anything. https://github.com/elastic/kibana/issues/35965 test_api_keys: { elasticsearch: { diff --git a/x-pack/test/functional/es_archives/rule_registry/alerts/data.json b/x-pack/test/functional/es_archives/rule_registry/alerts/data.json index c8c01883197f5..940ebe5321b9d 100644 --- a/x-pack/test/functional/es_archives/rule_registry/alerts/data.json +++ b/x-pack/test/functional/es_archives/rule_registry/alerts/data.json @@ -82,3 +82,35 @@ } } } + +{ + "type": "doc", + "value": { + "index": ".alerts-security.alerts", + "id": "space1securityalert", + "source": { + "@timestamp": "2020-12-16T15:16:18.570Z", + "rule.id": "siem.signals", + "message": "hello world security", + "kibana.alert.owner": "siem", + "kibana.alert.status": "open", + "kibana.space_ids": ["space1"] + } + } +} + +{ + "type": "doc", + "value": { + "index": ".alerts-security.alerts", + "id": "space2securityalert", + "source": { + "@timestamp": "2020-12-16T15:16:18.570Z", + "rule.id": "siem.signals", + "message": "hello world security", + "kibana.alert.owner": "siem", + "kibana.alert.status": "open", + "kibana.space_ids": ["space2"] + } + } +} diff --git a/x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup.json b/x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup.json new file mode 100644 index 0000000000000..00596d865f03d --- /dev/null +++ b/x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup.json @@ -0,0 +1,39 @@ +{ + "attributes": { + "accessibility:disableAnimations": true, + "buildNum": 9007199254740991, + "dateFormat:tz": "UTC", + "defaultIndex": "rollup", + "visualization:visualize:legacyChartsLibrary": true, + "visualization:visualize:legacyPieChartsLibrary": true + }, + "coreMigrationVersion": "7.15.0", + "id": "7.15.0", + "migrationVersion": { + "config": "7.13.0" + }, + "references": [], + "type": "config", + "updated_at": "2021-08-04T23:35:47.992Z", + "version": "WzQwLDFd" +} + +{ + "attributes": { + "fieldAttrs": "{}", + "fields": "[]", + "runtimeFieldMap": "{}", + "timeFieldName": "@timestamp.date_histogram.timestamp", + "title": "rollup*", + "typeMeta": "{}" + }, + "coreMigrationVersion": "7.15.0", + "id": "rollup", + "migrationVersion": { + "index-pattern": "7.11.0" + }, + "references": [], + "type": "index-pattern", + "updated_at": "2021-08-04T23:22:14.902Z", + "version": "WzIyLDFd" +} \ No newline at end of file diff --git a/x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup_hybrid.json b/x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup_hybrid.json new file mode 100644 index 0000000000000..a148ac8612d2b --- /dev/null +++ b/x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup_hybrid.json @@ -0,0 +1 @@ +{"attributes":{"fieldAttrs":"{}","fields":"[]","runtimeFieldMap":"{}","timeFieldName":"@timestamp","title":"regular-index*,rollup-target-data","type":"rollup","typeMeta":"{\"params\":{\"rollup_index\":\"rollup-target-data\"},\"aggs\":{\"date_histogram\":{\"@timestamp\":{\"agg\":\"date_histogram\",\"fixed_interval\":\"1000ms\",\"time_zone\":\"UTC\"}}}}"},"coreMigrationVersion":"8.0.0","id":"b8f05720-f5b0-11eb-a2ec-8d77790684d1","migrationVersion":{"index-pattern":"7.11.0"},"references":[],"type":"index-pattern","updated_at":"2021-08-05T05:48:13.077Z","version":"WzksMl0="} diff --git a/x-pack/test/functional/services/transform/api.ts b/x-pack/test/functional/services/transform/api.ts index 78a6623a74787..484d794aac879 100644 --- a/x-pack/test/functional/services/transform/api.ts +++ b/x-pack/test/functional/services/transform/api.ts @@ -12,6 +12,9 @@ import { TransformState, TRANSFORM_STATE } from '../../../../plugins/transform/c import type { TransformStats } from '../../../../plugins/transform/common/types/transform_stats'; import { FtrProviderContext } from '../../ftr_provider_context'; +import { GetTransformsResponseSchema } from '../../../../plugins/transform/common/api_schemas/transforms'; +import { PostTransformsUpdateRequestSchema } from '../../../../plugins/transform/common/api_schemas/update_transforms'; +import { TransformPivotConfig } from '../../../../plugins/transform/common/types/transform'; export async function asyncForEach(array: any[], callback: Function) { for (let index = 0; index < array.length; index++) { @@ -174,10 +177,28 @@ export function TransformAPIProvider({ getService }: FtrProviderContext) { }); }, + async getTransformList(size: number = 10): Promise { + return (await esSupertest + .get(`/_transform`) + .expect(200) + .then((response) => response.body)) as GetTransformsResponseSchema; + }, + async getTransform(transformId: string, expectedCode = 200) { return await esSupertest.get(`/_transform/${transformId}`).expect(expectedCode); }, + async updateTransform( + transformId: string, + updates: Partial + ): Promise { + return await esSupertest + .post(`/_transform/${transformId}/_update`) + .send(updates) + .expect(200) + .then((response: { body: TransformPivotConfig }) => response.body); + }, + async createTransform(transformId: string, transformConfig: PutTransformsRequestSchema) { log.debug(`Creating transform with id '${transformId}'...`); await esSupertest.put(`/_transform/${transformId}`).send(transformConfig).expect(200); diff --git a/x-pack/test/observability_api_integration/basic/tests/annotations.ts b/x-pack/test/observability_api_integration/basic/tests/annotations.ts index 4a2c7b68f612e..6b1cdb43f5f54 100644 --- a/x-pack/test/observability_api_integration/basic/tests/annotations.ts +++ b/x-pack/test/observability_api_integration/basic/tests/annotations.ts @@ -6,7 +6,7 @@ */ import expect from '@kbn/expect'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { FtrProviderContext } from '../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/observability_api_integration/trial/tests/annotations.ts b/x-pack/test/observability_api_integration/trial/tests/annotations.ts index b1ef717ddfd88..48b16b712bf3a 100644 --- a/x-pack/test/observability_api_integration/trial/tests/annotations.ts +++ b/x-pack/test/observability_api_integration/trial/tests/annotations.ts @@ -6,7 +6,7 @@ */ import expect from '@kbn/expect'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { Annotation } from '../../../../plugins/observability/common/annotations'; import { FtrProviderContext } from '../../common/ftr_provider_context'; diff --git a/x-pack/test/performance/config.ts b/x-pack/test/performance/config.ts new file mode 100644 index 0000000000000..89b7b52e28670 --- /dev/null +++ b/x-pack/test/performance/config.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrConfigProviderContext } from '@kbn/test'; + +import { services } from './services'; +import { pageObjects } from './page_objects'; + +// These "secret" values are intentionally written in the source. We would make the APM server accept annonymous traffic if we could +const APM_SERVER_URL = 'https://2fad4006bf784bb8a54e52f4a5862609.apm.us-west1.gcp.cloud.es.io:443'; +const APM_PUBLIC_TOKEN = 'Q5q5rWQEw6tKeirBpw'; + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const functionalConfig = await readConfigFile(require.resolve('../functional/config')); + + return { + testFiles: [require.resolve('./tests/index.ts')], + services, + pageObjects, + servers: functionalConfig.get('servers'), + esTestCluster: functionalConfig.get('esTestCluster'), + apps: functionalConfig.get('apps'), + screenshots: functionalConfig.get('screenshots'), + junit: { + reportName: 'Performance Tests', + }, + kbnTestServer: { + ...functionalConfig.get('kbnTestServer'), + env: { + ELASTIC_APM_ACTIVE: 'true', + ELASTIC_APM_ENVIRONMENT: process.env.CI ? 'ci' : 'development', + ELASTIC_APM_TRANSACTION_SAMPLE_RATE: '1.0', + ELASTIC_APM_SERVER_URL: APM_SERVER_URL, + ELASTIC_APM_SECRET_TOKEN: APM_PUBLIC_TOKEN, + ELASTIC_APM_GLOBAL_LABELS: Object.entries({ + ftrConfig: `x-pack/test/performance`, + jenkinsJobName: process.env.JOB_NAME, + jenkinsBuildNumber: process.env.BUILD_NUMBER, + prId: process.env.PR_NUMBER, + branch: process.env.GIT_BRANCH, + commit: process.env.GIT_COMMIT, + mergeBase: process.env.PR_MERGE_BASE, + targetBranch: process.env.PR_TARGET_BRANCH, + }) + .filter(([, v]) => !!v) + .reduce((acc, [k, v]) => (acc ? `${acc},${k}=${v}` : `${k}=${v}`), ''), + }, + // delay shutdown by 15 seconds to ensure that APM can report the data it collects during test execution + delayShutdown: 15_000, + }, + }; +} diff --git a/x-pack/test/performance/es_archives/reporting_dashboard/data.json.gz b/x-pack/test/performance/es_archives/reporting_dashboard/data.json.gz new file mode 100644 index 0000000000000..7631d7eef2300 Binary files /dev/null and b/x-pack/test/performance/es_archives/reporting_dashboard/data.json.gz differ diff --git a/x-pack/test/performance/es_archives/reporting_dashboard/mappings.json b/x-pack/test/performance/es_archives/reporting_dashboard/mappings.json new file mode 100644 index 0000000000000..a4f39b8ab3cfa --- /dev/null +++ b/x-pack/test/performance/es_archives/reporting_dashboard/mappings.json @@ -0,0 +1,41 @@ +{ + "type": "index", + "value": { + "aliases": { + }, + "index": "foo", + "mappings": { + "properties": { + "@timestamp": { + "type": "date" + }, + "group": { + "ignore_above": 256, + "type": "keyword" + }, + "randomInt": { + "type": "integer" + }, + "geo": { + "properties": { + "country_code": { + "type": "keyword" + }, + "country_name": { + "type": "keyword" + }, + "point": { + "type": "geo_point" + } + } + } + } + }, + "settings": { + "index": { + "number_of_replicas": "1", + "number_of_shards": "1" + } + } + } +} diff --git a/x-pack/test/performance/ftr_provider_context.ts b/x-pack/test/performance/ftr_provider_context.ts new file mode 100644 index 0000000000000..e757164fa1de9 --- /dev/null +++ b/x-pack/test/performance/ftr_provider_context.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { GenericFtrProviderContext, GenericFtrService } from '@kbn/test'; + +import { pageObjects } from './page_objects'; +import { services } from './services'; + +export type FtrProviderContext = GenericFtrProviderContext; +export class FtrService extends GenericFtrService {} diff --git a/x-pack/test/performance/kbn_archives/reporting_dashboard.json b/x-pack/test/performance/kbn_archives/reporting_dashboard.json new file mode 100644 index 0000000000000..fe9edc0274da0 --- /dev/null +++ b/x-pack/test/performance/kbn_archives/reporting_dashboard.json @@ -0,0 +1,193 @@ +{ + "attributes": { + "fieldAttrs": "{}", + "fields": "[]", + "timeFieldName": "@timestamp", + "title": "foo" + }, + "coreMigrationVersion": "8.0.0", + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "migrationVersion": { + "index-pattern": "7.11.0" + }, + "references": [], + "type": "index-pattern", + "updated_at": "2021-08-03T02:30:35.243Z", + "version": "Wzg0NCwxXQ==" +} + +{ + "attributes": { + "columns": [ + "_source" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "sort": [], + "title": "search", + "version": 1 + }, + "coreMigrationVersion": "8.0.0", + "id": "0c0b1700-2dc6-11eb-8af3-cb3aa84dbabd", + "migrationVersion": { + "search": "7.9.3" + }, + "references": [ + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "search", + "updated_at": "2021-08-03T02:30:35.243Z", + "version": "Wzg0NSwxXQ==" +} + +{ + "attributes": { + "description": "", + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "c6af0915-fc1c-41b5-b195-7b05a51b0271": { + "columnOrder": [ + "0ee222c6-215d-4adc-aac0-b45469d5f9c1" + ], + "columns": { + "0ee222c6-215d-4adc-aac0-b45469d5f9c1": { + "dataType": "number", + "isBucketed": false, + "label": "Average of field", + "operationType": "average", + "scale": "ratio", + "sourceField": "field" + } + } + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "accessor": "0ee222c6-215d-4adc-aac0-b45469d5f9c1", + "layerId": "c6af0915-fc1c-41b5-b195-7b05a51b0271" + } + }, + "title": "visualization", + "visualizationType": "lnsMetric" + }, + "coreMigrationVersion": "8.0.0", + "id": "2be82220-2dc6-11eb-8af3-cb3aa84dbabd", + "migrationVersion": { + "lens": "7.14.0" + }, + "references": [ + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "indexpattern-datasource-layer-c6af0915-fc1c-41b5-b195-7b05a51b0271", + "type": "index-pattern" + } + ], + "type": "lens", + "updated_at": "2021-08-03T02:30:35.243Z", + "version": "Wzg0NiwxXQ==" +} + +{ + "attributes": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}" + }, + "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}", + "panelsJSON": "[{\"version\":\"8.0.0\",\"type\":\"lens\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"8b528b1e-a8da-4a62-a667-9524370f3f9c\"},\"panelIndex\":\"8b528b1e-a8da-4a62-a667-9524370f3f9c\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"type\":\"lens\",\"visualizationType\":\"lnsXY\",\"state\":{\"datasourceStates\":{\"indexpattern\":{\"layers\":{\"5ea9080d-1b03-49ea-8d74-b1b0ec785508\":{\"columns\":{\"d73c1d27-24c0-4b8d-b355-5f16337c271d\":{\"label\":\"Top values of group\",\"dataType\":\"string\",\"operationType\":\"terms\",\"scale\":\"ordinal\",\"sourceField\":\"group\",\"isBucketed\":true,\"params\":{\"size\":30,\"orderBy\":{\"type\":\"column\",\"columnId\":\"0bd996a2-80ff-4c62-a8a0-c2752a8ca9e3\"},\"orderDirection\":\"desc\",\"otherBucket\":true,\"missingBucket\":false}},\"b9aca667-73eb-49eb-bfe2-765e1a3bfecb\":{\"label\":\"@timestamp\",\"dataType\":\"date\",\"operationType\":\"date_histogram\",\"sourceField\":\"@timestamp\",\"isBucketed\":true,\"scale\":\"interval\",\"params\":{\"interval\":\"auto\"}},\"0bd996a2-80ff-4c62-a8a0-c2752a8ca9e3\":{\"label\":\"Count of records\",\"dataType\":\"number\",\"operationType\":\"count\",\"isBucketed\":false,\"scale\":\"ratio\",\"sourceField\":\"Records\"}},\"columnOrder\":[\"d73c1d27-24c0-4b8d-b355-5f16337c271d\",\"b9aca667-73eb-49eb-bfe2-765e1a3bfecb\",\"0bd996a2-80ff-4c62-a8a0-c2752a8ca9e3\"],\"incompleteColumns\":{}}}}},\"visualization\":{\"legend\":{\"isVisible\":true,\"position\":\"right\"},\"valueLabels\":\"hide\",\"fittingFunction\":\"None\",\"yLeftExtent\":{\"mode\":\"full\"},\"yRightExtent\":{\"mode\":\"full\"},\"axisTitlesVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"tickLabelsVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"labelsOrientation\":{\"x\":0,\"yLeft\":0,\"yRight\":0},\"gridlinesVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"preferredSeriesType\":\"line\",\"layers\":[{\"layerId\":\"5ea9080d-1b03-49ea-8d74-b1b0ec785508\",\"accessors\":[\"0bd996a2-80ff-4c62-a8a0-c2752a8ca9e3\"],\"position\":\"top\",\"seriesType\":\"line\",\"showGridlines\":false,\"xAccessor\":\"b9aca667-73eb-49eb-bfe2-765e1a3bfecb\",\"splitAccessor\":\"d73c1d27-24c0-4b8d-b355-5f16337c271d\"}]},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[]},\"references\":[{\"type\":\"index-pattern\",\"id\":\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\",\"name\":\"indexpattern-datasource-current-indexpattern\"},{\"type\":\"index-pattern\",\"id\":\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\",\"name\":\"indexpattern-datasource-layer-5ea9080d-1b03-49ea-8d74-b1b0ec785508\"}]},\"enhancements\":{}}},{\"version\":\"8.0.0\",\"type\":\"search\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"a719fa94-58cc-4023-b95d-5aec25315045\"},\"panelIndex\":\"a719fa94-58cc-4023-b95d-5aec25315045\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_a719fa94-58cc-4023-b95d-5aec25315045\"},{\"version\":\"8.0.0\",\"type\":\"lens\",\"gridData\":{\"x\":0,\"y\":15,\"w\":24,\"h\":15,\"i\":\"48e8bad8-53fa-490c-a433-3917b8844718\"},\"panelIndex\":\"48e8bad8-53fa-490c-a433-3917b8844718\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"type\":\"lens\",\"visualizationType\":\"lnsXY\",\"state\":{\"datasourceStates\":{\"indexpattern\":{\"layers\":{\"98273c17-bb3f-4411-9e39-2e244577b14d\":{\"columns\":{\"92e17bbb-9774-467c-8e1e-95fccccaa72c\":{\"label\":\"Top values of geo.country_code\",\"dataType\":\"string\",\"operationType\":\"terms\",\"scale\":\"ordinal\",\"sourceField\":\"geo.country_code\",\"isBucketed\":true,\"params\":{\"size\":3,\"orderBy\":{\"type\":\"column\",\"columnId\":\"43d2d90b-a3cd-40fe-ba98-2b384d41bde0\"},\"orderDirection\":\"desc\",\"otherBucket\":true,\"missingBucket\":false}},\"5930e809-738d-4966-9aa4-1ceab4b8fee0\":{\"label\":\"@timestamp\",\"dataType\":\"date\",\"operationType\":\"date_histogram\",\"sourceField\":\"@timestamp\",\"isBucketed\":true,\"scale\":\"interval\",\"params\":{\"interval\":\"auto\"}},\"43d2d90b-a3cd-40fe-ba98-2b384d41bde0\":{\"label\":\"Count of records\",\"dataType\":\"number\",\"operationType\":\"count\",\"isBucketed\":false,\"scale\":\"ratio\",\"sourceField\":\"Records\"},\"92986504-3b17-43cc-b6ba-71456b05cd81\":{\"label\":\"Median of randomInt\",\"dataType\":\"number\",\"operationType\":\"median\",\"sourceField\":\"randomInt\",\"isBucketed\":false,\"scale\":\"ratio\"}},\"columnOrder\":[\"92e17bbb-9774-467c-8e1e-95fccccaa72c\",\"5930e809-738d-4966-9aa4-1ceab4b8fee0\",\"43d2d90b-a3cd-40fe-ba98-2b384d41bde0\",\"92986504-3b17-43cc-b6ba-71456b05cd81\"],\"incompleteColumns\":{}}}}},\"visualization\":{\"legend\":{\"isVisible\":true,\"position\":\"right\"},\"valueLabels\":\"hide\",\"fittingFunction\":\"None\",\"yLeftExtent\":{\"mode\":\"full\"},\"yRightExtent\":{\"mode\":\"full\"},\"axisTitlesVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"tickLabelsVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"labelsOrientation\":{\"x\":0,\"yLeft\":0,\"yRight\":0},\"gridlinesVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"preferredSeriesType\":\"area_percentage_stacked\",\"layers\":[{\"layerId\":\"98273c17-bb3f-4411-9e39-2e244577b14d\",\"accessors\":[\"43d2d90b-a3cd-40fe-ba98-2b384d41bde0\",\"92986504-3b17-43cc-b6ba-71456b05cd81\"],\"position\":\"top\",\"seriesType\":\"area_percentage_stacked\",\"showGridlines\":false,\"xAccessor\":\"5930e809-738d-4966-9aa4-1ceab4b8fee0\",\"splitAccessor\":\"92e17bbb-9774-467c-8e1e-95fccccaa72c\"}]},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[]},\"references\":[{\"type\":\"index-pattern\",\"id\":\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\",\"name\":\"indexpattern-datasource-current-indexpattern\"},{\"type\":\"index-pattern\",\"id\":\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\",\"name\":\"indexpattern-datasource-layer-98273c17-bb3f-4411-9e39-2e244577b14d\"}]},\"enhancements\":{}}},{\"version\":\"8.0.0\",\"type\":\"lens\",\"gridData\":{\"x\":24,\"y\":15,\"w\":24,\"h\":15,\"i\":\"cd6222f7-9db1-49b3-bdd1-b0a7b8b580f5\"},\"panelIndex\":\"cd6222f7-9db1-49b3-bdd1-b0a7b8b580f5\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"type\":\"lens\",\"visualizationType\":\"lnsXY\",\"state\":{\"datasourceStates\":{\"indexpattern\":{\"layers\":{\"bd86ba26-72d3-4338-b962-5f69e2b7a693\":{\"columns\":{\"cfbd0aec-f3f9-4e87-99ba-686537b7f51e\":{\"label\":\"Top values of geo.country_code\",\"dataType\":\"string\",\"operationType\":\"terms\",\"scale\":\"ordinal\",\"sourceField\":\"geo.country_code\",\"isBucketed\":true,\"params\":{\"size\":200,\"orderBy\":{\"type\":\"column\",\"columnId\":\"c36080f3-db58-45ed-9193-b2a9ff05f710\"},\"orderDirection\":\"desc\",\"otherBucket\":true,\"missingBucket\":false}},\"b0af72ea-46a9-42b2-a55f-6a5614c814fa\":{\"label\":\"@timestamp\",\"dataType\":\"date\",\"operationType\":\"date_histogram\",\"sourceField\":\"@timestamp\",\"isBucketed\":true,\"scale\":\"interval\",\"params\":{\"interval\":\"auto\"}},\"c36080f3-db58-45ed-9193-b2a9ff05f710\":{\"label\":\"Count of records\",\"dataType\":\"number\",\"operationType\":\"count\",\"isBucketed\":false,\"scale\":\"ratio\",\"sourceField\":\"Records\"}},\"columnOrder\":[\"cfbd0aec-f3f9-4e87-99ba-686537b7f51e\",\"b0af72ea-46a9-42b2-a55f-6a5614c814fa\",\"c36080f3-db58-45ed-9193-b2a9ff05f710\"],\"incompleteColumns\":{}}}}},\"visualization\":{\"legend\":{\"isVisible\":true,\"position\":\"right\"},\"valueLabels\":\"hide\",\"fittingFunction\":\"None\",\"yLeftExtent\":{\"mode\":\"full\"},\"yRightExtent\":{\"mode\":\"full\"},\"axisTitlesVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"tickLabelsVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"labelsOrientation\":{\"x\":0,\"yLeft\":0,\"yRight\":0},\"gridlinesVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"preferredSeriesType\":\"bar_stacked\",\"layers\":[{\"layerId\":\"bd86ba26-72d3-4338-b962-5f69e2b7a693\",\"accessors\":[\"c36080f3-db58-45ed-9193-b2a9ff05f710\"],\"position\":\"top\",\"seriesType\":\"bar_stacked\",\"showGridlines\":false,\"xAccessor\":\"b0af72ea-46a9-42b2-a55f-6a5614c814fa\",\"splitAccessor\":\"cfbd0aec-f3f9-4e87-99ba-686537b7f51e\"}]},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[]},\"references\":[{\"type\":\"index-pattern\",\"id\":\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\",\"name\":\"indexpattern-datasource-current-indexpattern\"},{\"type\":\"index-pattern\",\"id\":\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\",\"name\":\"indexpattern-datasource-layer-bd86ba26-72d3-4338-b962-5f69e2b7a693\"}]},\"enhancements\":{}}},{\"version\":\"8.0.0\",\"type\":\"lens\",\"gridData\":{\"x\":0,\"y\":30,\"w\":24,\"h\":15,\"i\":\"2316251f-b789-4864-bca9-b2473851c221\"},\"panelIndex\":\"2316251f-b789-4864-bca9-b2473851c221\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"type\":\"lens\",\"visualizationType\":\"lnsPie\",\"state\":{\"datasourceStates\":{\"indexpattern\":{\"layers\":{\"e0fa5d77-06a7-4f87-9e71-f8727829ed78\":{\"columns\":{\"ec8d42da-bba6-46b9-b11f-4aba33f30704\":{\"label\":\"Top values of geo.country_name\",\"dataType\":\"string\",\"operationType\":\"terms\",\"scale\":\"ordinal\",\"sourceField\":\"geo.country_name\",\"isBucketed\":true,\"params\":{\"size\":500,\"orderBy\":{\"type\":\"column\",\"columnId\":\"acb7ed45-a2b8-429e-9b35-c6d7e34afbee\"},\"orderDirection\":\"desc\",\"otherBucket\":true,\"missingBucket\":false}},\"acb7ed45-a2b8-429e-9b35-c6d7e34afbee\":{\"label\":\"Count of records\",\"dataType\":\"number\",\"operationType\":\"count\",\"isBucketed\":false,\"scale\":\"ratio\",\"sourceField\":\"Records\"},\"8b6de72d-1157-4d98-8de7-6c909942826b\":{\"label\":\"Top values of group\",\"dataType\":\"string\",\"operationType\":\"terms\",\"scale\":\"ordinal\",\"sourceField\":\"group\",\"isBucketed\":true,\"params\":{\"size\":3,\"orderBy\":{\"type\":\"column\",\"columnId\":\"acb7ed45-a2b8-429e-9b35-c6d7e34afbee\"},\"orderDirection\":\"desc\",\"otherBucket\":true,\"missingBucket\":false}}},\"columnOrder\":[\"ec8d42da-bba6-46b9-b11f-4aba33f30704\",\"8b6de72d-1157-4d98-8de7-6c909942826b\",\"acb7ed45-a2b8-429e-9b35-c6d7e34afbee\"],\"incompleteColumns\":{}}}}},\"visualization\":{\"shape\":\"treemap\",\"layers\":[{\"layerId\":\"e0fa5d77-06a7-4f87-9e71-f8727829ed78\",\"groups\":[\"ec8d42da-bba6-46b9-b11f-4aba33f30704\",\"8b6de72d-1157-4d98-8de7-6c909942826b\"],\"metric\":\"acb7ed45-a2b8-429e-9b35-c6d7e34afbee\",\"numberDisplay\":\"percent\",\"categoryDisplay\":\"default\",\"legendDisplay\":\"default\",\"nestedLegend\":false}]},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[]},\"references\":[{\"type\":\"index-pattern\",\"id\":\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\",\"name\":\"indexpattern-datasource-current-indexpattern\"},{\"type\":\"index-pattern\",\"id\":\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\",\"name\":\"indexpattern-datasource-layer-e0fa5d77-06a7-4f87-9e71-f8727829ed78\"}]},\"enhancements\":{}}},{\"version\":\"8.0.0\",\"type\":\"lens\",\"gridData\":{\"x\":24,\"y\":30,\"w\":24,\"h\":15,\"i\":\"2889665f-3703-4057-96a5-9d0fe2f79dba\"},\"panelIndex\":\"2889665f-3703-4057-96a5-9d0fe2f79dba\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"type\":\"lens\",\"visualizationType\":\"lnsPie\",\"state\":{\"datasourceStates\":{\"indexpattern\":{\"layers\":{\"2405161c-3904-4b41-a1c7-4a368bd1f0c6\":{\"columns\":{\"ef810dda-cc9f-412f-a90e-cd0cf05dae91\":{\"label\":\"Top values of geo.country_code\",\"dataType\":\"string\",\"operationType\":\"terms\",\"scale\":\"ordinal\",\"sourceField\":\"geo.country_code\",\"isBucketed\":true,\"params\":{\"size\":500,\"orderBy\":{\"type\":\"column\",\"columnId\":\"38c4ec2f-4d31-48a8-8305-b9cd0ee92911\"},\"orderDirection\":\"desc\",\"otherBucket\":true,\"missingBucket\":false}},\"38c4ec2f-4d31-48a8-8305-b9cd0ee92911\":{\"label\":\"Count of records\",\"dataType\":\"number\",\"operationType\":\"count\",\"isBucketed\":false,\"scale\":\"ratio\",\"sourceField\":\"Records\"}},\"columnOrder\":[\"ef810dda-cc9f-412f-a90e-cd0cf05dae91\",\"38c4ec2f-4d31-48a8-8305-b9cd0ee92911\"],\"incompleteColumns\":{}}}}},\"visualization\":{\"shape\":\"donut\",\"layers\":[{\"layerId\":\"2405161c-3904-4b41-a1c7-4a368bd1f0c6\",\"groups\":[\"ef810dda-cc9f-412f-a90e-cd0cf05dae91\"],\"metric\":\"38c4ec2f-4d31-48a8-8305-b9cd0ee92911\",\"numberDisplay\":\"percent\",\"categoryDisplay\":\"default\",\"legendDisplay\":\"default\",\"nestedLegend\":false}]},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[]},\"references\":[{\"type\":\"index-pattern\",\"id\":\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\",\"name\":\"indexpattern-datasource-current-indexpattern\"},{\"type\":\"index-pattern\",\"id\":\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\",\"name\":\"indexpattern-datasource-layer-2405161c-3904-4b41-a1c7-4a368bd1f0c6\"}]},\"enhancements\":{}}},{\"version\":\"8.0.0\",\"type\":\"map\",\"gridData\":{\"x\":0,\"y\":45,\"w\":48,\"h\":35,\"i\":\"83c116f7-8024-446d-9562-88193ffd1a4d\"},\"panelIndex\":\"83c116f7-8024-446d-9562-88193ffd1a4d\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"description\":\"\",\"layerListJSON\":\"[{\\\"sourceDescriptor\\\":{\\\"type\\\":\\\"EMS_TMS\\\",\\\"isAutoSelect\\\":true},\\\"id\\\":\\\"1cee2790-c106-4038-9bf1-9c6b9727f609\\\",\\\"label\\\":null,\\\"minZoom\\\":0,\\\"maxZoom\\\":24,\\\"alpha\\\":1,\\\"visible\\\":true,\\\"style\\\":{\\\"type\\\":\\\"TILE\\\"},\\\"includeInFitToBounds\\\":true,\\\"type\\\":\\\"VECTOR_TILE\\\"},{\\\"sourceDescriptor\\\":{\\\"indexPatternId\\\":\\\"f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd\\\",\\\"geoField\\\":\\\"geo.point\\\",\\\"filterByMapBounds\\\":true,\\\"scalingType\\\":\\\"MVT\\\",\\\"id\\\":\\\"f0f89620-d98e-48ae-9922-120f12bbdd01\\\",\\\"type\\\":\\\"ES_SEARCH\\\",\\\"applyGlobalQuery\\\":true,\\\"applyGlobalTime\\\":true,\\\"tooltipProperties\\\":[],\\\"sortField\\\":\\\"\\\",\\\"sortOrder\\\":\\\"desc\\\",\\\"topHitsSplitField\\\":\\\"\\\",\\\"topHitsSize\\\":1},\\\"id\\\":\\\"de69c1d8-50db-495c-8c13-381e5ee4e338\\\",\\\"label\\\":null,\\\"minZoom\\\":0,\\\"maxZoom\\\":24,\\\"alpha\\\":0.75,\\\"visible\\\":true,\\\"style\\\":{\\\"type\\\":\\\"VECTOR\\\",\\\"properties\\\":{\\\"icon\\\":{\\\"type\\\":\\\"STATIC\\\",\\\"options\\\":{\\\"value\\\":\\\"marker\\\"}},\\\"fillColor\\\":{\\\"type\\\":\\\"STATIC\\\",\\\"options\\\":{\\\"color\\\":\\\"#54B399\\\"}},\\\"lineColor\\\":{\\\"type\\\":\\\"STATIC\\\",\\\"options\\\":{\\\"color\\\":\\\"#41937c\\\"}},\\\"lineWidth\\\":{\\\"type\\\":\\\"STATIC\\\",\\\"options\\\":{\\\"size\\\":1}},\\\"iconSize\\\":{\\\"type\\\":\\\"STATIC\\\",\\\"options\\\":{\\\"size\\\":6}},\\\"iconOrientation\\\":{\\\"type\\\":\\\"STATIC\\\",\\\"options\\\":{\\\"orientation\\\":0}},\\\"labelText\\\":{\\\"type\\\":\\\"STATIC\\\",\\\"options\\\":{\\\"value\\\":\\\"\\\"}},\\\"labelColor\\\":{\\\"type\\\":\\\"STATIC\\\",\\\"options\\\":{\\\"color\\\":\\\"#000000\\\"}},\\\"labelSize\\\":{\\\"type\\\":\\\"STATIC\\\",\\\"options\\\":{\\\"size\\\":14}},\\\"labelBorderColor\\\":{\\\"type\\\":\\\"STATIC\\\",\\\"options\\\":{\\\"color\\\":\\\"#FFFFFF\\\"}},\\\"symbolizeAs\\\":{\\\"options\\\":{\\\"value\\\":\\\"circle\\\"}},\\\"labelBorderSize\\\":{\\\"options\\\":{\\\"size\\\":\\\"SMALL\\\"}}},\\\"isTimeAware\\\":true},\\\"includeInFitToBounds\\\":true,\\\"type\\\":\\\"TILED_VECTOR\\\",\\\"joins\\\":[]}]\",\"mapStateJSON\":\"{\\\"zoom\\\":7.42,\\\"center\\\":{\\\"lon\\\":-1.10319,\\\"lat\\\":53.12713},\\\"timeFilters\\\":{\\\"from\\\":\\\"2021-08-03T02:19:31.649Z\\\",\\\"to\\\":\\\"2021-08-03T02:47:08.470Z\\\"},\\\"refreshConfig\\\":{\\\"isPaused\\\":false,\\\"interval\\\":10000},\\\"query\\\":{\\\"query\\\":\\\"\\\",\\\"language\\\":\\\"kuery\\\"},\\\"filters\\\":[],\\\"settings\\\":{\\\"autoFitToDataBounds\\\":false,\\\"backgroundColor\\\":\\\"#ffffff\\\",\\\"disableInteractive\\\":false,\\\"disableTooltipControl\\\":false,\\\"hideToolbarOverlay\\\":false,\\\"hideLayerControl\\\":false,\\\"hideViewControl\\\":false,\\\"initialLocation\\\":\\\"LAST_SAVED_LOCATION\\\",\\\"fixedLocation\\\":{\\\"lat\\\":0,\\\"lon\\\":0,\\\"zoom\\\":2},\\\"browserLocation\\\":{\\\"zoom\\\":2},\\\"maxZoom\\\":24,\\\"minZoom\\\":0,\\\"showScaleControl\\\":false,\\\"showSpatialFilters\\\":true,\\\"showTimesliderToggleButton\\\":true,\\\"spatialFiltersAlpa\\\":0.3,\\\"spatialFiltersFillColor\\\":\\\"#DA8B45\\\",\\\"spatialFiltersLineColor\\\":\\\"#DA8B45\\\"}}\",\"uiStateJSON\":\"{\\\"isLayerTOCOpen\\\":true,\\\"openTOCDetails\\\":[]}\"},\"mapCenter\":{\"lat\":53.12713,\"lon\":-1.10319,\"zoom\":7.42},\"mapBuffer\":{\"minLon\":-4.21875,\"minLat\":52.48278,\"maxLon\":2.8125,\"maxLat\":54.16243},\"isLayerTOCOpen\":true,\"openTOCDetails\":[],\"hiddenLayers\":[],\"enhancements\":{}}}]", + "timeRestore": false, + "title": "dashboard", + "version": 1 + }, + "coreMigrationVersion": "8.0.0", + "id": "37b49c50-2dc6-11eb-8af3-cb3aa84dbabd", + "migrationVersion": { + "dashboard": "7.14.0" + }, + "references": [ + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "8b528b1e-a8da-4a62-a667-9524370f3f9c:indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "8b528b1e-a8da-4a62-a667-9524370f3f9c:indexpattern-datasource-layer-5ea9080d-1b03-49ea-8d74-b1b0ec785508", + "type": "index-pattern" + }, + { + "id": "0c0b1700-2dc6-11eb-8af3-cb3aa84dbabd", + "name": "a719fa94-58cc-4023-b95d-5aec25315045:panel_a719fa94-58cc-4023-b95d-5aec25315045", + "type": "search" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "48e8bad8-53fa-490c-a433-3917b8844718:indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "48e8bad8-53fa-490c-a433-3917b8844718:indexpattern-datasource-layer-98273c17-bb3f-4411-9e39-2e244577b14d", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "cd6222f7-9db1-49b3-bdd1-b0a7b8b580f5:indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "cd6222f7-9db1-49b3-bdd1-b0a7b8b580f5:indexpattern-datasource-layer-bd86ba26-72d3-4338-b962-5f69e2b7a693", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "2316251f-b789-4864-bca9-b2473851c221:indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "2316251f-b789-4864-bca9-b2473851c221:indexpattern-datasource-layer-e0fa5d77-06a7-4f87-9e71-f8727829ed78", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "2889665f-3703-4057-96a5-9d0fe2f79dba:indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "2889665f-3703-4057-96a5-9d0fe2f79dba:indexpattern-datasource-layer-2405161c-3904-4b41-a1c7-4a368bd1f0c6", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "83c116f7-8024-446d-9562-88193ffd1a4d:layer_1_source_index_pattern", + "type": "index-pattern" + } + ], + "type": "dashboard", + "updated_at": "2021-08-03T02:37:36.415Z", + "version": "WzExNjAsMV0=" +} \ No newline at end of file diff --git a/x-pack/test/performance/page_objects.ts b/x-pack/test/performance/page_objects.ts new file mode 100644 index 0000000000000..4744980b82592 --- /dev/null +++ b/x-pack/test/performance/page_objects.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from '../functional/page_objects'; diff --git a/x-pack/test/performance/services.ts b/x-pack/test/performance/services.ts new file mode 100644 index 0000000000000..ecaac6362761d --- /dev/null +++ b/x-pack/test/performance/services.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from '../functional/services'; diff --git a/x-pack/test/performance/tests/index.ts b/x-pack/test/performance/tests/index.ts new file mode 100644 index 0000000000000..b1023bde688e2 --- /dev/null +++ b/x-pack/test/performance/tests/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('performance', function () { + this.tags('ciGroup8'); + + loadTestFile(require.resolve('./reporting_dashboard')); + }); +} diff --git a/x-pack/test/performance/tests/reporting_dashboard.ts b/x-pack/test/performance/tests/reporting_dashboard.ts new file mode 100644 index 0000000000000..f363f8449df96 --- /dev/null +++ b/x-pack/test/performance/tests/reporting_dashboard.ts @@ -0,0 +1,53 @@ +/* + * 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 { FtrProviderContext } from '../ftr_provider_context'; + +export default function ({ getService, getPageObject }: FtrProviderContext) { + const retry = getService('retry'); + const es = getService('es'); + const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); + const common = getPageObject('common'); + const dashboard = getPageObject('dashboard'); + const reporting = getPageObject('reporting'); + + describe('reporting dashbaord', () => { + before(async () => { + await kibanaServer.importExport.load( + 'x-pack/test/performance/kbn_archives/reporting_dashboard' + ); + await esArchiver.loadIfNeeded('x-pack/test/performance/es_archives/reporting_dashboard'); + }); + + after(async () => { + await kibanaServer.importExport.unload( + 'x-pack/test/performance/kbn_archives/reporting_dashboard' + ); + await esArchiver.unload('x-pack/test/performance/es_archives/reporting_dashboard'); + await es.deleteByQuery({ + index: '.reporting-*', + refresh: true, + body: { query: { match_all: {} } }, + }); + }); + + it('downloaded PDF has OK status', async function () { + this.timeout(180000); + + await common.navigateToApp('dashboards'); + await retry.waitFor('dashboard landing page', async () => { + return await dashboard.onDashboardLandingPage(); + }); + await dashboard.loadSavedDashboard('dashboard'); + await reporting.openPdfReportingPanel(); + await reporting.clickGenerateReportButton(); + + await reporting.getReportURL(60000); + }); + }); +} diff --git a/x-pack/test/rule_registry/security_and_spaces/roles_users_utils/index.ts b/x-pack/test/rule_registry/security_and_spaces/roles_users_utils/index.ts index b320446cbe05f..5601f74f94227 100644 --- a/x-pack/test/rule_registry/security_and_spaces/roles_users_utils/index.ts +++ b/x-pack/test/rule_registry/security_and_spaces/roles_users_utils/index.ts @@ -5,120 +5,4 @@ * 2.0. */ -import { assertUnreachable } from '../../../../plugins/security_solution/common/utility_types'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { - t1AnalystUser, - t2AnalystUser, - hunterUser, - ruleAuthorUser, - socManagerUser, - platformEngineerUser, - detectionsAdminUser, - readerUser, - t1AnalystRole, - t2AnalystRole, - hunterRole, - ruleAuthorRole, - socManagerRole, - platformEngineerRole, - detectionsAdminRole, - readerRole, -} from '../../../../plugins/security_solution/server/lib/detection_engine/scripts/roles_users'; - -import { ROLES } from '../../../../plugins/security_solution/common/test'; - -export const createUserAndRole = async ( - getService: FtrProviderContext['getService'], - role: ROLES -): Promise => { - switch (role) { - case ROLES.detections_admin: - return postRoleAndUser( - ROLES.detections_admin, - detectionsAdminRole, - detectionsAdminUser, - getService - ); - case ROLES.t1_analyst: - return postRoleAndUser(ROLES.t1_analyst, t1AnalystRole, t1AnalystUser, getService); - case ROLES.t2_analyst: - return postRoleAndUser(ROLES.t2_analyst, t2AnalystRole, t2AnalystUser, getService); - case ROLES.hunter: - return postRoleAndUser(ROLES.hunter, hunterRole, hunterUser, getService); - case ROLES.rule_author: - return postRoleAndUser(ROLES.rule_author, ruleAuthorRole, ruleAuthorUser, getService); - case ROLES.soc_manager: - return postRoleAndUser(ROLES.soc_manager, socManagerRole, socManagerUser, getService); - case ROLES.platform_engineer: - return postRoleAndUser( - ROLES.platform_engineer, - platformEngineerRole, - platformEngineerUser, - getService - ); - case ROLES.reader: - return postRoleAndUser(ROLES.reader, readerRole, readerUser, getService); - default: - return assertUnreachable(role); - } -}; - -/** - * Given a roleName and security service this will delete the roleName - * and user - * @param roleName The user and role to delete with the same name - * @param securityService The security service - */ -export const deleteUserAndRole = async ( - getService: FtrProviderContext['getService'], - roleName: ROLES -): Promise => { - const securityService = getService('security'); - await securityService.user.delete(roleName); - await securityService.role.delete(roleName); -}; - -interface UserInterface { - password: string; - roles: string[]; - full_name: string; - email: string; -} - -interface RoleInterface { - elasticsearch: { - cluster: string[]; - indices: Array<{ - names: string[]; - privileges: string[]; - }>; - }; - kibana: Array<{ - feature: { - ml: string[]; - siem: string[]; - actions: string[]; - builtInAlerts: string[]; - }; - spaces: string[]; - }>; -} - -export const postRoleAndUser = async ( - roleName: string, - role: RoleInterface, - user: UserInterface, - getService: FtrProviderContext['getService'] -): Promise => { - const securityService = getService('security'); - await securityService.role.create(roleName, { - kibana: role.kibana, - elasticsearch: role.elasticsearch, - }); - await securityService.user.create(roleName, { - password: 'changeme', - full_name: user.full_name, - roles: user.roles, - }); -}; +export * from '../../../common/services/security_solution/roles_users_utils'; diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/bulk_update_alerts.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/bulk_update_alerts.ts new file mode 100644 index 0000000000000..aa8eb6bc8fcaa --- /dev/null +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/bulk_update_alerts.ts @@ -0,0 +1,225 @@ +/* + * 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 expect from '@kbn/expect'; + +import { + superUser, + globalRead, + obsOnly, + obsOnlyRead, + obsSec, + obsSecRead, + secOnly, + secOnlyRead, + secOnlySpace2, + secOnlyReadSpace2, + obsSecAllSpace2, + obsSecReadSpace2, + obsOnlySpace2, + obsOnlyReadSpace2, + obsOnlySpacesAll, + obsSecSpacesAll, + secOnlySpacesAll, + noKibanaPrivileges, +} from '../../../common/lib/authentication/users'; +import type { User } from '../../../common/lib/authentication/types'; +import { FtrProviderContext } from '../../../common/ftr_provider_context'; +import { getSpaceUrlPrefix } from '../../../common/lib/authentication/spaces'; + +interface TestCase { + /** The space where the alert exists */ + space: string; + /** The ID of the alert */ + alertId: string; + /** The index of the alert */ + index: string; + /** Authorized users */ + authorizedUsers: User[]; + /** Unauthorized users */ + unauthorizedUsers: User[]; +} + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + + const TEST_URL = '/internal/rac/alerts'; + const ALERTS_INDEX_URL = `${TEST_URL}/index`; + const SPACE1 = 'space1'; + const SPACE2 = 'space2'; + const APM_ALERT_ID = 'NoxgpHkBqbdrfX07MqXV'; + const APM_ALERT_INDEX = '.alerts-observability-apm'; + const SECURITY_SOLUTION_ALERT_ID = '020202'; + const SECURITY_SOLUTION_ALERT_INDEX = '.alerts-security.alerts'; + // const ALERT_VERSION = Buffer.from(JSON.stringify([0, 1]), 'utf8').toString('base64'); // required for optimistic concurrency control + + const getAPMIndexName = async (user: User) => { + const { + body: indexNames, + }: { body: { index_name: string[] | undefined } } = await supertestWithoutAuth + .get(`${getSpaceUrlPrefix(SPACE1)}${ALERTS_INDEX_URL}`) + .auth(user.username, user.password) + .set('kbn-xsrf', 'true') + .expect(200); + const observabilityIndex = indexNames?.index_name?.find( + (indexName) => indexName === APM_ALERT_INDEX + ); + expect(observabilityIndex).to.eql(APM_ALERT_INDEX); // assert this here so we can use constants in the dynamically-defined test cases below + }; + + const getSecuritySolutionIndexName = async (user: User) => { + const { + body: indexNames, + }: { body: { index_name: string[] | undefined } } = await supertestWithoutAuth + .get(`${getSpaceUrlPrefix(SPACE1)}${ALERTS_INDEX_URL}`) + .auth(user.username, user.password) + .set('kbn-xsrf', 'true') + .expect(200); + const securitySolution = indexNames?.index_name?.find( + (indexName) => indexName === SECURITY_SOLUTION_ALERT_INDEX + ); + expect(securitySolution).to.eql(SECURITY_SOLUTION_ALERT_INDEX); // assert this here so we can use constants in the dynamically-defined test cases below + }; + + describe('Alert - Bulk Update - RBAC - spaces', () => { + before(async () => { + await getSecuritySolutionIndexName(superUser); + await getAPMIndexName(superUser); + }); + + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/rule_registry/alerts'); + }); + + function addTests({ space, authorizedUsers, unauthorizedUsers, alertId, index }: TestCase) { + authorizedUsers.forEach(({ username, password }) => { + it(`${username} should bulk update alert with given id ${alertId} in ${space}/${index}`, async () => { + await esArchiver.load('x-pack/test/functional/es_archives/rule_registry/alerts'); // since this is a success case, reload the test data immediately beforehand + const { body: updated } = await supertestWithoutAuth + .post(`${getSpaceUrlPrefix(space)}${TEST_URL}/bulk_update`) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send({ + ids: [alertId], + status: 'closed', + index, + }); + expect(updated.statusCode).to.eql(200); + const items = updated.body.items; + // @ts-expect-error + items.map((item) => expect(item.update.result).to.eql('updated')); + }); + + it(`${username} should bulk update alerts which match query in ${space}/${index}`, async () => { + const { body: updated } = await supertestWithoutAuth + .post(`${getSpaceUrlPrefix(space)}${TEST_URL}/bulk_update`) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send({ + status: 'closed', + query: 'kibana.alert.status: open', + index, + }); + expect(updated.statusCode).to.eql(200); + expect(updated.body.updated).to.greaterThan(0); + }); + }); + + unauthorizedUsers.forEach(({ username, password }) => { + it(`${username} should NOT be able to update alert ${alertId} in ${space}/${index}`, async () => { + const res = await supertestWithoutAuth + .post(`${getSpaceUrlPrefix(space)}${TEST_URL}/bulk_update`) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send({ + ids: [alertId], + status: 'closed', + index, + }); + expect([403, 404]).to.contain(res.statusCode); + }); + }); + } + + // Alert - Update - RBAC - spaces Security Solution superuser should bulk update alerts which match query in space1/.alerts-security.alerts + // Alert - Update - RBAC - spaces superuser should bulk update alert with given id 020202 in space1/.alerts-security.alerts + describe('Security Solution', () => { + const authorizedInAllSpaces = [superUser, secOnlySpacesAll, obsSecSpacesAll]; + const authorizedOnlyInSpace1 = [secOnly, obsSec]; + const authorizedOnlyInSpace2 = [secOnlySpace2, obsSecAllSpace2]; + const unauthorized = [ + // these users are not authorized to update alerts for the Security Solution in any space + globalRead, + secOnlyRead, + obsSecRead, + secOnlyReadSpace2, + obsSecReadSpace2, + obsOnly, + obsOnlyRead, + obsOnlySpace2, + obsOnlyReadSpace2, + obsOnlySpacesAll, + noKibanaPrivileges, + ]; + + addTests({ + space: SPACE1, + alertId: SECURITY_SOLUTION_ALERT_ID, + index: SECURITY_SOLUTION_ALERT_INDEX, + authorizedUsers: [...authorizedInAllSpaces, ...authorizedOnlyInSpace1], + unauthorizedUsers: [...authorizedOnlyInSpace2, ...unauthorized], + }); + addTests({ + space: SPACE2, + alertId: SECURITY_SOLUTION_ALERT_ID, + index: SECURITY_SOLUTION_ALERT_INDEX, + authorizedUsers: [...authorizedInAllSpaces, ...authorizedOnlyInSpace2], + unauthorizedUsers: [...authorizedOnlyInSpace1, ...unauthorized], + }); + }); + + describe('APM', () => { + const authorizedInAllSpaces = [superUser, obsOnlySpacesAll, obsSecSpacesAll]; + const authorizedOnlyInSpace1 = [obsOnly, obsSec]; + const authorizedOnlyInSpace2 = [obsOnlySpace2, obsSecAllSpace2]; + const unauthorized = [ + // these users are not authorized to update alerts for APM in any space + globalRead, + obsOnlyRead, + obsSecRead, + obsOnlyReadSpace2, + obsSecReadSpace2, + secOnly, + secOnlyRead, + secOnlySpace2, + secOnlyReadSpace2, + secOnlySpacesAll, + noKibanaPrivileges, + ]; + + addTests({ + space: SPACE1, + alertId: APM_ALERT_ID, + index: APM_ALERT_INDEX, + authorizedUsers: [...authorizedInAllSpaces, ...authorizedOnlyInSpace1], + unauthorizedUsers: [...authorizedOnlyInSpace2, ...unauthorized], + }); + addTests({ + space: SPACE2, + alertId: APM_ALERT_ID, + index: APM_ALERT_INDEX, + authorizedUsers: [...authorizedInAllSpaces, ...authorizedOnlyInSpace2], + unauthorizedUsers: [...authorizedOnlyInSpace1, ...unauthorized], + }); + }); + }); +}; diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alert_by_id.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alert_by_id.ts index 05b55128fab36..15729f83ebcf1 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alert_by_id.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_alert_by_id.ts @@ -152,11 +152,11 @@ export default ({ getService }: FtrProviderContext) => { unauthorizedUsers.forEach(({ username, password }) => { it(`${username} should NOT be able to access alert ${alertId} in ${space}/${index}`, async () => { - await supertestWithoutAuth + const res = await supertestWithoutAuth .get(`${getSpaceUrlPrefix(space)}${TEST_URL}?id=${alertId}&index=${index}`) .auth(username, password) - .set('kbn-xsrf', 'true') - .expect(403); + .set('kbn-xsrf', 'true'); + expect([403, 404]).to.contain(res.statusCode); }); }); } diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/index.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/index.ts index baea62c157218..26bd5b72771d7 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/index.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/index.ts @@ -25,5 +25,6 @@ export default ({ loadTestFile, getService }: FtrProviderContext): void => { // Basic loadTestFile(require.resolve('./get_alert_by_id')); loadTestFile(require.resolve('./update_alert')); + loadTestFile(require.resolve('./bulk_update_alerts')); }); }; diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/update_alert.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/update_alert.ts index 4fb087e813768..917cb31869bcc 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/update_alert.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/update_alert.ts @@ -145,25 +145,11 @@ export default ({ getService }: FtrProviderContext) => { }) .expect(404); }); - - it(`${username} should return a 404 when superuser accesses not-existent alerts as data index`, async () => { - await supertestWithoutAuth - .get(`${getSpaceUrlPrefix(space)}${TEST_URL}?id=${APM_ALERT_ID}&index=myfakeindex`) - .auth(username, password) - .set('kbn-xsrf', 'true') - .send({ - ids: [APM_ALERT_ID], - status: 'closed', - index: 'this index does not exist', - _version: ALERT_VERSION, - }) - .expect(404); - }); }); unauthorizedUsers.forEach(({ username, password }) => { it(`${username} should NOT be able to update alert ${alertId} in ${space}/${index}`, async () => { - await supertestWithoutAuth + const res = await supertestWithoutAuth .post(`${getSpaceUrlPrefix(space)}${TEST_URL}`) .auth(username, password) .set('kbn-xsrf', 'true') @@ -172,8 +158,8 @@ export default ({ getService }: FtrProviderContext) => { status: 'closed', index, _version: ALERT_VERSION, - }) - .expect(403); + }); + expect([403, 404]).to.contain(res.statusCode); }); }); } diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/trial/get_alerts.ts b/x-pack/test/rule_registry/security_and_spaces/tests/trial/get_alerts.ts index a38f6cf3263b1..56c2ba94c5ad3 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/trial/get_alerts.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/trial/get_alerts.ts @@ -73,7 +73,7 @@ export default ({ getService }: FtrProviderContext) => { .get(`${getSpaceUrlPrefix(SPACE1)}${TEST_URL}?id=NoxgpHkBqbdrfX07MqXV&index=${apmIndex}`) .auth(obsMinRead.username, obsMinRead.password) .set('kbn-xsrf', 'true') - .expect(403); + .expect(404); }); it(`${obsMinReadSpacesAll.username} should NOT be able to access the APM alert in ${SPACE1}`, async () => { @@ -82,7 +82,7 @@ export default ({ getService }: FtrProviderContext) => { .get(`${getSpaceUrlPrefix(SPACE1)}${TEST_URL}?id=NoxgpHkBqbdrfX07MqXV&index=${apmIndex}`) .auth(obsMinReadSpacesAll.username, obsMinReadSpacesAll.password) .set('kbn-xsrf', 'true') - .expect(403); + .expect(404); }); }); diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/trial/update_alert.ts b/x-pack/test/rule_registry/security_and_spaces/tests/trial/update_alert.ts index 14d903c7ac556..0442e25fcf20c 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/trial/update_alert.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/trial/update_alert.ts @@ -166,7 +166,7 @@ export default ({ getService }: FtrProviderContext) => { index: apmIndex, _version: Buffer.from(JSON.stringify([0, 1]), 'utf8').toString('base64'), }) - .expect(403); + .expect(404); }); it(`${obsMinAllSpacesAll.username} should NOT be able to update the APM alert in ${SPACE1}`, async () => { @@ -181,7 +181,7 @@ export default ({ getService }: FtrProviderContext) => { index: apmIndex, _version: Buffer.from(JSON.stringify([0, 1]), 'utf8').toString('base64'), }) - .expect(403); + .expect(404); }); }); }); diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_permissions.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_permissions.ts new file mode 100644 index 0000000000000..9a887ced424bd --- /dev/null +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_permissions.ts @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { + createUserAndRole, + deleteUserAndRole, + ROLES, +} from '../../../common/services/security_solution'; +import { IndexedHostsAndAlertsResponse } from '../../../../plugins/security_solution/common/endpoint/index_data'; + +export default ({ getPageObjects, getService }: FtrProviderContext) => { + const PageObjects = getPageObjects(['security', 'endpoint', 'detections', 'hosts']); + const testSubjects = getService('testSubjects'); + const endpointTestResources = getService('endpointTestResources'); + const policyTestResources = getService('policyTestResources'); + + describe('Endpoint permissions:', () => { + let indexedData: IndexedHostsAndAlertsResponse; + + before(async () => { + // todo: way to force an endpoint to be created in isolated mode so we can check that state in the UI + const endpointPackage = await policyTestResources.getEndpointPackage(); + await endpointTestResources.setMetadataTransformFrequency('1s', endpointPackage.version); + indexedData = await endpointTestResources.loadEndpointData(); + + // Force a logout so that we start from the login page + await PageObjects.security.forceLogout(); + }); + + after(async () => { + await endpointTestResources.unloadEndpointData(indexedData); + }); + + // Run the same set of tests against all of the Security Solution roles + for (const role of Object.keys(ROLES) as Array) { + describe(`when running with user/role [${role}]`, () => { + before(async () => { + // create role/user + await createUserAndRole(getService, ROLES[role]); + + // log back in with new uer + await PageObjects.security.login(role, 'changeme'); + }); + + after(async () => { + // Log the user back out + await PageObjects.security.forceLogout(); + + // delete role/user + await deleteUserAndRole(getService, ROLES[role]); + }); + + it('should NOT allow access to endpoint management pages', async () => { + await PageObjects.endpoint.navigateToEndpointList(); + await testSubjects.existOrFail('noIngestPermissions'); + }); + + it('should display endpoint data on Host Details', async () => { + const endpoint = indexedData.hosts[0]; + await PageObjects.hosts.navigateToHostDetails(endpoint.host.name); + const endpointSummary = await PageObjects.hosts.hostDetailsEndpointOverviewData(); + + expect(endpointSummary['Endpoint integration policy']).to.be( + endpoint.Endpoint.policy.applied.name + ); + expect(endpointSummary['Endpoint version']).to.be(endpoint.agent.version); + + // The values for these are calculated, so let's just make sure its not teh default when no data is returned + expect(endpointSummary['Policy status']).not.be('—'); + expect(endpointSummary['Agent status']).not.to.be('—'); + }); + + // FIXME: this area (detections) is unstable and due to time, skipping it. + // The page does not always (its intermittent) display with the created roles. Sometimes you get a + // "not enought priviliges" and others the data shows up. + it.skip('should display endpoint data on Alert Details', async () => { + await PageObjects.detections.navigateToAlerts(); + await PageObjects.detections.openFirstAlertDetailsForHostName( + indexedData.hosts[0].host.name + ); + + const hostAgentStatus = await testSubjects.getVisibleText('rowHostStatus'); + + expect(hostAgentStatus).to.eql('Healthy'); + }); + }); + } + }); +}; diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts index 1e736c1b00a70..70d60ba5c1b67 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts @@ -18,6 +18,7 @@ export default function (providerContext: FtrProviderContext) { describe('endpoint', function () { const ingestManager = getService('ingestManager'); const log = getService('log'); + const endpointTestResources = getService('endpointTestResources'); if (!isRegistryEnabled()) { log.warning('These tests are being run with an external package registry'); @@ -27,12 +28,17 @@ export default function (providerContext: FtrProviderContext) { log.info(`Package registry URL for tests: ${registryUrl}`); before(async () => { + log.info('calling Fleet setup'); await ingestManager.setup(); + + log.info('installing/upgrading Endpoint fleet package'); + await endpointTestResources.installOrUpgradeEndpointFleetPackage(); }); loadTestFile(require.resolve('./endpoint_list')); loadTestFile(require.resolve('./policy_details')); loadTestFile(require.resolve('./endpoint_telemetry')); loadTestFile(require.resolve('./trusted_apps_list')); loadTestFile(require.resolve('./fleet_integrations')); + loadTestFile(require.resolve('./endpoint_permissions')); }); } diff --git a/x-pack/test/security_solution_endpoint/page_objects/index.ts b/x-pack/test/security_solution_endpoint/page_objects/index.ts index 961e5ae44716d..7d32ba7b71e26 100644 --- a/x-pack/test/security_solution_endpoint/page_objects/index.ts +++ b/x-pack/test/security_solution_endpoint/page_objects/index.ts @@ -12,6 +12,8 @@ import { TrustedAppsPageProvider } from './trusted_apps_page'; import { EndpointPageUtils } from './page_utils'; import { IngestManagerCreatePackagePolicy } from './ingest_manager_create_package_policy_page'; import { FleetIntegrations } from './fleet_integrations_page'; +import { DetectionsPageObject } from '../../security_solution_ftr/page_objects/detections'; +import { HostsPageObject } from '../../security_solution_ftr/page_objects/hosts'; export const pageObjects = { ...xpackFunctionalPageObjects, @@ -21,4 +23,6 @@ export const pageObjects = { endpointPageUtils: EndpointPageUtils, ingestManagerCreatePackagePolicy: IngestManagerCreatePackagePolicy, fleetIntegrations: FleetIntegrations, + detections: DetectionsPageObject, + hosts: HostsPageObject, }; diff --git a/x-pack/test/security_solution_endpoint/services/endpoint.ts b/x-pack/test/security_solution_endpoint/services/endpoint.ts new file mode 100644 index 0000000000000..ae9e714315289 --- /dev/null +++ b/x-pack/test/security_solution_endpoint/services/endpoint.ts @@ -0,0 +1,195 @@ +/* + * 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 { ResponseError } from '@elastic/elasticsearch/lib/errors'; +import { Client } from '@elastic/elasticsearch'; +import { FtrService } from '../../functional/ftr_provider_context'; +import { + metadataCurrentIndexPattern, + metadataTransformPrefix, +} from '../../../plugins/security_solution/common/endpoint/constants'; +import { EndpointError } from '../../../plugins/security_solution/server'; +import { + deleteIndexedHostsAndAlerts, + IndexedHostsAndAlertsResponse, + indexHostsAndAlerts, +} from '../../../plugins/security_solution/common/endpoint/index_data'; +import { TransformPivotConfig } from '../../../plugins/transform/common/types/transform'; +import { GetTransformsResponseSchema } from '../../../plugins/transform/common/api_schemas/transforms'; +import { catchAndWrapError } from '../../../plugins/security_solution/server/endpoint/utils'; +import { installOrUpgradeEndpointFleetPackage } from '../../../plugins/security_solution/common/endpoint/data_loaders/setup_fleet_for_endpoint'; + +export class EndpointTestResources extends FtrService { + private readonly esClient = this.ctx.getService('es'); + private readonly retry = this.ctx.getService('retry'); + private readonly kbnClient = this.ctx.getService('kibanaServer'); + private readonly transform = this.ctx.getService('transform'); + + private generateTransformId(endpointPackageVersion?: string): string { + return `${metadataTransformPrefix}-${endpointPackageVersion ?? ''}`; + } + + /** + * Fetches the information for the endpoint transform + * + * @param [endpointPackageVersion] if set, it will be used to get the specific transform this this package version. Else just returns first one found + */ + async getTransform(endpointPackageVersion?: string): Promise { + const transformId = this.generateTransformId(endpointPackageVersion); + let transform: TransformPivotConfig | undefined; + + if (endpointPackageVersion) { + await this.transform.api.waitForTransformToExist(transformId); + + transform = (( + await this.transform.api + .getTransform(transformId) + .catch(catchAndWrapError) + .then((response: { body: GetTransformsResponseSchema }) => response) + ).body as GetTransformsResponseSchema).transforms[0]; + } else { + transform = ( + await this.transform.api.getTransformList(100).catch(catchAndWrapError) + ).transforms.find((t) => t.id.startsWith(transformId)); + } + + if (!transform) { + throw new EndpointError('Endpoint metadata transform not found'); + } + + return transform; + } + + async setMetadataTransformFrequency( + frequency: string, + /** Used to update the transform installed with the given package version */ + endpointPackageVersion?: string + ): Promise { + const transform = await this.getTransform(endpointPackageVersion).catch(catchAndWrapError); + await this.transform.api.updateTransform(transform.id, { frequency }).catch(catchAndWrapError); + } + + /** + * Loads endpoint host/alert/event data into elasticsearch + * @param [options] + * @param [options.numHosts=1] Number of Endpoint Hosts to be loaded + * @param [options.numHostDocs=1] Number of Document to be loaded per Endpoint Host (Endpoint hosts index uses a append-only index) + * @param [options.alertsPerHost=1] Number of Alerts and Events to be loaded per Endpoint Host + * @param [options.enableFleetIntegration=true] When set to `true`, Fleet data will also be loaded (ex. Integration Policies, Agent Policies, "fake" Agents) + * @param [options.generatorSeed='seed`] The seed to be used by the data generator. Important in order to ensure the same data is generated on very run. + * @param [options.waitUntilTransformed=true] If set to `true`, the data loading process will wait until the endpoint hosts metadata is processd by the transform + */ + async loadEndpointData( + options: Partial<{ + numHosts: number; + numHostDocs: number; + alertsPerHost: number; + enableFleetIntegration: boolean; + generatorSeed: string; + waitUntilTransformed: boolean; + }> = {} + ): Promise { + const { + numHosts = 1, + numHostDocs = 1, + alertsPerHost = 1, + enableFleetIntegration = true, + generatorSeed = 'seed', + waitUntilTransformed = true, + } = options; + + // load data into the system + const indexedData = await indexHostsAndAlerts( + this.esClient as Client, + this.kbnClient, + generatorSeed, + numHosts, + numHostDocs, + 'metrics-endpoint.metadata-default', + 'metrics-endpoint.policy-default', + 'logs-endpoint.events.process-default', + 'logs-endpoint.alerts-default', + alertsPerHost, + enableFleetIntegration + ); + + if (waitUntilTransformed) { + await this.waitForEndpoints(indexedData.hosts.map((host) => host.agent.id)); + } + + return indexedData; + } + + /** + * Deletes the loaded data created via `loadEndpointData()` + * @param indexedData + */ + async unloadEndpointData(indexedData: IndexedHostsAndAlertsResponse) { + return deleteIndexedHostsAndAlerts(this.esClient as Client, this.kbnClient, indexedData); + } + + /** + * Waits for endpoints to show up on the `metadata-current` index. + * Optionally, specific endpoint IDs (agent.id) can be provided to ensure those specific ones show up. + * + * @param [ids] optional list of ids to check for. If empty, it will just check if data exists in the index + */ + async waitForEndpoints(ids: string[] = []) { + const body = ids.length + ? { + query: { + bool: { + filter: [ + { + terms: { + 'agent.id': ids, + }, + }, + ], + }, + }, + } + : { + query: { + match_all: {}, + }, + }; + + // If we have a specific number of endpoint hosts to check for, then use that number, + // else we just want to make sure the index has data, thus just having one in the index will do + const size = ids.length || 1; + + await this.retry.waitFor('wait for endpoints hosts', async () => { + try { + const searchResponse = await this.esClient.search({ + index: metadataCurrentIndexPattern, + size, + body, + rest_total_hits_as_int: true, + }); + + return searchResponse.body.hits.total === size; + } catch (error) { + // We ignore 404's (index might not exist) + if (error instanceof ResponseError && error.statusCode === 404) { + return false; + } + + // Wrap the ES error so that we get a good stack trace + throw new EndpointError(error.message, error); + } + }); + } + + /** + * installs (or upgrades) the Endpoint Fleet package + * (NOTE: ensure that fleet is setup first before calling this function) + */ + async installOrUpgradeEndpointFleetPackage(): Promise { + return installOrUpgradeEndpointFleetPackage(this.kbnClient); + } +} diff --git a/x-pack/test/security_solution_endpoint/services/endpoint_policy.ts b/x-pack/test/security_solution_endpoint/services/endpoint_policy.ts index 2b7702b399f17..22c3af10af367 100644 --- a/x-pack/test/security_solution_endpoint/services/endpoint_policy.ts +++ b/x-pack/test/security_solution_endpoint/services/endpoint_policy.ts @@ -23,6 +23,7 @@ import { Immutable } from '../../../plugins/security_solution/common/endpoint/ty // NOTE: import path below should be the deep path to the actual module - else we get CI errors import { pkgKeyFromPackageInfo } from '../../../plugins/fleet/public/services/pkg_key_from_package_info'; +import { EndpointError } from '../../../plugins/security_solution/server'; const INGEST_API_ROOT = '/api/fleet'; const INGEST_API_AGENT_POLICIES = `${INGEST_API_ROOT}/agent_policies`; @@ -119,6 +120,19 @@ export function EndpointPolicyTestResourcesProvider({ getService }: FtrProviderC return pkgKeyFromPackageInfo((await retrieveEndpointPackageInfo())!); }, + /** + * Retrieves the currently installed endpoint package + */ + async getEndpointPackage(): Promise> { + const endpointPackage = await retrieveEndpointPackageInfo(); + + if (!endpointPackage) { + throw new EndpointError(`endpoint package not instealled`); + } + + return endpointPackage; + }, + /** * Retrieves the full Agent policy, which mirrors what the Elastic Agent would get * once they checkin. diff --git a/x-pack/test/security_solution_endpoint/services/index.ts b/x-pack/test/security_solution_endpoint/services/index.ts index f94d309e1c68c..a7e8985541191 100644 --- a/x-pack/test/security_solution_endpoint/services/index.ts +++ b/x-pack/test/security_solution_endpoint/services/index.ts @@ -9,9 +9,11 @@ import { services as xPackFunctionalServices } from '../../functional/services'; import { EndpointPolicyTestResourcesProvider } from './endpoint_policy'; import { IngestManagerProvider } from '../../common/services/ingest_manager'; import { EndpointTelemetryTestResourcesProvider } from './endpoint_telemetry'; +import { EndpointTestResources } from './endpoint'; export const services = { ...xPackFunctionalServices, + endpointTestResources: EndpointTestResources, policyTestResources: EndpointPolicyTestResourcesProvider, telemetryTestResources: EndpointTelemetryTestResourcesProvider, ingestManager: IngestManagerProvider, diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/resolver/events.ts b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/events.ts index b3aeb55eb38a1..81299e1cc7e2b 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/resolver/events.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/events.ts @@ -6,7 +6,7 @@ */ import expect from '@kbn/expect'; -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { eventsIndexPattern } from '../../../../plugins/security_solution/common/endpoint/constants'; import { eventIDSafeVersion, diff --git a/x-pack/test/security_solution_ftr/page_objects/detections/index.ts b/x-pack/test/security_solution_ftr/page_objects/detections/index.ts index 6f26e0b3ad364..d18b7fefed0d1 100644 --- a/x-pack/test/security_solution_ftr/page_objects/detections/index.ts +++ b/x-pack/test/security_solution_ftr/page_objects/detections/index.ts @@ -12,11 +12,17 @@ export class DetectionsPageObject extends FtrService { private readonly find = this.ctx.getService('find'); private readonly common = this.ctx.getPageObject('common'); private readonly testSubjects = this.ctx.getService('testSubjects'); + private readonly headerPageObjects = this.ctx.getPageObject('header'); async navigateHome(): Promise { await this.navigateToDetectionsPage(); } + async navigateToAlerts(): Promise { + await this.navigateToDetectionsPage('alerts'); + await this.headerPageObjects.waitUntilLoadingHasFinished(); + } + async navigateToRules(): Promise { await this.navigateToDetectionsPage('rules'); } @@ -139,6 +145,39 @@ export class DetectionsPageObject extends FtrService { await this.common.clickAndValidate('thresholdRuleType', 'input'); } + async ensureOnAlertsPage(): Promise { + await this.testSubjects.existOrFail('detectionsAlertsPage'); + } + + async openFirstAlertDetailsForHostName(hostName: string): Promise { + await this.ensureOnAlertsPage(); + + let foundAndHandled = false; + + // Get all event rows + const allEvents = await this.testSubjects.findAll('event'); + + for (const eventRow of allEvents) { + const hostNameButton = await this.testSubjects.findDescendant( + 'host-details-button', + eventRow + ); + const eventRowHostName = (await hostNameButton.getVisibleText()).trim(); + + if (eventRowHostName === hostName) { + const expandAlertButton = await this.testSubjects.findDescendant('expand-event', eventRow); + await expandAlertButton.click(); + await this.testSubjects.existOrFail('eventDetails'); + foundAndHandled = true; + break; + } + } + + if (!foundAndHandled) { + throw new Error(`no alerts found for host: ${hostName}`); + } + } + private async navigateToDetectionsPage(path: string = ''): Promise { const subUrl = `detections${path ? `/${path}` : ''}`; await this.common.navigateToUrl('securitySolution', subUrl, { diff --git a/x-pack/test/security_solution_ftr/page_objects/hosts/index.ts b/x-pack/test/security_solution_ftr/page_objects/hosts/index.ts new file mode 100644 index 0000000000000..0d80db3141214 --- /dev/null +++ b/x-pack/test/security_solution_ftr/page_objects/hosts/index.ts @@ -0,0 +1,60 @@ +/* + * 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 { FtrService } from '../../../functional/ftr_provider_context'; +import { WebElementWrapper } from '../../../../../test/functional/services/lib/web_element_wrapper'; + +export class HostsPageObject extends FtrService { + private readonly pageObjects = this.ctx.getPageObjects(['common', 'header']); + private readonly testSubjects = this.ctx.getService('testSubjects'); + + async navigateToHostDetails(hostName: string): Promise { + await this.pageObjects.common.navigateToUrl('securitySolution', `hosts/${hostName}`, { + shouldUseHashForSubUrl: false, + }); + await this.pageObjects.header.waitUntilLoadingHasFinished(); + } + + async ensureOnHostDetails(): Promise { + await this.testSubjects.existOrFail('hostDetailsPage'); + } + + /** + * Returns an object with the Endpoint overview data, where the keys are the visible labels in the UI. + * Must be on the Host details in order for this page object to work + */ + async hostDetailsEndpointOverviewData(): Promise> { + await this.ensureOnHostDetails(); + const endpointDescriptionLists: WebElementWrapper[] = await this.testSubjects.findAll( + 'endpoint-overview' + ); + + const data: Record = {}; + + for (const dlElement of endpointDescriptionLists) { + const $ = await dlElement.parseDomContent(); + + const title = $('dt') + .text() + .replace(/ /g, '') + .trim(); + + // The value could be draggable, in which case we need to grab the value displayed from a deeper element + const $ddElement = $('dd'); + const $valueContainer = $ddElement.find('.draggable-keyboard-wrapper .euiToolTipAnchor'); + + const value = ($valueContainer.length > 0 ? $valueContainer : $ddElement) + .text() + .replace(/ /g, '') + .trim(); + + data[title] = value; + } + + return data; + } +} diff --git a/x-pack/test/timeline/security_and_spaces/tests/basic/events.ts b/x-pack/test/timeline/security_and_spaces/tests/basic/events.ts index 79f5768b9a3ba..12f5012b0b08c 100644 --- a/x-pack/test/timeline/security_and_spaces/tests/basic/events.ts +++ b/x-pack/test/timeline/security_and_spaces/tests/basic/events.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import expect from '@kbn/expect'; import { ALERT_ID, ALERT_OWNER } from '@kbn/rule-data-utils'; diff --git a/x-pack/test/timeline/security_and_spaces/tests/trial/events.ts b/x-pack/test/timeline/security_and_spaces/tests/trial/events.ts index 2ebb534c4a451..c51532967cd09 100644 --- a/x-pack/test/timeline/security_and_spaces/tests/trial/events.ts +++ b/x-pack/test/timeline/security_and_spaces/tests/trial/events.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import expect from '@kbn/expect'; import { ALERT_ID, ALERT_OWNER } from '@kbn/rule-data-utils'; diff --git a/x-pack/test/timeline/security_only/tests/basic/events.ts b/x-pack/test/timeline/security_only/tests/basic/events.ts index fc8ee95dedfc4..8c118de8f3287 100644 --- a/x-pack/test/timeline/security_only/tests/basic/events.ts +++ b/x-pack/test/timeline/security_only/tests/basic/events.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { ALERT_ID, ALERT_OWNER } from '@kbn/rule-data-utils'; import { getSpaceUrlPrefix } from '../../../../rule_registry/common/lib/authentication/spaces'; diff --git a/x-pack/test/timeline/security_only/tests/trial/events.ts b/x-pack/test/timeline/security_only/tests/trial/events.ts index fc8ee95dedfc4..8c118de8f3287 100644 --- a/x-pack/test/timeline/security_only/tests/trial/events.ts +++ b/x-pack/test/timeline/security_only/tests/trial/events.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import { ALERT_ID, ALERT_OWNER } from '@kbn/rule-data-utils'; import { getSpaceUrlPrefix } from '../../../../rule_registry/common/lib/authentication/spaces'; diff --git a/x-pack/test/timeline/spaces_only/tests/events.ts b/x-pack/test/timeline/spaces_only/tests/events.ts index 829d46905b6d1..2c2d221129721 100644 --- a/x-pack/test/timeline/spaces_only/tests/events.ts +++ b/x-pack/test/timeline/spaces_only/tests/events.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { JsonObject } from '@kbn/common-utils'; +import { JsonObject } from '@kbn/utility-types'; import expect from '@kbn/expect'; import { ALERT_ID, ALERT_OWNER } from '@kbn/rule-data-utils'; diff --git a/yarn.lock b/yarn.lock index 7f42fc1902b11..c5f9de5dfe305 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2750,10 +2750,6 @@ version "0.0.0" uid "" -"@kbn/common-utils@link:bazel-bin/packages/kbn-common-utils": - version "0.0.0" - uid "" - "@kbn/config-schema@link:bazel-bin/packages/kbn-config-schema": version "0.0.0" uid ""