From 981fdda966d55295893e0cdf7cbe9384fab1fedb Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Wed, 12 Aug 2020 18:31:30 -0500 Subject: [PATCH 01/15] Reduce number of indexed fields in index pattern saved object (#74817) * reduce number of indexed fields in index pattern saved object --- src/plugins/data/server/saved_objects/index_patterns.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/plugins/data/server/saved_objects/index_patterns.ts b/src/plugins/data/server/saved_objects/index_patterns.ts index 44d2813f6e3e8..6aabcdf7c1c01 100644 --- a/src/plugins/data/server/saved_objects/index_patterns.ts +++ b/src/plugins/data/server/saved_objects/index_patterns.ts @@ -42,16 +42,10 @@ export const indexPatternSavedObjectType: SavedObjectsType = { }, }, mappings: { + dynamic: false, properties: { - fieldFormatMap: { type: 'text' }, - fields: { type: 'text' }, - intervalName: { type: 'keyword' }, - notExpandable: { type: 'boolean' }, - sourceFilters: { type: 'text' }, - timeFieldName: { type: 'keyword' }, title: { type: 'text' }, type: { type: 'keyword' }, - typeMeta: { type: 'keyword' }, }, }, migrations: indexPatternSavedObjectTypeMigrations as any, From a735a9f8259a30a790d07936caaf279e922ceb3b Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 12 Aug 2020 16:38:08 -0700 Subject: [PATCH 02/15] [bin/kibana-plugin] support KP plugins instead (#74604) * [cli/kibana-plugin] support KP plugins instead * fix some Logger imports from cli/kibana_keystore Co-authored-by: spalger Co-authored-by: Elastic Machine --- package.json | 1 - packages/kbn-pm/dist/index.js | 72 ----- packages/kbn-pm/src/index.ts | 2 +- packages/kbn-pm/src/production/index.ts | 1 - .../prepare_project_dependencies.test.ts | 40 --- .../prepare_project_dependencies.ts | 59 ---- src/cli_keystore/add.js | 2 +- src/cli_keystore/add.test.js | 2 +- src/cli_keystore/create.js | 2 +- src/cli_keystore/create.test.js | 2 +- src/cli_keystore/get_keystore.js | 2 +- src/cli_keystore/get_keystore.test.js | 2 +- src/cli_keystore/list.js | 2 +- src/cli_keystore/list.test.js | 2 +- src/cli_plugin/cli.js | 15 +- .../__fixtures__/replies/invalid_name.zip | Bin 2333 -> 1295 bytes .../replies/package.no_version.json | 3 - .../__fixtures__/replies/test_plugin.zip | Bin 2988 -> 5382 bytes .../replies/test_plugin_different_version.zip | Bin 2326 -> 2951 bytes .../__fixtures__/replies/test_plugin_many.zip | Bin 421587 -> 413276 bytes src/cli_plugin/install/cleanup.js | 1 - src/cli_plugin/install/cleanup.test.js | 2 +- src/cli_plugin/install/download.js | 7 +- src/cli_plugin/install/download.test.js | 10 +- src/cli_plugin/install/downloaders/file.js | 5 +- src/cli_plugin/install/downloaders/http.js | 8 +- src/cli_plugin/install/index.js | 18 +- src/cli_plugin/install/index.test.js | 13 +- src/cli_plugin/install/install.js | 16 +- src/cli_plugin/install/kibana.js | 11 +- src/cli_plugin/install/kibana.test.js | 27 +- src/cli_plugin/install/pack.js | 19 +- src/cli_plugin/install/pack.test.js | 202 ++++++-------- src/cli_plugin/install/progress.js | 2 +- src/cli_plugin/install/progress.test.js | 5 +- src/cli_plugin/install/rename.js | 9 +- src/cli_plugin/install/rename.test.js | 3 +- src/cli_plugin/install/settings.js | 13 +- src/cli_plugin/install/settings.test.js | 261 +++++------------- src/cli_plugin/install/zip.js | 89 +++--- src/cli_plugin/install/zip.test.js | 106 +++---- src/cli_plugin/lib/error_if_x_pack.js | 6 +- src/cli_plugin/lib/is_oss.js | 2 +- src/cli_plugin/lib/is_oss.test.js | 4 +- src/cli_plugin/lib/log_warnings.js | 2 +- src/cli_plugin/lib/logger.js | 2 +- src/cli_plugin/lib/logger.test.js | 3 +- .../lib/warn_if_plugin_dir_option.js | 27 -- src/cli_plugin/list/index.js | 39 +-- src/cli_plugin/list/list.js | 17 +- src/cli_plugin/list/list.test.js | 91 +++--- src/cli_plugin/list/settings.js | 26 -- src/cli_plugin/list/settings.test.js | 50 ---- src/cli_plugin/remove/index.js | 24 +- src/cli_plugin/remove/remove.js | 5 +- src/cli_plugin/remove/remove.test.js | 10 +- src/cli_plugin/remove/settings.js | 4 +- src/cli_plugin/remove/settings.test.js | 116 +++----- yarn.lock | 12 - 59 files changed, 481 insertions(+), 995 deletions(-) delete mode 100644 packages/kbn-pm/src/production/prepare_project_dependencies.test.ts delete mode 100644 packages/kbn-pm/src/production/prepare_project_dependencies.ts delete mode 100644 src/cli_plugin/install/__fixtures__/replies/package.no_version.json delete mode 100644 src/cli_plugin/lib/warn_if_plugin_dir_option.js delete mode 100644 src/cli_plugin/list/settings.js delete mode 100644 src/cli_plugin/list/settings.test.js diff --git a/package.json b/package.json index becd670e4ddcf..200aa41743f51 100644 --- a/package.json +++ b/package.json @@ -276,7 +276,6 @@ "url-loader": "2.2.0", "uuid": "3.3.2", "val-loader": "^1.1.1", - "validate-npm-package-name": "2.2.2", "vega": "^5.13.0", "vega-lite": "^4.13.1", "vega-schema-url-parser": "^1.1.0", diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 9427cc57805e6..e411dcd472768 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -97,8 +97,6 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(511); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["buildProductionProjects"]; }); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); - /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getProjects", function() { return _utils_projects__WEBPACK_IMPORTED_MODULE_2__["getProjects"]; }); @@ -59477,9 +59475,6 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(512); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); -/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(748); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); - /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -59500,7 +59495,6 @@ __webpack_require__.r(__webpack_exports__); */ - /***/ }), /* 512 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { @@ -90331,71 +90325,5 @@ NestedError.prototype.name = 'NestedError'; module.exports = NestedError; -/***/ }), -/* 748 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return prepareExternalProjectDependencies; }); -/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(164); -/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(163); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -/** - * All external projects are located within `./plugins/{plugin}` relative - * to the Kibana root directory or `../kibana-extra/{plugin}` relative - * to Kibana itself. - */ - -const isKibanaDep = depVersion => // For ../kibana-extra/ directory (legacy only) -depVersion.includes('../../kibana/packages/') || // For plugins/ directory -depVersion.includes('../../packages/'); -/** - * This prepares the dependencies for an _external_ project. - */ - - -async function prepareExternalProjectDependencies(projectPath) { - const project = await _utils_project__WEBPACK_IMPORTED_MODULE_1__["Project"].fromPath(projectPath); - - if (!project.hasDependencies()) { - return; - } - - const deps = project.allDependencies; - - for (const depName of Object.keys(deps)) { - const depVersion = deps[depName]; // Kibana currently only supports `link:` dependencies on Kibana's own - // packages, as these are packaged into the `node_modules` folder when - // Kibana is built, so we don't need to take any action to enable - // `require(...)` to resolve for these packages. - - if (Object(_utils_package_json__WEBPACK_IMPORTED_MODULE_0__["isLinkDependency"])(depVersion) && !isKibanaDep(depVersion)) { - // For non-Kibana packages we need to set up symlinks during the - // installation process, but this is not something we support yet. - throw new Error('This plugin is using `link:` dependencies for non-Kibana packages'); - } - } -} - /***/ }) /******/ ]); \ No newline at end of file diff --git a/packages/kbn-pm/src/index.ts b/packages/kbn-pm/src/index.ts index 0aa58adb4382f..27ce0a417fdeb 100644 --- a/packages/kbn-pm/src/index.ts +++ b/packages/kbn-pm/src/index.ts @@ -18,7 +18,7 @@ */ export { run } from './cli'; -export { buildProductionProjects, prepareExternalProjectDependencies } from './production'; +export { buildProductionProjects } from './production'; export { getProjects } from './utils/projects'; export { Project } from './utils/project'; export { copyWorkspacePackages } from './utils/workspaces'; diff --git a/packages/kbn-pm/src/production/index.ts b/packages/kbn-pm/src/production/index.ts index 493af2beb648d..f74ab8a4484f1 100644 --- a/packages/kbn-pm/src/production/index.ts +++ b/packages/kbn-pm/src/production/index.ts @@ -18,4 +18,3 @@ */ export { buildProductionProjects } from './build_production_projects'; -export { prepareExternalProjectDependencies } from './prepare_project_dependencies'; diff --git a/packages/kbn-pm/src/production/prepare_project_dependencies.test.ts b/packages/kbn-pm/src/production/prepare_project_dependencies.test.ts deleted file mode 100644 index 13ab8d56e0190..0000000000000 --- a/packages/kbn-pm/src/production/prepare_project_dependencies.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { join, resolve } from 'path'; - -import { prepareExternalProjectDependencies } from './prepare_project_dependencies'; - -const packagesFixtures = resolve(__dirname, '__fixtures__/external_packages'); - -test('does nothing when Kibana `link:` dependencies', async () => { - const projectPath = join(packagesFixtures, 'with_kibana_link_deps'); - - // We're checking for undefined, but we don't really care about what's - // returned, we only care about it resolving. - await expect(prepareExternalProjectDependencies(projectPath)).resolves.toBeUndefined(); -}); - -test('throws if non-Kibana `link` dependencies', async () => { - const projectPath = join(packagesFixtures, 'with_other_link_deps'); - - await expect(prepareExternalProjectDependencies(projectPath)).rejects.toThrow( - 'This plugin is using `link:` dependencies for non-Kibana packages' - ); -}); diff --git a/packages/kbn-pm/src/production/prepare_project_dependencies.ts b/packages/kbn-pm/src/production/prepare_project_dependencies.ts deleted file mode 100644 index 9817770166480..0000000000000 --- a/packages/kbn-pm/src/production/prepare_project_dependencies.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { isLinkDependency } from '../utils/package_json'; -import { Project } from '../utils/project'; - -/** - * All external projects are located within `./plugins/{plugin}` relative - * to the Kibana root directory or `../kibana-extra/{plugin}` relative - * to Kibana itself. - */ -const isKibanaDep = (depVersion: string) => - // For ../kibana-extra/ directory (legacy only) - depVersion.includes('../../kibana/packages/') || - // For plugins/ directory - depVersion.includes('../../packages/'); - -/** - * This prepares the dependencies for an _external_ project. - */ -export async function prepareExternalProjectDependencies(projectPath: string) { - const project = await Project.fromPath(projectPath); - - if (!project.hasDependencies()) { - return; - } - - const deps = project.allDependencies; - - for (const depName of Object.keys(deps)) { - const depVersion = deps[depName]; - - // Kibana currently only supports `link:` dependencies on Kibana's own - // packages, as these are packaged into the `node_modules` folder when - // Kibana is built, so we don't need to take any action to enable - // `require(...)` to resolve for these packages. - if (isLinkDependency(depVersion) && !isKibanaDep(depVersion)) { - // For non-Kibana packages we need to set up symlinks during the - // installation process, but this is not something we support yet. - throw new Error('This plugin is using `link:` dependencies for non-Kibana packages'); - } - } -} diff --git a/src/cli_keystore/add.js b/src/cli_keystore/add.js index 87266702a26cc..44737e387c2d2 100644 --- a/src/cli_keystore/add.js +++ b/src/cli_keystore/add.js @@ -17,7 +17,7 @@ * under the License. */ -import Logger from '../cli_plugin/lib/logger'; +import { Logger } from '../cli_plugin/lib/logger'; import { confirm, question } from '../legacy/server/utils'; import { createPromiseFromStreams, createConcatStream } from '../legacy/utils'; diff --git a/src/cli_keystore/add.test.js b/src/cli_keystore/add.test.js index 320581b470c2b..b5d5009667eb4 100644 --- a/src/cli_keystore/add.test.js +++ b/src/cli_keystore/add.test.js @@ -41,7 +41,7 @@ import { PassThrough } from 'stream'; import { Keystore } from '../legacy/server/keystore'; import { add } from './add'; -import Logger from '../cli_plugin/lib/logger'; +import { Logger } from '../cli_plugin/lib/logger'; import * as prompt from '../legacy/server/utils/prompt'; describe('Kibana keystore', () => { diff --git a/src/cli_keystore/create.js b/src/cli_keystore/create.js index 1af0959821f80..8be1eb36882f1 100644 --- a/src/cli_keystore/create.js +++ b/src/cli_keystore/create.js @@ -17,7 +17,7 @@ * under the License. */ -import Logger from '../cli_plugin/lib/logger'; +import { Logger } from '../cli_plugin/lib/logger'; import { confirm } from '../legacy/server/utils'; export async function create(keystore, command, options) { diff --git a/src/cli_keystore/create.test.js b/src/cli_keystore/create.test.js index 33b5aa4bd07d8..f48b3775ddfff 100644 --- a/src/cli_keystore/create.test.js +++ b/src/cli_keystore/create.test.js @@ -40,7 +40,7 @@ import sinon from 'sinon'; import { Keystore } from '../legacy/server/keystore'; import { create } from './create'; -import Logger from '../cli_plugin/lib/logger'; +import { Logger } from '../cli_plugin/lib/logger'; import * as prompt from '../legacy/server/utils/prompt'; describe('Kibana keystore', () => { diff --git a/src/cli_keystore/get_keystore.js b/src/cli_keystore/get_keystore.js index c8ff2555563ad..e181efe9196b8 100644 --- a/src/cli_keystore/get_keystore.js +++ b/src/cli_keystore/get_keystore.js @@ -20,7 +20,7 @@ import { existsSync } from 'fs'; import { join } from 'path'; -import Logger from '../cli_plugin/lib/logger'; +import { Logger } from '../cli_plugin/lib/logger'; import { getConfigDirectory, getDataPath } from '../core/server/path'; export function getKeystore() { diff --git a/src/cli_keystore/get_keystore.test.js b/src/cli_keystore/get_keystore.test.js index 88102b8f51d57..b1c42fca2f73c 100644 --- a/src/cli_keystore/get_keystore.test.js +++ b/src/cli_keystore/get_keystore.test.js @@ -18,7 +18,7 @@ */ import { getKeystore } from './get_keystore'; -import Logger from '../cli_plugin/lib/logger'; +import { Logger } from '../cli_plugin/lib/logger'; import fs from 'fs'; import sinon from 'sinon'; diff --git a/src/cli_keystore/list.js b/src/cli_keystore/list.js index e9158735a214f..4a99de271bc6a 100644 --- a/src/cli_keystore/list.js +++ b/src/cli_keystore/list.js @@ -17,7 +17,7 @@ * under the License. */ -import Logger from '../cli_plugin/lib/logger'; +import { Logger } from '../cli_plugin/lib/logger'; export function list(keystore, command, options = {}) { const logger = new Logger(options); diff --git a/src/cli_keystore/list.test.js b/src/cli_keystore/list.test.js index 857991b5ae3b9..11c474f908216 100644 --- a/src/cli_keystore/list.test.js +++ b/src/cli_keystore/list.test.js @@ -38,7 +38,7 @@ jest.mock('fs', () => ({ import sinon from 'sinon'; import { Keystore } from '../legacy/server/keystore'; import { list } from './list'; -import Logger from '../cli_plugin/lib/logger'; +import { Logger } from '../cli_plugin/lib/logger'; describe('Kibana keystore', () => { describe('list', () => { diff --git a/src/cli_plugin/cli.js b/src/cli_plugin/cli.js index da1068b54b4b5..e483385b5b9e8 100644 --- a/src/cli_plugin/cli.js +++ b/src/cli_plugin/cli.js @@ -17,12 +17,11 @@ * under the License. */ -import _ from 'lodash'; import { pkg } from '../core/server/utils'; import Command from '../cli/command'; -import listCommand from './list'; -import installCommand from './install'; -import removeCommand from './remove'; +import { listCommand } from './list'; +import { installCommand } from './install'; +import { removeCommand } from './remove'; const argv = process.env.kbnWorkerArgv ? JSON.parse(process.env.kbnWorkerArgv) @@ -44,8 +43,12 @@ program .command('help ') .description('get the help for a specific command') .action(function (cmdName) { - const cmd = _.find(program.commands, { _name: cmdName }); - if (!cmd) return program.error(`unknown command ${cmdName}`); + const cmd = program.commands.find((c) => c._name === cmdName); + + if (!cmd) { + return program.error(`unknown command ${cmdName}`); + } + cmd.help(); }); diff --git a/src/cli_plugin/install/__fixtures__/replies/invalid_name.zip b/src/cli_plugin/install/__fixtures__/replies/invalid_name.zip index 5de9a0677b6cb6681b890ca59cae3988cca1afd4..4d77ba0d389a699887e9706c134b82e7e98f1bba 100644 GIT binary patch literal 1295 zcmWIWW@Zs#0D*>Bwm>igO0Y91Fl1*YCFUjShlcPnuowF4#8(0_h%T+*W?*Fb%E-U~ z)*Jvgq!-N)5riR`d1Z+?nJKz?iMgo|6T5&W!7x@6IT$!loW&x+z#xDyQO_kfKDZ>m zC>8ELklV1h@9hk0zC#8AF6qu)9sxU+d|}nt(b)QcC8oh&V*-;1$E%Pz-HRulIPA{F zvBJT?KWeYi?y^f2dl?g&WACxcH1J%sc%Ub_*wHDvC##pq`^k&M-j{#3N?qAHcU4wz zZD?`y{zFRl&voBS3%=3a&8gTT@JKUfb>#2O>lIsmIKBFO@N%Qx;@n8nK$ZDzat&8*cN+i!ZpSGxxC^z%dc$VSczTGaeWB)?Yr?39mA3FRqp5x=;2rC(W z_8mMdyszS3ubyG>yh5+0K+xk6|6#p#l_33VPd5n6f4~yp&Ca2Fvx@H_Fz!Hs1c?yz z;Hv=2N&|y0KHk^S**`c!9~!-S@t7ew2N;qdj217+38KmA2}ubbe0{<`@P~B-G%!t& zU{)89X51(((ELNx;S59YLxlqk%oc4eERHip4Psw_T*J=6-EqLe6lg!l4G7mwL`p7( zKpA;N@MdHZVaA;wfJ(sNts{scI(Hxp z#g;!HMlvwGb#z4-isF5+pJ6!#M5Fl`=4@DmBPRt=eu04{jnfe}V8%I)+=Fg9a#Vtn z6AUbAyvE2tN#a7b2$V9AV+NEmU|>mO2@^c@Q38sDbQ0jr$_6r!6$oDg-Oa}g;sF3w CgHP1} literal 2333 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 O10N7d0^L>%<^cdfumkS^ diff --git a/src/cli_plugin/install/__fixtures__/replies/test_plugin_different_version.zip b/src/cli_plugin/install/__fixtures__/replies/test_plugin_different_version.zip index 12baa165fdb566d22237d72a9b0afb7d9c965219..b84473cebf954a4f5b186b8d92db55d7ad9da975 100644 GIT binary patch literal 2951 zcmWIWW@Zs#0D;Z1Y=K|~l#pXkU?@o~E{QM5DNWDJi%-c+OG_AzvQnIe;J4m1?t3?R&X;gvV3J^U;vvL05+S0frH^d9KviC2?hprf@bTv1jh%L zc{{_9>yU$h>;EGPjI(uhzjNJ75VUO+H^@?E3+|}ZI{);d&yDqL zlN!Rh{;?m{HrhPf#M+uM;q&J_HVX#HMTL&~l8c?4qI;@(l|S9hjLtc==|%i%=V0q& zjMX_4w!eORl(j{`iQ}VK&c>ThHm_G~`QbF{^TErF>lXE%7q-g1YHA1N%C!m zKl`q(XA4th?0T%F)kTW8EI%AQU+2hugRUaq|M5u$|HPgC7);X(>$a3*c5GjE{g>6X zGdu5bv+FT={zkd*Mj*C*@)e^^IA1JeWvW_1B+#*NYf%|ApP z&M*W&R5;MUY|+-j;y6>(Aoc~wk?b7Y9S1B-fzARs4dQ4Z10?}~_^JdGKz3$QVqPL7 zjlrTGM5DPAd$@o?OpjPAFvA39ADUfnXV`+0TI>BIBH*OPBnC-q0=*pqApyTb=AB+V zbHjQ0j>ZVhUv@KUT+`G%H}4i^FtdBAe1P$UK(BG!Btt2cEk{>W@oaQ&6ux$2&%3J& z*1dh)A(08_^3#qcZP#9ttgQ%4b0rPZ+1LKR$>vbpH=(NbL&<{E8IS+A_|4Cf zdHd2~`o&{=TKr!2lxp%J}KN5B3o>5D_!`{U9 zHSYE58OG0xv~w&uR6e#pWazg6CfS~Ai4Gn91+1XhbN*GDb{`l&_>-I^@ktIEjRTkR z)}s|`hQuZdP*&1~lzos?cp6yBT_;r19YQMUynz8}LymQjK-0@A&d&oEe`lb@ABaXv zldGQv1q7V(3EUJEpyjEn$9Y22_xzdQON^bI7aoO0H)ncwR(2+G zSOzbcvrs5pR~(#Mvl}+qTLYa5aw;M#A$wv2P{y6)_(l#qy?AW?A-UWslm(VM(h?m^ zeTs^X0csw{nH0nvf)8~FO!qo>{;Ic*#tF}>r#*G_GE~5#4cEEh+MXVYC{-U z(g<=Le!GY+uwWj9S&CdXgQ^V}SkkzHk%0!42+V$vJ;+S}5Fb>xT#9B#};06_$FtDUinuX}#CcOYf4s~p$AIuql9j^nOfj_B1ZAZ?| z;FONHEJVZrs31WuVnC%K3~Xt1Vd bAIKp>QUMp>%?h-Pfq@eUOM&742h0NiMn!Wx literal 2326 zcmWIWW@Zs#0D)}@J|18Ol;8u>sX2+oC7H>^sfk6&8TtWmwTji6p2%w1ft>8jq{O^L zBt_C_ii8o0N>YnUbPIAy(=+qH8o0oQeagP!wv=su2M>@3!m`*k=%r_tWTxlk7p3Oq zr=-T`=BJeAq!xo52QkLGt z%%2<#AQxF2dulruXv8}pmd0*WW?o8agQ=!+K3^&dkqu-EN!D>OYtO^;0$Wn^Gr zWny5E$L_0w#N_P6^i-g~^7CQ??&cj*5ZO1+|KN^7Z;|?4Gtcba+aBrk($hQD!J@=B zx#qj4&bW1R=k1QI5&apgE1JH2JhVmD zO)b)BbM@!I>6g5M=A`NON6w$J_2ClB^hAdD0q){$DrzkoEPmLmyf*QY(G}Lo6V%-H z$FHr@ILX|^5`1X~_i_oYzFSFC)T-C6ZqRK!J9YC59*)Pawlgn}mQ8untIMIh-b-76#23#i@?h!ybaODre=Mh5G_gS-t20xSpihpy3I z$fo@x&Inz8!vh7CD)1HZQm_?|U3UL$nu zc7d6_%X8Irm&LEkBeD!Aov+d7*A@cW55h9o-4W#K=;G_Dmz(0LkeI8Gr~t~w3Xp7! z2#cL)huXsM>uT;Fqh-@%=Yzs3W8ytu*7`d23 zw&dbhWlNAHFnVQK)mD&iAeP`N3}Kci04-?3ZV94jM7ECMOEbfobr%>bXF&V{qmiw{ zEHsg=JBi&o+(jsg^^4uUHUfiCbC=;nkS}30B1o|nw8++r01GN;TppY()ypE(M@nC3x+E6fnp(!jevOG{hztjhu8a3lC%)|6sQfUX)<7 z&5svi8;nK{OU&X0W*aChJy?(m8)Tzh!;|KN5+6Dp;LXYg)W^ULgcE_9^MROw0RX19 BoUi}@ diff --git a/src/cli_plugin/install/__fixtures__/replies/test_plugin_many.zip b/src/cli_plugin/install/__fixtures__/replies/test_plugin_many.zip index e4fc8d73feef86f0f34073e0597c6c2351dc4d05..bc58c2bdb9dd7e108ef80ddf6f7c189dc4b92e97 100644 GIT binary patch delta 296290 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 ~%N`^ZJW#&H|R=s50E81?f{-bBH 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%0D{BxmKwG=BV)UvKoc7uRR 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%0AL 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

}$Ej$&^%9{5_hU;1 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 yeX)LL*6atv{b*(X@I(%r7EjZZiL diff --git a/src/cli_plugin/install/cleanup.js b/src/cli_plugin/install/cleanup.js index f31e028226c27..38354bac4a3df 100644 --- a/src/cli_plugin/install/cleanup.js +++ b/src/cli_plugin/install/cleanup.js @@ -45,6 +45,5 @@ export function cleanArtifacts(settings) { // At this point we're bailing, so swallow any errors on delete. try { del.sync(settings.workingPath); - del.sync(settings.plugins[0].path); } catch (e) {} // eslint-disable-line no-empty } diff --git a/src/cli_plugin/install/cleanup.test.js b/src/cli_plugin/install/cleanup.test.js index 46089f61d5e83..1a4cabbc82b5d 100644 --- a/src/cli_plugin/install/cleanup.test.js +++ b/src/cli_plugin/install/cleanup.test.js @@ -22,7 +22,7 @@ import fs from 'fs'; import del from 'del'; import { cleanPrevious, cleanArtifacts } from './cleanup'; -import Logger from '../lib/logger'; +import { Logger } from '../lib/logger'; describe('kibana cli', function () { describe('plugin installer', function () { diff --git a/src/cli_plugin/install/download.js b/src/cli_plugin/install/download.js index 10d20367c1b7b..b7f5fbec46edc 100644 --- a/src/cli_plugin/install/download.js +++ b/src/cli_plugin/install/download.js @@ -17,11 +17,12 @@ * under the License. */ -import downloadHttpFile from './downloaders/http'; -import downloadLocalFile from './downloaders/file'; -import { UnsupportedProtocolError } from '../lib/errors'; import { parse } from 'url'; +import { UnsupportedProtocolError } from '../lib/errors'; +import { downloadHttpFile } from './downloaders/http'; +import { downloadLocalFile } from './downloaders/file'; + function _isWindows() { return /^win/.test(process.platform); } diff --git a/src/cli_plugin/install/download.test.js b/src/cli_plugin/install/download.test.js index 93e5e414fed74..ae926b77f7d58 100644 --- a/src/cli_plugin/install/download.test.js +++ b/src/cli_plugin/install/download.test.js @@ -17,16 +17,18 @@ * under the License. */ +import Fs from 'fs'; +import { join } from 'path'; +import http from 'http'; + import sinon from 'sinon'; import nock from 'nock'; import glob from 'glob-all'; import del from 'del'; -import Fs from 'fs'; -import Logger from '../lib/logger'; + +import { Logger } from '../lib/logger'; import { UnsupportedProtocolError } from '../lib/errors'; import { download, _downloadSingle, _getFilePath, _checkFilePathDeprecation } from './download'; -import { join } from 'path'; -import http from 'http'; describe('kibana cli', function () { describe('plugin downloader', function () { diff --git a/src/cli_plugin/install/downloaders/file.js b/src/cli_plugin/install/downloaders/file.js index 56f83b03d5a90..c262f1010bbc8 100644 --- a/src/cli_plugin/install/downloaders/file.js +++ b/src/cli_plugin/install/downloaders/file.js @@ -17,9 +17,10 @@ * under the License. */ -import Progress from '../progress'; import { createWriteStream, createReadStream, statSync } from 'fs'; +import { Progress } from '../progress'; + function openSourceFile({ sourcePath }) { try { const fileInfo = statSync(sourcePath); @@ -58,7 +59,7 @@ async function copyFile({ readStream, writeStream, progress }) { /* // Responsible for managing local file transfers */ -export default async function copyLocalFile(logger, sourcePath, targetPath) { +export async function downloadLocalFile(logger, sourcePath, targetPath) { try { const { readStream, fileInfo } = openSourceFile({ sourcePath }); const writeStream = createWriteStream(targetPath); diff --git a/src/cli_plugin/install/downloaders/http.js b/src/cli_plugin/install/downloaders/http.js index 0fc01453f2b4c..e9eafe3737ccb 100644 --- a/src/cli_plugin/install/downloaders/http.js +++ b/src/cli_plugin/install/downloaders/http.js @@ -17,13 +17,15 @@ * under the License. */ -import Wreck from '@hapi/wreck'; -import Progress from '../progress'; import { createWriteStream } from 'fs'; + +import Wreck from '@hapi/wreck'; import HttpProxyAgent from 'http-proxy-agent'; import HttpsProxyAgent from 'https-proxy-agent'; import { getProxyForUrl } from 'proxy-from-env'; +import { Progress } from '../progress'; + function getProxyAgent(sourceUrl, logger) { const proxy = getProxyForUrl(sourceUrl); @@ -91,7 +93,7 @@ function downloadResponse({ resp, targetPath, progress }) { /* Responsible for managing http transfers */ -export default async function downloadUrl(logger, sourceUrl, targetPath, timeout) { +export async function downloadHttpFile(logger, sourceUrl, targetPath, timeout) { try { const { req, resp } = await sendRequest({ sourceUrl, timeout }, logger); diff --git a/src/cli_plugin/install/index.js b/src/cli_plugin/install/index.js index e3c465ea7a3f5..bc7e95b8489f0 100644 --- a/src/cli_plugin/install/index.js +++ b/src/cli_plugin/install/index.js @@ -17,13 +17,12 @@ * under the License. */ -import { fromRoot, pkg } from '../../core/server/utils'; -import install from './install'; -import Logger from '../lib/logger'; +import { pkg } from '../../core/server/utils'; +import { install } from './install'; +import { Logger } from '../lib/logger'; import { getConfigPath } from '../../core/server/path'; import { parse, parseMilliseconds } from './settings'; -import logWarnings from '../lib/log_warnings'; -import { warnIfUsingPluginDirOption } from '../lib/warn_if_plugin_dir_option'; +import { logWarnings } from '../lib/log_warnings'; function processCommand(command, options) { let settings; @@ -37,12 +36,11 @@ function processCommand(command, options) { const logger = new Logger(settings); - warnIfUsingPluginDirOption(settings, fromRoot('plugins'), logger); logWarnings(settings, logger); install(settings, logger); } -export default function pluginInstall(program) { +export function installCommand(program) { program .command('install ') .option('-q, --quiet', 'disable all process messaging except errors') @@ -53,15 +51,9 @@ export default function pluginInstall(program) { 'length of time before failing; 0 for never fail', parseMilliseconds ) - .option( - '-d, --plugin-dir ', - 'path to the directory where plugins are stored (DEPRECATED, known to not work for all plugins)', - fromRoot('plugins') - ) .description( 'install a plugin', `Common examples: - install x-pack install file:///Path/to/my/x-pack.zip install https://path.to/my/x-pack.zip` ) diff --git a/src/cli_plugin/install/index.test.js b/src/cli_plugin/install/index.test.js index 39352f52f20fd..657ca0904041a 100644 --- a/src/cli_plugin/install/index.test.js +++ b/src/cli_plugin/install/index.test.js @@ -18,7 +18,8 @@ */ import sinon from 'sinon'; -import index from './index'; + +import { installCommand } from './index'; describe('kibana cli', function () { describe('plugin installer', function () { @@ -41,7 +42,7 @@ describe('kibana cli', function () { it('should define the command', function () { sinon.spy(program, 'command'); - index(program); + installCommand(program); expect(program.command.calledWith('install ')).toBe(true); program.command.restore(); @@ -50,7 +51,7 @@ describe('kibana cli', function () { it('should define the description', function () { sinon.spy(program, 'description'); - index(program); + installCommand(program); expect(program.description.calledWith('install a plugin')).toBe(true); program.description.restore(); @@ -59,9 +60,9 @@ describe('kibana cli', function () { it('should define the command line options', function () { const spy = sinon.spy(program, 'option'); - const options = [/-q/, /-s/, /-c/, /-t/, /-d/]; + const options = [/-q/, /-s/, /-c/, /-t/]; - index(program); + installCommand(program); for (let i = 0; i < spy.callCount; i++) { const call = spy.getCall(i); @@ -80,7 +81,7 @@ describe('kibana cli', function () { it('should call the action function', function () { sinon.spy(program, 'action'); - index(program); + installCommand(program); expect(program.action.calledOnce).toBe(true); program.action.restore(); diff --git a/src/cli_plugin/install/install.js b/src/cli_plugin/install/install.js index 92be2ac250320..b74b589459112 100644 --- a/src/cli_plugin/install/install.js +++ b/src/cli_plugin/install/install.js @@ -19,20 +19,20 @@ import Fs from 'fs'; import { promisify } from 'util'; +import path from 'path'; + +import del from 'del'; import { download } from './download'; -import path from 'path'; import { cleanPrevious, cleanArtifacts } from './cleanup'; import { extract, getPackData } from './pack'; import { renamePlugin } from './rename'; -import del from 'del'; import { errorIfXPackInstall } from '../lib/error_if_x_pack'; import { existingInstall, assertVersion } from './kibana'; -import { prepareExternalProjectDependencies } from '@kbn/pm'; const mkdir = promisify(Fs.mkdir); -export default async function install(settings, logger) { +export async function install(settings, logger) { try { errorIfXPackInstall(settings, logger); @@ -52,12 +52,8 @@ export default async function install(settings, logger) { assertVersion(settings); - await prepareExternalProjectDependencies(settings.workingPath); - - await renamePlugin( - settings.workingPath, - path.join(settings.pluginDir, settings.plugins[0].name) - ); + const targetDir = path.join(settings.pluginDir, settings.plugins[0].id); + await renamePlugin(settings.workingPath, targetDir); logger.log('Plugin installation complete'); } catch (err) { diff --git a/src/cli_plugin/install/kibana.js b/src/cli_plugin/install/kibana.js index edbcef3e7fed0..f093c1eee3db0 100644 --- a/src/cli_plugin/install/kibana.js +++ b/src/cli_plugin/install/kibana.js @@ -18,15 +18,16 @@ */ import path from 'path'; -import { versionSatisfies, cleanVersion } from '../../legacy/utils/version'; import { statSync } from 'fs'; +import { versionSatisfies, cleanVersion } from '../../legacy/utils/version'; + export function existingInstall(settings, logger) { try { - statSync(path.join(settings.pluginDir, settings.plugins[0].name)); + statSync(path.join(settings.pluginDir, settings.plugins[0].id)); logger.error( - `Plugin ${settings.plugins[0].name} already exists, please remove before installing a new version` + `Plugin ${settings.plugins[0].id} already exists, please remove before installing a new version` ); process.exit(70); } catch (e) { @@ -37,7 +38,7 @@ export function existingInstall(settings, logger) { export function assertVersion(settings) { if (!settings.plugins[0].kibanaVersion) { throw new Error( - `Plugin package.json is missing both a version property (required) and a kibana.version property (optional).` + `Plugin kibana.json is missing both a version property (required) and a kibanaVersion property (optional).` ); } @@ -45,7 +46,7 @@ export function assertVersion(settings) { const expected = cleanVersion(settings.version); if (!versionSatisfies(actual, expected)) { throw new Error( - `Plugin ${settings.plugins[0].name} [${actual}] is incompatible with Kibana [${expected}]` + `Plugin ${settings.plugins[0].id} [${actual}] is incompatible with Kibana [${expected}]` ); } } diff --git a/src/cli_plugin/install/kibana.test.js b/src/cli_plugin/install/kibana.test.js index 8c5dd00d09953..ef3400be73069 100644 --- a/src/cli_plugin/install/kibana.test.js +++ b/src/cli_plugin/install/kibana.test.js @@ -17,12 +17,14 @@ * under the License. */ -import sinon from 'sinon'; -import Logger from '../lib/logger'; import { join } from 'path'; -import del from 'del'; import fs from 'fs'; + +import sinon from 'sinon'; +import del from 'del'; + import { existingInstall, assertVersion } from './kibana'; +import { Logger } from '../lib/logger'; jest.spyOn(fs, 'statSync'); @@ -42,7 +44,7 @@ describe('kibana cli', function () { tempArchiveFile: tempArchiveFilePath, plugin: 'test-plugin', version: '1.0.0', - plugins: [{ name: 'foo' }], + plugins: [{ id: 'foo' }], pluginDir, }; @@ -69,7 +71,10 @@ describe('kibana cli', function () { plugin: 'test-plugin', version: '5.0.0-SNAPSHOT', plugins: [ - { name: 'foo', path: join(testWorkingPath, 'foo'), kibanaVersion: '5.0.0-SNAPSHOT' }, + { + id: 'foo', + kibanaVersion: '5.0.0-SNAPSHOT', + }, ], }; @@ -77,15 +82,17 @@ describe('kibana cli', function () { }); it('should throw an error if plugin is missing a kibana version.', function () { - expect(() => assertVersion(settings)).toThrow( - /plugin package\.json is missing both a version property/i + expect(() => assertVersion(settings)).toThrowErrorMatchingInlineSnapshot( + `"Plugin kibana.json is missing both a version property (required) and a kibanaVersion property (optional)."` ); }); it('should throw an error if plugin kibanaVersion does not match kibana version', function () { settings.plugins[0].kibanaVersion = '1.2.3.4'; - expect(() => assertVersion(settings)).toThrow(/incompatible with Kibana/i); + expect(() => assertVersion(settings)).toThrowErrorMatchingInlineSnapshot( + `"Plugin foo [1.2.3] is incompatible with Kibana [1.0.0]"` + ); }); it('should not throw an error if plugin kibanaVersion matches kibana version', function () { @@ -103,7 +110,9 @@ describe('kibana cli', function () { it('should ignore version info after the dash in checks on invalid version', function () { settings.plugins[0].kibanaVersion = '2.0.0-foo-bar-version-1.2.3'; - expect(() => assertVersion(settings)).toThrow(/incompatible with Kibana/i); + expect(() => assertVersion(settings)).toThrowErrorMatchingInlineSnapshot( + `"Plugin foo [2.0.0] is incompatible with Kibana [1.0.0]"` + ); }); }); diff --git a/src/cli_plugin/install/pack.js b/src/cli_plugin/install/pack.js index 87c94fce2b677..56d7be78e44bc 100644 --- a/src/cli_plugin/install/pack.js +++ b/src/cli_plugin/install/pack.js @@ -18,7 +18,11 @@ */ import { analyzeArchive, extractArchive } from './zip'; -import validate from 'validate-npm-package-name'; + +const CAMEL_CASE_REG_EXP = /^[a-z]{1}([a-zA-Z0-9]{1,})$/; +export function isCamelCase(candidate) { + return CAMEL_CASE_REG_EXP.test(candidate); +} /** * Checks the plugin name. Will throw an exception if it does not meet @@ -27,9 +31,10 @@ import validate from 'validate-npm-package-name'; * @param {object} plugin - a package object from listPackages() */ function assertValidPackageName(plugin) { - const validation = validate(plugin.name); - if (!validation.validForNewPackages) { - throw new Error(`Invalid plugin name [${plugin.name}] in package.json`); + if (!isCamelCase(plugin.id)) { + throw new Error( + `Invalid plugin name [${plugin.id}] in kibana.json, expected it to be valid camelCase` + ); } } @@ -60,17 +65,13 @@ export async function getPackData(settings, logger) { /** * Extracts files from a zip archive to a file path using a filter function - * - * @param {string} archive - file path to a zip archive - * @param {string} targetDir - directory path to where the files should - * extracted */ export async function extract(settings, logger) { try { const plugin = settings.plugins[0]; logger.log('Extracting plugin archive'); - await extractArchive(settings.tempArchiveFile, settings.workingPath, plugin.archivePath); + await extractArchive(settings.tempArchiveFile, settings.workingPath, plugin.stripPrefix); logger.log('Extraction complete'); } catch (err) { logger.error(err.stack); diff --git a/src/cli_plugin/install/pack.test.js b/src/cli_plugin/install/pack.test.js index 05a60107f80ff..c31437e61bebf 100644 --- a/src/cli_plugin/install/pack.test.js +++ b/src/cli_plugin/install/pack.test.js @@ -18,14 +18,15 @@ */ import Fs from 'fs'; +import { join } from 'path'; import sinon from 'sinon'; import glob from 'glob-all'; import del from 'del'; -import Logger from '../lib/logger'; + +import { Logger } from '../lib/logger'; import { extract, getPackData } from './pack'; import { _downloadSingle } from './download'; -import { join } from 'path'; describe('kibana cli', function () { describe('pack', function () { @@ -73,133 +74,104 @@ describe('kibana cli', function () { return _downloadSingle(settings, logger, sourceUrl); } - function shouldReject() { - throw new Error('expected the promise to reject'); - } - describe('extract', function () { - //Also only extracts the content from the kibana folder. - //Ignores the others. - it('successfully extract a valid zip', function () { - return copyReplyFile('test_plugin.zip') - .then(() => { - return getPackData(settings, logger); - }) - .then(() => { - return extract(settings, logger); - }) - .then(() => { - const files = glob.sync('**/*', { cwd: testWorkingPath }); - const expected = [ - 'archive.part', - 'README.md', - 'index.js', - 'package.json', - 'public', - 'public/app.js', - 'extra file only in zip.txt', - ]; - expect(files.sort()).toEqual(expected.sort()); - }); + // Also only extracts the content from the kibana folder. + // Ignores the others. + it('successfully extract a valid zip', async () => { + await copyReplyFile('test_plugin.zip'); + await getPackData(settings, logger); + await extract(settings, logger); + + expect(glob.sync('**/*', { cwd: testWorkingPath })).toMatchInlineSnapshot(` + Array [ + "archive.part", + "bin", + "bin/executable", + "bin/not-executable", + "kibana.json", + "node_modules", + "node_modules/some-package", + "node_modules/some-package/index.js", + "node_modules/some-package/package.json", + "public", + "public/index.js", + ] + `); }); }); - describe('getPackData', function () { - it('populate settings.plugins', function () { - return copyReplyFile('test_plugin.zip') - .then(() => { - return getPackData(settings, logger); - }) - .then(() => { - expect(settings.plugins[0].name).toBe('test-plugin'); - expect(settings.plugins[0].archivePath).toBe('kibana/test-plugin'); - expect(settings.plugins[0].version).toBe('1.0.0'); - expect(settings.plugins[0].kibanaVersion).toBe('1.0.0'); - }); - }); - - it('populate settings.plugin.kibanaVersion', function () { - //kibana.version is defined in this package.json and is different than plugin version - return copyReplyFile('test_plugin_different_version.zip') - .then(() => { - return getPackData(settings, logger); - }) - .then(() => { - expect(settings.plugins[0].kibanaVersion).toBe('5.0.1'); - }); + describe('getPackData', () => { + it('populate settings.plugins', async () => { + await copyReplyFile('test_plugin.zip'); + await getPackData(settings, logger); + expect(settings.plugins).toMatchInlineSnapshot(` + Array [ + Object { + "id": "testPlugin", + "kibanaVersion": "1.0.0", + "stripPrefix": "kibana/test-plugin", + }, + ] + `); }); - it('populate settings.plugin.kibanaVersion (default to plugin version)', function () { - //kibana.version is not defined in this package.json, defaults to plugin version - return copyReplyFile('test_plugin.zip') - .then(() => { - return getPackData(settings, logger); - }) - .then(() => { - expect(settings.plugins[0].kibanaVersion).toBe('1.0.0'); - }); + it('populate settings.plugin.kibanaVersion', async () => { + await copyReplyFile('test_plugin_different_version.zip'); + await getPackData(settings, logger); + expect(settings.plugins).toMatchInlineSnapshot(` + Array [ + Object { + "id": "testPlugin", + "kibanaVersion": "5.0.1", + "stripPrefix": "kibana/test-plugin", + }, + ] + `); }); - it('populate settings.plugins with multiple plugins', function () { - return copyReplyFile('test_plugin_many.zip') - .then(() => { - return getPackData(settings, logger); - }) - .then(() => { - expect(settings.plugins[0].name).toBe('funger-plugin'); - expect(settings.plugins[0].archivePath).toBe('kibana/funger-plugin'); - expect(settings.plugins[0].version).toBe('1.0.0'); - - expect(settings.plugins[1].name).toBe('pdf'); - expect(settings.plugins[1].archivePath).toBe('kibana/pdf-linux'); - expect(settings.plugins[1].version).toBe('1.0.0'); - - expect(settings.plugins[2].name).toBe('pdf'); - expect(settings.plugins[2].archivePath).toBe('kibana/pdf-win32'); - expect(settings.plugins[2].version).toBe('1.0.0'); - - expect(settings.plugins[3].name).toBe('pdf'); - expect(settings.plugins[3].archivePath).toBe('kibana/pdf-win64'); - expect(settings.plugins[3].version).toBe('1.0.0'); - - expect(settings.plugins[4].name).toBe('pdf'); - expect(settings.plugins[4].archivePath).toBe('kibana/pdf'); - expect(settings.plugins[4].version).toBe('1.0.0'); - - expect(settings.plugins[5].name).toBe('test-plugin'); - expect(settings.plugins[5].archivePath).toBe('kibana/test-plugin'); - expect(settings.plugins[5].version).toBe('1.0.0'); - }); + it('populate settings.plugins with multiple plugins', async () => { + await copyReplyFile('test_plugin_many.zip'); + await getPackData(settings, logger); + expect(settings.plugins).toMatchInlineSnapshot(` + Array [ + Object { + "id": "fungerPlugin", + "kibanaVersion": "1.0.0", + "stripPrefix": "kibana/funger-plugin", + }, + Object { + "id": "pdf", + "kibanaVersion": "1.0.0", + "stripPrefix": "kibana/pdf", + }, + Object { + "id": "testPlugin", + "kibanaVersion": "1.0.0", + "stripPrefix": "kibana/test-plugin", + }, + ] + `); }); - it('throw an error if there is no kibana plugin', function () { - return copyReplyFile('test_plugin_no_kibana.zip') - .then(() => { - return getPackData(settings, logger); - }) - .then(shouldReject, (err) => { - expect(err.message).toMatch(/No kibana plugins found in archive/i); - }); + it('throw an error if there is no kibana plugin', async () => { + await copyReplyFile('test_plugin_no_kibana.zip'); + await expect(getPackData(settings, logger)).rejects.toThrowErrorMatchingInlineSnapshot( + `"No kibana plugins found in archive"` + ); }); - it('throw an error with a corrupt zip', function () { - return copyReplyFile('corrupt.zip') - .then(() => { - return getPackData(settings, logger); - }) - .then(shouldReject, (err) => { - expect(err.message).toMatch(/error retrieving/i); - }); + it('throw an error with a corrupt zip', async () => { + await copyReplyFile('corrupt.zip'); + await expect(getPackData(settings, logger)).rejects.toThrowErrorMatchingInlineSnapshot( + `"Error retrieving metadata from plugin archive"` + ); }); - it('throw an error if there an invalid plugin name', function () { - return copyReplyFile('invalid_name.zip') - .then(() => { - return getPackData(settings, logger); - }) - .then(shouldReject, (err) => { - expect(err.message).toMatch(/invalid plugin name/i); - }); + it('throw an error if there an invalid plugin name', async () => { + await copyReplyFile('invalid_name.zip'); + await expect(getPackData(settings, logger)).rejects.toThrowErrorMatchingInlineSnapshot( + `"Invalid plugin name [invalid name] in kibana.json, expected it to be valid camelCase"` + ); }); }); }); diff --git a/src/cli_plugin/install/progress.js b/src/cli_plugin/install/progress.js index e58e4472150b9..5c7d5074603dc 100644 --- a/src/cli_plugin/install/progress.js +++ b/src/cli_plugin/install/progress.js @@ -20,7 +20,7 @@ /** * Generates file transfer progress messages */ -export default class Progress { +export class Progress { constructor(logger) { const self = this; diff --git a/src/cli_plugin/install/progress.test.js b/src/cli_plugin/install/progress.test.js index 3b66e8b3dc86c..ef948bafca836 100644 --- a/src/cli_plugin/install/progress.test.js +++ b/src/cli_plugin/install/progress.test.js @@ -18,8 +18,9 @@ */ import sinon from 'sinon'; -import Progress from './progress'; -import Logger from '../lib/logger'; + +import { Progress } from './progress'; +import { Logger } from '../lib/logger'; describe('kibana cli', function () { describe('plugin installer', function () { diff --git a/src/cli_plugin/install/rename.js b/src/cli_plugin/install/rename.js index 1e5d94d474375..897222a579a4a 100644 --- a/src/cli_plugin/install/rename.js +++ b/src/cli_plugin/install/rename.js @@ -18,6 +18,7 @@ */ import { rename } from 'fs'; + import { delay } from 'lodash'; export function renamePlugin(workingPath, finalPath) { @@ -31,8 +32,12 @@ export function renamePlugin(workingPath, finalPath) { // Retry for up to retryTime seconds const windowsEPERM = process.platform === 'win32' && err.code === 'EPERM'; const retryAvailable = Date.now() - start < retryTime; - if (windowsEPERM && retryAvailable) - return delay(rename, retryDelay, workingPath, finalPath, retry); + + if (windowsEPERM && retryAvailable) { + delay(rename, retryDelay, workingPath, finalPath, retry); + return; + } + reject(err); } resolve(); diff --git a/src/cli_plugin/install/rename.test.js b/src/cli_plugin/install/rename.test.js index 40df75adc5efa..8525c367540f8 100644 --- a/src/cli_plugin/install/rename.test.js +++ b/src/cli_plugin/install/rename.test.js @@ -17,9 +17,10 @@ * under the License. */ -import sinon from 'sinon'; import fs from 'fs'; +import sinon from 'sinon'; + import { renamePlugin } from './rename'; describe('plugin folder rename', function () { diff --git a/src/cli_plugin/install/settings.js b/src/cli_plugin/install/settings.js index 40c845fc37a9e..20a11479321ee 100644 --- a/src/cli_plugin/install/settings.js +++ b/src/cli_plugin/install/settings.js @@ -17,9 +17,12 @@ * under the License. */ -import expiry from 'expiry-js'; import { resolve } from 'path'; +import expiry from 'expiry-js'; + +import { fromRoot } from '../../core/server/utils'; + function generateUrls({ version, plugin }) { return [ plugin, @@ -46,20 +49,14 @@ export function parse(command, options, kbnPackage) { quiet: options.quiet || false, silent: options.silent || false, config: options.config || '', - optimize: options.optimize, plugin: command, version: kbnPackage.version, - pluginDir: options.pluginDir || '', + pluginDir: fromRoot('plugins'), }; settings.urls = generateUrls(settings); settings.workingPath = resolve(settings.pluginDir, '.plugin.installing'); settings.tempArchiveFile = resolve(settings.workingPath, 'archive.part'); - settings.tempPackageFile = resolve(settings.workingPath, 'package.json'); - settings.setPlugin = function (plugin) { - settings.plugin = plugin; - settings.pluginPath = resolve(settings.pluginDir, settings.plugin.name); - }; return settings; } diff --git a/src/cli_plugin/install/settings.test.js b/src/cli_plugin/install/settings.test.js index 39ca07405ade2..54ad453de9ef8 100644 --- a/src/cli_plugin/install/settings.test.js +++ b/src/cli_plugin/install/settings.test.js @@ -17,199 +17,82 @@ * under the License. */ +import { createAbsolutePathSerializer } from '@kbn/dev-utils'; + import { fromRoot } from '../../core/server/utils'; -import { resolve } from 'path'; import { parseMilliseconds, parse } from './settings'; -describe('kibana cli', function () { - describe('plugin installer', function () { - describe('command line option parsing', function () { - describe('parseMilliseconds function', function () { - it('should return 0 for an empty string', function () { - const value = ''; - const result = parseMilliseconds(value); - - expect(result).toBe(0); - }); - - it('should return 0 for a number with an invalid unit of measure', function () { - const result = parseMilliseconds('1gigablasts'); - expect(result).toBe(0); - }); - - it('should assume a number with no unit of measure is specified as milliseconds', function () { - const result = parseMilliseconds(1); - expect(result).toBe(1); - - const result2 = parseMilliseconds('1'); - expect(result2).toBe(1); - }); - - it('should interpret a number with "s" as the unit of measure as seconds', function () { - const result = parseMilliseconds('5s'); - expect(result).toBe(5 * 1000); - }); - - it('should interpret a number with "second" as the unit of measure as seconds', function () { - const result = parseMilliseconds('5second'); - expect(result).toBe(5 * 1000); - }); - - it('should interpret a number with "seconds" as the unit of measure as seconds', function () { - const result = parseMilliseconds('5seconds'); - expect(result).toBe(5 * 1000); - }); - - it('should interpret a number with "m" as the unit of measure as minutes', function () { - const result = parseMilliseconds('9m'); - expect(result).toBe(9 * 1000 * 60); - }); - - it('should interpret a number with "minute" as the unit of measure as minutes', function () { - const result = parseMilliseconds('9minute'); - expect(result).toBe(9 * 1000 * 60); - }); - - it('should interpret a number with "minutes" as the unit of measure as minutes', function () { - const result = parseMilliseconds('9minutes'); - expect(result).toBe(9 * 1000 * 60); - }); - }); - - describe('parse function', function () { - const command = 'plugin name'; - let options = {}; - const kbnPackage = { version: 1234 }; - beforeEach(function () { - options = { pluginDir: fromRoot('plugins') }; - }); - - describe('timeout option', function () { - it('should default to 0 (milliseconds)', function () { - const settings = parse(command, options, kbnPackage); - - expect(settings.timeout).toBe(0); - }); - - it('should set settings.timeout property', function () { - options.timeout = 1234; - const settings = parse(command, options, kbnPackage); - - expect(settings.timeout).toBe(1234); - }); - }); - - describe('quiet option', function () { - it('should default to false', function () { - const settings = parse(command, options, kbnPackage); - - expect(settings.quiet).toBe(false); - }); - - it('should set settings.quiet property to true', function () { - options.quiet = true; - const settings = parse(command, options, kbnPackage); - - expect(settings.quiet).toBe(true); - }); - }); - - describe('silent option', function () { - it('should default to false', function () { - const settings = parse(command, options, kbnPackage); - - expect(settings.silent).toBe(false); - }); - - it('should set settings.silent property to true', function () { - options.silent = true; - const settings = parse(command, options, kbnPackage); - - expect(settings.silent).toBe(true); - }); - }); - - describe('config option', function () { - it('should default to ZLS', function () { - const settings = parse(command, options, kbnPackage); - - expect(settings.config).toBe(''); - }); - - it('should set settings.config property', function () { - options.config = 'foo bar baz'; - const settings = parse(command, options, kbnPackage); - - expect(settings.config).toBe('foo bar baz'); - }); - }); - - describe('pluginDir option', function () { - it('should default to plugins', function () { - const settings = parse(command, options, kbnPackage); - - expect(settings.pluginDir).toBe(fromRoot('plugins')); - }); - - it('should set settings.config property', function () { - options.pluginDir = 'foo bar baz'; - const settings = parse(command, options, kbnPackage); - - expect(settings.pluginDir).toBe('foo bar baz'); - }); - }); - - describe('command value', function () { - it('should set settings.plugin property', function () { - const settings = parse(command, options, kbnPackage); - - expect(settings.plugin).toBe(command); - }); - }); - - describe('urls collection', function () { - it('should populate the settings.urls property', function () { - const settings = parse(command, options, kbnPackage); - - const expected = [ - command, - `https://artifacts.elastic.co/downloads/kibana-plugins/${command}/${command}-1234.zip`, - ]; - - expect(settings.urls).toEqual(expected); - }); - }); - - describe('workingPath value', function () { - it('should set settings.workingPath property', function () { - options.pluginDir = 'foo/bar/baz'; - const settings = parse(command, options, kbnPackage); - const expected = resolve('foo/bar/baz', '.plugin.installing'); - - expect(settings.workingPath).toBe(expected); - }); - }); - - describe('tempArchiveFile value', function () { - it('should set settings.tempArchiveFile property', function () { - options.pluginDir = 'foo/bar/baz'; - const settings = parse(command, options, kbnPackage); - const expected = resolve('foo/bar/baz', '.plugin.installing', 'archive.part'); - - expect(settings.tempArchiveFile).toBe(expected); - }); - }); +const SECOND = 1000; +const MINUTE = SECOND * 60; + +expect.addSnapshotSerializer(createAbsolutePathSerializer()); + +describe('parseMilliseconds function', function () { + it.each([ + ['', 0], + ['1gigablasts', 0], + [1, 1], + ['1', 1], + ['5s', 5 * SECOND], + ['5second', 5 * SECOND], + ['5seconds', 5 * SECOND], + ['9m', 9 * MINUTE], + ['9minute', 9 * MINUTE], + ['9minutes', 9 * MINUTE], + ])('should parse %j to %j', (input, result) => { + expect(parseMilliseconds(input)).toBe(result); + }); +}); - describe('tempPackageFile value', function () { - it('should set settings.tempPackageFile property', function () { - options.pluginDir = 'foo/bar/baz'; - const settings = parse(command, options, kbnPackage); - const expected = resolve('foo/bar/baz', '.plugin.installing', 'package.json'); +describe('parse function', function () { + const command = 'plugin name'; + const defaultOptions = { pluginDir: fromRoot('plugins') }; + const kbnPackage = { version: 1234 }; + + it('produces expected defaults', function () { + expect(parse(command, { ...defaultOptions }, kbnPackage)).toMatchInlineSnapshot(` + Object { + "config": "", + "plugin": "plugin name", + "pluginDir": /plugins, + "quiet": false, + "silent": false, + "tempArchiveFile": /plugins/.plugin.installing/archive.part, + "timeout": 0, + "urls": Array [ + "plugin name", + "https://artifacts.elastic.co/downloads/kibana-plugins/plugin name/plugin name-1234.zip", + ], + "version": 1234, + "workingPath": /plugins/.plugin.installing, + } + `); + }); - expect(settings.tempPackageFile).toBe(expected); - }); - }); - }); - }); + it('consumes overrides', function () { + const options = { + quiet: true, + silent: true, + config: 'foo bar baz', + ...defaultOptions, + }; + + expect(parse(command, options, kbnPackage)).toMatchInlineSnapshot(` + Object { + "config": "foo bar baz", + "plugin": "plugin name", + "pluginDir": /plugins, + "quiet": true, + "silent": true, + "tempArchiveFile": /plugins/.plugin.installing/archive.part, + "timeout": 0, + "urls": Array [ + "plugin name", + "https://artifacts.elastic.co/downloads/kibana-plugins/plugin name/plugin name-1234.zip", + ], + "version": 1234, + "workingPath": /plugins/.plugin.installing, + } + `); }); }); diff --git a/src/cli_plugin/install/zip.js b/src/cli_plugin/install/zip.js index 52eba2ea239a2..b906dd59a302b 100644 --- a/src/cli_plugin/install/zip.js +++ b/src/cli_plugin/install/zip.js @@ -17,21 +17,24 @@ * under the License. */ -import yauzl from 'yauzl'; import path from 'path'; import { createWriteStream, mkdir } from 'fs'; -import { get } from 'lodash'; + +import yauzl from 'yauzl'; + +const isDirectoryRegex = /(\/|\\)$/; +function isDirectory(filename) { + return isDirectoryRegex.test(filename); +} /** * Returns an array of package objects. There will be one for each of - * package.json files in the archive - * - * @param {string} archive - path to plugin archive zip file + * package.json files in the archive */ export function analyzeArchive(archive) { const plugins = []; - const regExp = new RegExp('(kibana[\\\\/][^\\\\/]+)[\\\\/]package.json', 'i'); + const regExp = new RegExp('(kibana[\\\\/][^\\\\/]+)[\\\\/]kibana.json', 'i'); return new Promise((resolve, reject) => { yauzl.open(archive, { lazyEntries: true }, function (err, zipfile) { @@ -47,31 +50,32 @@ export function analyzeArchive(archive) { return zipfile.readEntry(); } - zipfile.openReadStream(entry, function (err, readable) { + zipfile.openReadStream(entry, function (error, readable) { const chunks = []; - if (err) { - return reject(err); + if (error) { + return reject(error); } readable.on('data', (chunk) => chunks.push(chunk)); readable.on('end', function () { - const contents = Buffer.concat(chunks).toString(); - const pkg = JSON.parse(contents); - - plugins.push( - Object.assign(pkg, { - archivePath: match[1], - archive: archive, - - // Plugins must specify their version, and by default that version should match - // the version of kibana down to the patch level. If these two versions need - // to diverge, they can specify a kibana.version to indicate the version of - // kibana the plugin is intended to work with. - kibanaVersion: get(pkg, 'kibana.version', pkg.version), - }) - ); + const manifestJson = Buffer.concat(chunks).toString(); + const manifest = JSON.parse(manifestJson); + + plugins.push({ + id: manifest.id, + stripPrefix: match[1], + + // Plugins must specify their version, and by default that version in the plugin + // manifest should match the version of kibana down to the patch level. If these + // two versions need plugins can specify a kibanaVersion to indicate the version + // of kibana the plugin is intended to work with. + kibanaVersion: + typeof manifest.kibanaVersion === 'string' && manifest.kibanaVersion + ? manifest.kibanaVersion + : manifest.version, + }); zipfile.readEntry(); }); @@ -85,12 +89,7 @@ export function analyzeArchive(archive) { }); } -const isDirectoryRegex = /(\/|\\)$/; -export function _isDirectory(filename) { - return isDirectoryRegex.test(filename); -} - -export function extractArchive(archive, targetDir, extractPath) { +export function extractArchive(archive, targetDir, stripPrefix) { return new Promise((resolve, reject) => { yauzl.open(archive, { lazyEntries: true }, function (err, zipfile) { if (err) { @@ -102,8 +101,8 @@ export function extractArchive(archive, targetDir, extractPath) { zipfile.on('entry', function (entry) { let fileName = entry.fileName; - if (extractPath && fileName.startsWith(extractPath)) { - fileName = fileName.substring(extractPath.length); + if (stripPrefix && fileName.startsWith(stripPrefix)) { + fileName = fileName.substring(stripPrefix.length); } else { return zipfile.readEntry(); } @@ -112,30 +111,34 @@ export function extractArchive(archive, targetDir, extractPath) { fileName = path.join(targetDir, fileName); } - if (_isDirectory(fileName)) { - mkdir(fileName, { recursive: true }, function (err) { - if (err) { - return reject(err); + if (isDirectory(fileName)) { + mkdir(fileName, { recursive: true }, function (error) { + if (error) { + return reject(error); } zipfile.readEntry(); }); } else { // file entry - zipfile.openReadStream(entry, function (err, readStream) { - if (err) { - return reject(err); + zipfile.openReadStream(entry, function (error, readStream) { + if (error) { + return reject(error); } // ensure parent directory exists - mkdir(path.dirname(fileName), { recursive: true }, function (err) { - if (err) { - return reject(err); + mkdir(path.dirname(fileName), { recursive: true }, function (error2) { + if (error2) { + return reject(error2); } readStream.pipe( - createWriteStream(fileName, { mode: entry.externalFileAttributes >>> 16 }) + createWriteStream(fileName, { + // eslint-disable-next-line no-bitwise + mode: entry.externalFileAttributes >>> 16, + }) ); + readStream.on('end', function () { zipfile.readEntry(); }); diff --git a/src/cli_plugin/install/zip.test.js b/src/cli_plugin/install/zip.test.js index 28367e9e24453..0f56c0d0322aa 100644 --- a/src/cli_plugin/install/zip.test.js +++ b/src/cli_plugin/install/zip.test.js @@ -17,12 +17,16 @@ * under the License. */ -import del from 'del'; import path from 'path'; import os from 'os'; -import glob from 'glob'; import fs from 'fs'; -import { analyzeArchive, extractArchive, _isDirectory } from './zip'; + +import del from 'del'; +import glob from 'glob'; + +import { analyzeArchive, extractArchive } from './zip'; + +const getMode = (path) => (fs.statSync(path).mode & parseInt('777', 8)).toString(8); describe('kibana cli', function () { describe('zip', function () { @@ -43,32 +47,37 @@ describe('kibana cli', function () { describe('analyzeArchive', function () { it('returns array of plugins', async () => { const packages = await analyzeArchive(archivePath); - const plugin = packages[0]; - - expect(packages).toBeInstanceOf(Array); - expect(plugin.name).toBe('test-plugin'); - expect(plugin.archivePath).toBe('kibana/test-plugin'); - expect(plugin.archive).toBe(archivePath); - expect(plugin.kibanaVersion).toBe('1.0.0'); + expect(packages).toMatchInlineSnapshot(` + Array [ + Object { + "id": "testPlugin", + "kibanaVersion": "1.0.0", + "stripPrefix": "kibana/test-plugin", + }, + ] + `); }); }); describe('extractArchive', () => { it('extracts files using the extractPath filter', async () => { - const archive = path.resolve(repliesPath, 'test_plugin_many.zip'); - + const archive = path.resolve(repliesPath, 'test_plugin.zip'); await extractArchive(archive, tempPath, 'kibana/test-plugin'); - const files = await glob.sync('**/*', { cwd: tempPath }); - - const expected = [ - 'extra file only in zip.txt', - 'index.js', - 'package.json', - 'public', - 'public/app.js', - 'README.md', - ]; - expect(files.sort()).toEqual(expected.sort()); + + expect(glob.sync('**/*', { cwd: tempPath })).toMatchInlineSnapshot(` + Array [ + "bin", + "bin/executable", + "bin/not-executable", + "kibana.json", + "node_modules", + "node_modules/some-package", + "node_modules/some-package/index.js", + "node_modules/some-package/package.json", + "public", + "public/index.js", + ] + `); }); }); @@ -76,49 +85,26 @@ describe('kibana cli', function () { it('verify consistency of modes of files', async () => { const archivePath = path.resolve(repliesPath, 'test_plugin.zip'); - await extractArchive(archivePath, tempPath, 'kibana/libs'); - const files = await glob.sync('**/*', { cwd: tempPath }); - - const expected = ['executable', 'unexecutable']; - expect(files.sort()).toEqual(expected.sort()); + await extractArchive(archivePath, tempPath, 'kibana/test-plugin/bin'); - const executableMode = - '0' + - (fs.statSync(path.resolve(tempPath, 'executable')).mode & parseInt('777', 8)).toString(8); - const unExecutableMode = - '0' + - (fs.statSync(path.resolve(tempPath, 'unexecutable')).mode & parseInt('777', 8)).toString( - 8 - ); + expect(glob.sync('**/*', { cwd: tempPath })).toMatchInlineSnapshot(` + Array [ + "executable", + "not-executable", + ] + `); - expect(executableMode).toEqual('0755'); - expect(unExecutableMode).toEqual('0644'); + expect(getMode(path.resolve(tempPath, 'executable'))).toEqual('755'); + expect(getMode(path.resolve(tempPath, 'not-executable'))).toEqual('644'); }); }); it('handles a corrupt zip archive', async () => { - try { - await extractArchive(path.resolve(repliesPath, 'corrupt.zip')); - throw new Error('This should have failed'); - } catch (e) { - return; - } - }); - }); - - describe('_isDirectory', () => { - it('should check for a forward slash', () => { - expect(_isDirectory('/foo/bar/')).toBe(true); - }); - - it('should check for a backslash', () => { - expect(_isDirectory('\\foo\\bar\\')).toBe(true); - }); - - it('should return false for files', () => { - expect(_isDirectory('foo.txt')).toBe(false); - expect(_isDirectory('\\path\\to\\foo.txt')).toBe(false); - expect(_isDirectory('/path/to/foo.txt')).toBe(false); + await expect( + extractArchive(path.resolve(repliesPath, 'corrupt.zip')) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"end of central directory record signature not found"` + ); }); }); }); diff --git a/src/cli_plugin/lib/error_if_x_pack.js b/src/cli_plugin/lib/error_if_x_pack.js index d6624f5308ec0..4ea7ceb37478e 100644 --- a/src/cli_plugin/lib/error_if_x_pack.js +++ b/src/cli_plugin/lib/error_if_x_pack.js @@ -17,7 +17,7 @@ * under the License. */ -import { isOSS } from './is_oss'; +import { isOss } from './is_oss'; function isXPack(plugin) { return /x-pack/.test(plugin); @@ -25,7 +25,7 @@ function isXPack(plugin) { export function errorIfXPackInstall(settings) { if (isXPack(settings.plugin)) { - if (isOSS()) { + if (isOss()) { throw new Error( 'You are using the OSS-only distribution of Kibana. ' + 'As of version 6.3+ X-Pack is bundled in the standard distribution of this software by default; ' + @@ -40,7 +40,7 @@ export function errorIfXPackInstall(settings) { } export function errorIfXPackRemove(settings) { - if (isXPack(settings.plugin) && !isOSS()) { + if (isXPack(settings.plugin) && !isOss()) { throw new Error( 'You are using the standard distribution of Kibana. Please install the OSS-only distribution to remove X-Pack features.' ); diff --git a/src/cli_plugin/lib/is_oss.js b/src/cli_plugin/lib/is_oss.js index 3f2190d8346ec..53f19a41228d6 100644 --- a/src/cli_plugin/lib/is_oss.js +++ b/src/cli_plugin/lib/is_oss.js @@ -20,6 +20,6 @@ import fs from 'fs'; import path from 'path'; -export function isOSS() { +export function isOss() { return !fs.existsSync(path.resolve(__dirname, '../../../x-pack')); } diff --git a/src/cli_plugin/lib/is_oss.test.js b/src/cli_plugin/lib/is_oss.test.js index a4673710c63ce..636e1616e7d3c 100644 --- a/src/cli_plugin/lib/is_oss.test.js +++ b/src/cli_plugin/lib/is_oss.test.js @@ -17,12 +17,12 @@ * under the License. */ -import { isOSS } from './is_oss'; +import { isOss } from './is_oss'; describe('is_oss', () => { describe('x-pack installed', () => { it('should return false', () => { - expect(isOSS()).toEqual(false); + expect(isOss()).toEqual(false); }); }); }); diff --git a/src/cli_plugin/lib/log_warnings.js b/src/cli_plugin/lib/log_warnings.js index b4542acecb305..f31c3d4bd2e9a 100644 --- a/src/cli_plugin/lib/log_warnings.js +++ b/src/cli_plugin/lib/log_warnings.js @@ -17,7 +17,7 @@ * under the License. */ -export default function (settings, logger) { +export function logWarnings(logger) { process.on('warning', (warning) => { // deprecation warnings do no reflect a current problem for // the user and therefor should be filtered out. diff --git a/src/cli_plugin/lib/logger.js b/src/cli_plugin/lib/logger.js index efd6130322c38..592618fbecfc8 100644 --- a/src/cli_plugin/lib/logger.js +++ b/src/cli_plugin/lib/logger.js @@ -20,7 +20,7 @@ /** * Logs messages and errors */ -export default class Logger { +export class Logger { constructor(settings = {}) { this.previousLineEnded = true; this.silent = !!settings.silent; diff --git a/src/cli_plugin/lib/logger.test.js b/src/cli_plugin/lib/logger.test.js index 00cad1a9bbb11..7ff683ea50c95 100644 --- a/src/cli_plugin/lib/logger.test.js +++ b/src/cli_plugin/lib/logger.test.js @@ -18,7 +18,8 @@ */ import sinon from 'sinon'; -import Logger from './logger'; + +import { Logger } from './logger'; describe('kibana cli', function () { describe('plugin installer', function () { diff --git a/src/cli_plugin/lib/warn_if_plugin_dir_option.js b/src/cli_plugin/lib/warn_if_plugin_dir_option.js deleted file mode 100644 index eb85ba063c3c9..0000000000000 --- a/src/cli_plugin/lib/warn_if_plugin_dir_option.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export function warnIfUsingPluginDirOption(options, defaultValue, logger) { - if (options && options.pluginDir !== defaultValue) { - logger.log( - 'Warning: Using the -d, --plugin-dir option is deprecated, and is ' + - 'known to not work for all plugins, including X-Pack.' - ); - } -} diff --git a/src/cli_plugin/list/index.js b/src/cli_plugin/list/index.js index c0f708b8ccf83..a3cf1a54a8a62 100644 --- a/src/cli_plugin/list/index.js +++ b/src/cli_plugin/list/index.js @@ -18,37 +18,16 @@ */ import { fromRoot } from '../../core/server/utils'; -import list from './list'; -import Logger from '../lib/logger'; -import { parse } from './settings'; -import logWarnings from '../lib/log_warnings'; -import { warnIfUsingPluginDirOption } from '../lib/warn_if_plugin_dir_option'; +import { list } from './list'; +import { Logger } from '../lib/logger'; +import { logWarnings } from '../lib/log_warnings'; -function processCommand(command, options) { - let settings; - try { - settings = parse(command, options); - } catch (ex) { - //The logger has not yet been initialized. - console.error(ex.message); - process.exit(64); // eslint-disable-line no-process-exit - } - - const logger = new Logger(settings); - - warnIfUsingPluginDirOption(settings, fromRoot('plugins'), logger); - logWarnings(settings, logger); - list(settings, logger); +function processCommand() { + const logger = new Logger(); + logWarnings(logger); + list(fromRoot('plugins'), logger); } -export default function pluginList(program) { - program - .command('list') - .option( - '-d, --plugin-dir ', - 'path to the directory where plugins are stored (DEPRECATED, known to not work for all plugins)', - fromRoot('plugins') - ) - .description('list installed plugins') - .action(processCommand); +export function listCommand(program) { + program.command('list').description('list installed plugins').action(processCommand); } diff --git a/src/cli_plugin/list/list.js b/src/cli_plugin/list/list.js index b34631e5dfd08..bf6a082a91878 100644 --- a/src/cli_plugin/list/list.js +++ b/src/cli_plugin/list/list.js @@ -20,19 +20,20 @@ import { statSync, readdirSync, readFileSync } from 'fs'; import { join } from 'path'; -export default function list(settings, logger) { - readdirSync(settings.pluginDir).forEach((filename) => { - const stat = statSync(join(settings.pluginDir, filename)); +export function list(pluginDir, logger) { + readdirSync(pluginDir).forEach((name) => { + const stat = statSync(join(pluginDir, name)); - if (stat.isDirectory() && filename[0] !== '.') { + if (stat.isDirectory() && name[0] !== '.') { try { - const packagePath = join(settings.pluginDir, filename, 'package.json'); - const { version } = JSON.parse(readFileSync(packagePath, 'utf8')); - logger.log(filename + '@' + version); + const packagePath = join(pluginDir, name, 'kibana.json'); + const pkg = JSON.parse(readFileSync(packagePath, 'utf8')); + logger.log(pkg.id + '@' + pkg.version); } catch (e) { - throw new Error('Unable to read package.json file for plugin ' + filename); + throw new Error('Unable to read kibana.json file for plugin ' + name); } } }); + logger.log(''); //intentional blank line for aesthetics } diff --git a/src/cli_plugin/list/list.test.js b/src/cli_plugin/list/list.test.js index 071a253fa87fe..b1b5d1cde6a35 100644 --- a/src/cli_plugin/list/list.test.js +++ b/src/cli_plugin/list/list.test.js @@ -17,78 +17,67 @@ * under the License. */ -import sinon from 'sinon'; -import del from 'del'; -import Logger from '../lib/logger'; -import list from './list'; import { join } from 'path'; -import { writeFileSync, appendFileSync, mkdirSync } from 'fs'; +import { writeFileSync, mkdirSync } from 'fs'; + +import del from 'del'; + +import { list } from './list'; function createPlugin(name, version, pluginBaseDir) { const pluginDir = join(pluginBaseDir, name); mkdirSync(pluginDir, { recursive: true }); - appendFileSync(join(pluginDir, 'package.json'), '{"version": "' + version + '"}'); + writeFileSync( + join(pluginDir, 'kibana.json'), + JSON.stringify({ + id: name, + version, + }) + ); } +const logger = { + messages: [], + log(msg) { + this.messages.push(`log: ${msg}`); + }, + error(msg) { + this.messages.push(`error: ${msg}`); + }, +}; + describe('kibana cli', function () { describe('plugin lister', function () { const pluginDir = join(__dirname, '.test.data.list'); - let logger; - - const settings = { - pluginDir: pluginDir, - }; beforeEach(function () { - logger = new Logger(settings); - sinon.stub(logger, 'log'); - sinon.stub(logger, 'error'); + logger.messages.length = 0; del.sync(pluginDir); mkdirSync(pluginDir, { recursive: true }); }); afterEach(function () { - logger.log.restore(); - logger.error.restore(); del.sync(pluginDir); }); - it('list all of the folders in the plugin folder', function () { - createPlugin('plugin1', '5.0.0-alpha2', pluginDir); - createPlugin('plugin2', '3.2.1', pluginDir); - createPlugin('plugin3', '1.2.3', pluginDir); - - list(settings, logger); - - expect(logger.log.calledWith('plugin1@5.0.0-alpha2')).toBe(true); - expect(logger.log.calledWith('plugin2@3.2.1')).toBe(true); - expect(logger.log.calledWith('plugin3@1.2.3')).toBe(true); - }); - - it('ignore folders that start with a period', function () { + it('list all of the folders in the plugin folder, ignoring dot prefixed plugins and regular files', function () { createPlugin('.foo', '1.0.0', pluginDir); createPlugin('plugin1', '5.0.0-alpha2', pluginDir); createPlugin('plugin2', '3.2.1', pluginDir); createPlugin('plugin3', '1.2.3', pluginDir); createPlugin('.bar', '1.0.0', pluginDir); - - list(settings, logger); - - expect(logger.log.calledWith('.foo@1.0.0')).toBe(false); - expect(logger.log.calledWith('.bar@1.0.0')).toBe(false); - }); - - it('list should only list folders', function () { - createPlugin('plugin1', '1.0.0', pluginDir); - createPlugin('plugin2', '1.0.0', pluginDir); - createPlugin('plugin3', '1.0.0', pluginDir); writeFileSync(join(pluginDir, 'plugin4'), 'This is a file, and not a folder.'); - list(settings, logger); + list(pluginDir, logger); - expect(logger.log.calledWith('plugin1@1.0.0')).toBe(true); - expect(logger.log.calledWith('plugin2@1.0.0')).toBe(true); - expect(logger.log.calledWith('plugin3@1.0.0')).toBe(true); + expect(logger.messages).toMatchInlineSnapshot(` + Array [ + "log: plugin1@5.0.0-alpha2", + "log: plugin2@3.2.1", + "log: plugin3@1.2.3", + "log: ", + ] + `); }); it('list should throw an exception if a plugin does not have a package.json', function () { @@ -96,19 +85,23 @@ describe('kibana cli', function () { mkdirSync(join(pluginDir, 'empty-plugin'), { recursive: true }); expect(function () { - list(settings, logger); - }).toThrowError('Unable to read package.json file for plugin empty-plugin'); + list(pluginDir, logger); + }).toThrowErrorMatchingInlineSnapshot( + `"Unable to read kibana.json file for plugin empty-plugin"` + ); }); it('list should throw an exception if a plugin have an empty package.json', function () { createPlugin('plugin1', '1.0.0', pluginDir); const invalidPluginDir = join(pluginDir, 'invalid-plugin'); mkdirSync(invalidPluginDir, { recursive: true }); - appendFileSync(join(invalidPluginDir, 'package.json'), ''); + writeFileSync(join(invalidPluginDir, 'package.json'), ''); expect(function () { - list(settings, logger); - }).toThrowError('Unable to read package.json file for plugin invalid-plugin'); + list(pluginDir, logger); + }).toThrowErrorMatchingInlineSnapshot( + `"Unable to read kibana.json file for plugin invalid-plugin"` + ); }); }); }); diff --git a/src/cli_plugin/list/settings.js b/src/cli_plugin/list/settings.js deleted file mode 100644 index d17ce5deaec30..0000000000000 --- a/src/cli_plugin/list/settings.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export function parse(command) { - const settings = { - pluginDir: command.pluginDir || '', - }; - - return settings; -} diff --git a/src/cli_plugin/list/settings.test.js b/src/cli_plugin/list/settings.test.js deleted file mode 100644 index 85e6cb88e82fd..0000000000000 --- a/src/cli_plugin/list/settings.test.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { fromRoot } from '../../core/server/utils'; -import { parse } from './settings'; - -describe('kibana cli', function () { - describe('plugin installer', function () { - describe('command line option parsing', function () { - describe('parse function', function () { - let command; - const options = {}; - beforeEach(function () { - command = { pluginDir: fromRoot('plugins') }; - }); - - describe('pluginDir option', function () { - it('should default to plugins', function () { - const settings = parse(command, options); - - expect(settings.pluginDir).toBe(fromRoot('plugins')); - }); - - it('should set settings.config property', function () { - command.pluginDir = 'foo bar baz'; - const settings = parse(command, options); - - expect(settings.pluginDir).toBe('foo bar baz'); - }); - }); - }); - }); - }); -}); diff --git a/src/cli_plugin/remove/index.js b/src/cli_plugin/remove/index.js index 9ff06e0e760bf..c3bd96086db9b 100644 --- a/src/cli_plugin/remove/index.js +++ b/src/cli_plugin/remove/index.js @@ -17,46 +17,34 @@ * under the License. */ -import { fromRoot } from '../../core/server/utils'; -import remove from './remove'; -import Logger from '../lib/logger'; +import { remove } from './remove'; +import { Logger } from '../lib/logger'; import { parse } from './settings'; import { getConfigPath } from '../../core/server/path'; -import logWarnings from '../lib/log_warnings'; -import { warnIfUsingPluginDirOption } from '../lib/warn_if_plugin_dir_option'; +import { logWarnings } from '../lib/log_warnings'; function processCommand(command, options) { let settings; try { settings = parse(command, options); } catch (ex) { - //The logger has not yet been initialized. + // The logger has not yet been initialized. console.error(ex.message); process.exit(64); // eslint-disable-line no-process-exit } const logger = new Logger(settings); - warnIfUsingPluginDirOption(settings, fromRoot('plugins'), logger); logWarnings(settings, logger); remove(settings, logger); } -export default function pluginRemove(program) { +export function removeCommand(program) { program .command('remove ') .option('-q, --quiet', 'disable all process messaging except errors') .option('-s, --silent', 'disable all process messaging') .option('-c, --config ', 'path to the config file', getConfigPath()) - .option( - '-d, --plugin-dir ', - 'path to the directory where plugins are stored (DEPRECATED, known to not work for all plugins)', - fromRoot('plugins') - ) - .description( - 'remove a plugin', - `common examples: - remove x-pack` - ) + .description('remove a plugin') .action(processCommand); } diff --git a/src/cli_plugin/remove/remove.js b/src/cli_plugin/remove/remove.js index 353e592390ff4..0c218301242be 100644 --- a/src/cli_plugin/remove/remove.js +++ b/src/cli_plugin/remove/remove.js @@ -18,11 +18,12 @@ */ import { statSync } from 'fs'; -import { errorIfXPackRemove } from '../lib/error_if_x_pack'; import del from 'del'; -export default function remove(settings, logger) { +import { errorIfXPackRemove } from '../lib/error_if_x_pack'; + +export function remove(settings, logger) { try { let stat; try { diff --git a/src/cli_plugin/remove/remove.test.js b/src/cli_plugin/remove/remove.test.js index 4bf061820aa05..44c66468bbb55 100644 --- a/src/cli_plugin/remove/remove.test.js +++ b/src/cli_plugin/remove/remove.test.js @@ -17,13 +17,15 @@ * under the License. */ +import { join } from 'path'; +import { writeFileSync, existsSync, mkdirSync } from 'fs'; + import sinon from 'sinon'; import glob from 'glob-all'; import del from 'del'; -import Logger from '../lib/logger'; -import remove from './remove'; -import { join } from 'path'; -import { writeFileSync, existsSync, mkdirSync } from 'fs'; + +import { Logger } from '../lib/logger'; +import { remove } from './remove'; describe('kibana cli', function () { describe('plugin remover', function () { diff --git a/src/cli_plugin/remove/settings.js b/src/cli_plugin/remove/settings.js index dc8d3c87e6eab..8a7d41b35ae57 100644 --- a/src/cli_plugin/remove/settings.js +++ b/src/cli_plugin/remove/settings.js @@ -19,12 +19,14 @@ import { resolve } from 'path'; +import { fromRoot } from '../../core/server/utils'; + export function parse(command, options) { const settings = { quiet: options.quiet || false, silent: options.silent || false, config: options.config || '', - pluginDir: options.pluginDir || '', + pluginDir: fromRoot('plugins'), plugin: command, }; diff --git a/src/cli_plugin/remove/settings.test.js b/src/cli_plugin/remove/settings.test.js index b3110e1ff0499..9ae555d79cd1a 100644 --- a/src/cli_plugin/remove/settings.test.js +++ b/src/cli_plugin/remove/settings.test.js @@ -17,88 +17,42 @@ * under the License. */ -import { fromRoot } from '../../core/server/utils'; -import { parse } from './settings'; - -describe('kibana cli', function () { - describe('plugin installer', function () { - describe('command line option parsing', function () { - describe('parse function', function () { - const command = 'plugin name'; - let options = {}; - const kbnPackage = { version: 1234 }; - beforeEach(function () { - options = { pluginDir: fromRoot('plugins') }; - }); - - describe('quiet option', function () { - it('should default to false', function () { - const settings = parse(command, options, kbnPackage); - - expect(settings.quiet).toBe(false); - }); - - it('should set settings.quiet property to true', function () { - options.quiet = true; - const settings = parse(command, options, kbnPackage); - - expect(settings.quiet).toBe(true); - }); - }); - - describe('silent option', function () { - it('should default to false', function () { - const settings = parse(command, options, kbnPackage); - - expect(settings.silent).toBe(false); - }); - - it('should set settings.silent property to true', function () { - options.silent = true; - const settings = parse(command, options, kbnPackage); - - expect(settings.silent).toBe(true); - }); - }); +import { createAbsolutePathSerializer } from '@kbn/dev-utils'; - describe('config option', function () { - it('should default to ZLS', function () { - const settings = parse(command, options, kbnPackage); - - expect(settings.config).toBe(''); - }); - - it('should set settings.config property', function () { - options.config = 'foo bar baz'; - const settings = parse(command, options, kbnPackage); - - expect(settings.config).toBe('foo bar baz'); - }); - }); - - describe('pluginDir option', function () { - it('should default to plugins', function () { - const settings = parse(command, options, kbnPackage); - - expect(settings.pluginDir).toBe(fromRoot('plugins')); - }); - - it('should set settings.config property', function () { - options.pluginDir = 'foo bar baz'; - const settings = parse(command, options, kbnPackage); - - expect(settings.pluginDir).toBe('foo bar baz'); - }); - }); +import { parse } from './settings'; - describe('command value', function () { - it('should set settings.plugin property', function () { - const settings = parse(command, options, kbnPackage); +const command = 'plugin name'; + +expect.addSnapshotSerializer(createAbsolutePathSerializer()); + +it('produces the defaults', () => { + expect(parse(command, {})).toMatchInlineSnapshot(` + Object { + "config": "", + "plugin": "plugin name", + "pluginDir": /plugins, + "pluginPath": /plugins/plugin name, + "quiet": false, + "silent": false, + } + `); +}); - expect(settings.plugin).toBe(command); - }); - }); - }); - }); - }); +it('overrides the defaults with the parsed cli options', () => { + expect( + parse(command, { + quiet: true, + silent: true, + config: 'foo/bar', + }) + ).toMatchInlineSnapshot(` + Object { + "config": "foo/bar", + "plugin": "plugin name", + "pluginDir": /plugins, + "pluginPath": /plugins/plugin name, + "quiet": true, + "silent": true, + } + `); }); diff --git a/yarn.lock b/yarn.lock index 332215a59e788..42c4b800e6b0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7878,11 +7878,6 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= -builtins@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-0.0.7.tgz#355219cd6cf18dbe7c01cc7fd2dce765cfdc549a" - integrity sha1-NVIZzWzxjb58Acx/0tznZc/cVJo= - bytes@1: version "1.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" @@ -29959,13 +29954,6 @@ validate-npm-package-license@^3.0.1: spdx-correct "~1.0.0" spdx-expression-parse "~1.0.0" -validate-npm-package-name@2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-2.2.2.tgz#f65695b22f7324442019a3c7fa39a6e7fd299085" - integrity sha1-9laVsi9zJEQgGaPH+jmm5/0pkIU= - dependencies: - builtins "0.0.7" - validator@^10.11.0: version "10.11.0" resolved "https://registry.yarnpkg.com/validator/-/validator-10.11.0.tgz#003108ea6e9a9874d31ccc9e5006856ccd76b228" From 4ca52e678a86bc4c9ffef02a9886f6242fdb2273 Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Wed, 12 Aug 2020 19:26:06 -0500 Subject: [PATCH 03/15] [Security Solution][Detections] Refactor ML calls for newest ML permissions (#74582) ## Summary Addresses https://github.com/elastic/kibana/issues/73567. ML Users (role: `machine_learning_user`) were previously able to invoke the ML Recognizer API, which we use to get not-yet-installed ML Jobs relevant to our index patterns. As of https://github.com/elastic/kibana/pull/64662 this is not true, and so we receive errors from components using the underlying hook, `useSiemJobs`. To solve this I've created two separate hooks to replace `useSiemJobs`: * `useSecurityJobs` * used on ML Popover * includes uninstalled ML Jobs * checks (and returns) `isMlAdmin` before fetching data * `useInstalledSecurityJobs` * used on ML Jobs Dropdown and Anomalies Table * includes only installed ML Jobs * checks (and returns) `isMlUser` before fetching data Note that we while we now receive the knowledge to do so, we do not always inform the user in the case of invalid permissions, and instead have the following behaviors: #### User has insufficient license * ML Popover: shows an upgrade CTA * Anomalies Tables: show no data * Rule Creation: ML Rule option is disabled, shows upgrade CTA * Rule Details: ML Job Id is displayed as text #### User is ML User * ML Popover: not shown * Anomalies Tables: show no data * Rule Creation: ML Rule option is disabled * Rule Details: ML Job Id is displayed as text #### User is ML Admin * ML Popover: shown * Anomalies Tables: show data __for installed ML Jobs__ * This is the same as previous logic, but worth calling out that you can't view historical anomalies * Rule Creation: ML Rule option is enabled, all ML Jobs available * Rule Details: ML Job Id is displayed as hyperlink, job status badge shown ### Checklist - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process) --- .../anomaly_detection_jobs/summary_job.ts | 4 +- x-pack/plugins/ml/public/shared.ts | 1 + .../machine_learning/has_ml_license.test.ts | 20 ++++ .../common/machine_learning/has_ml_license.ts | 10 ++ .../machine_learning/is_security_job.ts | 3 +- .../ml/anomaly/use_anomalies_table_data.ts | 28 ++--- .../components/ml/api/get_jobs_summary.ts | 35 ++++++ .../components/ml/api/get_ml_capabilities.ts | 13 ++- .../ml/hooks/use_get_jobs_summary.ts | 12 ++ .../ml/hooks/use_get_ml_capabilities.ts | 12 ++ .../hooks/use_installed_security_jobs.test.ts | 99 ++++++++++++++++ .../ml/hooks/use_installed_security_jobs.ts | 63 ++++++++++ .../hooks/use_ml_capabilities.ts} | 2 +- .../permissions/ml_capabilities_provider.tsx | 47 +++----- .../ml/tables/anomalies_host_table.tsx | 2 +- .../ml/tables/anomalies_network_table.tsx | 2 +- .../{ml_popover/hooks => ml}/translations.ts | 0 .../{__mocks__/api.tsx => api.mock.ts} | 12 +- .../components/ml_popover/{api.tsx => api.ts} | 19 --- .../components/ml_popover/helpers.test.tsx | 12 +- .../common/components/ml_popover/helpers.tsx | 8 +- .../hooks/use_security_jobs.test.ts | 110 ++++++++++++++++++ .../ml_popover/hooks/use_security_jobs.ts | 95 +++++++++++++++ ...tsx => use_security_jobs_helpers.test.tsx} | 28 ++--- ...pers.tsx => use_security_jobs_helpers.tsx} | 71 +++++------ .../ml_popover/hooks/use_siem_jobs.tsx | 81 ------------- .../jobs_table_filters.test.tsx.snap | 2 +- .../filters/groups_filter_popover.test.tsx | 15 ++- .../filters/groups_filter_popover.tsx | 14 +-- .../filters/jobs_table_filters.test.tsx | 18 +-- .../jobs_table/filters/jobs_table_filters.tsx | 16 ++- .../ml_popover/jobs_table/job_switch.test.tsx | 24 ++-- .../ml_popover/jobs_table/job_switch.tsx | 12 +- .../ml_popover/jobs_table/jobs_table.test.tsx | 24 ++-- .../ml_popover/jobs_table/jobs_table.tsx | 27 +++-- .../components/ml_popover/ml_popover.tsx | 29 +++-- .../common/components/ml_popover/types.ts | 30 +---- .../anomalies_query_tab_body/index.tsx | 6 +- .../anomalies_query_tab_body/utils.ts | 9 +- .../common/hooks/use_app_toasts.mock.ts | 14 +++ .../common/lib/kibana/__mocks__/index.ts | 1 + .../public/common/mock/kibana_core.ts | 2 + .../public/common/mock/kibana_react.ts | 18 --- .../rules/description_step/index.tsx | 6 +- .../ml_job_description.test.tsx | 25 +--- .../description_step/ml_job_description.tsx | 14 +-- .../rules/ml_job_select/index.test.tsx | 6 +- .../components/rules/ml_job_select/index.tsx | 12 +- .../rules/step_define_rule/index.tsx | 5 +- .../detection_engine/rules/all/index.tsx | 6 +- .../detection_engine/rules/details/index.tsx | 6 +- .../public/hosts/pages/details/index.tsx | 2 +- .../public/hosts/pages/hosts.tsx | 2 +- .../network/components/ip_overview/index.tsx | 2 +- .../public/network/pages/index.tsx | 2 +- .../components/host_overview/index.tsx | 2 +- 56 files changed, 733 insertions(+), 407 deletions(-) create mode 100644 x-pack/plugins/security_solution/common/machine_learning/has_ml_license.test.ts create mode 100644 x-pack/plugins/security_solution/common/machine_learning/has_ml_license.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/ml/api/get_jobs_summary.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs_summary.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_ml_capabilities.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/ml/hooks/use_installed_security_jobs.test.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/ml/hooks/use_installed_security_jobs.ts rename x-pack/plugins/security_solution/public/common/components/{ml_popover/hooks/use_ml_capabilities.tsx => ml/hooks/use_ml_capabilities.ts} (80%) rename x-pack/plugins/security_solution/public/common/components/{ml_popover/hooks => ml}/translations.ts (100%) rename x-pack/plugins/security_solution/public/common/components/ml_popover/{__mocks__/api.tsx => api.mock.ts} (99%) rename x-pack/plugins/security_solution/public/common/components/ml_popover/{api.tsx => api.ts} (89%) create mode 100644 x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.test.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.ts rename x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/{use_siem_jobs_helpers.test.tsx => use_security_jobs_helpers.test.tsx} (83%) rename x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/{use_siem_jobs_helpers.tsx => use_security_jobs_helpers.tsx} (59%) delete mode 100644 x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs.tsx create mode 100644 x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.mock.ts diff --git a/x-pack/plugins/ml/common/types/anomaly_detection_jobs/summary_job.ts b/x-pack/plugins/ml/common/types/anomaly_detection_jobs/summary_job.ts index 2102673060273..d0bce8508e82e 100644 --- a/x-pack/plugins/ml/common/types/anomaly_detection_jobs/summary_job.ts +++ b/x-pack/plugins/ml/common/types/anomaly_detection_jobs/summary_job.ts @@ -36,8 +36,8 @@ export interface MlSummaryJob { export interface AuditMessage { job_id: string; msgTime: number; - level: number; - highestLevel: number; + level: string; + highestLevel: string; highestLevelText: string; text: string; } diff --git a/x-pack/plugins/ml/public/shared.ts b/x-pack/plugins/ml/public/shared.ts index 4b1d7ee733dcf..ec884bfac5351 100644 --- a/x-pack/plugins/ml/public/shared.ts +++ b/x-pack/plugins/ml/public/shared.ts @@ -9,6 +9,7 @@ export * from '../common/constants/anomalies'; export * from '../common/types/data_recognizer'; export * from '../common/types/capabilities'; export * from '../common/types/anomalies'; +export * from '../common/types/anomaly_detection_jobs'; export * from '../common/types/modules'; export * from '../common/types/audit_message'; diff --git a/x-pack/plugins/security_solution/common/machine_learning/has_ml_license.test.ts b/x-pack/plugins/security_solution/common/machine_learning/has_ml_license.test.ts new file mode 100644 index 0000000000000..1ffc2e16b78f7 --- /dev/null +++ b/x-pack/plugins/security_solution/common/machine_learning/has_ml_license.test.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { emptyMlCapabilities } from './empty_ml_capabilities'; +import { hasMlLicense } from './has_ml_license'; + +describe('hasMlLicense', () => { + test('it returns false when license is not platinum or trial', () => { + const capabilities = { ...emptyMlCapabilities, isPlatinumOrTrialLicense: false }; + expect(hasMlLicense(capabilities)).toEqual(false); + }); + + test('it returns true when license is platinum or trial', () => { + const capabilities = { ...emptyMlCapabilities, isPlatinumOrTrialLicense: true }; + expect(hasMlLicense(capabilities)).toEqual(true); + }); +}); diff --git a/x-pack/plugins/security_solution/common/machine_learning/has_ml_license.ts b/x-pack/plugins/security_solution/common/machine_learning/has_ml_license.ts new file mode 100644 index 0000000000000..c0b6862ac30fe --- /dev/null +++ b/x-pack/plugins/security_solution/common/machine_learning/has_ml_license.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { MlCapabilitiesResponse } from '../../../ml/common/types/capabilities'; + +export const hasMlLicense = (capabilities: MlCapabilitiesResponse): boolean => + capabilities.isPlatinumOrTrialLicense; diff --git a/x-pack/plugins/security_solution/common/machine_learning/is_security_job.ts b/x-pack/plugins/security_solution/common/machine_learning/is_security_job.ts index 43cfa4ad59964..f5783fc9b3973 100644 --- a/x-pack/plugins/security_solution/common/machine_learning/is_security_job.ts +++ b/x-pack/plugins/security_solution/common/machine_learning/is_security_job.ts @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { MlSummaryJob } from '../../../ml/common/types/anomaly_detection_jobs'; import { ML_GROUP_IDS } from '../constants'; -export const isSecurityJob = (job: MlSummaryJob): boolean => +export const isSecurityJob = (job: { groups: string[] }): boolean => job.groups.some((group) => ML_GROUP_IDS.includes(group)); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts b/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts index 6fbb308672e5d..e6597de892bff 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts @@ -9,13 +9,11 @@ import { useState, useEffect, useMemo } from 'react'; import { DEFAULT_ANOMALY_SCORE } from '../../../../../common/constants'; import { anomaliesTableData } from '../api/anomalies_table_data'; import { InfluencerInput, Anomalies, CriteriaFields } from '../types'; -import { hasMlUserPermissions } from '../../../../../common/machine_learning/has_ml_user_permissions'; -import { useSiemJobs } from '../../ml_popover/hooks/use_siem_jobs'; -import { useMlCapabilities } from '../../ml_popover/hooks/use_ml_capabilities'; -import { useStateToaster, errorToToaster } from '../../toasters'; import * as i18n from './translations'; import { useTimeZone, useUiSetting$ } from '../../../lib/kibana'; +import { useAppToasts } from '../../../hooks/use_app_toasts'; +import { useInstalledSecurityJobs } from '../hooks/use_installed_security_jobs'; interface Args { influencers?: InfluencerInput[]; @@ -58,15 +56,13 @@ export const useAnomaliesTableData = ({ skip = false, }: Args): Return => { const [tableData, setTableData] = useState(null); - const [, siemJobs] = useSiemJobs(true); + const { isMlUser, jobs } = useInstalledSecurityJobs(); const [loading, setLoading] = useState(true); - const capabilities = useMlCapabilities(); - const userPermissions = hasMlUserPermissions(capabilities); - const [, dispatchToaster] = useStateToaster(); + const { addError } = useAppToasts(); const timeZone = useTimeZone(); const [anomalyScore] = useUiSetting$(DEFAULT_ANOMALY_SCORE); - const siemJobIds = siemJobs.filter((job) => job.isInstalled).map((job) => job.id); + const jobIds = jobs.map((job) => job.id); const startDateMs = useMemo(() => new Date(startDate).getTime(), [startDate]); const endDateMs = useMemo(() => new Date(endDate).getTime(), [endDate]); @@ -81,11 +77,11 @@ export const useAnomaliesTableData = ({ earliestMs: number, latestMs: number ) { - if (userPermissions && !skip && siemJobIds.length > 0) { + if (isMlUser && !skip && jobIds.length > 0) { try { const data = await anomaliesTableData( { - jobIds: siemJobIds, + jobIds, criteriaFields: criteriaFieldsInput, aggregationInterval: 'auto', threshold: getThreshold(anomalyScore, threshold), @@ -104,13 +100,13 @@ export const useAnomaliesTableData = ({ } } catch (error) { if (isSubscribed) { - errorToToaster({ title: i18n.SIEM_TABLE_FETCH_FAILURE, error, dispatchToaster }); + addError(error, { title: i18n.SIEM_TABLE_FETCH_FAILURE }); setLoading(false); } } - } else if (!userPermissions && isSubscribed) { + } else if (!isMlUser && isSubscribed) { setLoading(false); - } else if (siemJobIds.length === 0 && isSubscribed) { + } else if (jobIds.length === 0 && isSubscribed) { setLoading(false); } else if (isSubscribed) { setTableData(null); @@ -132,9 +128,9 @@ export const useAnomaliesTableData = ({ startDateMs, endDateMs, skip, - userPermissions, + isMlUser, // eslint-disable-next-line react-hooks/exhaustive-deps - siemJobIds.sort().join(), + jobIds.sort().join(), ]); return [loading, tableData]; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/api/get_jobs_summary.ts b/x-pack/plugins/security_solution/public/common/components/ml/api/get_jobs_summary.ts new file mode 100644 index 0000000000000..15f823814d7fc --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/ml/api/get_jobs_summary.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { HttpSetup } from '../../../../../../../../src/core/public'; +import { MlSummaryJob } from '../../../../../../ml/public'; + +export interface GetJobsSummaryArgs { + http: HttpSetup; + jobIds?: string[]; + signal: AbortSignal; +} + +/** + * Fetches a summary of all ML jobs currently installed + * + * @param http HTTP Service + * @param jobIds Array of job IDs to filter against + * @param signal to cancel request + * + * @throws An error if response is not OK + */ +export const getJobsSummary = async ({ + http, + jobIds, + signal, +}: GetJobsSummaryArgs): Promise => + http.fetch('/api/ml/jobs/jobs_summary', { + method: 'POST', + body: JSON.stringify({ jobIds: jobIds ?? [] }), + asSystemRequest: true, + signal, + }); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/api/get_ml_capabilities.ts b/x-pack/plugins/security_solution/public/common/components/ml/api/get_ml_capabilities.ts index 32f6f888ab8d7..8ee765c1dea47 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/api/get_ml_capabilities.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/api/get_ml_capabilities.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { HttpSetup } from '../../../../../../../../src/core/public'; import { MlCapabilitiesResponse } from '../../../../../../ml/public'; -import { KibanaServices } from '../../../lib/kibana'; import { InfluencerInput } from '../types'; export interface Body { @@ -21,10 +21,15 @@ export interface Body { maxExamples: number; } -export const getMlCapabilities = async (signal: AbortSignal): Promise => { - return KibanaServices.get().http.fetch('/api/ml/ml_capabilities', { +export const getMlCapabilities = async ({ + http, + signal, +}: { + http: HttpSetup; + signal: AbortSignal; +}): Promise => + http.fetch('/api/ml/ml_capabilities', { method: 'GET', asSystemRequest: true, signal, }); -}; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs_summary.ts b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs_summary.ts new file mode 100644 index 0000000000000..a80bfb59649cb --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs_summary.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useAsync, withOptionalSignal } from '../../../../shared_imports'; +import { getJobsSummary } from '../api/get_jobs_summary'; + +const _getJobsSummary = withOptionalSignal(getJobsSummary); + +export const useGetJobsSummary = () => useAsync(_getJobsSummary); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_ml_capabilities.ts b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_ml_capabilities.ts new file mode 100644 index 0000000000000..aabd8c7b62e85 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_ml_capabilities.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getMlCapabilities } from '../api/get_ml_capabilities'; +import { useAsync, withOptionalSignal } from '../../../../shared_imports'; + +const _getMlCapabilities = withOptionalSignal(getMlCapabilities); + +export const useGetMlCapabilities = () => useAsync(_getMlCapabilities); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_installed_security_jobs.test.ts b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_installed_security_jobs.test.ts new file mode 100644 index 0000000000000..72690a1773926 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_installed_security_jobs.test.ts @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { renderHook } from '@testing-library/react-hooks'; + +import { hasMlUserPermissions } from '../../../../../common/machine_learning/has_ml_user_permissions'; +import { hasMlLicense } from '../../../../../common/machine_learning/has_ml_license'; +import { isSecurityJob } from '../../../../../common/machine_learning/is_security_job'; +import { useAppToasts } from '../../../hooks/use_app_toasts'; +import { useAppToastsMock } from '../../../hooks/use_app_toasts.mock'; +import { mockJobsSummaryResponse } from '../../ml_popover/api.mock'; +import { getJobsSummary } from '../api/get_jobs_summary'; +import { useInstalledSecurityJobs } from './use_installed_security_jobs'; + +jest.mock('../../../../../common/machine_learning/has_ml_user_permissions'); +jest.mock('../../../../../common/machine_learning/has_ml_license'); +jest.mock('../../../hooks/use_app_toasts'); +jest.mock('../api/get_jobs_summary'); + +describe('useInstalledSecurityJobs', () => { + let appToastsMock: jest.Mocked>; + + beforeEach(() => { + appToastsMock = useAppToastsMock.create(); + (useAppToasts as jest.Mock).mockReturnValue(appToastsMock); + (getJobsSummary as jest.Mock).mockResolvedValue(mockJobsSummaryResponse); + }); + + describe('when the user has permissions', () => { + beforeEach(() => { + (hasMlUserPermissions as jest.Mock).mockReturnValue(true); + (hasMlLicense as jest.Mock).mockReturnValue(true); + }); + + it('returns jobs and permissions', async () => { + const { result, waitForNextUpdate } = renderHook(() => useInstalledSecurityJobs()); + await waitForNextUpdate(); + + expect(result.current.jobs).toHaveLength(3); + expect(result.current.jobs).toEqual( + expect.arrayContaining([ + { + datafeedId: 'datafeed-siem-api-rare_process_linux_ecs', + datafeedIndices: ['auditbeat-*'], + datafeedState: 'stopped', + description: 'SIEM Auditbeat: Detect unusually rare processes on Linux (beta)', + earliestTimestampMs: 1557353420495, + groups: ['siem'], + hasDatafeed: true, + id: 'siem-api-rare_process_linux_ecs', + isSingleMetricViewerJob: true, + jobState: 'closed', + latestTimestampMs: 1557434782207, + memory_status: 'hard_limit', + processed_record_count: 582251, + }, + ]) + ); + expect(result.current.isMlUser).toEqual(true); + expect(result.current.isLicensed).toEqual(true); + }); + + it('filters out non-security jobs', async () => { + const { result, waitForNextUpdate } = renderHook(() => useInstalledSecurityJobs()); + await waitForNextUpdate(); + + expect(result.current.jobs.length).toBeGreaterThan(0); + expect(result.current.jobs.every(isSecurityJob)).toEqual(true); + }); + + it('renders a toast error if the ML call fails', async () => { + (getJobsSummary as jest.Mock).mockRejectedValue('whoops'); + const { waitForNextUpdate } = renderHook(() => useInstalledSecurityJobs()); + await waitForNextUpdate(); + + expect(appToastsMock.addError).toHaveBeenCalledWith('whoops', { + title: 'Security job fetch failure', + }); + }); + }); + + describe('when the user does not have valid permissions', () => { + beforeEach(() => { + (hasMlUserPermissions as jest.Mock).mockReturnValue(false); + (hasMlLicense as jest.Mock).mockReturnValue(false); + }); + + it('returns empty jobs and false predicates', () => { + const { result } = renderHook(() => useInstalledSecurityJobs()); + + expect(result.current.jobs).toEqual([]); + expect(result.current.isMlUser).toEqual(false); + expect(result.current.isLicensed).toEqual(false); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_installed_security_jobs.ts b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_installed_security_jobs.ts new file mode 100644 index 0000000000000..a9a728f81cc6c --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_installed_security_jobs.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useEffect, useState } from 'react'; + +import { MlSummaryJob } from '../../../../../../ml/public'; +import { hasMlUserPermissions } from '../../../../../common/machine_learning/has_ml_user_permissions'; +import { hasMlLicense } from '../../../../../common/machine_learning/has_ml_license'; +import { isSecurityJob } from '../../../../../common/machine_learning/is_security_job'; +import { useAppToasts } from '../../../hooks/use_app_toasts'; +import { useHttp } from '../../../lib/kibana'; +import { useMlCapabilities } from './use_ml_capabilities'; +import * as i18n from '../translations'; +import { useGetJobsSummary } from './use_get_jobs_summary'; + +export interface UseInstalledSecurityJobsReturn { + loading: boolean; + jobs: MlSummaryJob[]; + isMlUser: boolean; + isLicensed: boolean; +} + +/** + * Returns a collection of installed ML jobs (MlSummaryJob) relevant to + * Security Solution, i.e. all installed jobs in the `security` ML group. + * Use the corresponding helper functions to filter the job list as + * necessary (running jobs, etc). + * + */ +export const useInstalledSecurityJobs = (): UseInstalledSecurityJobsReturn => { + const [jobs, setJobs] = useState([]); + const { addError } = useAppToasts(); + const mlCapabilities = useMlCapabilities(); + const http = useHttp(); + const { error, loading, result, start } = useGetJobsSummary(); + + const isMlUser = hasMlUserPermissions(mlCapabilities); + const isLicensed = hasMlLicense(mlCapabilities); + + useEffect(() => { + if (isMlUser && isLicensed) { + start({ http }); + } + }, [http, isMlUser, isLicensed, start]); + + useEffect(() => { + if (result) { + const securityJobs = result.filter(isSecurityJob); + setJobs(securityJobs); + } + }, [result]); + + useEffect(() => { + if (error) { + addError(error, { title: i18n.SIEM_JOB_FETCH_FAILURE }); + } + }, [addError, error]); + + return { isLicensed, isMlUser, jobs, loading }; +}; diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_ml_capabilities.tsx b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_ml_capabilities.ts similarity index 80% rename from x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_ml_capabilities.tsx rename to x-pack/plugins/security_solution/public/common/components/ml/hooks/use_ml_capabilities.ts index d897b2554b4fd..4f804a355e4b5 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_ml_capabilities.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_ml_capabilities.ts @@ -6,6 +6,6 @@ import { useContext } from 'react'; -import { MlCapabilitiesContext } from '../../ml/permissions/ml_capabilities_provider'; +import { MlCapabilitiesContext } from '../permissions/ml_capabilities_provider'; export const useMlCapabilities = () => useContext(MlCapabilitiesContext); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx b/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx index c83271a56be5a..c12c8d78da714 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/permissions/ml_capabilities_provider.tsx @@ -8,9 +8,9 @@ import React, { useState, useEffect } from 'react'; import { MlCapabilitiesResponse } from '../../../../../../ml/public'; import { emptyMlCapabilities } from '../../../../../common/machine_learning/empty_ml_capabilities'; -import { getMlCapabilities } from '../api/get_ml_capabilities'; -import { errorToToaster, useStateToaster } from '../../toasters'; - +import { useAppToasts } from '../../../hooks/use_app_toasts'; +import { useHttp } from '../../../lib/kibana'; +import { useGetMlCapabilities } from '../hooks/use_get_ml_capabilities'; import * as i18n from './translations'; interface MlCapabilitiesProvider extends MlCapabilitiesResponse { @@ -32,36 +32,27 @@ export const MlCapabilitiesProvider = React.memo<{ children: JSX.Element }>(({ c const [capabilities, setCapabilities] = useState( emptyMlCapabilitiesProvider ); - const [, dispatchToaster] = useStateToaster(); + const http = useHttp(); + const { addError } = useAppToasts(); + const { start, result, error } = useGetMlCapabilities(); useEffect(() => { - let isSubscribed = true; - const abortCtrl = new AbortController(); + start({ http }); + }, [http, start]); - async function fetchMlCapabilities() { - try { - const mlCapabilities = await getMlCapabilities(abortCtrl.signal); - if (isSubscribed) { - setCapabilities({ ...mlCapabilities, capabilitiesFetched: true }); - } - } catch (error) { - if (isSubscribed) { - errorToToaster({ - title: i18n.MACHINE_LEARNING_PERMISSIONS_FAILURE, - error, - dispatchToaster, - }); - } - } + useEffect(() => { + if (result) { + setCapabilities({ ...result, capabilitiesFetched: true }); } + }, [result]); - fetchMlCapabilities(); - return () => { - isSubscribed = false; - abortCtrl.abort(); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useEffect(() => { + if (error) { + addError(error, { + title: i18n.MACHINE_LEARNING_PERMISSIONS_FAILURE, + }); + } + }, [addError, error]); return ( {children} diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/anomalies_host_table.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/anomalies_host_table.tsx index 9bfae686b1a59..7fdf41e6b6500 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/anomalies_host_table.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/anomalies_host_table.tsx @@ -16,7 +16,7 @@ import { convertAnomaliesToHosts } from './convert_anomalies_to_hosts'; import { Loader } from '../../loader'; import { getIntervalFromAnomalies } from '../anomaly/get_interval_from_anomalies'; import { AnomaliesHostTableProps } from '../types'; -import { useMlCapabilities } from '../../ml_popover/hooks/use_ml_capabilities'; +import { useMlCapabilities } from '../hooks/use_ml_capabilities'; import { BasicTable } from './basic_table'; import { hostEquality } from './host_equality'; import { getCriteriaFromHostType } from '../criteria/get_criteria_from_host_type'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/anomalies_network_table.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/anomalies_network_table.tsx index af27d411b990d..124d8d9a794c1 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/anomalies_network_table.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/anomalies_network_table.tsx @@ -14,7 +14,7 @@ import { convertAnomaliesToNetwork } from './convert_anomalies_to_network'; import { Loader } from '../../loader'; import { AnomaliesNetworkTableProps } from '../types'; import { getAnomaliesNetworkTableColumnsCurated } from './get_anomalies_network_table_columns'; -import { useMlCapabilities } from '../../ml_popover/hooks/use_ml_capabilities'; +import { useMlCapabilities } from '../hooks/use_ml_capabilities'; import { BasicTable } from './basic_table'; import { networkEquality } from './network_equality'; import { getCriteriaFromNetworkType } from '../criteria/get_criteria_from_network_type'; diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/translations.ts b/x-pack/plugins/security_solution/public/common/components/ml/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/translations.ts rename to x-pack/plugins/security_solution/public/common/components/ml/translations.ts diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/__mocks__/api.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/api.mock.ts similarity index 99% rename from x-pack/plugins/security_solution/public/common/components/ml_popover/__mocks__/api.tsx rename to x-pack/plugins/security_solution/public/common/components/ml_popover/api.mock.ts index 54bb0a96207e1..0e8f033ff0cf3 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/__mocks__/api.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/api.mock.ts @@ -4,16 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ +import { MlSummaryJob } from '../../../../../ml/public'; import { Group, - JobSummary, Module, RecognizerModule, SetupMlResponse, - SiemJob, + SecurityJob, StartDatafeedResponse, StopDatafeedResponse, -} from '../types'; +} from './types'; export const mockGroupsResponse: Group[] = [ { @@ -31,7 +31,7 @@ export const mockGroupsResponse: Group[] = [ { id: 'suricata', jobIds: ['suricata_alert_rate'], calendarIds: [] }, ]; -export const mockOpenedJob: JobSummary = { +export const mockOpenedJob: MlSummaryJob = { datafeedId: 'datafeed-siem-api-rare_process_linux_ecs', datafeedIndices: ['auditbeat-*'], datafeedState: 'started', @@ -48,7 +48,7 @@ export const mockOpenedJob: JobSummary = { processed_record_count: 3425264, }; -export const mockJobsSummaryResponse: JobSummary[] = [ +export const mockJobsSummaryResponse: MlSummaryJob[] = [ { id: 'rc-rare-process-windows-5', description: @@ -491,7 +491,7 @@ export const mockStopDatafeedsSuccess: StopDatafeedResponse = { 'datafeed-linux_anomalous_network_service': { stopped: true }, }; -export const mockSiemJobs: SiemJob[] = [ +export const mockSecurityJobs: SecurityJob[] = [ { id: 'linux_anomalous_network_activity_ecs', description: diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/api.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/api.ts similarity index 89% rename from x-pack/plugins/security_solution/public/common/components/ml_popover/api.tsx rename to x-pack/plugins/security_solution/public/common/components/ml_popover/api.ts index 7c72098209a06..dd0fb33fd2bc6 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/api.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/api.ts @@ -9,7 +9,6 @@ import { CloseJobsResponse, ErrorResponse, GetModulesProps, - JobSummary, MlSetupArgs, Module, RecognizerModule, @@ -165,21 +164,3 @@ export const stopDatafeeds = async ({ return [stopDatafeedsResponse, closeJobsResponse]; }; - -/** - * Fetches a summary of all ML jobs currently installed - * - * NOTE: If not sending jobIds in the body, you must at least send an empty body or the server will - * return a 500 - * - * @param signal to cancel request - * - * @throws An error if response is not OK - */ -export const getJobsSummary = async (signal: AbortSignal): Promise => - KibanaServices.get().http.fetch('/api/ml/jobs/jobs_summary', { - method: 'POST', - body: JSON.stringify({}), - asSystemRequest: true, - signal, - }); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/helpers.test.tsx index 0b8da6be57e1b..2a2db46d42307 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/helpers.test.tsx @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { mockSiemJobs } from './__mocks__/api'; +import { mockSecurityJobs } from './api.mock'; import { filterJobs, getStablePatternTitles, searchFilter } from './helpers'; describe('helpers', () => { describe('filterJobs', () => { test('returns all jobs when no filter is suplied', () => { const filteredJobs = filterJobs({ - jobs: mockSiemJobs, + jobs: mockSecurityJobs, selectedGroups: [], showCustomJobs: false, showElasticJobs: false, @@ -23,17 +23,17 @@ describe('helpers', () => { describe('searchFilter', () => { test('returns all jobs when nullfilterQuery is provided', () => { - const jobsToDisplay = searchFilter(mockSiemJobs); - expect(jobsToDisplay.length).toEqual(mockSiemJobs.length); + const jobsToDisplay = searchFilter(mockSecurityJobs); + expect(jobsToDisplay.length).toEqual(mockSecurityJobs.length); }); test('returns correct DisplayJobs when filterQuery matches job.id', () => { - const jobsToDisplay = searchFilter(mockSiemJobs, 'rare_process'); + const jobsToDisplay = searchFilter(mockSecurityJobs, 'rare_process'); expect(jobsToDisplay.length).toEqual(2); }); test('returns correct DisplayJobs when filterQuery matches job.description', () => { - const jobsToDisplay = searchFilter(mockSiemJobs, 'Detect unusually'); + const jobsToDisplay = searchFilter(mockSecurityJobs, 'Detect unusually'); expect(jobsToDisplay.length).toEqual(2); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/helpers.tsx index 5989d052f7cd2..daf9da855c0f9 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/helpers.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SiemJob } from './types'; +import { SecurityJob } from './types'; /** * Returns a filtered array of Jobs according to JobsTableFilters selections @@ -22,12 +22,12 @@ export const filterJobs = ({ showElasticJobs, filterQuery, }: { - jobs: SiemJob[]; + jobs: SecurityJob[]; selectedGroups: string[]; showCustomJobs: boolean; showElasticJobs: boolean; filterQuery: string; -}): SiemJob[] => +}): SecurityJob[] => searchFilter( jobs .filter((job) => !showCustomJobs || (showCustomJobs && !job.isElasticJob)) @@ -44,7 +44,7 @@ export const filterJobs = ({ * @param jobs to filter * @param filterQuery user-provided search string to filter for occurrence in job names/description */ -export const searchFilter = (jobs: SiemJob[], filterQuery?: string): SiemJob[] => +export const searchFilter = (jobs: SecurityJob[], filterQuery?: string): SecurityJob[] => jobs.filter((job) => filterQuery == null ? true diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.test.ts b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.test.ts new file mode 100644 index 0000000000000..80f50912a84f2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.test.ts @@ -0,0 +1,110 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { renderHook } from '@testing-library/react-hooks'; + +import { hasMlAdminPermissions } from '../../../../../common/machine_learning/has_ml_admin_permissions'; +import { hasMlLicense } from '../../../../../common/machine_learning/has_ml_license'; +import { useAppToasts } from '../../../hooks/use_app_toasts'; +import { useAppToastsMock } from '../../../hooks/use_app_toasts.mock'; +import { getJobsSummary } from '../../ml/api/get_jobs_summary'; +import { checkRecognizer, getModules } from '../api'; +import { SecurityJob } from '../types'; +import { + mockJobsSummaryResponse, + mockGetModuleResponse, + checkRecognizerSuccess, +} from '../api.mock'; +import { useSecurityJobs } from './use_security_jobs'; + +jest.mock('../../../../../common/machine_learning/has_ml_admin_permissions'); +jest.mock('../../../../../common/machine_learning/has_ml_license'); +jest.mock('../../../lib/kibana'); +jest.mock('../../../hooks/use_app_toasts'); +jest.mock('../../ml/hooks/use_ml_capabilities'); +jest.mock('../../ml/api/get_jobs_summary'); +jest.mock('../api'); + +describe('useSecurityJobs', () => { + let appToastsMock: jest.Mocked>; + + beforeEach(() => { + appToastsMock = useAppToastsMock.create(); + (useAppToasts as jest.Mock).mockReturnValue(appToastsMock); + }); + + describe('when user has valid permissions', () => { + beforeEach(() => { + (hasMlAdminPermissions as jest.Mock).mockReturnValue(true); + (hasMlLicense as jest.Mock).mockReturnValue(true); + (getJobsSummary as jest.Mock).mockResolvedValue(mockJobsSummaryResponse); + (getModules as jest.Mock).mockResolvedValue(mockGetModuleResponse); + (checkRecognizer as jest.Mock).mockResolvedValue(checkRecognizerSuccess); + }); + + it('combines multiple ML calls into an array of SecurityJobs', async () => { + const expectedSecurityJob: SecurityJob = { + datafeedId: 'datafeed-siem-api-rare_process_linux_ecs', + datafeedIndices: ['auditbeat-*'], + datafeedState: 'stopped', + defaultIndexPattern: '', + description: 'SIEM Auditbeat: Detect unusually rare processes on Linux (beta)', + earliestTimestampMs: 1557353420495, + groups: ['siem'], + hasDatafeed: true, + id: 'siem-api-rare_process_linux_ecs', + isCompatible: true, + isElasticJob: false, + isInstalled: true, + isSingleMetricViewerJob: true, + jobState: 'closed', + latestTimestampMs: 1557434782207, + memory_status: 'hard_limit', + moduleId: '', + processed_record_count: 582251, + }; + + const { result, waitForNextUpdate } = renderHook(() => useSecurityJobs(false)); + await waitForNextUpdate(); + + expect(result.current.jobs).toHaveLength(6); + expect(result.current.jobs).toEqual(expect.arrayContaining([expectedSecurityJob])); + }); + + it('returns those permissions', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSecurityJobs(false)); + await waitForNextUpdate(); + + expect(result.current.isMlAdmin).toEqual(true); + expect(result.current.isLicensed).toEqual(true); + }); + + it('renders a toast error if an ML call fails', async () => { + (getModules as jest.Mock).mockRejectedValue('whoops'); + const { waitForNextUpdate } = renderHook(() => useSecurityJobs(false)); + await waitForNextUpdate(); + + expect(appToastsMock.addError).toHaveBeenCalledWith('whoops', { + title: 'Security job fetch failure', + }); + }); + }); + + describe('when the user does not have valid permissions', () => { + beforeEach(() => { + (hasMlAdminPermissions as jest.Mock).mockReturnValue(false); + (hasMlLicense as jest.Mock).mockReturnValue(false); + }); + + it('returns empty jobs and false predicates', () => { + const { result } = renderHook(() => useSecurityJobs(false)); + + expect(result.current.jobs).toEqual([]); + expect(result.current.isMlAdmin).toEqual(false); + expect(result.current.isLicensed).toEqual(false); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.ts b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.ts new file mode 100644 index 0000000000000..e8809e8366eed --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs.ts @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useEffect, useState } from 'react'; + +import { DEFAULT_INDEX_KEY } from '../../../../../common/constants'; +import { hasMlAdminPermissions } from '../../../../../common/machine_learning/has_ml_admin_permissions'; +import { hasMlLicense } from '../../../../../common/machine_learning/has_ml_license'; +import { useAppToasts } from '../../../hooks/use_app_toasts'; +import { useUiSetting$, useHttp } from '../../../lib/kibana'; +import { checkRecognizer, getModules } from '../api'; +import { SecurityJob } from '../types'; +import { createSecurityJobs } from './use_security_jobs_helpers'; +import { useMlCapabilities } from '../../ml/hooks/use_ml_capabilities'; +import * as i18n from '../../ml/translations'; +import { getJobsSummary } from '../../ml/api/get_jobs_summary'; + +export interface UseSecurityJobsReturn { + loading: boolean; + jobs: SecurityJob[]; + isMlAdmin: boolean; + isLicensed: boolean; +} + +/** + * Compiles a collection of SecurityJobs, which are a list of all jobs relevant to the Security Solution App. This + * includes all installed jobs in the `Security` ML group, and all jobs within ML Modules defined in + * ml_module (whether installed or not). Use the corresponding helper functions to filter the job + * list as necessary. E.g. installed jobs, running jobs, etc. + * + * NOTE: If the user is not an ml admin, jobs will be empty and isMlAdmin will be false. + * + * @param refetchData + */ +export const useSecurityJobs = (refetchData: boolean): UseSecurityJobsReturn => { + const [jobs, setJobs] = useState([]); + const [loading, setLoading] = useState(true); + const mlCapabilities = useMlCapabilities(); + const [siemDefaultIndex] = useUiSetting$(DEFAULT_INDEX_KEY); + const http = useHttp(); + const { addError } = useAppToasts(); + + const isMlAdmin = hasMlAdminPermissions(mlCapabilities); + const isLicensed = hasMlLicense(mlCapabilities); + + useEffect(() => { + let isSubscribed = true; + const abortCtrl = new AbortController(); + setLoading(true); + + async function fetchSecurityJobIdsFromGroupsData() { + if (isMlAdmin && isLicensed) { + try { + // Batch fetch all installed jobs, ML modules, and check which modules are compatible with siemDefaultIndex + const [jobSummaryData, modulesData, compatibleModules] = await Promise.all([ + getJobsSummary({ http, signal: abortCtrl.signal }), + getModules({ signal: abortCtrl.signal }), + checkRecognizer({ + indexPatternName: siemDefaultIndex, + signal: abortCtrl.signal, + }), + ]); + + const compositeSecurityJobs = createSecurityJobs( + jobSummaryData, + modulesData, + compatibleModules + ); + + if (isSubscribed) { + setJobs(compositeSecurityJobs); + } + } catch (error) { + if (isSubscribed) { + addError(error, { title: i18n.SIEM_JOB_FETCH_FAILURE }); + } + } + } + if (isSubscribed) { + setLoading(false); + } + } + + fetchSecurityJobIdsFromGroupsData(); + return () => { + isSubscribed = false; + abortCtrl.abort(); + }; + }, [refetchData, isMlAdmin, isLicensed, siemDefaultIndex, addError, http]); + + return { isLicensed, isMlAdmin, jobs, loading }; +}; diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs_helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs_helpers.test.tsx similarity index 83% rename from x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs_helpers.test.tsx rename to x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs_helpers.test.tsx index fc9f369a305aa..7fb4e6f59d9f7 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs_helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs_helpers.test.tsx @@ -6,29 +6,29 @@ import { composeModuleAndInstalledJobs, - createSiemJobs, + createSecurityJobs, getAugmentedFields, getInstalledJobs, getModuleJobs, - moduleToSiemJob, -} from './use_siem_jobs_helpers'; + moduleToSecurityJob, +} from './use_security_jobs_helpers'; import { checkRecognizerSuccess, mockGetModuleResponse, mockJobsSummaryResponse, -} from '../__mocks__/api'; +} from '../api.mock'; // TODO: Expand test coverage -describe('useSiemJobsHelpers', () => { - describe('moduleToSiemJob', () => { - test('correctly converts module to SiemJob', () => { - const siemJob = moduleToSiemJob( +describe('useSecurityJobsHelpers', () => { + describe('moduleToSecurityJob', () => { + test('correctly converts module to SecurityJob', () => { + const securityJob = moduleToSecurityJob( mockGetModuleResponse[0], mockGetModuleResponse[0].jobs[0], false ); - expect(siemJob).toEqual({ + expect(securityJob).toEqual({ datafeedId: '', datafeedIndices: [], datafeedState: '', @@ -86,19 +86,19 @@ describe('useSiemJobsHelpers', () => { const installedJobs = getInstalledJobs(mockJobsSummaryResponse, moduleJobs, [ 'siem_auditbeat', ]); - const siemJobs = composeModuleAndInstalledJobs(installedJobs, moduleJobs); - expect(siemJobs.length).toEqual(6); + const securityJobs = composeModuleAndInstalledJobs(installedJobs, moduleJobs); + expect(securityJobs.length).toEqual(6); }); }); - describe('createSiemJobs', () => { + describe('createSecurityJobs', () => { test('returns correct number of jobs when creating jobs with successful responses', () => { - const siemJobs = createSiemJobs( + const securityJobs = createSecurityJobs( mockJobsSummaryResponse, mockGetModuleResponse, checkRecognizerSuccess ); - expect(siemJobs.length).toEqual(6); + expect(securityJobs.length).toEqual(6); }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs_helpers.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs_helpers.tsx similarity index 59% rename from x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs_helpers.tsx rename to x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs_helpers.tsx index adbd712ffeb3e..d0109fd29b5fb 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs_helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_security_jobs_helpers.tsx @@ -5,26 +5,26 @@ */ import { - AugmentedSiemJobFields, - JobSummary, + AugmentedSecurityJobFields, Module, ModuleJob, RecognizerModule, - SiemJob, + SecurityJob, } from '../types'; import { mlModules } from '../ml_modules'; +import { MlSummaryJob } from '../../../../../../ml/public'; /** - * Helper function for converting from ModuleJob -> SiemJob + * Helper function for converting from ModuleJob -> SecurityJob * @param module * @param moduleJob * @param isCompatible */ -export const moduleToSiemJob = ( +export const moduleToSecurityJob = ( module: Module, moduleJob: ModuleJob, isCompatible: boolean -): SiemJob => { +): SecurityJob => { return { datafeedId: '', datafeedIndices: [], @@ -46,7 +46,7 @@ export const moduleToSiemJob = ( }; /** - * Returns fields necessary to augment a ModuleJob to a SiemJob + * Returns fields necessary to augment a ModuleJob to a SecurityJob * * @param jobId * @param moduleJobs @@ -54,9 +54,9 @@ export const moduleToSiemJob = ( */ export const getAugmentedFields = ( jobId: string, - moduleJobs: SiemJob[], + moduleJobs: SecurityJob[], compatibleModuleIds: string[] -): AugmentedSiemJobFields => { +): AugmentedSecurityJobFields => { const moduleJob = moduleJobs.find((mj) => mj.id === jobId); return moduleJob !== undefined ? { @@ -74,24 +74,27 @@ export const getAugmentedFields = ( }; /** - * Process Modules[] from the `get_module` ML API into SiemJobs[] by filtering to SIEM specific + * Process Modules[] from the `get_module` ML API into SecurityJobs[] by filtering to Security specific * modules and unpacking jobs from each module * * @param modulesData * @param compatibleModuleIds */ -export const getModuleJobs = (modulesData: Module[], compatibleModuleIds: string[]): SiemJob[] => +export const getModuleJobs = ( + modulesData: Module[], + compatibleModuleIds: string[] +): SecurityJob[] => modulesData .filter((module) => mlModules.includes(module.id)) .map((module) => [ ...module.jobs.map((moduleJob) => - moduleToSiemJob(module, moduleJob, compatibleModuleIds.includes(module.id)) + moduleToSecurityJob(module, moduleJob, compatibleModuleIds.includes(module.id)) ), ]) .flat(); /** - * Process JobSummary[] from the `jobs_summary` ML API into SiemJobs[] by filtering to to SIEM jobs + * Process data from the `jobs_summary` ML API into SecurityJobs[] by filtering to Security jobs * and augmenting with moduleId/defaultIndexPattern/isCompatible * * @param jobSummaryData @@ -99,57 +102,57 @@ export const getModuleJobs = (modulesData: Module[], compatibleModuleIds: string * @param compatibleModuleIds */ export const getInstalledJobs = ( - jobSummaryData: JobSummary[], - moduleJobs: SiemJob[], + jobSummaryData: MlSummaryJob[], + moduleJobs: SecurityJob[], compatibleModuleIds: string[] -): SiemJob[] => +): SecurityJob[] => jobSummaryData .filter(({ groups }) => groups.includes('siem') || groups.includes('security')) - .map((jobSummary) => ({ + .map((jobSummary) => ({ ...jobSummary, ...getAugmentedFields(jobSummary.id, moduleJobs, compatibleModuleIds), isInstalled: true, })); /** - * Combines installed jobs + moduleSiemJobs that don't overlap and sorts by name asc + * Combines installed jobs + moduleSecurityJobs that don't overlap and sorts by name asc * * @param installedJobs - * @param moduleSiemJobs + * @param moduleSecurityJobs */ export const composeModuleAndInstalledJobs = ( - installedJobs: SiemJob[], - moduleSiemJobs: SiemJob[] -): SiemJob[] => { + installedJobs: SecurityJob[], + moduleSecurityJobs: SecurityJob[] +): SecurityJob[] => { const installedJobsIds = installedJobs.map((installedJob) => installedJob.id); return [ ...installedJobs, - ...moduleSiemJobs.filter((mj) => !installedJobsIds.includes(mj.id)), + ...moduleSecurityJobs.filter((mj) => !installedJobsIds.includes(mj.id)), ].sort((a, b) => a.id.localeCompare(b.id)); }; /** - * Creates a list of SiemJobs by composing JobSummary jobs (installed jobs) and Module - * jobs (pre-packaged SIEM jobs) into a single job object that can be used throughout the SIEM app + * Creates a list of SecurityJobs by composing jobs summaries (installed jobs) and Module + * jobs (pre-packaged Security jobs) into a single job object that can be used throughout the Security app * * @param jobSummaryData * @param modulesData * @param compatibleModules */ -export const createSiemJobs = ( - jobSummaryData: JobSummary[], +export const createSecurityJobs = ( + jobSummaryData: MlSummaryJob[], modulesData: Module[], compatibleModules: RecognizerModule[] -): SiemJob[] => { +): SecurityJob[] => { // Create lookup of compatible modules const compatibleModuleIds = compatibleModules.map((module) => module.id); - // Process modulesData: Filter to SIEM specific modules, and unpack jobs from modules - const moduleSiemJobs = getModuleJobs(modulesData, compatibleModuleIds); + // Process modulesData: Filter to Security specific modules, and unpack jobs from modules + const moduleSecurityJobs = getModuleJobs(modulesData, compatibleModuleIds); - // Process jobSummaryData: Filter to SIEM jobs, and augment with moduleId/defaultIndexPattern/isCompatible - const installedJobs = getInstalledJobs(jobSummaryData, moduleSiemJobs, compatibleModuleIds); + // Process jobSummaryData: Filter to Security jobs, and augment with moduleId/defaultIndexPattern/isCompatible + const installedJobs = getInstalledJobs(jobSummaryData, moduleSecurityJobs, compatibleModuleIds); - // Combine installed jobs + moduleSiemJobs that don't overlap, and sort by name asc - return composeModuleAndInstalledJobs(installedJobs, moduleSiemJobs); + // Combine installed jobs + moduleSecurityJobs that don't overlap, and sort by name asc + return composeModuleAndInstalledJobs(installedJobs, moduleSecurityJobs); }; diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs.tsx deleted file mode 100644 index 7f0a8dea1913e..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { useEffect, useState } from 'react'; - -import { DEFAULT_INDEX_KEY } from '../../../../../common/constants'; -import { checkRecognizer, getJobsSummary, getModules } from '../api'; -import { SiemJob } from '../types'; -import { hasMlUserPermissions } from '../../../../../common/machine_learning/has_ml_user_permissions'; -import { errorToToaster, useStateToaster } from '../../toasters'; -import { useUiSetting$ } from '../../../lib/kibana'; - -import * as i18n from './translations'; -import { createSiemJobs } from './use_siem_jobs_helpers'; -import { useMlCapabilities } from './use_ml_capabilities'; - -type Return = [boolean, SiemJob[]]; - -/** - * Compiles a collection of SiemJobs, which are a list of all jobs relevant to the SIEM App. This - * includes all installed jobs in the `SIEM` ML group, and all jobs within ML Modules defined in - * ml_module (whether installed or not). Use the corresponding helper functions to filter the job - * list as necessary. E.g. installed jobs, running jobs, etc. - * - * @param refetchData - */ -export const useSiemJobs = (refetchData: boolean): Return => { - const [siemJobs, setSiemJobs] = useState([]); - const [loading, setLoading] = useState(true); - const mlCapabilities = useMlCapabilities(); - const userPermissions = hasMlUserPermissions(mlCapabilities); - const [siemDefaultIndex] = useUiSetting$(DEFAULT_INDEX_KEY); - const [, dispatchToaster] = useStateToaster(); - - useEffect(() => { - let isSubscribed = true; - const abortCtrl = new AbortController(); - setLoading(true); - - async function fetchSiemJobIdsFromGroupsData() { - if (userPermissions) { - try { - // Batch fetch all installed jobs, ML modules, and check which modules are compatible with siemDefaultIndex - const [jobSummaryData, modulesData, compatibleModules] = await Promise.all([ - getJobsSummary(abortCtrl.signal), - getModules({ signal: abortCtrl.signal }), - checkRecognizer({ - indexPatternName: siemDefaultIndex, - signal: abortCtrl.signal, - }), - ]); - - const compositeSiemJobs = createSiemJobs(jobSummaryData, modulesData, compatibleModules); - - if (isSubscribed) { - setSiemJobs(compositeSiemJobs); - } - } catch (error) { - if (isSubscribed) { - errorToToaster({ title: i18n.SIEM_JOB_FETCH_FAILURE, error, dispatchToaster }); - } - } - } - if (isSubscribed) { - setLoading(false); - } - } - - fetchSiemJobIdsFromGroupsData(); - return () => { - isSubscribed = false; - abortCtrl.abort(); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [refetchData, userPermissions]); - - return [loading, siemJobs]; -}; diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/__snapshots__/jobs_table_filters.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/__snapshots__/jobs_table_filters.test.tsx.snap index 747ac63551b55..9bee321e9fbde 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/__snapshots__/jobs_table_filters.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/__snapshots__/jobs_table_filters.test.tsx.snap @@ -25,7 +25,7 @@ exports[`JobsTableFilters renders correctly against snapshot 1`] = ` { - let siemJobs: SiemJob[]; + let securityJobs: SecurityJob[]; beforeEach(() => { - siemJobs = cloneDeep(mockSiemJobs); + securityJobs = cloneDeep(mockSecurityJobs); }); test('renders correctly against snapshot', () => { const wrapper = shallow( - + ); expect(wrapper).toMatchSnapshot(); }); @@ -29,7 +32,7 @@ describe('GroupsFilterPopover', () => { const mockOnSelectedGroupsChanged = jest.fn(); const wrapper = mount( ); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/groups_filter_popover.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/groups_filter_popover.tsx index d879942b8b101..362fb94dc1ec4 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/groups_filter_popover.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/groups_filter_popover.tsx @@ -15,30 +15,30 @@ import { EuiSpacer, } from '@elastic/eui'; import * as i18n from './translations'; -import { SiemJob } from '../../types'; +import { SecurityJob } from '../../types'; import { toggleSelectedGroup } from './toggle_selected_group'; interface GroupsFilterPopoverProps { - siemJobs: SiemJob[]; + securityJobs: SecurityJob[]; onSelectedGroupsChanged: Dispatch>; } /** - * Popover for selecting which SiemJob groups to filter on. Component extracts unique groups and - * their counts from the provided SiemJobs. The 'siem' & 'security' groups are filtered out as all jobs will be + * Popover for selecting which SecurityJob groups to filter on. Component extracts unique groups and + * their counts from the provided SecurityJobs. The 'siem' & 'security' groups are filtered out as all jobs will be * siem/security jobs * - * @param siemJobs jobs to fetch groups from to display for filtering + * @param securityJobs jobs to fetch groups from to display for filtering * @param onSelectedGroupsChanged change listener to be notified when group selection changes */ export const GroupsFilterPopoverComponent = ({ - siemJobs, + securityJobs, onSelectedGroupsChanged, }: GroupsFilterPopoverProps) => { const [isGroupPopoverOpen, setIsGroupPopoverOpen] = useState(false); const [selectedGroups, setSelectedGroups] = useState([]); - const groups = siemJobs + const groups = securityJobs .map((j) => j.groups) .flat() .filter((g) => g !== 'siem' && g !== 'security'); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/jobs_table_filters.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/jobs_table_filters.test.tsx index 5b656adc3e581..6b7699d57aedf 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/jobs_table_filters.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/jobs_table_filters.test.tsx @@ -7,20 +7,20 @@ import { mount, shallow } from 'enzyme'; import React from 'react'; import { JobsTableFiltersComponent } from './jobs_table_filters'; -import { SiemJob } from '../../types'; +import { SecurityJob } from '../../types'; import { cloneDeep } from 'lodash/fp'; -import { mockSiemJobs } from '../../__mocks__/api'; +import { mockSecurityJobs } from '../../api.mock'; describe('JobsTableFilters', () => { - let siemJobs: SiemJob[]; + let securityJobs: SecurityJob[]; beforeEach(() => { - siemJobs = cloneDeep(mockSiemJobs); + securityJobs = cloneDeep(mockSecurityJobs); }); test('renders correctly against snapshot', () => { const wrapper = shallow( - + ); expect(wrapper).toMatchSnapshot(); }); @@ -28,7 +28,7 @@ describe('JobsTableFilters', () => { test('when you click Elastic Jobs filter, state is updated and it is selected', () => { const onFilterChanged = jest.fn(); const wrapper = mount( - + ); wrapper.find('[data-test-subj="show-elastic-jobs-filter-button"]').first().simulate('click'); @@ -45,7 +45,7 @@ describe('JobsTableFilters', () => { test('when you click Custom Jobs filter, state is updated and it is selected', () => { const onFilterChanged = jest.fn(); const wrapper = mount( - + ); wrapper.find('[data-test-subj="show-custom-jobs-filter-button"]').first().simulate('click'); @@ -62,7 +62,7 @@ describe('JobsTableFilters', () => { test('when you click Custom Jobs filter once, then Elastic Jobs filter, state is updated and selected changed', () => { const onFilterChanged = jest.fn(); const wrapper = mount( - + ); wrapper.find('[data-test-subj="show-custom-jobs-filter-button"]').first().simulate('click'); @@ -88,7 +88,7 @@ describe('JobsTableFilters', () => { test('when you click Custom Jobs filter twice, state is updated and it is revert', () => { const onFilterChanged = jest.fn(); const wrapper = mount( - + ); wrapper.find('[data-test-subj="show-custom-jobs-filter-button"]').first().simulate('click'); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/jobs_table_filters.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/jobs_table_filters.tsx index 4cfb7f8ad2b5b..f25ea667b3411 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/jobs_table_filters.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/jobs_table_filters.tsx @@ -15,11 +15,11 @@ import { } from '@elastic/eui'; import { EuiSearchBarQuery } from '../../../../../timelines/components/open_timeline/types'; import * as i18n from './translations'; -import { JobsFilters, SiemJob } from '../../types'; +import { JobsFilters, SecurityJob } from '../../types'; import { GroupsFilterPopover } from './groups_filter_popover'; interface JobsTableFiltersProps { - siemJobs: SiemJob[]; + securityJobs: SecurityJob[]; onFilterChanged: Dispatch>; } @@ -27,10 +27,13 @@ interface JobsTableFiltersProps { * Collection of filters for filtering data within the JobsTable. Contains search bar, Elastic/Custom * Jobs filter button toggle, and groups selection * - * @param siemJobs jobs to fetch groups from to display for filtering + * @param securityJobs jobs to fetch groups from to display for filtering * @param onFilterChanged change listener to be notified on filter changes */ -export const JobsTableFiltersComponent = ({ siemJobs, onFilterChanged }: JobsTableFiltersProps) => { +export const JobsTableFiltersComponent = ({ + securityJobs, + onFilterChanged, +}: JobsTableFiltersProps) => { const [filterQuery, setFilterQuery] = useState(''); const [selectedGroups, setSelectedGroups] = useState([]); const [showCustomJobs, setShowCustomJobs] = useState(false); @@ -71,7 +74,10 @@ export const JobsTableFiltersComponent = ({ siemJobs, onFilterChanged }: JobsTab - + diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.test.tsx index ade8c6fe80525..e58d76bd1dde0 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.test.tsx @@ -9,22 +9,22 @@ import React from 'react'; import { JobSwitchComponent } from './job_switch'; import { cloneDeep } from 'lodash/fp'; -import { mockSiemJobs } from '../__mocks__/api'; -import { SiemJob } from '../types'; +import { mockSecurityJobs } from '../api.mock'; +import { SecurityJob } from '../types'; describe('JobSwitch', () => { - let siemJobs: SiemJob[]; + let securityJobs: SecurityJob[]; let onJobStateChangeMock = jest.fn(); beforeEach(() => { - siemJobs = cloneDeep(mockSiemJobs); + securityJobs = cloneDeep(mockSecurityJobs); onJobStateChangeMock = jest.fn(); }); test('renders correctly against snapshot', () => { const wrapper = shallow( ); @@ -34,8 +34,8 @@ describe('JobSwitch', () => { test('should call onJobStateChange when the switch is clicked to be true/open', () => { const wrapper = mount( ); @@ -57,8 +57,8 @@ describe('JobSwitch', () => { test('should have a switch when it is not in the loading state', () => { const wrapper = mount( ); @@ -68,8 +68,8 @@ describe('JobSwitch', () => { test('should not have a switch when it is in the loading state', () => { const wrapper = mount( ); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.tsx index d370d475bd6e5..3ad71ee6b6919 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/job_switch.tsx @@ -12,7 +12,7 @@ import { isJobFailed, isJobStarted, } from '../../../../../common/machine_learning/helpers'; -import { SiemJob } from '../types'; +import { SecurityJob } from '../types'; const StaticSwitch = styled(EuiSwitch)` .euiSwitch__thumb, @@ -24,14 +24,14 @@ const StaticSwitch = styled(EuiSwitch)` StaticSwitch.displayName = 'StaticSwitch'; export interface JobSwitchProps { - job: SiemJob; - isSiemJobsLoading: boolean; - onJobStateChange: (job: SiemJob, latestTimestampMs: number, enable: boolean) => Promise; + job: SecurityJob; + isSecurityJobsLoading: boolean; + onJobStateChange: (job: SecurityJob, latestTimestampMs: number, enable: boolean) => Promise; } export const JobSwitchComponent = ({ job, - isSiemJobsLoading, + isSecurityJobsLoading, onJobStateChange, }: JobSwitchProps) => { const [isLoading, setIsLoading] = useState(false); @@ -47,7 +47,7 @@ export const JobSwitchComponent = ({ return ( - {isSiemJobsLoading || isLoading || isJobLoading(job.jobState, job.datafeedState) ? ( + {isSecurityJobsLoading || isLoading || isJobLoading(job.jobState, job.datafeedState) ? ( ) : ( { - let siemJobs: SiemJob[]; + let securityJobs: SecurityJob[]; let onJobStateChangeMock = jest.fn(); beforeEach(() => { - siemJobs = cloneDeep(mockSiemJobs); + securityJobs = cloneDeep(mockSecurityJobs); onJobStateChangeMock = jest.fn(); }); @@ -25,7 +25,7 @@ describe('JobsTableComponent', () => { const wrapper = shallow( ); @@ -36,7 +36,7 @@ describe('JobsTableComponent', () => { const wrapper = mount( ); @@ -46,11 +46,11 @@ describe('JobsTableComponent', () => { }); test('should render the hyperlink with URI encodings which points specifically to the job id', () => { - siemJobs[0].id = 'job id with spaces'; + securityJobs[0].id = 'job id with spaces'; const wrapper = mount( ); @@ -63,7 +63,7 @@ describe('JobsTableComponent', () => { const wrapper = mount( ); @@ -73,14 +73,14 @@ describe('JobsTableComponent', () => { .simulate('click', { target: { checked: true }, }); - expect(onJobStateChangeMock.mock.calls[0]).toEqual([siemJobs[0], 1571022859393, true]); + expect(onJobStateChangeMock.mock.calls[0]).toEqual([securityJobs[0], 1571022859393, true]); }); test('should have a switch when it is not in the loading state', () => { const wrapper = mount( ); @@ -91,7 +91,7 @@ describe('JobsTableComponent', () => { const wrapper = mount( ); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/jobs_table.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/jobs_table.tsx index f28a99c9947d5..be911a1cd8537 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/jobs_table.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/jobs_table.tsx @@ -25,7 +25,7 @@ import styled from 'styled-components'; import { useBasePath } from '../../../lib/kibana'; import * as i18n from './translations'; import { JobSwitch } from './job_switch'; -import { SiemJob } from '../types'; +import { SecurityJob } from '../types'; const JobNameWrapper = styled.div` margin: 5px 0; @@ -38,12 +38,12 @@ const truncateThreshold = 200; const getJobsTableColumns = ( isLoading: boolean, - onJobStateChange: (job: SiemJob, latestTimestampMs: number, enable: boolean) => Promise, + onJobStateChange: (job: SecurityJob, latestTimestampMs: number, enable: boolean) => Promise, basePath: string ) => [ { name: i18n.COLUMN_JOB_NAME, - render: ({ id, description }: SiemJob) => ( + render: ({ id, description }: SecurityJob) => ( ( + render: ({ groups }: SecurityJob) => ( {groups.map((group) => ( @@ -76,9 +76,13 @@ const getJobsTableColumns = ( { name: i18n.COLUMN_RUN_JOB, - render: (job: SiemJob) => + render: (job: SecurityJob) => job.isCompatible ? ( - + ) : ( ), @@ -87,13 +91,16 @@ const getJobsTableColumns = ( } as const, ]; -const getPaginatedItems = (items: SiemJob[], pageIndex: number, pageSize: number): SiemJob[] => - items.slice(pageIndex * pageSize, pageIndex * pageSize + pageSize); +const getPaginatedItems = ( + items: SecurityJob[], + pageIndex: number, + pageSize: number +): SecurityJob[] => items.slice(pageIndex * pageSize, pageIndex * pageSize + pageSize); export interface JobTableProps { isLoading: boolean; - jobs: SiemJob[]; - onJobStateChange: (job: SiemJob, latestTimestampMs: number, enable: boolean) => Promise; + jobs: SecurityJob[]; + onJobStateChange: (job: SecurityJob, latestTimestampMs: number, enable: boolean) => Promise; } export const JobsTableComponent = ({ isLoading, jobs, onJobStateChange }: JobTableProps) => { diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx index 0ebf367471848..f2bf2273c4b3f 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_popover.tsx @@ -12,19 +12,17 @@ import styled from 'styled-components'; import { useKibana } from '../../lib/kibana'; import { METRIC_TYPE, TELEMETRY_EVENT, track } from '../../lib/telemetry'; -import { hasMlAdminPermissions } from '../../../../common/machine_learning/has_ml_admin_permissions'; import { errorToToaster, useStateToaster, ActionToaster } from '../toasters'; import { setupMlJob, startDatafeeds, stopDatafeeds } from './api'; import { filterJobs } from './helpers'; -import { useSiemJobs } from './hooks/use_siem_jobs'; import { JobsTableFilters } from './jobs_table/filters/jobs_table_filters'; import { JobsTable } from './jobs_table/jobs_table'; import { ShowingCount } from './jobs_table/showing_count'; import { PopoverDescription } from './popover_description'; import * as i18n from './translations'; -import { JobsFilters, SiemJob } from './types'; +import { JobsFilters, SecurityJob } from './types'; import { UpgradeContents } from './upgrade_contents'; -import { useMlCapabilities } from './hooks/use_ml_capabilities'; +import { useSecurityJobs } from './hooks/use_security_jobs'; const PopoverContentsDiv = styled.div` max-width: 684px; @@ -87,24 +85,25 @@ export const MlPopover = React.memo(() => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [filterProperties, setFilterProperties] = useState(defaultFilterProps); - const [isLoadingSiemJobs, siemJobs] = useSiemJobs(refreshToggle); + const { isMlAdmin, isLicensed, loading: isLoadingSecurityJobs, jobs } = useSecurityJobs( + refreshToggle + ); const [, dispatchToaster] = useStateToaster(); - const capabilities = useMlCapabilities(); const docLinks = useKibana().services.docLinks; const handleJobStateChange = useCallback( - (job: SiemJob, latestTimestampMs: number, enable: boolean) => + (job: SecurityJob, latestTimestampMs: number, enable: boolean) => enableDatafeed(job, latestTimestampMs, enable, dispatch, dispatchToaster), [dispatch, dispatchToaster] ); const filteredJobs = filterJobs({ - jobs: siemJobs, + jobs, ...filterProperties, }); - const incompatibleJobCount = siemJobs.filter((j) => !j.isCompatible).length; + const incompatibleJobCount = jobs.filter((j) => !j.isCompatible).length; - if (!capabilities.isPlatinumOrTrialLicense) { + if (!isLicensed) { // If the user does not have platinum show upgrade UI return ( { ); - } else if (hasMlAdminPermissions(capabilities)) { + } else if (isMlAdmin) { // If the user has Platinum License & ML Admin Permissions, show Anomaly Detection button & full config UI return ( { - + @@ -194,7 +193,7 @@ export const MlPopover = React.memo(() => { )} @@ -209,7 +208,7 @@ export const MlPopover = React.memo(() => { // Enable/Disable Job & Datafeed -- passed to JobsTable for use as callback on JobSwitch const enableDatafeed = async ( - job: SiemJob, + job: SecurityJob, latestTimestampMs: number, enable: boolean, dispatch: Dispatch, @@ -257,7 +256,7 @@ const enableDatafeed = async ( dispatch({ type: 'refresh' }); }; -const submitTelemetry = (job: SiemJob, enabled: boolean) => { +const submitTelemetry = (job: SecurityJob, enabled: boolean) => { // Report type of job enabled/disabled track( METRIC_TYPE.COUNT, diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/types.ts b/x-pack/plugins/security_solution/public/common/components/ml_popover/types.ts index f39daa0b9a7fb..c839f5110fe7f 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/types.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AuditMessageBase } from '../../../../../ml/public'; import { MlError } from '../ml/types'; +import { MlSummaryJob } from '../../../../../ml/public'; export interface Group { id: string; @@ -98,28 +98,6 @@ export interface MlSetupArgs { prefix?: string; } -/** - * Representation of an ML Job as returned from the `ml/jobs/jobs_summary` API - */ -export interface JobSummary { - auditMessage?: AuditMessageBase; - datafeedId: string; - datafeedIndices: string[]; - datafeedState: string; - description: string; - earliestTimestampMs?: number; - latestResultsTimestampMs?: number; - groups: string[]; - hasDatafeed: boolean; - id: string; - isSingleMetricViewerJob: boolean; - jobState: string; - latestTimestampMs?: number; - memory_status: string; - nodeName?: string; - processed_record_count: number; -} - export interface Detector { detector_description: string; function: string; @@ -133,10 +111,10 @@ export interface CustomURL { } /** - * Representation of an ML Job as used by the SIEM App -- a composition of ModuleJob and JobSummary + * Representation of an ML Job as used by the SIEM App -- a composition of ModuleJob and MlSummaryJob * that includes necessary metadata like moduleName, defaultIndexPattern, etc. */ -export interface SiemJob extends JobSummary { +export interface SecurityJob extends MlSummaryJob { moduleId: string; defaultIndexPattern: string; isCompatible: boolean; @@ -144,7 +122,7 @@ export interface SiemJob extends JobSummary { isElasticJob: boolean; } -export interface AugmentedSiemJobFields { +export interface AugmentedSecurityJobFields { moduleId: string; defaultIndexPattern: string; isCompatible: boolean; diff --git a/x-pack/plugins/security_solution/public/common/containers/anomalies/anomalies_query_tab_body/index.tsx b/x-pack/plugins/security_solution/public/common/containers/anomalies/anomalies_query_tab_body/index.tsx index 76270a7c08cd6..94019b26c180b 100644 --- a/x-pack/plugins/security_solution/public/common/containers/anomalies/anomalies_query_tab_body/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/anomalies/anomalies_query_tab_body/index.tsx @@ -9,7 +9,7 @@ import React, { useEffect } from 'react'; import { DEFAULT_ANOMALY_SCORE } from '../../../../../common/constants'; import { AnomaliesQueryTabBodyProps } from './types'; import { getAnomaliesFilterQuery } from './utils'; -import { useSiemJobs } from '../../../components/ml_popover/hooks/use_siem_jobs'; +import { useInstalledSecurityJobs } from '../../../components/ml/hooks/use_installed_security_jobs'; import { useUiSetting$ } from '../../../lib/kibana'; import { MatrixHistogramContainer } from '../../../components/matrix_histogram'; import { histogramConfigs } from './histogram_configs'; @@ -38,13 +38,13 @@ export const AnomaliesQueryTabBody = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const [, siemJobs] = useSiemJobs(true); + const { jobs } = useInstalledSecurityJobs(); const [anomalyScore] = useUiSetting$(DEFAULT_ANOMALY_SCORE); const mergedFilterQuery = getAnomaliesFilterQuery( filterQuery, anomaliesFilterQuery, - siemJobs, + jobs, anomalyScore, flowTarget, ip diff --git a/x-pack/plugins/security_solution/public/common/containers/anomalies/anomalies_query_tab_body/utils.ts b/x-pack/plugins/security_solution/public/common/containers/anomalies/anomalies_query_tab_body/utils.ts index 10d5d1c60a6c2..5248801d723b6 100644 --- a/x-pack/plugins/security_solution/public/common/containers/anomalies/anomalies_query_tab_body/utils.ts +++ b/x-pack/plugins/security_solution/public/common/containers/anomalies/anomalies_query_tab_body/utils.ts @@ -6,21 +6,20 @@ import deepmerge from 'deepmerge'; +import { MlSummaryJob } from '../../../../../../ml/public'; import { ESTermQuery } from '../../../../../common/typed_json'; import { createFilter } from '../../helpers'; -import { SiemJob } from '../../../components/ml_popover/types'; import { FlowTarget } from '../../../../graphql/types'; export const getAnomaliesFilterQuery = ( filterQuery: string | ESTermQuery | undefined, anomaliesFilterQuery: object = {}, - siemJobs: SiemJob[] = [], + securityJobs: MlSummaryJob[] = [], anomalyScore: number, flowTarget?: FlowTarget, ip?: string ): string => { - const siemJobIds = siemJobs - .filter((job) => job.isInstalled) + const securityJobIds = securityJobs .map((job) => job.id) .map((jobId) => ({ match_phrase: { @@ -38,7 +37,7 @@ export const getAnomaliesFilterQuery = ( filter: [ { bool: { - should: siemJobIds, + should: securityJobIds, minimum_should_match: 1, }, }, diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.mock.ts b/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.mock.ts new file mode 100644 index 0000000000000..1af4ba3ba9233 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/hooks/use_app_toasts.mock.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; + * you may not use this file except in compliance with the Elastic License. + */ + +const createAppToastsMock = () => ({ + addError: jest.fn(), + addSuccess: jest.fn(), +}); + +export const useAppToastsMock = { + create: createAppToastsMock, +}; diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts index 2c52acd3ec747..5f4285f2747ae 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts @@ -17,6 +17,7 @@ export const KibanaServices = { get: jest.fn(), getKibanaVersion: jest.fn(() => export const useKibana = jest.fn(createUseKibanaMock()); export const useUiSetting = jest.fn(createUseUiSettingMock()); export const useUiSetting$ = jest.fn(createUseUiSetting$Mock()); +export const useHttp = jest.fn(() => useKibana().services.http); export const useTimeZone = jest.fn(); export const useDateFormat = jest.fn(); export const useBasePath = jest.fn(() => '/test/base/path'); diff --git a/x-pack/plugins/security_solution/public/common/mock/kibana_core.ts b/x-pack/plugins/security_solution/public/common/mock/kibana_core.ts index 13b3c4b249bfe..f8eed75cf9bf1 100644 --- a/x-pack/plugins/security_solution/public/common/mock/kibana_core.ts +++ b/x-pack/plugins/security_solution/public/common/mock/kibana_core.ts @@ -6,8 +6,10 @@ import { coreMock } from '../../../../../../src/core/public/mocks'; import { dataPluginMock } from '../../../../../../src/plugins/data/public/mocks'; +import { securityMock } from '../../../../../plugins/security/public/mocks'; export const createKibanaCoreStartMock = () => coreMock.createStart(); export const createKibanaPluginsStartMock = () => ({ data: dataPluginMock.createStartContract(), + security: securityMock.createSetup(), }); diff --git a/x-pack/plugins/security_solution/public/common/mock/kibana_react.ts b/x-pack/plugins/security_solution/public/common/mock/kibana_react.ts index c5d50e1379482..bdb8ca85b0d77 100644 --- a/x-pack/plugins/security_solution/public/common/mock/kibana_react.ts +++ b/x-pack/plugins/security_solution/public/common/mock/kibana_react.ts @@ -96,28 +96,10 @@ export const createUseKibanaMock = () => { export const createStartServices = () => { const core = createKibanaCoreStartMock(); const plugins = createKibanaPluginsStartMock(); - const security = { - authc: { - getCurrentUser: jest.fn(), - areAPIKeysEnabled: jest.fn(), - }, - sessionTimeout: { - start: jest.fn(), - stop: jest.fn(), - extend: jest.fn(), - }, - license: { - isEnabled: jest.fn(), - getFeatures: jest.fn(), - features$: jest.fn(), - }, - __legacyCompat: { logoutUrl: 'logoutUrl', tenant: 'tenant' }, - }; const services = ({ ...core, ...plugins, - security, } as unknown) as StartServices; return services; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.tsx index 47c12d1934174..00141c9a453d8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.tsx @@ -38,7 +38,7 @@ import { buildRuleTypeDescription, buildThresholdDescription, } from './helpers'; -import { useSiemJobs } from '../../../../common/components/ml_popover/hooks/use_siem_jobs'; +import { useSecurityJobs } from '../../../../common/components/ml_popover/hooks/use_security_jobs'; import { buildMlJobDescription } from './ml_job_description'; import { buildActionsDescription } from './actions_description'; import { buildThrottleDescription } from './throttle_description'; @@ -67,7 +67,7 @@ export const StepRuleDescriptionComponent: React.FC = }) => { const kibana = useKibana(); const [filterManager] = useState(new FilterManager(kibana.services.uiSettings)); - const [, siemJobs] = useSiemJobs(true); + const { jobs } = useSecurityJobs(false); const keys = Object.keys(schema); const listItems = keys.reduce((acc: ListItems[], key: string) => { @@ -77,7 +77,7 @@ export const StepRuleDescriptionComponent: React.FC = buildMlJobDescription( get(key, data) as string, (get(key, schema) as { label: string }).label, - siemJobs + jobs ), ]; } diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/ml_job_description.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/ml_job_description.test.tsx index c82a465f08c3a..3152fef12c652 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/ml_job_description.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/ml_job_description.test.tsx @@ -7,31 +7,14 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { mockOpenedJob } from '../../../../common/components/ml_popover/api.mock'; import { MlJobDescription, AuditIcon, JobStatusBadge } from './ml_job_description'; -jest.mock('../../../../common/lib/kibana'); -const job = { - moduleId: 'moduleId', - defaultIndexPattern: 'defaultIndexPattern', - isCompatible: true, - isInstalled: true, - isElasticJob: true, - datafeedId: 'datafeedId', - datafeedIndices: [], - datafeedState: 'datafeedState', - description: 'description', - groups: [], - hasDatafeed: true, - id: 'id', - isSingleMetricViewerJob: false, - jobState: 'jobState', - memory_status: 'memory_status', - processed_record_count: 0, -}; +jest.mock('../../../../common/lib/kibana'); describe('MlJobDescription', () => { it('renders correctly', () => { - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.find('[data-test-subj="machineLearningJobId"]')).toHaveLength(1); }); @@ -47,7 +30,7 @@ describe('AuditIcon', () => { describe('JobStatusBadge', () => { it('renders correctly', () => { - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.find('EuiBadge')).toHaveLength(1); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/ml_job_description.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/ml_job_description.tsx index d7e06511e7937..6baa2abab33d1 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/ml_job_description.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/ml_job_description.tsx @@ -8,9 +8,9 @@ import React from 'react'; import styled from 'styled-components'; import { EuiBadge, EuiIcon, EuiLink, EuiToolTip } from '@elastic/eui'; +import { MlSummaryJob } from '../../../../../../ml/public'; import { isJobStarted } from '../../../../../common/machine_learning/helpers'; import { useKibana } from '../../../../common/lib/kibana'; -import { SiemJob } from '../../../../common/components/ml_popover/types'; import { ListItems } from './types'; import { ML_JOB_STARTED, ML_JOB_STOPPED } from './translations'; @@ -21,7 +21,7 @@ enum MessageLevels { } const AuditIconComponent: React.FC<{ - message: SiemJob['auditMessage']; + message: MlSummaryJob['auditMessage']; }> = ({ message }) => { if (!message) { return null; @@ -47,7 +47,7 @@ const AuditIconComponent: React.FC<{ export const AuditIcon = React.memo(AuditIconComponent); -const JobStatusBadgeComponent: React.FC<{ job: SiemJob }> = ({ job }) => { +const JobStatusBadgeComponent: React.FC<{ job: MlSummaryJob }> = ({ job }) => { const isStarted = isJobStarted(job.jobState, job.datafeedState); const color = isStarted ? 'secondary' : 'danger'; const text = isStarted ? ML_JOB_STARTED : ML_JOB_STOPPED; @@ -69,7 +69,7 @@ const Wrapper = styled.div` overflow: hidden; `; -const MlJobDescriptionComponent: React.FC<{ job: SiemJob }> = ({ job }) => { +const MlJobDescriptionComponent: React.FC<{ job: MlSummaryJob }> = ({ job }) => { const jobUrl = useKibana().services.application.getUrlForApp( `ml#/jobs?mlManagement=(jobId:${encodeURI(job.id)})` ); @@ -92,12 +92,12 @@ export const MlJobDescription = React.memo(MlJobDescriptionComponent); export const buildMlJobDescription = ( jobId: string, label: string, - siemJobs: SiemJob[] + jobs: MlSummaryJob[] ): ListItems => { - const siemJob = siemJobs.find((job) => job.id === jobId); + const job = jobs.find(({ id }) => id === jobId); return { title: label, - description: siemJob ? : jobId, + description: job ? : jobId, }; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.test.tsx index 6f6581e4de1c3..4a08adbedab3f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.test.tsx @@ -8,14 +8,14 @@ import React from 'react'; import { shallow } from 'enzyme'; import { MlJobSelect } from './index'; -import { useSiemJobs } from '../../../../common/components/ml_popover/hooks/use_siem_jobs'; +import { useSecurityJobs } from '../../../../common/components/ml_popover/hooks/use_security_jobs'; import { useFormFieldMock } from '../../../../common/mock'; -jest.mock('../../../../common/components/ml_popover/hooks/use_siem_jobs'); +jest.mock('../../../../common/components/ml_popover/hooks/use_security_jobs'); jest.mock('../../../../common/lib/kibana'); describe('MlJobSelect', () => { beforeAll(() => { - (useSiemJobs as jest.Mock).mockReturnValue([false, []]); + (useSecurityJobs as jest.Mock).mockReturnValue({ loading: false, jobs: [] }); }); it('renders correctly', () => { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx index cdfdf4ca6b66b..b0aa0329fe8f4 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx @@ -19,7 +19,7 @@ import { import styled from 'styled-components'; import { isJobStarted } from '../../../../../common/machine_learning/helpers'; import { FieldHook, getFieldValidityAndErrorMessage } from '../../../../shared_imports'; -import { useSiemJobs } from '../../../../common/components/ml_popover/hooks/use_siem_jobs'; +import { useSecurityJobs } from '../../../../common/components/ml_popover/hooks/use_security_jobs'; import { useKibana } from '../../../../common/lib/kibana'; import { ML_JOB_SELECT_PLACEHOLDER_TEXT, @@ -81,7 +81,7 @@ interface MlJobSelectProps { export const MlJobSelect: React.FC = ({ describedByIds = [], field }) => { const jobId = field.value as string; const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); - const [isLoading, siemJobs] = useSiemJobs(false); + const { loading, jobs } = useSecurityJobs(false); const mlUrl = useKibana().services.application.getUrlForApp('ml'); const handleJobChange = useCallback( (machineLearningJobId: string) => { @@ -96,7 +96,7 @@ export const MlJobSelect: React.FC = ({ describedByIds = [], f disabled: true, }; - const jobOptions = siemJobs.map((job) => ({ + const jobOptions = jobs.map((job) => ({ value: job.id, inputDisplay: job.id, dropdownDisplay: , @@ -107,9 +107,9 @@ export const MlJobSelect: React.FC = ({ describedByIds = [], f const isJobRunning = useMemo(() => { // If the selected job is not found in the list, it means the placeholder is selected // and so we don't want to show the warning, thus isJobRunning will be true when 'job == null' - const job = siemJobs.find((j) => j.id === jobId); + const job = jobs.find(({ id }) => id === jobId); return job == null || isJobStarted(job.jobState, job.datafeedState); - }, [siemJobs, jobId]); + }, [jobs, jobId]); return ( @@ -126,7 +126,7 @@ export const MlJobSelect: React.FC = ({ describedByIds = [], f = ({ componentProps={{ describedByIds: ['detectionEngineStepDefineRuleType'], isReadOnly: isUpdateView, - hasValidLicense: mlCapabilities.isPlatinumOrTrialLicense, + hasValidLicense: hasMlLicense(mlCapabilities), isMlAdmin: hasMlAdminPermissions(mlCapabilities), }} /> diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.tsx index 85dce907084e8..110691328b13b 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.tsx @@ -47,8 +47,9 @@ import { getColumns, getMonitoringColumns } from './columns'; import { showRulesTable } from './helpers'; import { allRulesReducer, State } from './reducer'; import { RulesTableFilters } from './rules_table_filters/rules_table_filters'; -import { useMlCapabilities } from '../../../../../common/components/ml_popover/hooks/use_ml_capabilities'; +import { useMlCapabilities } from '../../../../../common/components/ml/hooks/use_ml_capabilities'; import { hasMlAdminPermissions } from '../../../../../../common/machine_learning/has_ml_admin_permissions'; +import { hasMlLicense } from '../../../../../../common/machine_learning/has_ml_license'; import { SecurityPageName } from '../../../../../app/types'; import { useFormatUrl } from '../../../../../common/components/link_to'; @@ -145,8 +146,7 @@ export const AllRules = React.memo( const { formatUrl } = useFormatUrl(SecurityPageName.detections); // TODO: Refactor license check + hasMlAdminPermissions to common check - const hasMlPermissions = - mlCapabilities.isPlatinumOrTrialLicense && hasMlAdminPermissions(mlCapabilities); + const hasMlPermissions = hasMlLicense(mlCapabilities) && hasMlAdminPermissions(mlCapabilities); const setRules = useCallback((newRules: Rule[], newPagination: Partial) => { dispatch({ 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 016d0c7c67a9e..8a969a4cf098c 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 @@ -71,8 +71,9 @@ import { RuleActionsOverflow } from '../../../../components/rules/rule_actions_o import { RuleStatusFailedCallOut } from './status_failed_callout'; import { FailureHistory } from './failure_history'; import { RuleStatus } from '../../../../components/rules//rule_status'; -import { useMlCapabilities } from '../../../../../common/components/ml_popover/hooks/use_ml_capabilities'; +import { useMlCapabilities } from '../../../../../common/components/ml/hooks/use_ml_capabilities'; import { hasMlAdminPermissions } from '../../../../../../common/machine_learning/has_ml_admin_permissions'; +import { hasMlLicense } from '../../../../../../common/machine_learning/has_ml_license'; import { SecurityPageName } from '../../../../../app/types'; import { LinkButton } from '../../../../../common/components/links'; import { useFormatUrl } from '../../../../../common/components/link_to'; @@ -161,8 +162,7 @@ export const RuleDetailsPageComponent: FC = ({ const { globalFullScreen } = useFullScreen(); // TODO: Refactor license check + hasMlAdminPermissions to common check - const hasMlPermissions = - mlCapabilities.isPlatinumOrTrialLicense && hasMlAdminPermissions(mlCapabilities); + const hasMlPermissions = hasMlLicense(mlCapabilities) && hasMlAdminPermissions(mlCapabilities); const ruleDetailTabs = getRuleDetailsTabs(rule); // persist rule until refresh is complete 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 34840b2826626..67f563e944f42 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 @@ -17,7 +17,7 @@ import { LastEventTime } from '../../../common/components/last_event_time'; import { AnomalyTableProvider } from '../../../common/components/ml/anomaly/anomaly_table_provider'; import { hostToCriteria } from '../../../common/components/ml/criteria/host_to_criteria'; import { hasMlUserPermissions } from '../../../../common/machine_learning/has_ml_user_permissions'; -import { useMlCapabilities } from '../../../common/components/ml_popover/hooks/use_ml_capabilities'; +import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; import { scoreIntervalToDateTime } from '../../../common/components/ml/score/score_interval_to_datetime'; import { SiemNavigation } from '../../../common/components/navigation'; import { KpiHostsComponent } from '../../components/kpi_hosts'; diff --git a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx index e4e69443c510d..2b19249dc426f 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx @@ -34,7 +34,7 @@ import { setAbsoluteRangeDatePicker as dispatchSetAbsoluteRangeDatePicker } from import { SpyRoute } from '../../common/utils/route/spy_routes'; import { esQuery } from '../../../../../../src/plugins/data/public'; -import { useMlCapabilities } from '../../common/components/ml_popover/hooks/use_ml_capabilities'; +import { useMlCapabilities } from '../../common/components/ml/hooks/use_ml_capabilities'; import { OverviewEmpty } from '../../overview/components/overview_empty'; import { Display } from './display'; import { HostsTabs } from './hosts_tabs'; diff --git a/x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx b/x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx index cf08b084d2197..d6dfe1769308e 100644 --- a/x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx @@ -30,7 +30,7 @@ import { DescriptionListStyled, OverviewWrapper } from '../../../common/componen import { Loader } from '../../../common/components/loader'; import { Anomalies, NarrowDateRange } from '../../../common/components/ml/types'; import { AnomalyScores } from '../../../common/components/ml/score/anomaly_scores'; -import { useMlCapabilities } from '../../../common/components/ml_popover/hooks/use_ml_capabilities'; +import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; import { hasMlUserPermissions } from '../../../../common/machine_learning/has_ml_user_permissions'; import { InspectButton, InspectButtonContainer } from '../../../common/components/inspect'; diff --git a/x-pack/plugins/security_solution/public/network/pages/index.tsx b/x-pack/plugins/security_solution/public/network/pages/index.tsx index 9ac05cc98bb45..07abe7bc8c209 100644 --- a/x-pack/plugins/security_solution/public/network/pages/index.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/index.tsx @@ -7,7 +7,7 @@ import React, { useMemo } from 'react'; import { Route, Switch, RouteComponentProps, useHistory } from 'react-router-dom'; -import { useMlCapabilities } from '../../common/components/ml_popover/hooks/use_ml_capabilities'; +import { useMlCapabilities } from '../../common/components/ml/hooks/use_ml_capabilities'; import { hasMlUserPermissions } from '../../../common/machine_learning/has_ml_user_permissions'; import { FlowTarget } from '../../graphql/types'; diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx index 0a15b039b96af..c7aba6fcc8a5b 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx @@ -23,7 +23,7 @@ import { HostItem } from '../../../graphql/types'; import { Loader } from '../../../common/components/loader'; import { IPDetailsLink } from '../../../common/components/links'; import { hasMlUserPermissions } from '../../../../common/machine_learning/has_ml_user_permissions'; -import { useMlCapabilities } from '../../../common/components/ml_popover/hooks/use_ml_capabilities'; +import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; import { AnomalyScores } from '../../../common/components/ml/score/anomaly_scores'; import { Anomalies, NarrowDateRange } from '../../../common/components/ml/types'; import { DescriptionListStyled, OverviewWrapper } from '../../../common/components/page'; From e2ef219a7cd0b1d492e5cb929b3a3891a92e8e2e Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Wed, 12 Aug 2020 21:02:00 -0400 Subject: [PATCH 04/15] [Security Solution][Resolver] fix presentation role on edgeline (#74869) Co-authored-by: Elastic Machine --- .../plugins/security_solution/public/resolver/view/edge_line.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/resolver/view/edge_line.tsx b/x-pack/plugins/security_solution/public/resolver/view/edge_line.tsx index 9f310bb1cc0d6..061dfce64b4e4 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/edge_line.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/edge_line.tsx @@ -127,7 +127,6 @@ const EdgeLineComponent = React.memo( return ( Date: Wed, 12 Aug 2020 22:32:05 -0600 Subject: [PATCH 05/15] [Security Solution][lists] Adds tests for exception lists and items part 2 (#74815) ## Summary This is the basics of end to end tests, so there could be a lot more, but this ties to cover the basics of the tests. Test with: ```ts node scripts/functional_tests --config x-pack/test/lists_api_integration/security_and_spaces/config.ts ``` Adds these tests for the route counter parts: * create_exception_list_items.ts * create_exception_lists.ts * delete_exception_list_items.ts * delete_exception_lists.ts * find_exception_list_items.ts * find_exception_lists.ts * read_exception_list_items.ts * read_exception_lists.ts * update_exception_list_items.ts * update_exception_lists.ts Fixes a few minor strings, other tests, but no large bugs found with these tests ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../create_exception_list_item_schema.mock.ts | 24 +++ .../create_exception_list_schema.mock.ts | 20 ++ .../update_exception_list_item_schema.mock.ts | 13 ++ .../update_exception_list_schema.mock.ts | 11 ++ .../exception_list_item_schema.mock.ts | 24 +++ .../response/exception_list_schema.mock.ts | 24 +++ .../create_exception_list_item_route.ts | 2 +- .../routes/find_exception_list_item_route.ts | 2 +- .../update_exception_list_item_route.ts | 69 ++++--- .../routes/update_exception_list_route.ts | 6 +- .../utils/get_error_message_exception_list.ts | 6 +- .../get_error_message_exception_list_item.ts | 6 +- .../tests/create_exception_list_items.ts | 119 ++++++++++++ .../tests/create_exception_lists.ts | 77 ++++++++ .../tests/delete_exception_list_items.ts | 119 ++++++++++++ .../tests/delete_exception_lists.ts | 98 ++++++++++ .../tests/export_list_items.ts | 5 +- .../tests/find_exception_list_items.ts | 105 ++++++++++ .../tests/find_exception_lists.ts | 67 +++++++ .../tests/import_list_items.ts | 2 +- .../security_and_spaces/tests/index.ts | 10 + .../tests/read_exception_list_items.ts | 159 +++++++++++++++ .../tests/read_exception_lists.ts | 112 +++++++++++ .../tests/update_exception_list_items.ts | 168 ++++++++++++++++ .../tests/update_exception_lists.ts | 182 ++++++++++++++++++ x-pack/test/lists_api_integration/utils.ts | 60 +++++- 26 files changed, 1444 insertions(+), 46 deletions(-) create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/create_exception_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/create_exception_lists.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/delete_exception_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/delete_exception_lists.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/find_exception_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/find_exception_lists.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/read_exception_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/read_exception_lists.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/update_exception_list_items.ts create mode 100644 x-pack/test/lists_api_integration/security_and_spaces/tests/update_exception_lists.ts diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.mock.ts index 0450849931b30..da22e33dc7b52 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.mock.ts @@ -8,6 +8,7 @@ import { COMMENTS, DESCRIPTION, ENTRIES, + ITEM_ID, ITEM_TYPE, LIST_ID, META, @@ -32,3 +33,26 @@ export const getCreateExceptionListItemSchemaMock = (): CreateExceptionListItemS tags: TAGS, type: ITEM_TYPE, }); + +/** + * Useful for end to end testing + */ +export const getCreateExceptionListItemMinimalSchemaMock = (): CreateExceptionListItemSchema => ({ + description: DESCRIPTION, + entries: ENTRIES, + item_id: ITEM_ID, + list_id: LIST_ID, + name: NAME, + type: ITEM_TYPE, +}); + +/** + * Useful for end to end testing + */ +export const getCreateExceptionListItemMinimalSchemaMockWithoutId = (): CreateExceptionListItemSchema => ({ + description: DESCRIPTION, + entries: ENTRIES, + list_id: LIST_ID, + name: NAME, + type: ITEM_TYPE, +}); diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.mock.ts index d9c0474610369..f8431fcce1bf7 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.mock.ts @@ -7,6 +7,7 @@ import { DESCRIPTION, ENDPOINT_TYPE, + LIST_ID, META, NAME, NAMESPACE_TYPE, @@ -26,3 +27,22 @@ export const getCreateExceptionListSchemaMock = (): CreateExceptionListSchema => type: ENDPOINT_TYPE, version: VERSION, }); + +/** + * Useful for end to end testing + */ +export const getCreateExceptionListMinimalSchemaMock = (): CreateExceptionListSchema => ({ + description: DESCRIPTION, + list_id: LIST_ID, + name: NAME, + type: ENDPOINT_TYPE, +}); + +/** + * Useful for end to end testing + */ +export const getCreateExceptionListMinimalSchemaMockWithoutId = (): CreateExceptionListSchema => ({ + description: DESCRIPTION, + name: NAME, + type: ENDPOINT_TYPE, +}); diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.mock.ts index 90d70c273f490..4673c0fe7629d 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.mock.ts @@ -9,6 +9,7 @@ import { DESCRIPTION, ENTRIES, ID, + ITEM_ID, ITEM_TYPE, LIST_ITEM_ID, META, @@ -34,3 +35,15 @@ export const getUpdateExceptionListItemSchemaMock = (): UpdateExceptionListItemS tags: TAGS, type: ITEM_TYPE, }); + +/** + * Useful for end to end tests and other mechanisms which want to fill in the values + * after doing a get of the structure. + */ +export const getUpdateMinimalExceptionListItemSchemaMock = (): UpdateExceptionListItemSchema => ({ + description: DESCRIPTION, + entries: ENTRIES, + item_id: ITEM_ID, + name: NAME, + type: ITEM_TYPE, +}); diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.mock.ts index 22af29e6af0b7..b7dc2d9e0c948 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.mock.ts @@ -20,3 +20,14 @@ export const getUpdateExceptionListSchemaMock = (): UpdateExceptionListSchema => tags: ['malware'], type: 'endpoint', }); + +/** + * Useful for end to end tests and other mechanisms which want to fill in the values + * after doing a get of the structure. + */ +export const getUpdateMinimalExceptionListSchemaMock = (): UpdateExceptionListSchema => ({ + description: DESCRIPTION, + list_id: LIST_ID, + name: NAME, + type: 'endpoint', +}); diff --git a/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.mock.ts index c0d04c9823ca3..1a8f21a5232f8 100644 --- a/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.mock.ts @@ -7,8 +7,11 @@ import { COMMENTS, DATE_NOW, DESCRIPTION, + ELASTIC_USER, ENTRIES, + ITEM_ID, ITEM_TYPE, + LIST_ID, META, NAME, NAMESPACE_TYPE, @@ -38,3 +41,24 @@ export const getExceptionListItemSchemaMock = (): ExceptionListItemSchema => ({ updated_at: DATE_NOW, updated_by: USER, }); + +/** + * This is useful for end to end tests where we remove the auto generated parts for comparisons + * such as created_at, updated_at, and id. + */ +export const getExceptionListItemResponseMockWithoutAutoGeneratedValues = (): Partial< + ExceptionListItemSchema +> => ({ + _tags: [], + comments: [], + created_by: ELASTIC_USER, + description: DESCRIPTION, + entries: ENTRIES, + item_id: ITEM_ID, + list_id: LIST_ID, + name: NAME, + namespace_type: 'single', + tags: [], + type: ITEM_TYPE, + updated_by: ELASTIC_USER, +}); diff --git a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts index 2655b09631b23..e2f0a7c06b400 100644 --- a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts @@ -7,9 +7,12 @@ import { DATE_NOW, DESCRIPTION, + ELASTIC_USER, ENDPOINT_TYPE, IMMUTABLE, + LIST_ID, META, + NAME, TIE_BREAKER, USER, VERSION, @@ -18,6 +21,7 @@ import { import { ENDPOINT_LIST_ID } from '../..'; import { ExceptionListSchema } from './exception_list_schema'; + export const getExceptionListSchemaMock = (): ExceptionListSchema => ({ _tags: ['endpoint', 'process', 'malware', 'os:linux'], _version: _VERSION, @@ -37,3 +41,23 @@ export const getExceptionListSchemaMock = (): ExceptionListSchema => ({ updated_by: 'user_name', version: VERSION, }); + +/** + * This is useful for end to end tests where we remove the auto generated parts for comparisons + * such as created_at, updated_at, and id. + */ +export const getExceptionResponseMockWithoutAutoGeneratedValues = (): Partial< + ExceptionListSchema +> => ({ + _tags: [], + created_by: ELASTIC_USER, + description: DESCRIPTION, + immutable: IMMUTABLE, + list_id: LIST_ID, + name: NAME, + namespace_type: 'single', + tags: [], + type: ENDPOINT_TYPE, + updated_by: ELASTIC_USER, + version: VERSION, +}); diff --git a/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts index fc0473b2b3704..f092aec82a8f3 100644 --- a/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts @@ -57,7 +57,7 @@ export const createExceptionListItemRoute = (router: IRouter): void => { }); if (exceptionList == null) { return siemResponse.error({ - body: `list id: "${listId}" does not exist`, + body: `exception list id: "${listId}" does not exist`, statusCode: 404, }); } else { diff --git a/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts index 88643e53ff0a7..103cba700013f 100644 --- a/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts @@ -62,7 +62,7 @@ export const findExceptionListItemRoute = (router: IRouter): void => { }); if (exceptionListItems == null) { return siemResponse.error({ - body: `list id: "${listId}" does not exist`, + body: `exception list id: "${listId}" does not exist`, statusCode: 404, }); } diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts index 7e15f694aee13..745ad0735a174 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts @@ -54,39 +54,46 @@ export const updateExceptionListItemRoute = (router: IRouter): void => { namespace_type: namespaceType, tags, } = request.body; - const exceptionLists = getExceptionListClient(context); - const exceptionListItem = await exceptionLists.updateExceptionListItem({ - _tags, - _version, - comments, - description, - entries, - id, - itemId, - meta, - name, - namespaceType, - tags, - type, - }); - if (exceptionListItem == null) { - if (id != null) { - return siemResponse.error({ - body: `list item id: "${id}" not found`, - statusCode: 404, - }); - } else { - return siemResponse.error({ - body: `list item item_id: "${itemId}" not found`, - statusCode: 404, - }); - } + if (id == null && itemId == null) { + return siemResponse.error({ + body: 'either id or item_id need to be defined', + statusCode: 404, + }); } else { - const [validated, errors] = validate(exceptionListItem, exceptionListItemSchema); - if (errors != null) { - return siemResponse.error({ body: errors, statusCode: 500 }); + const exceptionLists = getExceptionListClient(context); + const exceptionListItem = await exceptionLists.updateExceptionListItem({ + _tags, + _version, + comments, + description, + entries, + id, + itemId, + meta, + name, + namespaceType, + tags, + type, + }); + if (exceptionListItem == null) { + if (id != null) { + return siemResponse.error({ + body: `exception list item id: "${id}" does not exist`, + statusCode: 404, + }); + } else { + return siemResponse.error({ + body: `exception list item item_id: "${itemId}" does not exist`, + statusCode: 404, + }); + } } else { - return response.ok({ body: validated ?? {} }); + const [validated, errors] = validate(exceptionListItem, exceptionListItemSchema); + if (errors != null) { + return siemResponse.error({ body: errors, statusCode: 500 }); + } else { + return response.ok({ body: validated ?? {} }); + } } } } catch (err) { diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts index 8102210b8430d..1903d0f601d1d 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts @@ -15,7 +15,7 @@ import { updateExceptionListSchema, } from '../../common/schemas'; -import { getExceptionListClient } from './utils'; +import { getErrorMessageExceptionList, getExceptionListClient } from './utils'; export const updateExceptionListRoute = (router: IRouter): void => { router.put( @@ -50,7 +50,7 @@ export const updateExceptionListRoute = (router: IRouter): void => { const exceptionLists = getExceptionListClient(context); if (id == null && listId == null) { return siemResponse.error({ - body: `either id or list_id need to be defined`, + body: 'either id or list_id need to be defined', statusCode: 404, }); } else { @@ -69,7 +69,7 @@ export const updateExceptionListRoute = (router: IRouter): void => { }); if (list == null) { return siemResponse.error({ - body: `exception list id: "${id}" not found`, + body: getErrorMessageExceptionList({ id, listId }), statusCode: 404, }); } else { diff --git a/x-pack/plugins/lists/server/routes/utils/get_error_message_exception_list.ts b/x-pack/plugins/lists/server/routes/utils/get_error_message_exception_list.ts index 665a7540184a0..7db3bedd9ec84 100644 --- a/x-pack/plugins/lists/server/routes/utils/get_error_message_exception_list.ts +++ b/x-pack/plugins/lists/server/routes/utils/get_error_message_exception_list.ts @@ -12,10 +12,10 @@ export const getErrorMessageExceptionList = ({ listId: string | undefined; }): string => { if (id != null) { - return `Exception list id: "${id}" does not exist`; + return `exception list id: "${id}" does not exist`; } else if (listId != null) { - return `Exception list list_id: "${listId}" does not exist`; + return `exception list list_id: "${listId}" does not exist`; } else { - return 'Exception list does not exist'; + return 'exception list does not exist'; } }; diff --git a/x-pack/plugins/lists/server/routes/utils/get_error_message_exception_list_item.ts b/x-pack/plugins/lists/server/routes/utils/get_error_message_exception_list_item.ts index 8e6730ef3db5c..efb6c0e59ade5 100644 --- a/x-pack/plugins/lists/server/routes/utils/get_error_message_exception_list_item.ts +++ b/x-pack/plugins/lists/server/routes/utils/get_error_message_exception_list_item.ts @@ -12,10 +12,10 @@ export const getErrorMessageExceptionListItem = ({ itemId: string | undefined; }): string => { if (id != null) { - return `Exception list item id: "${id}" does not exist`; + return `exception list item id: "${id}" does not exist`; } else if (itemId != null) { - return `Exception list item list_id: "${itemId}" does not exist`; + return `exception list item item_id: "${itemId}" does not exist`; } else { - return 'Exception list item does not exist'; + return 'exception list item does not exist'; } }; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/create_exception_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/create_exception_list_items.ts new file mode 100644 index 0000000000000..6148dbcc7090e --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/create_exception_list_items.ts @@ -0,0 +1,119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { ExceptionListItemSchema } from '../../../../plugins/lists/common'; +import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_item_schema.mock'; +import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; +import { + getCreateExceptionListItemMinimalSchemaMock, + getCreateExceptionListItemMinimalSchemaMockWithoutId, +} from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock'; +import { + EXCEPTION_LIST_ITEM_URL, + EXCEPTION_LIST_URL, +} from '../../../../plugins/lists/common/constants'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; + +import { + removeListItemServerGeneratedProperties, + removeExceptionListItemServerGeneratedProperties, +} from '../../utils'; + +import { deleteAllExceptions } from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('create_exception_list_items', () => { + describe('validation errors', () => { + it('should give a 404 error that the exception list must exist first before being able to add a list item to the exception list', async () => { + const { body } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(404); + + expect(body).to.eql({ + message: 'exception list id: "some-list-id" does not exist', + status_code: 404, + }); + }); + }); + + describe('creating exception list items', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should create a simple exception list item with a list item id', async () => { + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + const { body } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getExceptionListItemResponseMockWithoutAutoGeneratedValues()); + }); + + it('should create a simple exception list item without an id', async () => { + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + const { body } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMockWithoutId()) + .expect(200); + + const bodyToCompare = removeListItemServerGeneratedProperties(body); + const outputList: Partial = { + ...getExceptionListItemResponseMockWithoutAutoGeneratedValues(), + item_id: body.item_id, + }; + expect(bodyToCompare).to.eql(outputList); + }); + + it('should cause a 409 conflict if we attempt to create the same exception list item twice', async () => { + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + const { body } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(409); + + expect(body).to.eql({ + message: 'exception list item id: "some-list-item-id" already exists', + status_code: 409, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/create_exception_lists.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/create_exception_lists.ts new file mode 100644 index 0000000000000..2b654c72ae282 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/create_exception_lists.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { ExceptionListSchema } from '../../../../plugins/lists/common'; +import { EXCEPTION_LIST_URL } from '../../../../plugins/lists/common/constants'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { getExceptionResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_schema.mock'; +import { + getCreateExceptionListMinimalSchemaMock, + getCreateExceptionListMinimalSchemaMockWithoutId, +} from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; + +import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('create_exception_lists', () => { + describe('creating exception lists', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should create a simple exception list', async () => { + const { body } = await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getExceptionResponseMockWithoutAutoGeneratedValues()); + }); + + it('should create a simple exception list without a list_id', async () => { + const { body } = await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMockWithoutId()) + .expect(200); + + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + const outputtedList: Partial = { + ...getExceptionResponseMockWithoutAutoGeneratedValues(), + list_id: bodyToCompare.list_id, + }; + expect(bodyToCompare).to.eql(outputtedList); + }); + + it('should cause a 409 conflict if we attempt to create the same list_id twice', async () => { + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + const { body } = await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(409); + + expect(body).to.eql({ + message: 'exception list id: "some-list-id" already exists', + status_code: 409, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_exception_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_exception_list_items.ts new file mode 100644 index 0000000000000..16bdd264dc546 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_exception_list_items.ts @@ -0,0 +1,119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { ExceptionListItemSchema } from '../../../../plugins/lists/common'; +import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_item_schema.mock'; +import { + getCreateExceptionListItemMinimalSchemaMock, + getCreateExceptionListItemMinimalSchemaMockWithoutId, +} from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock'; +import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { + EXCEPTION_LIST_URL, + EXCEPTION_LIST_ITEM_URL, +} from '../../../../plugins/lists/common/constants'; + +import { deleteAllExceptions, removeExceptionListItemServerGeneratedProperties } from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('delete_exception_list_items', () => { + describe('delete exception list items', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should delete a single exception list item by its item_id', async () => { + // create an exception list + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // create an exception list item + await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + // delete the exception list item by its item_id + const { body } = await supertest + .delete( + `${EXCEPTION_LIST_ITEM_URL}?item_id=${ + getCreateExceptionListItemMinimalSchemaMock().item_id + }` + ) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getExceptionListItemResponseMockWithoutAutoGeneratedValues()); + }); + + it('should delete a single exception list item using an auto generated id', async () => { + // create an exception list + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // create an exception list item + const { body: bodyWithCreatedList } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMockWithoutId()) + .expect(200); + + // delete that exception list item by its auto-generated id + const { body } = await supertest + .delete(`${EXCEPTION_LIST_ITEM_URL}?id=${bodyWithCreatedList.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + const outputtedList: Partial = { + ...getExceptionListItemResponseMockWithoutAutoGeneratedValues(), + item_id: body.item_id, + }; + + const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputtedList); + }); + + it('should return an error if the id does not exist when trying to delete it', async () => { + const { body } = await supertest + .delete(`${EXCEPTION_LIST_ITEM_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + message: 'exception list item id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist', + status_code: 404, + }); + }); + + it('should return an error if the item_id does not exist when trying to delete it', async () => { + const { body } = await supertest + .delete(`${EXCEPTION_LIST_ITEM_URL}?item_id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + message: + 'exception list item item_id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist', + status_code: 404, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_exception_lists.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_exception_lists.ts new file mode 100644 index 0000000000000..56e4bcd9641cf --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/delete_exception_lists.ts @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { ExceptionListSchema } from '../../../../plugins/lists/common'; +import { getExceptionResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_schema.mock'; +import { + getCreateExceptionListMinimalSchemaMock, + getCreateExceptionListMinimalSchemaMockWithoutId, +} from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { EXCEPTION_LIST_URL } from '../../../../plugins/lists/common/constants'; + +import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('delete_exception_lists', () => { + describe('delete exception lists', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should delete a single exception list by its list_id', async () => { + // create an exception list + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // delete the exception list by its list id + const { body } = await supertest + .delete( + `${EXCEPTION_LIST_URL}?list_id=${getCreateExceptionListMinimalSchemaMock().list_id}` + ) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getExceptionResponseMockWithoutAutoGeneratedValues()); + }); + + it('should delete a single exception list using an auto generated id', async () => { + // create an exception list + const { body: bodyWithCreatedList } = await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMockWithoutId()) + .expect(200); + + // delete that list by its auto-generated id + const { body } = await supertest + .delete(`${EXCEPTION_LIST_URL}?id=${bodyWithCreatedList.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const outputtedList: Partial = { + ...getExceptionResponseMockWithoutAutoGeneratedValues(), + list_id: body.list_id, + }; + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputtedList); + }); + + it('should return an error if the id does not exist when trying to delete it', async () => { + const { body } = await supertest + .delete(`${EXCEPTION_LIST_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + message: 'exception list id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist', + status_code: 404, + }); + }); + + it('should return an error if the list_id does not exist when trying to delete it', async () => { + const { body } = await supertest + .delete(`${EXCEPTION_LIST_URL}?list_id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + message: 'exception list list_id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist', + status_code: 404, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/export_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/export_list_items.ts index 6fe783fc497f2..74c28f5abdfc1 100644 --- a/x-pack/test/lists_api_integration/security_and_spaces/tests/export_list_items.ts +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/export_list_items.ts @@ -96,8 +96,9 @@ export default ({ getService }: FtrProviderContext): void => { .set('kbn-xsrf', 'true') .expect(200) .parse(binaryToString); - - expect(body.toString()).to.eql('127.0.0.2\n127.0.0.1\n'); + const bodyString = body.toString(); + expect(bodyString.includes('127.0.0.1')).to.be(true); + expect(bodyString.includes('127.0.0.2')).to.be(true); }); }); }); diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/find_exception_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/find_exception_list_items.ts new file mode 100644 index 0000000000000..a65e9f344986f --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/find_exception_list_items.ts @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_item_schema.mock'; +import { getCreateExceptionListItemMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock'; +import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { + EXCEPTION_LIST_URL, + EXCEPTION_LIST_ITEM_URL, +} from '../../../../plugins/lists/common/constants'; + +import { deleteAllExceptions, removeExceptionListItemServerGeneratedProperties } from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('find_exception_list_items', () => { + describe('find exception list items', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should return an empty find body correctly if no exception list items are loaded', async () => { + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + const { body } = await supertest + .get( + `${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${ + getCreateExceptionListMinimalSchemaMock().list_id + }` + ) + .set('kbn-xsrf', 'true') + .send() + .expect(200); + + expect(body).to.eql({ + data: [], + page: 1, + per_page: 20, + total: 0, + }); + }); + + it('should return 404 if given a list_id that does not exist', async () => { + const { body } = await supertest + .get(`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=non_exist`) + .set('kbn-xsrf', 'true') + .send() + .expect(404); + + expect(body).to.eql({ + message: 'exception list id: "non_exist" does not exist', + status_code: 404, + }); + }); + + it('should return a single exception list item when a single exception list item is loaded from a find with defaults added', async () => { + // add the exception list + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // add a single exception list item + await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + // query the single exception list from _find + const { body } = await supertest + .get( + `${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${ + getCreateExceptionListMinimalSchemaMock().list_id + }` + ) + .set('kbn-xsrf', 'true') + .send() + .expect(200); + + body.data = [removeExceptionListItemServerGeneratedProperties(body.data[0])]; + expect(body).to.eql({ + data: [getExceptionListItemResponseMockWithoutAutoGeneratedValues()], + page: 1, + per_page: 20, + total: 1, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/find_exception_lists.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/find_exception_lists.ts new file mode 100644 index 0000000000000..c2328a7d112f4 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/find_exception_lists.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { getExceptionResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_schema.mock'; +import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { EXCEPTION_LIST_URL } from '../../../../plugins/lists/common/constants'; + +import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('find_exception_lists', () => { + describe('find exception lists', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should return an empty find body correctly if no exception lists are loaded', async () => { + const { body } = await supertest + .get(`${EXCEPTION_LIST_URL}/_find`) + .set('kbn-xsrf', 'true') + .send() + .expect(200); + + expect(body).to.eql({ + data: [], + page: 1, + per_page: 20, + total: 0, + }); + }); + + it('should return a single exception list when a single exception list is loaded from a find with defaults added', async () => { + // add a single exception list + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // query the single exception list from _find + const { body } = await supertest + .get(`${EXCEPTION_LIST_URL}/_find`) + .set('kbn-xsrf', 'true') + .send() + .expect(200); + + body.data = [removeExceptionListServerGeneratedProperties(body.data[0])]; + expect(body).to.eql({ + data: [getExceptionResponseMockWithoutAutoGeneratedValues()], + page: 1, + per_page: 20, + total: 1, + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/import_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/import_list_items.ts index 4befb6bbaf050..7b7a6173fb408 100644 --- a/x-pack/test/lists_api_integration/security_and_spaces/tests/import_list_items.ts +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/import_list_items.ts @@ -45,7 +45,7 @@ export default ({ getService }: FtrProviderContext): void => { }); }); - describe('importing rules with an index', () => { + describe('importing lists with an index', () => { beforeEach(async () => { await createListsIndex(supertest); }); diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts index 302877a680aa6..5458b4a9a7db2 100644 --- a/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/index.ts @@ -23,5 +23,15 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./find_list_items')); loadTestFile(require.resolve('./import_list_items')); loadTestFile(require.resolve('./export_list_items')); + loadTestFile(require.resolve('./create_exception_lists')); + loadTestFile(require.resolve('./create_exception_list_items')); + loadTestFile(require.resolve('./read_exception_lists')); + loadTestFile(require.resolve('./read_exception_list_items')); + loadTestFile(require.resolve('./update_exception_lists')); + loadTestFile(require.resolve('./update_exception_list_items')); + loadTestFile(require.resolve('./delete_exception_lists')); + loadTestFile(require.resolve('./delete_exception_list_items')); + loadTestFile(require.resolve('./find_exception_lists')); + loadTestFile(require.resolve('./find_exception_list_items')); }); }; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/read_exception_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/read_exception_list_items.ts new file mode 100644 index 0000000000000..26b969e940a2b --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/read_exception_list_items.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_item_schema.mock'; +import { + getCreateExceptionListItemMinimalSchemaMock, + getCreateExceptionListItemMinimalSchemaMockWithoutId, +} from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock'; +import { ExceptionListItemSchema } from '../../../../plugins/lists/common'; +import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { + EXCEPTION_LIST_URL, + EXCEPTION_LIST_ITEM_URL, +} from '../../../../plugins/lists/common/constants'; + +import { deleteAllExceptions, removeExceptionListItemServerGeneratedProperties } from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('read_exception_list_items', () => { + describe('reading exception list items', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should be able to read a single exception list items using item_id', async () => { + // create a simple exception list to read + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + const { body } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getExceptionListItemResponseMockWithoutAutoGeneratedValues()); + }); + + it('should be able to read a single exception list item using id', async () => { + // create a simple exception list to read + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // create a simple exception list item to read + const { body: createListBody } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + const { body } = await supertest + .get(`${EXCEPTION_LIST_ITEM_URL}?id=${createListBody.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getExceptionListItemResponseMockWithoutAutoGeneratedValues()); + }); + + it('should be able to read a single list item with an auto-generated id', async () => { + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // create a simple exception list item to read + const { body: createListBody } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMockWithoutId()) + .expect(200); + + const { body } = await supertest + .get(`${EXCEPTION_LIST_ITEM_URL}?id=${createListBody.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const outputtedList: Partial = { + ...getExceptionListItemResponseMockWithoutAutoGeneratedValues(), + item_id: body.item_id, + }; + + const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputtedList); + }); + + it('should be able to read a single list item with an auto-generated item_id', async () => { + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // create a simple exception list item to read + const { body: createListBody } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMockWithoutId()) + .expect(200); + + const { body } = await supertest + .get(`${EXCEPTION_LIST_ITEM_URL}?item_id=${createListBody.item_id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const outputtedList: Partial = { + ...getExceptionListItemResponseMockWithoutAutoGeneratedValues(), + item_id: body.item_id, + }; + + const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputtedList); + }); + + it('should return 404 if given a fake id', async () => { + const { body } = await supertest + .get(`${EXCEPTION_LIST_ITEM_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'exception list item id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist', + }); + }); + + it('should return 404 if given a fake list_id', async () => { + const { body } = await supertest + .get(`${EXCEPTION_LIST_ITEM_URL}?item_id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: + 'exception list item item_id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist', + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/read_exception_lists.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/read_exception_lists.ts new file mode 100644 index 0000000000000..ee6bef3200f5c --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/read_exception_lists.ts @@ -0,0 +1,112 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { ExceptionListSchema } from '../../../../plugins/lists/common'; +import { getExceptionResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_schema.mock'; +import { + getCreateExceptionListMinimalSchemaMock, + getCreateExceptionListMinimalSchemaMockWithoutId, +} from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { EXCEPTION_LIST_URL } from '../../../../plugins/lists/common/constants'; + +import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('read_exception_lists', () => { + describe('reading exception lists', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should be able to read a single exception list using list_id', async () => { + // create a simple exception list to read + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + const { body } = await supertest + .get(`${EXCEPTION_LIST_URL}?list_id=${getCreateExceptionListMinimalSchemaMock().list_id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getExceptionResponseMockWithoutAutoGeneratedValues()); + }); + + it('should be able to read a single exception list using id', async () => { + // create a simple exception list to read + const { body: createListBody } = await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + const { body } = await supertest + .get(`${EXCEPTION_LIST_URL}?id=${createListBody.id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(getExceptionResponseMockWithoutAutoGeneratedValues()); + }); + + it('should be able to read a single list with an auto-generated list_id', async () => { + // create a simple exception list to read + const { body: createListBody } = await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMockWithoutId()) + .expect(200); + + const { body } = await supertest + .get(`${EXCEPTION_LIST_URL}?list_id=${createListBody.list_id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + const outputtedList: Partial = { + ...getExceptionResponseMockWithoutAutoGeneratedValues(), + list_id: body.list_id, + }; + + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputtedList); + }); + + it('should return 404 if given a fake id', async () => { + const { body } = await supertest + .get(`${EXCEPTION_LIST_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'exception list id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist', + }); + }); + + it('should return 404 if given a fake list_id', async () => { + const { body } = await supertest + .get(`${EXCEPTION_LIST_URL}?list_id=c1e1b359-7ac1-4e96-bc81-c683c092436f`) + .set('kbn-xsrf', 'true') + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'exception list list_id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist', + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/update_exception_list_items.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/update_exception_list_items.ts new file mode 100644 index 0000000000000..40fb705620a19 --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/update_exception_list_items.ts @@ -0,0 +1,168 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_item_schema.mock'; +import { getCreateExceptionListItemMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock'; +import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { + EXCEPTION_LIST_URL, + EXCEPTION_LIST_ITEM_URL, +} from '../../../../plugins/lists/common/constants'; + +import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils'; +import { + UpdateExceptionListItemSchema, + ExceptionListItemSchema, +} from '../../../../plugins/lists/common/schemas'; + +import { getUpdateMinimalExceptionListItemSchemaMock } from '../../../../plugins/lists/common/schemas/request/update_exception_list_item_schema.mock'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('update_exception_list_items', () => { + describe('update exception list items', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should update a single exception list item property of name using an id', async () => { + // create a simple exception list + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // create a simple exception list item + await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListItemMinimalSchemaMock()) + .expect(200); + + // update a exception list item's name + const updatedList: UpdateExceptionListItemSchema = { + ...getUpdateMinimalExceptionListItemSchemaMock(), + name: 'some other name', + }; + + const { body } = await supertest + .put(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(200); + + const outputList: Partial = { + ...getExceptionListItemResponseMockWithoutAutoGeneratedValues(), + name: 'some other name', + }; + + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputList); + }); + + it('should update a single exception list item property of name using an auto-generated item_id', async () => { + // create a simple exception list + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // eslint-disable-next-line @typescript-eslint/naming-convention + const { item_id, ...itemNoId } = getCreateExceptionListItemMinimalSchemaMock(); + + // create a simple exception list item + const { body: createListBody } = await supertest + .post(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(itemNoId) + .expect(200); + + // update a exception list item's name + const updatedList: UpdateExceptionListItemSchema = { + ...getUpdateMinimalExceptionListItemSchemaMock(), + item_id: createListBody.item_id, + name: 'some other name', + }; + + const { body } = await supertest + .put(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(200); + + const outputList: Partial = { + ...getExceptionListItemResponseMockWithoutAutoGeneratedValues(), + name: 'some other name', + item_id: body.item_id, + }; + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputList); + }); + + it('should give a 404 if it is given a fake exception list item id', async () => { + const updatedList: UpdateExceptionListItemSchema = { + ...getUpdateMinimalExceptionListItemSchemaMock(), + id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', + }; + delete updatedList.item_id; + + const { body } = await supertest + .put(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'exception list item id: "5096dec6-b6b9-4d8d-8f93-6c2602079d9d" does not exist', + }); + }); + + it('should give a 404 if it is given a fake item_id', async () => { + const updatedList: UpdateExceptionListItemSchema = { + ...getUpdateMinimalExceptionListItemSchemaMock(), + item_id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', + }; + + const { body } = await supertest + .put(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: + 'exception list item item_id: "5096dec6-b6b9-4d8d-8f93-6c2602079d9d" does not exist', + }); + }); + + it('should give a 404 if both id and list_id is null', async () => { + // eslint-disable-next-line @typescript-eslint/naming-convention + const { item_id, ...listNoId } = getUpdateMinimalExceptionListItemSchemaMock(); + + const { body } = await supertest + .put(EXCEPTION_LIST_ITEM_URL) + .set('kbn-xsrf', 'true') + .send(listNoId) + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'either id or item_id need to be defined', + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/security_and_spaces/tests/update_exception_lists.ts b/x-pack/test/lists_api_integration/security_and_spaces/tests/update_exception_lists.ts new file mode 100644 index 0000000000000..bd30dd87963ed --- /dev/null +++ b/x-pack/test/lists_api_integration/security_and_spaces/tests/update_exception_lists.ts @@ -0,0 +1,182 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +import { getExceptionResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_schema.mock'; +import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { EXCEPTION_LIST_URL } from '../../../../plugins/lists/common/constants'; + +import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils'; +import { + UpdateExceptionListSchema, + ExceptionListSchema, +} from '../../../../plugins/lists/common/schemas'; + +import { getUpdateMinimalExceptionListSchemaMock } from '../../../../plugins/lists/common/schemas/request/update_exception_list_schema.mock'; + +// eslint-disable-next-line import/no-default-export +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('update_exception_lists', () => { + describe('update exception lists', () => { + afterEach(async () => { + await deleteAllExceptions(es); + }); + + it('should update a single exception list property of name using an id', async () => { + // create a simple exception list + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // update a exception list's name + const updatedList: UpdateExceptionListSchema = { + ...getUpdateMinimalExceptionListSchemaMock(), + name: 'some other name', + }; + + const { body } = await supertest + .put(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(200); + + const outputList: Partial = { + ...getExceptionResponseMockWithoutAutoGeneratedValues(), + name: 'some other name', + version: 2, + }; + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputList); + }); + + it('should update a single exception list property of name using an auto-generated list_id', async () => { + // eslint-disable-next-line @typescript-eslint/naming-convention + const { list_id, ...listNoId } = getCreateExceptionListMinimalSchemaMock(); + + // create a simple exception list + const { body: createListBody } = await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(listNoId) + .expect(200); + + // update a exception list's name + const updatedList: UpdateExceptionListSchema = { + ...getUpdateMinimalExceptionListSchemaMock(), + id: createListBody.id, + name: 'some other name', + }; + + const { body } = await supertest + .put(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(200); + + const outputList: Partial = { + ...getExceptionResponseMockWithoutAutoGeneratedValues(), + name: 'some other name', + list_id: body.list_id, + version: 2, + }; + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputList); + }); + + it('should change the version of a list when it updates two properties', async () => { + // create a simple exception list + await supertest + .post(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(getCreateExceptionListMinimalSchemaMock()) + .expect(200); + + // update a simple exception list property of name and description + // update a exception list's name + const updatedList: UpdateExceptionListSchema = { + ...getUpdateMinimalExceptionListSchemaMock(), + name: 'some other name', + description: 'some other description', + }; + + const { body } = await supertest + .put(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(200); + + const outputList: Partial = { + ...getExceptionResponseMockWithoutAutoGeneratedValues(), + name: 'some other name', + description: 'some other description', + version: 2, + }; + const bodyToCompare = removeExceptionListServerGeneratedProperties(body); + expect(bodyToCompare).to.eql(outputList); + }); + + it('should give a 404 if it is given a fake id', async () => { + const updatedList: UpdateExceptionListSchema = { + ...getUpdateMinimalExceptionListSchemaMock(), + id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', + }; + delete updatedList.list_id; + + const { body } = await supertest + .put(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'exception list id: "5096dec6-b6b9-4d8d-8f93-6c2602079d9d" does not exist', + }); + }); + + it('should give a 404 if it is given a fake list_id', async () => { + const updatedList: UpdateExceptionListSchema = { + ...getUpdateMinimalExceptionListSchemaMock(), + list_id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', + }; + + const { body } = await supertest + .put(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(updatedList) + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'exception list list_id: "5096dec6-b6b9-4d8d-8f93-6c2602079d9d" does not exist', + }); + }); + + it('should give a 404 if both id and list_id is null', async () => { + // eslint-disable-next-line @typescript-eslint/naming-convention + const { list_id, ...listNoId } = getUpdateMinimalExceptionListSchemaMock(); + + const { body } = await supertest + .put(EXCEPTION_LIST_URL) + .set('kbn-xsrf', 'true') + .send(listNoId) + .expect(404); + + expect(body).to.eql({ + status_code: 404, + message: 'either id or list_id need to be defined', + }); + }); + }); + }); +}; diff --git a/x-pack/test/lists_api_integration/utils.ts b/x-pack/test/lists_api_integration/utils.ts index 272768fdf50b3..54a13fc027c99 100644 --- a/x-pack/test/lists_api_integration/utils.ts +++ b/x-pack/test/lists_api_integration/utils.ts @@ -6,8 +6,13 @@ import { SuperTest } from 'supertest'; import supertestAsPromised from 'supertest-as-promised'; +import { Client } from '@elastic/elasticsearch'; -import { ListItemSchema } from '../../plugins/lists/common/schemas'; +import { + ListItemSchema, + ExceptionListSchema, + ExceptionListItemSchema, +} from '../../plugins/lists/common/schemas'; import { ListSchema } from '../../plugins/lists/common'; import { LIST_INDEX } from '../../plugins/lists/common/constants'; @@ -83,6 +88,30 @@ export const removeListItemServerGeneratedProperties = ( return removedProperties; }; +/** + * This will remove server generated properties such as date times, etc... + * @param list List to pass in to remove typical server generated properties + */ +export const removeExceptionListItemServerGeneratedProperties = ( + list: Partial +): Partial => { + /* eslint-disable-next-line @typescript-eslint/naming-convention */ + const { created_at, updated_at, id, tie_breaker_id, _version, ...removedProperties } = list; + return removedProperties; +}; + +/** + * This will remove server generated properties such as date times, etc... + * @param list List to pass in to remove typical server generated properties + */ +export const removeExceptionListServerGeneratedProperties = ( + list: Partial +): Partial => { + /* eslint-disable-next-line @typescript-eslint/naming-convention */ + const { created_at, updated_at, id, tie_breaker_id, _version, ...removedProperties } = list; + return removedProperties; +}; + // Similar to ReactJs's waitFor from here: https://testing-library.com/docs/dom-testing-library/api-async#waitfor export const waitFor = async ( functionToTest: () => Promise, @@ -124,3 +153,32 @@ export const binaryToString = (res: any, callback: any): void => { callback(null, Buffer.from(res.data)); }); }; + +/** + * Remove all exceptions from the .kibana index + * This will retry 20 times before giving up and hopefully still not interfere with other tests + * @param es The ElasticSearch handle + */ +export const deleteAllExceptions = async (es: Client, retryCount = 20): Promise => { + if (retryCount > 0) { + try { + await es.deleteByQuery({ + index: '.kibana', + q: 'type:exception-list or type:exception-list-agnostic', + wait_for_completion: true, + refresh: true, + body: {}, + }); + } catch (err) { + // eslint-disable-next-line no-console + console.log( + `Failure trying to deleteAllExceptions, retries left are: ${retryCount - 1}`, + err + ); + await deleteAllExceptions(es, retryCount - 1); + } + } else { + // eslint-disable-next-line no-console + console.log('Could not deleteAllExceptions, no retries are left'); + } +}; From b249af128ee73a1be0669f77a1e5c6c8bbceefc2 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Thu, 13 Aug 2020 09:38:15 +0200 Subject: [PATCH 06/15] Use jest.useFakeTimers instead of hard coded timeout for tooltip tests. (#74642) Refactor to use jest.useFakeTimers(). --- .../field_title_bar/field_title_bar.test.js | 31 +++++++++++++------ .../field_type_icon/field_type_icon.test.js | 19 ++++++++++-- .../configure_cases/button.test.tsx | 18 +++++++---- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/ml/public/application/components/field_title_bar/field_title_bar.test.js b/x-pack/plugins/ml/public/application/components/field_title_bar/field_title_bar.test.js index 1b33d68042295..329863fdc9986 100644 --- a/x-pack/plugins/ml/public/application/components/field_title_bar/field_title_bar.test.js +++ b/x-pack/plugins/ml/public/application/components/field_title_bar/field_title_bar.test.js @@ -62,7 +62,10 @@ describe('FieldTitleBar', () => { expect(hasClassName).toBeTruthy(); }); - test(`tooltip hovering`, (done) => { + test(`tooltip hovering`, () => { + // Use fake timers so we don't have to wait for the EuiToolTip timeout + jest.useFakeTimers(); + const props = { card: { fieldName: 'foo', type: 'bar' } }; const wrapper = mountWithIntl(); const container = wrapper.find({ className: 'field-name' }); @@ -70,14 +73,22 @@ describe('FieldTitleBar', () => { expect(wrapper.find('EuiToolTip').children()).toHaveLength(1); container.simulate('mouseover'); - // EuiToolTip mounts children after a 250ms delay - setTimeout(() => { - wrapper.update(); - expect(wrapper.find('EuiToolTip').children()).toHaveLength(2); - container.simulate('mouseout'); - wrapper.update(); - expect(wrapper.find('EuiToolTip').children()).toHaveLength(1); - done(); - }, 250); + + // Run the timers so the EuiTooltip will be visible + jest.runAllTimers(); + + wrapper.update(); + expect(wrapper.find('EuiToolTip').children()).toHaveLength(2); + + container.simulate('mouseout'); + + // Run the timers so the EuiTooltip will be hidden again + jest.runAllTimers(); + + wrapper.update(); + expect(wrapper.find('EuiToolTip').children()).toHaveLength(1); + + // Clearing all mocks will also reset fake timers. + jest.clearAllMocks(); }); }); diff --git a/x-pack/plugins/ml/public/application/components/field_type_icon/field_type_icon.test.js b/x-pack/plugins/ml/public/application/components/field_type_icon/field_type_icon.test.js index 7e37dc10ade33..d4200c2f8366b 100644 --- a/x-pack/plugins/ml/public/application/components/field_type_icon/field_type_icon.test.js +++ b/x-pack/plugins/ml/public/application/components/field_type_icon/field_type_icon.test.js @@ -27,6 +27,9 @@ describe('FieldTypeIcon', () => { }); test(`render with tooltip and test hovering`, () => { + // Use fake timers so we don't have to wait for the EuiToolTip timeout + jest.useFakeTimers(); + const typeIconComponent = mount( ); @@ -35,11 +38,23 @@ describe('FieldTypeIcon', () => { expect(typeIconComponent.find('EuiToolTip').children()).toHaveLength(1); container.simulate('mouseover'); - // EuiToolTip mounts children after a 250ms delay - setTimeout(() => expect(typeIconComponent.find('EuiToolTip').children()).toHaveLength(2), 250); + + // Run the timers so the EuiTooltip will be visible + jest.runAllTimers(); + + typeIconComponent.update(); + expect(typeIconComponent.find('EuiToolTip').children()).toHaveLength(2); container.simulate('mouseout'); + + // Run the timers so the EuiTooltip will be hidden again + jest.runAllTimers(); + + typeIconComponent.update(); expect(typeIconComponent.find('EuiToolTip').children()).toHaveLength(1); + + // Clearing all mocks will also reset fake timers. + jest.clearAllMocks(); }); test(`update component`, () => { diff --git a/x-pack/plugins/security_solution/public/cases/components/configure_cases/button.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/button.test.tsx index 6fb693e47560d..56daa9a8364f6 100644 --- a/x-pack/plugins/security_solution/public/cases/components/configure_cases/button.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/button.test.tsx @@ -80,6 +80,9 @@ describe('Configuration button', () => { }); test('it shows the tooltip when hovering the button', () => { + // Use fake timers so we don't have to wait for the EuiToolTip timeout + jest.useFakeTimers(); + const msgTooltip = 'My message tooltip'; const titleTooltip = 'My title'; @@ -96,11 +99,14 @@ describe('Configuration button', () => { ); newWrapper.find('[data-test-subj="configure-case-button"]').first().simulate('mouseOver'); - // EuiToolTip mounts children after a 250ms delay - setTimeout( - () => - expect(newWrapper.find('.euiToolTipPopover').text()).toBe(`${titleTooltip}${msgTooltip}`), - 250 - ); + + // Run the timers so the EuiTooltip will be visible + jest.runAllTimers(); + + newWrapper.update(); + expect(newWrapper.find('.euiToolTipPopover').text()).toBe(`${titleTooltip}${msgTooltip}`); + + // Clearing all mocks will also reset fake timers. + jest.clearAllMocks(); }); }); From 290f9bfde20cc6f689803afd0efbc158fdbbc5d8 Mon Sep 17 00:00:00 2001 From: Liza Katz Date: Thu, 13 Aug 2020 11:28:39 +0300 Subject: [PATCH 07/15] Data plugin: Suggested enhance pattern (#74505) * improve test stability * Enhance pattern * fix tests * fix test * Rename enhance to __enhance * Deleted unnecessary attribute * ISearchInterceptor interface * docs * Clean up internal docs * jest Co-authored-by: Elastic Machine --- ...ublic.searchinterceptor.abortcontroller.md | 13 ----- ...blic.searchinterceptor.getpendingcount_.md | 8 ++- ...data-public.searchinterceptor.hidetoast.md | 11 ---- ...blic.searchinterceptor.longrunningtoast.md | 13 ----- ...n-plugins-data-public.searchinterceptor.md | 11 +--- ...a-public.searchinterceptor.pendingcount.md | 13 ----- ...-public.searchinterceptor.pendingcount_.md | 13 ----- ...ns-data-public.searchinterceptor.search.md | 2 +- ...data-public.searchinterceptor.showtoast.md | 11 ---- ....searchinterceptor.timeoutsubscriptions.md | 13 ----- ...-data-public.searchinterceptordeps.http.md | 2 +- ...ugins-data-public.searchinterceptordeps.md | 8 +-- ...ic.searchinterceptordeps.startservices.md} | 6 +-- ...ata-public.searchinterceptordeps.toasts.md | 2 +- ...public.searchinterceptordeps.uisettings.md | 2 +- src/plugins/data/public/mocks.ts | 1 + src/plugins/data/public/plugin.ts | 18 ++++--- src/plugins/data/public/public.api.md | 35 ++++++++----- src/plugins/data/public/search/index.ts | 9 +++- src/plugins/data/public/search/mocks.ts | 2 +- .../public/search/search_interceptor.test.ts | 28 +++++------ .../data/public/search/search_interceptor.ts | 50 ++++++++++++------- .../data/public/search/search_service.test.ts | 2 +- .../data/public/search/search_service.ts | 35 +++++++------ src/plugins/data/public/search/types.ts | 16 ++++-- src/plugins/data/public/types.ts | 10 +++- x-pack/plugins/data_enhanced/public/plugin.ts | 18 ++++--- .../public/search/search_interceptor.test.ts | 48 +++++++++++------- .../public/search/search_interceptor.ts | 7 ++- 29 files changed, 194 insertions(+), 213 deletions(-) delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.abortcontroller.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.hidetoast.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.longrunningtoast.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.pendingcount.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.pendingcount_.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.showtoast.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.timeoutsubscriptions.md rename docs/development/plugins/data/public/{kibana-plugin-plugins-data-public.searchinterceptordeps.application.md => kibana-plugin-plugins-data-public.searchinterceptordeps.startservices.md} (61%) diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.abortcontroller.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.abortcontroller.md deleted file mode 100644 index 0451a2254dc40..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.abortcontroller.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [abortController](./kibana-plugin-plugins-data-public.searchinterceptor.abortcontroller.md) - -## SearchInterceptor.abortController property - -`abortController` used to signal all searches to abort. - -Signature: - -```typescript -protected abortController: AbortController; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.getpendingcount_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.getpendingcount_.md index db2c5d6957ad7..ef36b3f37b0c7 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.getpendingcount_.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.getpendingcount_.md @@ -2,12 +2,16 @@ [Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [getPendingCount$](./kibana-plugin-plugins-data-public.searchinterceptor.getpendingcount_.md) -## SearchInterceptor.getPendingCount$ property +## SearchInterceptor.getPendingCount$() method Returns an `Observable` over the current number of pending searches. This could mean that one of the search requests is still in flight, or that it has only received partial responses. Signature: ```typescript -getPendingCount$: () => Observable; +getPendingCount$(): Observable; ``` +Returns: + +`Observable` + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.hidetoast.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.hidetoast.md deleted file mode 100644 index 59938a755a99e..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.hidetoast.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [hideToast](./kibana-plugin-plugins-data-public.searchinterceptor.hidetoast.md) - -## SearchInterceptor.hideToast property - -Signature: - -```typescript -protected hideToast: () => void; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.longrunningtoast.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.longrunningtoast.md deleted file mode 100644 index 5799039de91bc..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.longrunningtoast.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [longRunningToast](./kibana-plugin-plugins-data-public.searchinterceptor.longrunningtoast.md) - -## SearchInterceptor.longRunningToast property - -The current long-running toast (if there is one). - -Signature: - -```typescript -protected longRunningToast?: Toast; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md index b3b7da05326d0..32954927504ae 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.md @@ -20,22 +20,15 @@ export declare class SearchInterceptor | Property | Modifiers | Type | Description | | --- | --- | --- | --- | -| [abortController](./kibana-plugin-plugins-data-public.searchinterceptor.abortcontroller.md) | | AbortController | abortController used to signal all searches to abort. | | [deps](./kibana-plugin-plugins-data-public.searchinterceptor.deps.md) | | SearchInterceptorDeps | | -| [getPendingCount$](./kibana-plugin-plugins-data-public.searchinterceptor.getpendingcount_.md) | | () => Observable<number> | Returns an Observable over the current number of pending searches. This could mean that one of the search requests is still in flight, or that it has only received partial responses. | -| [hideToast](./kibana-plugin-plugins-data-public.searchinterceptor.hidetoast.md) | | () => void | | -| [longRunningToast](./kibana-plugin-plugins-data-public.searchinterceptor.longrunningtoast.md) | | Toast | The current long-running toast (if there is one). | -| [pendingCount](./kibana-plugin-plugins-data-public.searchinterceptor.pendingcount.md) | | number | The number of pending search requests. | -| [pendingCount$](./kibana-plugin-plugins-data-public.searchinterceptor.pendingcount_.md) | | BehaviorSubject<number> | Observable that emits when the number of pending requests changes. | | [requestTimeout](./kibana-plugin-plugins-data-public.searchinterceptor.requesttimeout.md) | | number | undefined | | -| [showToast](./kibana-plugin-plugins-data-public.searchinterceptor.showtoast.md) | | () => void | | -| [timeoutSubscriptions](./kibana-plugin-plugins-data-public.searchinterceptor.timeoutsubscriptions.md) | | Subscription | The subscriptions from scheduling the automatic timeout for each request. | ## Methods | Method | Modifiers | Description | | --- | --- | --- | +| [getPendingCount$()](./kibana-plugin-plugins-data-public.searchinterceptor.getpendingcount_.md) | | Returns an Observable over the current number of pending searches. This could mean that one of the search requests is still in flight, or that it has only received partial responses. | | [runSearch(request, signal, strategy)](./kibana-plugin-plugins-data-public.searchinterceptor.runsearch.md) | | | -| [search(request, options)](./kibana-plugin-plugins-data-public.searchinterceptor.search.md) | | Searches using the given search method. Overrides the AbortSignal with one that will abort either when cancelPending is called, when the request times out, or when the original AbortSignal is aborted. Updates the pendingCount when the request is started/finalized. | +| [search(request, options)](./kibana-plugin-plugins-data-public.searchinterceptor.search.md) | | Searches using the given search method. Overrides the AbortSignal with one that will abort either when cancelPending is called, when the request times out, or when the original AbortSignal is aborted. Updates pendingCount$ when the request is started/finalized. | | [setupTimers(options)](./kibana-plugin-plugins-data-public.searchinterceptor.setuptimers.md) | | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.pendingcount.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.pendingcount.md deleted file mode 100644 index 7dd2bd3e6703f..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.pendingcount.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [pendingCount](./kibana-plugin-plugins-data-public.searchinterceptor.pendingcount.md) - -## SearchInterceptor.pendingCount property - -The number of pending search requests. - -Signature: - -```typescript -protected pendingCount: number; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.pendingcount_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.pendingcount_.md deleted file mode 100644 index dad0fca0bfe08..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.pendingcount_.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [pendingCount$](./kibana-plugin-plugins-data-public.searchinterceptor.pendingcount_.md) - -## SearchInterceptor.pendingCount$ property - -Observable that emits when the number of pending requests changes. - -Signature: - -```typescript -protected pendingCount$: BehaviorSubject; -``` 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 index 38ddda7b4e184..1752d183a8737 100644 --- 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 @@ -4,7 +4,7 @@ ## SearchInterceptor.search() method -Searches using the given `search` method. Overrides the `AbortSignal` with one that will abort either when `cancelPending` is called, when the request times out, or when the original `AbortSignal` is aborted. Updates the `pendingCount` when the request is started/finalized. +Searches using the given `search` method. Overrides the `AbortSignal` with one that will abort either when `cancelPending` is called, when the request times out, or when the original `AbortSignal` is aborted. Updates `pendingCount$` when the request is started/finalized. Signature: diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.showtoast.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.showtoast.md deleted file mode 100644 index e495c72b57215..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.showtoast.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [showToast](./kibana-plugin-plugins-data-public.searchinterceptor.showtoast.md) - -## SearchInterceptor.showToast property - -Signature: - -```typescript -protected showToast: () => void; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.timeoutsubscriptions.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.timeoutsubscriptions.md deleted file mode 100644 index 12f200e037784..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptor.timeoutsubscriptions.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) > [timeoutSubscriptions](./kibana-plugin-plugins-data-public.searchinterceptor.timeoutsubscriptions.md) - -## SearchInterceptor.timeoutSubscriptions property - -The subscriptions from scheduling the automatic timeout for each request. - -Signature: - -```typescript -protected timeoutSubscriptions: Subscription; -``` 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 index 1146179c13d63..66c31bb6fcf80 100644 --- 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 @@ -7,5 +7,5 @@ Signature: ```typescript -http: CoreStart['http']; +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 index 1291af5359887..63eb67ce48246 100644 --- 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 @@ -14,9 +14,9 @@ export interface SearchInterceptorDeps | Property | Type | Description | | --- | --- | --- | -| [application](./kibana-plugin-plugins-data-public.searchinterceptordeps.application.md) | ApplicationStart | | -| [http](./kibana-plugin-plugins-data-public.searchinterceptordeps.http.md) | CoreStart['http'] | | -| [toasts](./kibana-plugin-plugins-data-public.searchinterceptordeps.toasts.md) | ToastsStart | | -| [uiSettings](./kibana-plugin-plugins-data-public.searchinterceptordeps.uisettings.md) | CoreStart['uiSettings'] | | +| [http](./kibana-plugin-plugins-data-public.searchinterceptordeps.http.md) | CoreSetup['http'] | | +| [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.application.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.startservices.md similarity index 61% rename from docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.application.md rename to docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.startservices.md index a8cd1b170a595..855d0652058b8 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.application.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchinterceptordeps.startservices.md @@ -1,11 +1,11 @@ -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [SearchInterceptorDeps](./kibana-plugin-plugins-data-public.searchinterceptordeps.md) > [application](./kibana-plugin-plugins-data-public.searchinterceptordeps.application.md) +[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.application property +## SearchInterceptorDeps.startServices property Signature: ```typescript -application: ApplicationStart; +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 index 0023b34af10c3..1f560dfa5cf7c 100644 --- 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 @@ -7,5 +7,5 @@ Signature: ```typescript -toasts: ToastsStart; +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 index 425e177ec9300..a34d223c34ac2 100644 --- 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 @@ -7,5 +7,5 @@ Signature: ```typescript -uiSettings: CoreStart['uiSettings']; +uiSettings: CoreSetup['uiSettings']; ``` diff --git a/src/plugins/data/public/mocks.ts b/src/plugins/data/public/mocks.ts index 135b6121d1dd5..3fc1e6454829d 100644 --- a/src/plugins/data/public/mocks.ts +++ b/src/plugins/data/public/mocks.ts @@ -44,6 +44,7 @@ const createSetupContract = (): Setup => { search: searchServiceMock.createSetupContract(), fieldFormats: fieldFormatsServiceMock.createSetupContract(), query: querySetupMock, + __enhance: jest.fn(), }; }; diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts index 68c0f506f121d..e950434b287a7 100644 --- a/src/plugins/data/public/plugin.ts +++ b/src/plugins/data/public/plugin.ts @@ -34,6 +34,7 @@ import { DataSetupDependencies, DataStartDependencies, InternalStartServices, + DataPublicPluginEnhancements, } from './types'; import { AutocompleteService } from './autocomplete'; import { SearchService } from './search/search_service'; @@ -156,16 +157,21 @@ export class DataPublicPlugin })) ); + const searchService = this.searchService.setup(core, { + expressions, + usageCollection, + getInternalStartServices, + packageInfo: this.packageInfo, + }); + return { autocomplete: this.autocomplete.setup(core), - search: this.searchService.setup(core, { - expressions, - usageCollection, - getInternalStartServices, - packageInfo: this.packageInfo, - }), + search: searchService, fieldFormats: this.fieldFormatsService.setup(core), query: queryService, + __enhance: (enhancements: DataPublicPluginEnhancements) => { + searchService.__enhance(enhancements.search); + }, }; } diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 6225d74fb1b31..a61334905e9f5 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -8,12 +8,12 @@ import { $Values } from '@kbn/utility-types'; import _ from 'lodash'; import { Action } from 'history'; import { ApiResponse } from '@elastic/elasticsearch/lib/Transport'; -import { ApplicationStart } from 'kibana/public'; import { Assign } from '@kbn/utility-types'; import { BehaviorSubject } from 'rxjs'; import Boom from 'boom'; import { Component } from 'react'; 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 { Ensure } from '@kbn/utility-types'; @@ -65,7 +65,7 @@ import { SerializedFieldFormat as SerializedFieldFormat_2 } from 'src/plugins/ex import { Subscription } from 'rxjs'; import { Toast } from 'kibana/public'; import { ToastInputFields } from 'src/core/public/notifications'; -import { ToastsStart } from 'kibana/public'; +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'; @@ -222,6 +222,10 @@ export type CustomFilter = Filter & { // // @public (undocumented) export interface DataPublicPluginSetup { + // Warning: (ae-forgotten-export) The symbol "DataPublicPluginEnhancements" needs to be exported by the entry point index.d.ts + // + // @internal (undocumented) + __enhance: (enhancements: DataPublicPluginEnhancements) => void; // Warning: (ae-forgotten-export) The symbol "AutocompleteSetup" needs to be exported by the entry point index.d.ts // // (undocumented) @@ -1714,15 +1718,19 @@ export interface SearchError { // @public (undocumented) export class SearchInterceptor { constructor(deps: SearchInterceptorDeps, requestTimeout?: number | undefined); + // @internal protected abortController: AbortController; + // @internal (undocumented) + protected application: CoreStart['application']; // (undocumented) protected readonly deps: SearchInterceptorDeps; - getPendingCount$: () => Observable; - // (undocumented) + getPendingCount$(): Observable; + // @internal (undocumented) protected hideToast: () => void; + // @internal protected longRunningToast?: Toast; + // @internal protected pendingCount$: BehaviorSubject; - protected pendingCount: number; // (undocumented) protected readonly requestTimeout?: number | undefined; // (undocumented) @@ -1733,8 +1741,9 @@ export class SearchInterceptor { combinedSignal: AbortSignal; cleanup: () => void; }; - // (undocumented) + // @internal (undocumented) protected showToast: () => void; + // @internal protected timeoutSubscriptions: Subscription; } @@ -1743,13 +1752,13 @@ export class SearchInterceptor { // @public (undocumented) export interface SearchInterceptorDeps { // (undocumented) - application: ApplicationStart; + http: CoreSetup_2['http']; // (undocumented) - http: CoreStart['http']; + startServices: Promise<[CoreStart, any, unknown]>; // (undocumented) - toasts: ToastsStart; + toasts: ToastsSetup; // (undocumented) - uiSettings: CoreStart['uiSettings']; + uiSettings: CoreSetup_2['uiSettings']; // Warning: (ae-forgotten-export) The symbol "SearchUsageCollector" needs to be exported by the entry point index.d.ts // // (undocumented) @@ -1980,9 +1989,9 @@ export const UI_SETTINGS: { // src/plugins/data/public/index.ts:393:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:396:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:45:5 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/types.ts:54:5 - (ae-forgotten-export) The symbol "createFiltersFromValueClickAction" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/types.ts:55:5 - (ae-forgotten-export) The symbol "createFiltersFromRangeSelectAction" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/types.ts:63:5 - (ae-forgotten-export) The symbol "IndexPatternSelectProps" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/types.ts:62:5 - (ae-forgotten-export) The symbol "createFiltersFromValueClickAction" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/types.ts:63:5 - (ae-forgotten-export) The symbol "createFiltersFromRangeSelectAction" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/types.ts:71:5 - (ae-forgotten-export) The symbol "IndexPatternSelectProps" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/data/public/search/index.ts b/src/plugins/data/public/search/index.ts index 96445e5367147..ae028df31e401 100644 --- a/src/plugins/data/public/search/index.ts +++ b/src/plugins/data/public/search/index.ts @@ -21,7 +21,14 @@ export * from './aggs'; export * from './expressions'; export * from './tabify'; -export { ISearch, ISearchOptions, ISearchGeneric, ISearchSetup, ISearchStart } from './types'; +export { + ISearch, + ISearchOptions, + ISearchGeneric, + ISearchSetup, + ISearchStart, + SearchEnhancements, +} from './types'; export { IEsSearchResponse, IEsSearchRequest, ES_SEARCH_STRATEGY } from '../../common/search'; diff --git a/src/plugins/data/public/search/mocks.ts b/src/plugins/data/public/search/mocks.ts index c56331baffed2..8ccf46fe7c97d 100644 --- a/src/plugins/data/public/search/mocks.ts +++ b/src/plugins/data/public/search/mocks.ts @@ -26,13 +26,13 @@ export * from './search_source/mocks'; function createSetupContract(): jest.Mocked { return { aggs: searchAggsSetupMock(), + __enhance: jest.fn(), }; } function createStartContract(): jest.Mocked { return { aggs: searchAggsStartMock(), - setInterceptor: jest.fn(), search: jest.fn(), searchSource: searchSourceMock, __LEGACY: { diff --git a/src/plugins/data/public/search/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor.test.ts index f4c5de2bcaf31..2eded17bda88c 100644 --- a/src/plugins/data/public/search/search_interceptor.test.ts +++ b/src/plugins/data/public/search/search_interceptor.test.ts @@ -17,27 +17,27 @@ * under the License. */ -import { CoreStart } from '../../../../core/public'; +import { CoreSetup } from '../../../../core/public'; import { coreMock } from '../../../../core/public/mocks'; import { IEsSearchRequest } from '../../common/search'; import { SearchInterceptor } from './search_interceptor'; import { AbortError } from '../../common'; let searchInterceptor: SearchInterceptor; -let mockCoreStart: MockedKeys; +let mockCoreSetup: MockedKeys; const flushPromises = () => new Promise((resolve) => setImmediate(resolve)); jest.useFakeTimers(); describe('SearchInterceptor', () => { beforeEach(() => { - mockCoreStart = coreMock.createStart(); + mockCoreSetup = coreMock.createSetup(); searchInterceptor = new SearchInterceptor( { - toasts: mockCoreStart.notifications.toasts, - application: mockCoreStart.application, - uiSettings: mockCoreStart.uiSettings, - http: mockCoreStart.http, + toasts: mockCoreSetup.notifications.toasts, + startServices: mockCoreSetup.getStartServices(), + uiSettings: mockCoreSetup.uiSettings, + http: mockCoreSetup.http, }, 1000 ); @@ -46,7 +46,7 @@ describe('SearchInterceptor', () => { describe('search', () => { test('Observable should resolve if fetch is successful', async () => { const mockResponse: any = { result: 200 }; - mockCoreStart.http.fetch.mockResolvedValueOnce(mockResponse); + mockCoreSetup.http.fetch.mockResolvedValueOnce(mockResponse); const mockRequest: IEsSearchRequest = { params: {}, }; @@ -58,7 +58,7 @@ describe('SearchInterceptor', () => { test('Observable should fail if fetch has an error', async () => { const mockResponse: any = { result: 500 }; - mockCoreStart.http.fetch.mockRejectedValueOnce(mockResponse); + mockCoreSetup.http.fetch.mockRejectedValueOnce(mockResponse); const mockRequest: IEsSearchRequest = { params: {}, }; @@ -72,7 +72,7 @@ describe('SearchInterceptor', () => { }); test('Observable should fail if fetch times out (test merged signal)', async () => { - mockCoreStart.http.fetch.mockImplementationOnce((options: any) => { + mockCoreSetup.http.fetch.mockImplementationOnce((options: any) => { return new Promise((resolve, reject) => { options.signal.addEventListener('abort', () => { reject(new AbortError()); @@ -100,7 +100,7 @@ describe('SearchInterceptor', () => { test('Observable should fail if user aborts (test merged signal)', async () => { const abortController = new AbortController(); - mockCoreStart.http.fetch.mockImplementationOnce((options: any) => { + mockCoreSetup.http.fetch.mockImplementationOnce((options: any) => { return new Promise((resolve, reject) => { options.signal.addEventListener('abort', () => { reject(new AbortError()); @@ -136,7 +136,7 @@ describe('SearchInterceptor', () => { const error = (e: any) => { expect(e).toBeInstanceOf(AbortError); - expect(mockCoreStart.http.fetch).not.toBeCalled(); + expect(mockCoreSetup.http.fetch).not.toBeCalled(); done(); }; response.subscribe({ error }); @@ -150,7 +150,7 @@ describe('SearchInterceptor', () => { pendingCount$.subscribe(pendingNext); const mockResponse: any = { result: 200 }; - mockCoreStart.http.fetch.mockResolvedValue(mockResponse); + mockCoreSetup.http.fetch.mockResolvedValue(mockResponse); const mockRequest: IEsSearchRequest = { params: {}, }; @@ -169,7 +169,7 @@ describe('SearchInterceptor', () => { pendingCount$.subscribe(pendingNext); const mockResponse: any = { result: 500 }; - mockCoreStart.http.fetch.mockRejectedValue(mockResponse); + mockCoreSetup.http.fetch.mockRejectedValue(mockResponse); const mockRequest: IEsSearchRequest = { params: {}, }; diff --git a/src/plugins/data/public/search/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor.ts index d6fcde8e986f3..99fccda7fddf3 100644 --- a/src/plugins/data/public/search/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor.ts @@ -20,7 +20,7 @@ import { trimEnd } from 'lodash'; import { BehaviorSubject, throwError, timer, Subscription, defer, from, Observable } from 'rxjs'; import { finalize, filter } from 'rxjs/operators'; -import { ApplicationStart, Toast, ToastsStart, CoreStart } from 'kibana/public'; +import { Toast, CoreStart, ToastsSetup, CoreSetup } from 'kibana/public'; import { getCombinedSignal, AbortError } from '../../common/utils'; import { IEsSearchRequest, IEsSearchResponse, ES_SEARCH_STRATEGY } from '../../common/search'; import { ISearchOptions } from './types'; @@ -30,39 +30,43 @@ import { SearchUsageCollector } from './collectors'; const LONG_QUERY_NOTIFICATION_DELAY = 10000; export interface SearchInterceptorDeps { - toasts: ToastsStart; - application: ApplicationStart; - http: CoreStart['http']; - uiSettings: CoreStart['uiSettings']; + toasts: ToastsSetup; + http: CoreSetup['http']; + uiSettings: CoreSetup['uiSettings']; + startServices: Promise<[CoreStart, any, unknown]>; usageCollector?: SearchUsageCollector; } export class SearchInterceptor { /** * `abortController` used to signal all searches to abort. + * @internal */ protected abortController = new AbortController(); - /** - * The number of pending search requests. - */ - protected pendingCount = 0; - /** * Observable that emits when the number of pending requests changes. + * @internal */ - protected pendingCount$ = new BehaviorSubject(this.pendingCount); + protected pendingCount$ = new BehaviorSubject(0); /** * The subscriptions from scheduling the automatic timeout for each request. + * @internal */ protected timeoutSubscriptions: Subscription = new Subscription(); /** * The current long-running toast (if there is one). + * @internal */ protected longRunningToast?: Toast; + /** + * @internal + */ + protected application!: CoreStart['application']; + /** * This class should be instantiated with a `requestTimeout` corresponding with how many ms after * requests are initiated that they should automatically cancel. @@ -76,6 +80,10 @@ export class SearchInterceptor { ) { this.deps.http.addLoadingCountSource(this.pendingCount$); + this.deps.startServices.then(([coreStart]) => { + this.application = coreStart.application; + }); + // When search requests go out, a notification is scheduled allowing users to continue the // request past the timeout. When all search requests complete, we remove the notification. this.getPendingCount$() @@ -87,9 +95,9 @@ export class SearchInterceptor { * Returns an `Observable` over the current number of pending searches. This could mean that one * of the search requests is still in flight, or that it has only received partial responses. */ - public getPendingCount$ = () => { + public getPendingCount$() { return this.pendingCount$.asObservable(); - }; + } protected runSearch( request: IEsSearchRequest, @@ -112,7 +120,7 @@ export class SearchInterceptor { /** * Searches using the given `search` method. Overrides the `AbortSignal` with one that will abort * either when `cancelPending` is called, when the request times out, or when the original - * `AbortSignal` is aborted. Updates the `pendingCount` when the request is started/finalized. + * `AbortSignal` is aborted. Updates `pendingCount$` when the request is started/finalized. */ public search( request: IEsSearchRequest, @@ -125,11 +133,11 @@ export class SearchInterceptor { } const { combinedSignal, cleanup } = this.setupTimers(options); - this.pendingCount$.next(++this.pendingCount); + this.pendingCount$.next(this.pendingCount$.getValue() + 1); return this.runSearch(request, combinedSignal, options?.strategy).pipe( finalize(() => { - this.pendingCount$.next(--this.pendingCount); + this.pendingCount$.next(this.pendingCount$.getValue() - 1); cleanup(); }) ); @@ -173,13 +181,16 @@ export class SearchInterceptor { }; } + /** + * @internal + */ protected showToast = () => { if (this.longRunningToast) return; this.longRunningToast = this.deps.toasts.addInfo( { title: 'Your query is taking a while', text: getLongQueryNotification({ - application: this.deps.application, + application: this.application, }), }, { @@ -188,6 +199,9 @@ export class SearchInterceptor { ); }; + /** + * @internal + */ protected hideToast = () => { if (this.longRunningToast) { this.deps.toasts.remove(this.longRunningToast); @@ -198,3 +212,5 @@ export class SearchInterceptor { } }; } + +export type ISearchInterceptor = PublicMethodsOf; diff --git a/src/plugins/data/public/search/search_service.test.ts b/src/plugins/data/public/search/search_service.test.ts index 55d31db191733..f0a017847e06a 100644 --- a/src/plugins/data/public/search/search_service.test.ts +++ b/src/plugins/data/public/search/search_service.test.ts @@ -41,6 +41,7 @@ describe('Search service', () => { expressions: expressionsPluginMock.createSetupContract(), } as any); expect(setup).toHaveProperty('aggs'); + expect(setup).toHaveProperty('__enhance'); }); }); @@ -49,7 +50,6 @@ describe('Search service', () => { const start = searchService.start(mockCoreStart, { indexPatterns: {}, } as any); - expect(start).toHaveProperty('setInterceptor'); expect(start).toHaveProperty('search'); }); }); diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index 064e16014cb70..4c94925b66d6e 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -18,7 +18,7 @@ */ import { Plugin, CoreSetup, CoreStart, PackageInfo } from '../../../../core/public'; -import { ISearchSetup, ISearchStart } from './types'; +import { ISearchSetup, ISearchStart, SearchEnhancements } from './types'; import { ExpressionsSetup } from '../../../../plugins/expressions/public'; import { createSearchSource, SearchSource, SearchSourceDependencies } from './search_source'; @@ -28,7 +28,7 @@ import { calculateBounds, TimeRange } from '../../common/query'; import { IndexPatternsContract } from '../index_patterns/index_patterns'; import { GetInternalStartServicesFn } from '../types'; -import { SearchInterceptor } from './search_interceptor'; +import { ISearchInterceptor, SearchInterceptor } from './search_interceptor'; import { getAggTypes, getAggTypesFunctions, @@ -54,7 +54,7 @@ interface SearchServiceStartDependencies { export class SearchService implements Plugin { private esClient?: LegacyApiCaller; private readonly aggTypesRegistry = new AggTypesRegistry(); - private searchInterceptor!: SearchInterceptor; + private searchInterceptor!: ISearchInterceptor; private usageCollector?: SearchUsageCollector; /** @@ -91,15 +91,6 @@ export class SearchService implements Plugin { const aggFunctions = getAggTypesFunctions(); aggFunctions.forEach((fn) => expressions.registerFunction(fn)); - return { - aggs: { - calculateAutoTimeExpression: getCalculateAutoTimeExpression(core.uiSettings), - types: aggTypesSetup, - }, - }; - } - - public start(core: CoreStart, dependencies: SearchServiceStartDependencies): ISearchStart { /** * A global object that intercepts all searches and provides convenience methods for cancelling * all pending search requests, as well as getting the number of pending search requests. @@ -109,14 +100,27 @@ export class SearchService implements Plugin { this.searchInterceptor = new SearchInterceptor( { toasts: core.notifications.toasts, - application: core.application, http: core.http, uiSettings: core.uiSettings, + startServices: core.getStartServices(), usageCollector: this.usageCollector!, }, core.injectedMetadata.getInjectedVar('esRequestTimeout') as number ); + return { + usageCollector: this.usageCollector!, + __enhance: (enhancements: SearchEnhancements) => { + this.searchInterceptor = enhancements.searchInterceptor; + }, + aggs: { + calculateAutoTimeExpression: getCalculateAutoTimeExpression(core.uiSettings), + types: aggTypesSetup, + }, + }; + } + + public start(core: CoreStart, dependencies: SearchServiceStartDependencies): ISearchStart { const aggTypesStart = this.aggTypesRegistry.start(); const search: ISearchGeneric = (request, options) => { @@ -145,17 +149,12 @@ export class SearchService implements Plugin { types: aggTypesStart, }, search, - usageCollector: this.usageCollector!, searchSource: { create: createSearchSource(dependencies.indexPatterns, searchSourceDependencies), createEmpty: () => { return new SearchSource({}, searchSourceDependencies); }, }, - setInterceptor: (searchInterceptor: SearchInterceptor) => { - // TODO: should an intercepror have a destroy method? - this.searchInterceptor = searchInterceptor; - }, __LEGACY: legacySearch, }; } diff --git a/src/plugins/data/public/search/types.ts b/src/plugins/data/public/search/types.ts index f80a13d048a68..d85d4c4e5c935 100644 --- a/src/plugins/data/public/search/types.ts +++ b/src/plugins/data/public/search/types.ts @@ -21,7 +21,7 @@ import { Observable } from 'rxjs'; import { PackageInfo } from 'kibana/server'; import { SearchAggsSetup, SearchAggsStart } from './aggs'; import { LegacyApiCaller } from './legacy/es_client'; -import { SearchInterceptor } from './search_interceptor'; +import { ISearchInterceptor } from './search_interceptor'; import { ISearchSource, SearchSourceFields } from './search_source'; import { SearchUsageCollector } from './collectors'; import { @@ -54,23 +54,33 @@ export interface ISearchStartLegacy { esClient: LegacyApiCaller; } +export interface SearchEnhancements { + searchInterceptor: ISearchInterceptor; +} /** * The setup contract exposed by the Search plugin exposes the search strategy extension * point. */ export interface ISearchSetup { aggs: SearchAggsSetup; + usageCollector?: SearchUsageCollector; + /** + * @internal + */ + __enhance: (enhancements: SearchEnhancements) => void; } export interface ISearchStart { aggs: SearchAggsStart; - setInterceptor: (searchInterceptor: SearchInterceptor) => void; search: ISearchGeneric; searchSource: { create: (fields?: SearchSourceFields) => Promise; createEmpty: () => ISearchSource; }; - usageCollector?: SearchUsageCollector; + /** + * @deprecated + * @internal + */ __LEGACY: ISearchStartLegacy; } diff --git a/src/plugins/data/public/types.ts b/src/plugins/data/public/types.ts index 6d67127251424..c39b7d355d495 100644 --- a/src/plugins/data/public/types.ts +++ b/src/plugins/data/public/types.ts @@ -25,13 +25,17 @@ import { UiActionsSetup, UiActionsStart } from 'src/plugins/ui_actions/public'; import { AutocompleteSetup, AutocompleteStart } from './autocomplete'; import { FieldFormatsSetup, FieldFormatsStart } from './field_formats'; import { createFiltersFromRangeSelectAction, createFiltersFromValueClickAction } from './actions'; -import { ISearchSetup, ISearchStart } from './search'; +import { ISearchSetup, ISearchStart, SearchEnhancements } from './search'; import { QuerySetup, QueryStart } from './query'; import { IndexPatternSelectProps } from './ui/index_pattern_select'; import { IndexPatternsContract } from './index_patterns'; import { StatefulSearchBarProps } from './ui/search_bar/create_search_bar'; import { UsageCollectionSetup } from '../../usage_collection/public'; +export interface DataPublicPluginEnhancements { + search: SearchEnhancements; +} + export interface DataSetupDependencies { expressions: ExpressionsSetup; uiActions: UiActionsSetup; @@ -47,6 +51,10 @@ export interface DataPublicPluginSetup { search: ISearchSetup; fieldFormats: FieldFormatsSetup; query: QuerySetup; + /** + * @internal + */ + __enhance: (enhancements: DataPublicPluginEnhancements) => void; } export interface DataPublicPluginStart { diff --git a/x-pack/plugins/data_enhanced/public/plugin.ts b/x-pack/plugins/data_enhanced/public/plugin.ts index bdf3f6a0acf90..7f6e3feac0671 100644 --- a/x-pack/plugins/data_enhanced/public/plugin.ts +++ b/x-pack/plugins/data_enhanced/public/plugin.ts @@ -31,20 +31,26 @@ export class DataEnhancedPlugin KUERY_LANGUAGE_NAME, setupKqlQuerySuggestionProvider(core) ); - } - public start(core: CoreStart, plugins: DataEnhancedStartDependencies) { - setAutocompleteService(plugins.data.autocomplete); const enhancedSearchInterceptor = new EnhancedSearchInterceptor( { toasts: core.notifications.toasts, - application: core.application, http: core.http, uiSettings: core.uiSettings, - usageCollector: plugins.data.search.usageCollector, + startServices: core.getStartServices(), + usageCollector: data.search.usageCollector, }, core.injectedMetadata.getInjectedVar('esRequestTimeout') as number ); - plugins.data.search.setInterceptor(enhancedSearchInterceptor); + + data.__enhance({ + search: { + searchInterceptor: enhancedSearchInterceptor, + }, + }); + } + + public start(core: CoreStart, plugins: DataEnhancedStartDependencies) { + setAutocompleteService(plugins.data.autocomplete); } } diff --git a/x-pack/plugins/data_enhanced/public/search/search_interceptor.test.ts b/x-pack/plugins/data_enhanced/public/search/search_interceptor.test.ts index d004511fa4674..fe954f1602cd3 100644 --- a/x-pack/plugins/data_enhanced/public/search/search_interceptor.test.ts +++ b/x-pack/plugins/data_enhanced/public/search/search_interceptor.test.ts @@ -6,7 +6,7 @@ import { coreMock } from '../../../../../src/core/public/mocks'; import { EnhancedSearchInterceptor } from './search_interceptor'; -import { CoreStart } from 'kibana/public'; +import { CoreSetup, CoreStart } from 'kibana/public'; import { AbortError } from '../../../../../src/plugins/data/common'; const timeTravel = (msToRun = 0) => { @@ -19,13 +19,14 @@ const error = jest.fn(); const complete = jest.fn(); let searchInterceptor: EnhancedSearchInterceptor; +let mockCoreSetup: MockedKeys; let mockCoreStart: MockedKeys; jest.useFakeTimers(); function mockFetchImplementation(responses: any[]) { let i = 0; - mockCoreStart.http.fetch.mockImplementation(() => { + mockCoreSetup.http.fetch.mockImplementation(() => { const { time = 0, value = {}, isError = false } = responses[i++]; return new Promise((resolve, reject) => setTimeout(() => { @@ -39,6 +40,7 @@ describe('EnhancedSearchInterceptor', () => { let mockUsageCollector: any; beforeEach(() => { + mockCoreSetup = coreMock.createSetup(); mockCoreStart = coreMock.createStart(); next.mockClear(); @@ -54,12 +56,20 @@ describe('EnhancedSearchInterceptor', () => { trackLongQueryRunBeyondTimeout: jest.fn(), }; + const mockPromise = new Promise((resolve) => { + resolve([ + { + application: mockCoreStart.application, + }, + ]); + }); + searchInterceptor = new EnhancedSearchInterceptor( { - toasts: mockCoreStart.notifications.toasts, - application: mockCoreStart.application, - http: mockCoreStart.http, - uiSettings: mockCoreStart.uiSettings, + toasts: mockCoreSetup.notifications.toasts, + startServices: mockPromise as any, + http: mockCoreSetup.http, + uiSettings: mockCoreSetup.uiSettings, usageCollector: mockUsageCollector, }, 1000 @@ -229,8 +239,8 @@ describe('EnhancedSearchInterceptor', () => { expect(error).toHaveBeenCalled(); expect(error.mock.calls[0][0]).toBeInstanceOf(AbortError); - expect(mockCoreStart.http.fetch).toHaveBeenCalledTimes(2); - expect(mockCoreStart.http.delete).toHaveBeenCalled(); + expect(mockCoreSetup.http.fetch).toHaveBeenCalledTimes(2); + expect(mockCoreSetup.http.delete).toHaveBeenCalled(); }); test('should not DELETE a running async search on async timeout prior to first response', async () => { @@ -253,8 +263,8 @@ describe('EnhancedSearchInterceptor', () => { expect(error).toHaveBeenCalled(); expect(error.mock.calls[0][0]).toBeInstanceOf(AbortError); - expect(mockCoreStart.http.fetch).toHaveBeenCalled(); - expect(mockCoreStart.http.delete).not.toHaveBeenCalled(); + expect(mockCoreSetup.http.fetch).toHaveBeenCalled(); + expect(mockCoreSetup.http.delete).not.toHaveBeenCalled(); }); test('should DELETE a running async search on async timeout after first response', async () => { @@ -285,16 +295,16 @@ describe('EnhancedSearchInterceptor', () => { expect(next).toHaveBeenCalled(); expect(error).not.toHaveBeenCalled(); - expect(mockCoreStart.http.fetch).toHaveBeenCalled(); - expect(mockCoreStart.http.delete).not.toHaveBeenCalled(); + expect(mockCoreSetup.http.fetch).toHaveBeenCalled(); + expect(mockCoreSetup.http.delete).not.toHaveBeenCalled(); // Long enough to reach the timeout but not long enough to reach the next response await timeTravel(1000); expect(error).toHaveBeenCalled(); expect(error.mock.calls[0][0]).toBeInstanceOf(AbortError); - expect(mockCoreStart.http.fetch).toHaveBeenCalledTimes(2); - expect(mockCoreStart.http.delete).toHaveBeenCalled(); + expect(mockCoreSetup.http.fetch).toHaveBeenCalledTimes(2); + expect(mockCoreSetup.http.delete).toHaveBeenCalled(); }); test('should DELETE a running async search on async timeout on error from fetch', async () => { @@ -327,16 +337,16 @@ describe('EnhancedSearchInterceptor', () => { expect(next).toHaveBeenCalled(); expect(error).not.toHaveBeenCalled(); - expect(mockCoreStart.http.fetch).toHaveBeenCalled(); - expect(mockCoreStart.http.delete).not.toHaveBeenCalled(); + expect(mockCoreSetup.http.fetch).toHaveBeenCalled(); + expect(mockCoreSetup.http.delete).not.toHaveBeenCalled(); // Long enough to reach the timeout but not long enough to reach the next response await timeTravel(10); expect(error).toHaveBeenCalled(); expect(error.mock.calls[0][0]).toBe(responses[1].value); - expect(mockCoreStart.http.fetch).toHaveBeenCalledTimes(2); - expect(mockCoreStart.http.delete).toHaveBeenCalled(); + expect(mockCoreSetup.http.fetch).toHaveBeenCalledTimes(2); + expect(mockCoreSetup.http.delete).toHaveBeenCalled(); }); }); @@ -367,7 +377,7 @@ describe('EnhancedSearchInterceptor', () => { await timeTravel(); - const areAllRequestsAborted = mockCoreStart.http.fetch.mock.calls.every( + const areAllRequestsAborted = mockCoreSetup.http.fetch.mock.calls.every( ([{ signal }]) => signal?.aborted ); expect(areAllRequestsAborted).toBe(true); diff --git a/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts b/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts index bff9e2cb9048c..ae6dddf33536f 100644 --- a/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts +++ b/x-pack/plugins/data_enhanced/public/search/search_interceptor.ts @@ -20,8 +20,7 @@ export class EnhancedSearchInterceptor extends SearchInterceptor { /** * This class should be instantiated with a `requestTimeout` corresponding with how many ms after * requests are initiated that they should automatically cancel. - * @param toasts The `core.notifications.toasts` service - * @param application The `core.application` service + * @param deps `SearchInterceptorDeps` * @param requestTimeout Usually config value `elasticsearch.requestTimeout` */ constructor(deps: SearchInterceptorDeps, requestTimeout?: number) { @@ -78,7 +77,7 @@ export class EnhancedSearchInterceptor extends SearchInterceptor { const { combinedSignal, cleanup } = this.setupTimers(options); const aborted$ = from(toPromise(combinedSignal)); - this.pendingCount$.next(++this.pendingCount); + this.pendingCount$.next(this.pendingCount$.getValue() + 1); return this.runSearch(request, combinedSignal, options?.strategy).pipe( expand((response) => { @@ -113,7 +112,7 @@ export class EnhancedSearchInterceptor extends SearchInterceptor { }, }), finalize(() => { - this.pendingCount$.next(--this.pendingCount); + this.pendingCount$.next(this.pendingCount$.getValue() - 1); cleanup(); }) ); From 1a09c878b185b62ec72bf790d41f61a6e21f54c0 Mon Sep 17 00:00:00 2001 From: Angela Chuang <6295984+angorayc@users.noreply.github.com> Date: Thu, 13 Aug 2020 10:24:40 +0100 Subject: [PATCH 08/15] [Security Solution] Fix the status of timelines' bulk actions (#74560) * fix bulk actions * fix lint error Co-authored-by: Elastic Machine --- .../edit_timeline_batch_actions.tsx | 7 +- .../open_timeline/open_timeline.test.tsx | 83 ++++++++++++++++++- .../open_timeline/open_timeline.tsx | 1 - 3 files changed, 86 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/edit_timeline_batch_actions.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/edit_timeline_batch_actions.tsx index 27fda48b69598..cce4251135866 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/edit_timeline_batch_actions.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/edit_timeline_batch_actions.tsx @@ -7,7 +7,7 @@ import { EuiContextMenuPanel, EuiContextMenuItem, EuiBasicTable } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; -import { TimelineType, TimelineStatus } from '../../../../common/types/timeline'; +import { TimelineType } from '../../../../common/types/timeline'; import * as i18n from './translations'; import { DeleteTimelines, OpenTimelineResult } from './types'; @@ -66,7 +66,7 @@ export const useEditTimelineBatchActions = ({ const getBatchItemsPopoverContent = useCallback( (closePopover: () => void) => { - const disabled = selectedItems?.some((item) => item.status === TimelineStatus.immutable); + const disabled = selectedItems == null || selectedItems.length === 0; return ( <> , ); }, - // eslint-disable-next-line react-hooks/exhaustive-deps [ selectedItems, deleteTimelines, diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.test.tsx index 9de3242c5e303..3d5c5f60d1d9b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.test.tsx @@ -9,6 +9,7 @@ import { cloneDeep } from 'lodash/fp'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; import React from 'react'; import { ThemeProvider } from 'styled-components'; +import { act } from '@testing-library/react'; import '../../../common/mock/match_media'; import { DEFAULT_SEARCH_RESULTS_PER_PAGE } from '../../pages/timelines_page'; @@ -51,7 +52,7 @@ describe('OpenTimeline', () => { title, timelineType: TimelineType.default, timelineStatus: TimelineStatus.active, - templateTimelineFilter: [

], + templateTimelineFilter: [
,
], totalSearchResultsCount: mockSearchResults.length, }); @@ -279,6 +280,86 @@ describe('OpenTimeline', () => { expect(wrapper.find('[data-test-subj="utility-bar-action"]').exists()).toEqual(true); }); + test('it should disable export-timeline if no timeline is selected', async () => { + const defaultProps = { + ...getDefaultTestProps(mockResults), + timelineStatus: null, + selectedItems: [], + }; + const wrapper = mountWithIntl( + + + + ); + + wrapper.find('[data-test-subj="utility-bar-action"]').find('EuiLink').simulate('click'); + await act(async () => { + expect( + wrapper.find('[data-test-subj="export-timeline-action"]').first().prop('disabled') + ).toEqual(true); + }); + }); + + test('it should disable delete timeline if no timeline is selected', async () => { + const defaultProps = { + ...getDefaultTestProps(mockResults), + timelineStatus: null, + selectedItems: [], + }; + const wrapper = mountWithIntl( + + + + ); + + wrapper.find('[data-test-subj="utility-bar-action"]').find('EuiLink').simulate('click'); + await act(async () => { + expect( + wrapper.find('[data-test-subj="delete-timeline-action"]').first().prop('disabled') + ).toEqual(true); + }); + }); + + test('it should enable export-timeline if a timeline is selected', async () => { + const defaultProps = { + ...getDefaultTestProps(mockResults), + timelineStatus: null, + selectedItems: [{}], + }; + const wrapper = mountWithIntl( + + + + ); + + wrapper.find('[data-test-subj="utility-bar-action"]').find('EuiLink').simulate('click'); + await act(async () => { + expect( + wrapper.find('[data-test-subj="export-timeline-action"]').first().prop('disabled') + ).toEqual(false); + }); + }); + + test('it should enable delete timeline if a timeline is selected', async () => { + const defaultProps = { + ...getDefaultTestProps(mockResults), + timelineStatus: null, + selectedItems: [{}], + }; + const wrapper = mountWithIntl( + + + + ); + + wrapper.find('[data-test-subj="utility-bar-action"]').find('EuiLink').simulate('click'); + await act(async () => { + expect( + wrapper.find('[data-test-subj="delete-timeline-action"]').first().prop('disabled') + ).toEqual(false); + }); + }); + test("it should render a selectable timeline table if timelineStatus is active (selecting custom templates' tab)", () => { const defaultProps = { ...getDefaultTestProps(mockResults), diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.tsx index c9495c46d4acf..1f5f0ccca3b70 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline.tsx @@ -160,7 +160,6 @@ export const OpenTimeline = React.memo( }, [onDeleteSelected, deleteTimelines, timelineStatus]); const SearchRowContent = useMemo(() => <>{templateTimelineFilter}, [templateTimelineFilter]); - return ( <> Date: Thu, 13 Aug 2020 12:20:38 +0100 Subject: [PATCH 09/15] [Task manager] Prevents edge case where already running tasks are reschedule every polling interval (#74606) Fixes flaky tests in Task Manager and Alerting. The fix in #73244 was correct, but it missed an edge case which causes the already running task to be rescheduled over and over. This prevents that edge case which was effecting both TM in general and Alerting specifically. --- .../task_manager/server/task_store.test.ts | 104 +++++++++++++++++- .../plugins/task_manager/server/task_store.ts | 55 ++++----- .../tests/alerting/update.ts | 3 +- .../task_manager/task_manager_integration.js | 3 +- 4 files changed, 125 insertions(+), 40 deletions(-) diff --git a/x-pack/plugins/task_manager/server/task_store.test.ts b/x-pack/plugins/task_manager/server/task_store.test.ts index d65c39f4f454d..a02123c4a3f8d 100644 --- a/x-pack/plugins/task_manager/server/task_store.test.ts +++ b/x-pack/plugins/task_manager/server/task_store.test.ts @@ -627,7 +627,7 @@ if (doc['task.runAt'].size()!=0) { }); }); - test('it returns task objects', async () => { + test('it filters out running tasks', async () => { const taskManagerId = uuid.v1(); const claimOwnershipUntil = new Date(Date.now()); const runAt = new Date(); @@ -641,7 +641,7 @@ if (doc['task.runAt'].size()!=0) { taskType: 'foo', schedule: undefined, attempts: 0, - status: 'idle', + status: 'claiming', params: '{ "hello": "world" }', state: '{ "baby": "Henhen" }', user: 'jimbo', @@ -715,7 +715,103 @@ if (doc['task.runAt'].size()!=0) { runAt, scope: ['reporting'], state: { baby: 'Henhen' }, - status: 'idle', + status: 'claiming', + taskType: 'foo', + user: 'jimbo', + ownerId: taskManagerId, + }, + ]); + }); + + test('it returns task objects', async () => { + const taskManagerId = uuid.v1(); + const claimOwnershipUntil = new Date(Date.now()); + const runAt = new Date(); + const tasks = [ + { + _id: 'aaa', + _source: { + type: 'task', + task: { + runAt, + taskType: 'foo', + schedule: undefined, + attempts: 0, + status: 'claiming', + params: '{ "hello": "world" }', + state: '{ "baby": "Henhen" }', + user: 'jimbo', + scope: ['reporting'], + ownerId: taskManagerId, + }, + }, + _seq_no: 1, + _primary_term: 2, + sort: ['a', 1], + }, + { + _id: 'bbb', + _source: { + type: 'task', + task: { + runAt, + taskType: 'bar', + schedule: { interval: '5m' }, + attempts: 2, + status: 'claiming', + params: '{ "shazm": 1 }', + state: '{ "henry": "The 8th" }', + user: 'dabo', + scope: ['reporting', 'ceo'], + ownerId: taskManagerId, + }, + }, + _seq_no: 3, + _primary_term: 4, + sort: ['b', 2], + }, + ]; + const { + result: { docs }, + args: { + search: { + body: { query }, + }, + }, + } = await testClaimAvailableTasks({ + opts: { + taskManagerId, + }, + claimingOpts: { + claimOwnershipUntil, + size: 10, + }, + hits: tasks, + }); + + expect(query.bool.must).toContainEqual({ + bool: { + must: [ + { + term: { + 'task.ownerId': taskManagerId, + }, + }, + { term: { 'task.status': 'claiming' } }, + ], + }, + }); + + expect(docs).toMatchObject([ + { + attempts: 0, + id: 'aaa', + schedule: undefined, + params: { hello: 'world' }, + runAt, + scope: ['reporting'], + state: { baby: 'Henhen' }, + status: 'claiming', taskType: 'foo', user: 'jimbo', ownerId: taskManagerId, @@ -728,7 +824,7 @@ if (doc['task.runAt'].size()!=0) { runAt, scope: ['reporting', 'ceo'], state: { henry: 'The 8th' }, - status: 'running', + status: 'claiming', taskType: 'bar', user: 'dabo', ownerId: taskManagerId, diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index a18fb57b35b3d..f2da41053e6ab 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -217,48 +217,39 @@ export class TaskStore { claimTasksByIdWithRawIds, size ); + const docs = numberOfTasksClaimed > 0 ? await this.sweepForClaimedTasks(claimTasksByIdWithRawIds, size) : []; - // emit success/fail events for claimed tasks by id - if (claimTasksById && claimTasksById.length) { - const [documentsReturnedById, documentsClaimedBySchedule] = partition(docs, (doc) => - claimTasksById.includes(doc.id) - ); - - const [documentsClaimedById, documentsRequestedButNotClaimed] = partition( - documentsReturnedById, - // we filter the schduled tasks down by status is 'claiming' in the esearch, - // but we do not apply this limitation on tasks claimed by ID so that we can - // provide more detailed error messages when we fail to claim them - (doc) => doc.status === TaskStatus.Claiming - ); - - const documentsRequestedButNotReturned = difference( - claimTasksById, - map(documentsReturnedById, 'id') - ); + const [documentsReturnedById, documentsClaimedBySchedule] = partition(docs, (doc) => + claimTasksById.includes(doc.id) + ); - this.emitEvents( - [...documentsClaimedById, ...documentsClaimedBySchedule].map((doc) => - asTaskClaimEvent(doc.id, asOk(doc)) - ) - ); + const [documentsClaimedById, documentsRequestedButNotClaimed] = partition( + documentsReturnedById, + // we filter the schduled tasks down by status is 'claiming' in the esearch, + // but we do not apply this limitation on tasks claimed by ID so that we can + // provide more detailed error messages when we fail to claim them + (doc) => doc.status === TaskStatus.Claiming + ); - this.emitEvents( - documentsRequestedButNotClaimed.map((doc) => asTaskClaimEvent(doc.id, asErr(some(doc)))) - ); + const documentsRequestedButNotReturned = difference( + claimTasksById, + map(documentsReturnedById, 'id') + ); - this.emitEvents( - documentsRequestedButNotReturned.map((id) => asTaskClaimEvent(id, asErr(none))) - ); - } + this.emitEvents([ + ...documentsClaimedById.map((doc) => asTaskClaimEvent(doc.id, asOk(doc))), + ...documentsClaimedBySchedule.map((doc) => asTaskClaimEvent(doc.id, asOk(doc))), + ...documentsRequestedButNotClaimed.map((doc) => asTaskClaimEvent(doc.id, asErr(some(doc)))), + ...documentsRequestedButNotReturned.map((id) => asTaskClaimEvent(id, asErr(none))), + ]); return { - claimedTasks: numberOfTasksClaimed, - docs, + claimedTasks: documentsClaimedById.length + documentsClaimedBySchedule.length, + docs: docs.filter((doc) => doc.status === TaskStatus.Claiming), }; }; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts index cac6355409ac9..ab3a92d0b3f70 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts @@ -31,8 +31,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { .then((response: SupertestResponse) => response.body); } - // FLAKY: https://github.com/elastic/kibana/issues/72803 - describe.skip('update', () => { + describe('update', () => { const objectRemover = new ObjectRemover(supertest); after(() => objectRemover.removeAll()); diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js index ea95eb42dd6ff..c87a5039360b8 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js @@ -28,8 +28,7 @@ export default function ({ getService }) { const testHistoryIndex = '.kibana_task_manager_test_result'; const supertest = supertestAsPromised(url.format(config.get('servers.kibana'))); - // FLAKY: https://github.com/elastic/kibana/issues/71390 - describe.skip('scheduling and running tasks', () => { + describe('scheduling and running tasks', () => { beforeEach( async () => await supertest.delete('/api/sample_tasks').set('kbn-xsrf', 'xxx').expect(200) ); From c7a46d583a6f930641aa8ef6cc94fd94f5ab14a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Thu, 13 Aug 2020 12:41:39 +0100 Subject: [PATCH 10/15] [Observability] change ingest manager link (#74928) * chaning ingest manager link * chaning ingest manager link --- .../components/app/ingest_manager_panel/index.tsx | 13 ++++++++----- x-pack/plugins/translations/translations/ja-JP.json | 4 ---- x-pack/plugins/translations/translations/zh-CN.json | 4 ---- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/observability/public/components/app/ingest_manager_panel/index.tsx b/x-pack/plugins/observability/public/components/app/ingest_manager_panel/index.tsx index 1ab9f75632d9d..5d0c8a40ed3de 100644 --- a/x-pack/plugins/observability/public/components/app/ingest_manager_panel/index.tsx +++ b/x-pack/plugins/observability/public/components/app/ingest_manager_panel/index.tsx @@ -11,13 +11,16 @@ import { EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { EuiText } from '@elastic/eui'; import { EuiLink } from '@elastic/eui'; +import { usePluginContext } from '../../../hooks/use_plugin_context'; export function IngestManagerPanel() { + const { core } = usePluginContext(); + return ( @@ -25,7 +28,7 @@ export function IngestManagerPanel() {

- {i18n.translate('xpack.observability.ingestManafer.title', { + {i18n.translate('xpack.observability.ingestManager.title', { defaultMessage: 'Have you seen our new Ingest Manager?', })}

@@ -33,15 +36,15 @@ export function IngestManagerPanel() {
- {i18n.translate('xpack.observability.ingestManafer.text', { + {i18n.translate('xpack.observability.ingestManager.text', { defaultMessage: 'The Elastic Agent provides a simple, unified way to add monitoring for logs, metrics, and other types of data to your hosts. You no longer need to install multiple Beats and other agents, making it easier and faster to deploy configurations across your infrastructure.', })} - - {i18n.translate('xpack.observability.ingestManafer.button', { + + {i18n.translate('xpack.observability.ingestManager.button', { defaultMessage: 'Try Ingest Manager Beta', })} diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 55d1953247a93..81c06cf5c381f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -14047,10 +14047,6 @@ "xpack.observability.home.sectionsubtitle": "ログ、メトリック、トレースを大規模に、1つのスタックにまとめて、環境内のあらゆる場所で生じるイベントの監視、分析、対応を行います。", "xpack.observability.home.sectionTitle": "エコシステム全体の一元的な可視性", "xpack.observability.home.title": "オブザーバビリティ", - "xpack.observability.ingestManafer.beta": "ベータ", - "xpack.observability.ingestManafer.button": "Ingest Managerベータを試す", - "xpack.observability.ingestManafer.text": "Elasticエージェントでは、シンプルかつ統合された方法で、ログ、メトリック、他の種類のデータの監視をホストに追加することができます。複数のBeatsと他のエージェントをインストールする必要はありません。このため、インフラストラクチャ全体での構成のデプロイが簡単で高速になりました。", - "xpack.observability.ingestManafer.title": "新しいIngest Managerをご覧になりましたか?", "xpack.observability.landing.breadcrumb": "はじめて使う", "xpack.observability.news.readFullStory": "詳細なストーリーを読む", "xpack.observability.news.title": "新機能", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 40f4c9c5897d8..af5e68b7e44d7 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -14052,10 +14052,6 @@ "xpack.observability.home.sectionsubtitle": "通过根据需要将日志、指标和跟踪都置于单个堆栈上,来监测、分析和响应环境中任何位置发生的事件。", "xpack.observability.home.sectionTitle": "整个生态系统的统一可见性", "xpack.observability.home.title": "可观测性", - "xpack.observability.ingestManafer.beta": "公测版", - "xpack.observability.ingestManafer.button": "试用采集管理器公测版", - "xpack.observability.ingestManafer.text": "通过 Elastic 代理,您能够以简单统一的方式将日志、指标和其他类型数据的监测添加到主机。不再需要安装多个 Beats 和其他代理,这样在整个基础设施中部署配置会更轻松更快速。", - "xpack.observability.ingestManafer.title": "是否了解我们全新的采集管理器?", "xpack.observability.landing.breadcrumb": "入门", "xpack.observability.news.readFullStory": "详细了解", "xpack.observability.news.title": "最近的新闻", From 50f332867af9078f3b86085e96151b7854ee41d6 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Thu, 13 Aug 2020 14:57:04 +0200 Subject: [PATCH 11/15] [Ingest Pipelines] Processor forms for processors A-D (#72849) * First few processors of the first batch - Also refactored options to live in scoped objects to avoid overriding type (important fix!) - Have not polished copy or form layout. * add type to shared imports * Refactors for repeated fields and added forms - date_index_name - dissect - dot_expander - drop Fields refactored: - Field - Ignore missing * Fix broken imports and some other small refactors * added text editor field and updated pattern and if fields * Large copy improvements and updates and other small refactors - Added help text for all fields - Updated layout so that required fields are always on first - Replaced circle radio group with a select drop down * update circle shape type field to select * Added "long" option for convert type * fix path import * fix types and i18n * add validation for dot expander fix append value to be a combobox * fix i18n Co-authored-by: Elastic Machine --- .../field_components/index.ts | 3 +- .../field_components/text_editor.tsx | 38 +++ .../field_components/xjson_editor.tsx | 54 ++-- .../manage_processor_form.container.tsx | 7 +- .../manage_processor_form.tsx | 2 +- .../processor_settings_fields.tsx | 3 +- .../processors/append.tsx | 56 ++++ .../processors/bytes.tsx | 43 ++++ .../processors/circle.tsx | 140 ++++++++++ .../common_fields/common_processor_fields.tsx | 37 ++- .../common_fields/field_name_field.tsx | 58 +++++ .../common_fields/ignore_missing_field.tsx | 37 +++ .../common_fields/processor_type_field.tsx | 27 +- .../processors/convert.tsx | 136 ++++++++++ .../manage_processor_form/processors/csv.tsx | 164 ++++++++++++ .../manage_processor_form/processors/date.tsx | 122 +++++++++ .../processors/date_index_name.tsx | 242 ++++++++++++++++++ .../processors/dissect.tsx | 99 +++++++ .../processors/dot_expander.tsx | 55 ++++ .../manage_processor_form/processors/drop.tsx | 14 + .../manage_processor_form/processors/gsub.tsx | 21 +- .../manage_processor_form/processors/index.ts | 16 ++ .../manage_processor_form/processors/set.tsx | 6 +- .../processors/shared.ts | 16 ++ .../shared/map_processor_type_to_form.tsx | 33 ++- .../ingest_pipelines/public/shared_imports.ts | 5 + 26 files changed, 1347 insertions(+), 87 deletions(-) create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/text_editor.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/append.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/bytes.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/circle.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/field_name_field.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/ignore_missing_field.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/convert.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/csv.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date_index_name.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dissect.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dot_expander.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/drop.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/index.ts create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/shared.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/index.ts index 6f7b55a3ea4b0..6ce9eefd26445 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/index.ts @@ -4,4 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -export { OnXJsonEditorUpdateHandler, XJsonEditor } from './xjson_editor'; +export { XJsonEditor } from './xjson_editor'; +export { TextEditor } from './text_editor'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/text_editor.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/text_editor.tsx new file mode 100644 index 0000000000000..1d0e36c0d526c --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/text_editor.tsx @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiPanel } from '@elastic/eui'; +import React, { FunctionComponent } from 'react'; +import { EuiFormRow } from '@elastic/eui'; +import { + CodeEditor, + FieldHook, + getFieldValidityAndErrorMessage, +} from '../../../../../../shared_imports'; + +interface Props { + field: FieldHook; + editorProps: { [key: string]: any }; +} + +export const TextEditor: FunctionComponent = ({ field, editorProps }) => { + const { value, helpText, setValue, label } = field; + const { errorMessage } = getFieldValidityAndErrorMessage(field); + + return ( + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/xjson_editor.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/xjson_editor.tsx index a8456ad0ffd72..228094c0dfac5 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/xjson_editor.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/field_components/xjson_editor.tsx @@ -4,25 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiPanel } from '@elastic/eui'; import { XJsonLang } from '@kbn/monaco'; import React, { FunctionComponent, useCallback } from 'react'; -import { EuiFormRow } from '@elastic/eui'; -import { - CodeEditor, - FieldHook, - getFieldValidityAndErrorMessage, - Monaco, -} from '../../../../../../shared_imports'; +import { FieldHook, Monaco } from '../../../../../../shared_imports'; -export type OnXJsonEditorUpdateHandler = (arg: { - data: { - raw: string; - format(): T; - }; - validate(): boolean; - isValid: boolean | undefined; -}) => void; +import { TextEditor } from './text_editor'; interface Props { field: FieldHook; @@ -30,9 +16,8 @@ interface Props { } export const XJsonEditor: FunctionComponent = ({ field, editorProps }) => { - const { value, helpText, setValue, label } = field; + const { value, setValue } = field; const { xJson, setXJson, convertToJson } = Monaco.useXJsonMode(value); - const { errorMessage } = getFieldValidityAndErrorMessage(field); const onChange = useCallback( (s) => { @@ -42,25 +27,18 @@ export const XJsonEditor: FunctionComponent = ({ field, editorProps }) => [setValue, setXJson, convertToJson] ); return ( - - - { - XJsonLang.registerGrammarChecker(m); - }} - options={{ minimap: { enabled: false } }} - onChange={onChange} - {...(editorProps as any)} - /> - - + { + XJsonLang.registerGrammarChecker(m); + }, + onChange, + ...editorProps, + }} + /> ); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.container.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.container.tsx index ea137b87e66d5..84551ce152099 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.container.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.container.tsx @@ -40,18 +40,19 @@ export const ManageProcessorForm: FunctionComponent = ({ const handleSubmit = useCallback( async (data: FormData, isValid: boolean) => { if (isValid) { - const { type, customOptions, ...options } = data; + const { type, customOptions, fields } = data; onSubmit({ type, - options: customOptions ? customOptions : options, + options: customOptions ? customOptions : fields, }); } }, [onSubmit] ); + const maybeProcessorOptions = processor?.options; const { form } = useForm({ - defaultValue: processor?.options, + defaultValue: { fields: maybeProcessorOptions ?? {} }, onSubmit: handleSubmit, }); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.tsx index 4e172cce63027..ad6d191be802d 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/manage_processor_form.tsx @@ -14,12 +14,12 @@ import { EuiFlyoutHeader, EuiFlyoutBody, EuiFlyoutFooter, - EuiSpacer, EuiTabs, EuiTab, EuiTitle, EuiFlexGroup, EuiFlexItem, + EuiSpacer, } from '@elastic/eui'; import { Form, FormDataProvider, FormHook } from '../../../../../shared_imports'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx index 6b2568bad3afc..a6447bc30ac00 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processor_settings_fields.tsx @@ -5,7 +5,7 @@ */ import React, { FunctionComponent } from 'react'; -import { EuiHorizontalRule } from '@elastic/eui'; +import { EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; import { FormDataProvider } from '../../../../../shared_imports'; import { ProcessorInternal } from '../../types'; @@ -36,6 +36,7 @@ export const ProcessorSettingsFields: FunctionComponent = ({ processor }) return ( <> + ); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/append.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/append.tsx new file mode 100644 index 0000000000000..8eb484b56bafe --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/append.tsx @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { + FIELD_TYPES, + fieldValidators, + UseField, + ComboBoxField, +} from '../../../../../../shared_imports'; + +import { FieldsConfig } from './shared'; +import { FieldNameField } from './common_fields/field_name_field'; + +const { emptyField } = fieldValidators; + +const fieldsConfig: FieldsConfig = { + value: { + type: FIELD_TYPES.COMBO_BOX, + deserializer: (v) => (Array.isArray(v) ? v : [String(v)]), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.appendForm.valueFieldLabel', { + defaultMessage: 'Value', + }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.appendForm.valueFieldHelpText', { + defaultMessage: 'The value to be appended by this processor.', + }), + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.appendForm.valueRequiredError', { + defaultMessage: 'A value to set is required.', + }) + ), + }, + ], + }, +}; + +export const Append: FunctionComponent = () => { + return ( + <> + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/bytes.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/bytes.tsx new file mode 100644 index 0000000000000..64a501f03d454 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/bytes.tsx @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { FIELD_TYPES, UseField, Field } from '../../../../../../shared_imports'; + +import { FieldsConfig } from './shared'; +import { IgnoreMissingField } from './common_fields/ignore_missing_field'; +import { FieldNameField } from './common_fields/field_name_field'; + +const fieldsConfig: FieldsConfig = { + target_field: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.bytesForm.targetFieldLabel', { + defaultMessage: 'Target field (optional)', + }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.bytesForm.targetFieldHelpText', { + defaultMessage: 'The field to assign the converted value to', + }), + }, +}; + +export const Bytes: FunctionComponent = () => { + return ( + <> + + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/circle.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/circle.tsx new file mode 100644 index 0000000000000..3a39e597cb8dc --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/circle.tsx @@ -0,0 +1,140 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { + FIELD_TYPES, + fieldValidators, + UseField, + Field, + SelectField, + NumericField, +} from '../../../../../../shared_imports'; + +import { FieldsConfig } from './shared'; +import { IgnoreMissingField } from './common_fields/ignore_missing_field'; +import { FieldNameField } from './common_fields/field_name_field'; + +const { emptyField } = fieldValidators; + +const fieldsConfig: FieldsConfig = { + target_field: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.circleForm.targetFieldLabel', { + defaultMessage: 'Target field (optional)', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.circleForm.targetFieldHelpText', + { + defaultMessage: 'By default field is updated in-place.', + } + ), + }, + error_distance: { + type: FIELD_TYPES.NUMBER, + deserializer: (v) => (typeof v === 'number' && !isNaN(v) ? v : 1.0), + serializer: Number, + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.circleForm.errorDistanceFieldLabel', + { + defaultMessage: 'Error distance', + } + ), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.circleForm.errorDistanceHelpText', + { + defaultMessage: + 'The difference between the resulting inscribed distance from center to side and the circle’s radius (measured in meters for geo_shape, unit-less for shape).', + } + ), + validations: [ + { + validator: ({ value }) => { + return isNaN(Number(value)) + ? { + message: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.circleForm.errorDistanceError', + { + defaultMessage: 'An error distance value is required.', + } + ), + } + : undefined; + }, + }, + ], + }, + shape_type: { + type: FIELD_TYPES.SELECT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.circleForm.shapeTypeFieldLabel', { + defaultMessage: 'Shape type', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.circleForm.shapeTypeFieldHelpText', + { defaultMessage: 'Which field mapping type is to be used.' } + ), + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.circleForm.shapeTypeRequiredError', { + defaultMessage: 'A shape type value is required.', + }) + ), + }, + ], + }, +}; + +export const Circle: FunctionComponent = () => { + return ( + <> + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx index 4802653f9e680..7ae7b82c31a43 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/common_processor_fields.tsx @@ -15,41 +15,64 @@ import { ToggleField, } from '../../../../../../../shared_imports'; +import { TextEditor } from '../../field_components'; + const ignoreFailureConfig: FieldConfig = { defaultValue: false, + serializer: (v) => (v === false ? undefined : v), + deserializer: (v) => (typeof v === 'boolean' ? v : undefined), label: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.commonFields.ignoreFailureFieldLabel', { defaultMessage: 'Ignore failure', } ), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.commonFields.ignoreFailureHelpText', + { defaultMessage: 'Ignore failures for this processor.' } + ), type: FIELD_TYPES.TOGGLE, }; const ifConfig: FieldConfig = { - defaultValue: undefined, label: i18n.translate('xpack.ingestPipelines.pipelineEditor.commonFields.ifFieldLabel', { defaultMessage: 'Condition (optional)', }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.commonFields.ifFieldHelpText', { + defaultMessage: 'Conditionally execute this processor.', + }), type: FIELD_TYPES.TEXT, }; const tagConfig: FieldConfig = { - defaultValue: undefined, label: i18n.translate('xpack.ingestPipelines.pipelineEditor.commonFields.tagFieldLabel', { defaultMessage: 'Tag (optional)', }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.commonFields.tagFieldHelpText', { + defaultMessage: 'An identifier for this processor. Useful for debugging and metrics.', + }), type: FIELD_TYPES.TEXT, }; export const CommonProcessorFields: FunctionComponent = () => { return ( - <> - +
+ - + - - + +
); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/field_name_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/field_name_field.tsx new file mode 100644 index 0000000000000..7ef5ba6768c19 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/field_name_field.tsx @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { + FIELD_TYPES, + UseField, + Field, + fieldValidators, + ValidationConfig, +} from '../../../../../../../shared_imports'; + +import { FieldsConfig } from '../shared'; + +const { emptyField } = fieldValidators; + +export const fieldsConfig: FieldsConfig = { + field: { + type: FIELD_TYPES.TEXT, + deserializer: String, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.commonFields.fieldFieldLabel', { + defaultMessage: 'Field', + }), + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.commonFields.fieldRequiredError', { + defaultMessage: 'A field value is required.', + }) + ), + }, + ], + }, +}; + +interface Props { + helpText?: React.ReactNode; + /** + * The field name requires a value. Processor specific validation + * checks can be added here. + */ + additionalValidations?: ValidationConfig[]; +} + +export const FieldNameField: FunctionComponent = ({ helpText, additionalValidations }) => ( + +); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/ignore_missing_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/ignore_missing_field.tsx new file mode 100644 index 0000000000000..08eb0a425ef33 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/ignore_missing_field.tsx @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FIELD_TYPES, UseField, ToggleField } from '../../../../../../../shared_imports'; + +import { FieldsConfig } from '../shared'; + +export const fieldsConfig: FieldsConfig = { + ignore_missing: { + type: FIELD_TYPES.TOGGLE, + defaultValue: false, + serializer: (v) => (v === false ? undefined : v), + deserializer: (v) => (typeof v === 'boolean' ? v : undefined), + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.commonFields.ignoreMissingFieldLabel', + { + defaultMessage: 'Ignore missing', + } + ), + }, +}; + +interface Props { + helpText?: string; +} + +export const IgnoreMissingField: FunctionComponent = ({ helpText }) => ( + +); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/processor_type_field.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/processor_type_field.tsx index 71ee4a714a28e..e4ad90f61af0a 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/processor_type_field.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/common_fields/processor_type_field.tsx @@ -46,20 +46,12 @@ interface Props { const { emptyField } = fieldValidators; -const typeConfig: FieldConfig = { +const typeConfig: FieldConfig = { type: FIELD_TYPES.COMBO_BOX, label: i18n.translate('xpack.ingestPipelines.pipelineEditor.typeField.typeFieldLabel', { defaultMessage: 'Processor', }), - deserializer: (value: string | undefined) => { - if (value) { - return [value]; - } - return []; - }, - serializer: (value: string[]) => { - return value[0]; - }, + deserializer: String, validations: [ { validator: emptyField( @@ -73,11 +65,11 @@ const typeConfig: FieldConfig = { export const ProcessorTypeField: FunctionComponent = ({ initialType }) => { return ( - + config={typeConfig} defaultValue={initialType} path="type"> {(typeField) => { let selectedOptions: ProcessorTypeAndLabel[]; - if ((typeField.value as string[]).length) { - const [type] = typeField.value as string[]; + if (typeField.value?.length) { + const type = typeField.value; const descriptor = getProcessorDescriptor(type); selectedOptions = descriptor ? [{ label: descriptor.label, value: type }] @@ -103,9 +95,7 @@ export const ProcessorTypeField: FunctionComponent = ({ initialType }) => return false; } - const newValue = [...(typeField.value as string[]), value]; - - typeField.setValue(newValue); + typeField.setValue(value); }; return ( @@ -131,8 +121,9 @@ export const ProcessorTypeField: FunctionComponent = ({ initialType }) => options={processorTypesAndLabels} selectedOptions={selectedOptions} onCreateOption={onCreateComboOption} - onChange={(options: EuiComboBoxOptionOption[]) => { - typeField.setValue(options.map(({ value }) => value)); + onChange={(options: Array>) => { + const [selection] = options; + typeField.setValue(selection?.value! ?? ''); }} noSuggestions={false} singleSelection={{ diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/convert.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/convert.tsx new file mode 100644 index 0000000000000..b45f589bf0f92 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/convert.tsx @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { + FIELD_TYPES, + fieldValidators, + UseField, + Field, + SelectField, +} from '../../../../../../shared_imports'; + +import { FieldsConfig } from './shared'; +import { FieldNameField } from './common_fields/field_name_field'; +import { IgnoreMissingField } from './common_fields/ignore_missing_field'; + +const { emptyField } = fieldValidators; + +const fieldsConfig: FieldsConfig = { + /* Required fields config */ + type: { + type: FIELD_TYPES.TEXT, + defaultValue: '', + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.typeFieldLabel', { + defaultMessage: 'Type', + }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.typeFieldHelpText', { + defaultMessage: 'The type to convert the existing value to.', + }), + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.typeRequiredError', { + defaultMessage: 'A type value is required.', + }) + ), + }, + ], + }, + /* Optional fields config */ + target_field: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.targetFieldLabel', { + defaultMessage: 'Target field (optional)', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.convertForm.targetFieldHelpText', + { + defaultMessage: 'The field to assign the converted value to.', + } + ), + }, +}; + +export const Convert: FunctionComponent = () => { + return ( + <> + + + + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/csv.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/csv.tsx new file mode 100644 index 0000000000000..3ac0179ca02a6 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/csv.tsx @@ -0,0 +1,164 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { EuiCode } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { + FIELD_TYPES, + fieldValidators, + UseField, + Field, + ToggleField, + ComboBoxField, + ValidationFunc, +} from '../../../../../../shared_imports'; + +import { FieldsConfig } from './shared'; +import { IgnoreMissingField } from './common_fields/ignore_missing_field'; +import { FieldNameField } from './common_fields/field_name_field'; + +import { isArrayOfStrings } from './shared'; + +const { minLengthField } = fieldValidators; + +/** + * Allow empty strings ('') to pass this validation. + */ +const isStringLengthOne: ValidationFunc = ({ value }) => { + return typeof value === 'string' && value !== '' && value.length !== 1 + ? { + message: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.convertForm.separatorLengthError', + { + defaultMessage: 'A separator value must be 1 character.', + } + ), + } + : undefined; +}; + +const fieldsConfig: FieldsConfig = { + /* Required fields config */ + target_fields: { + type: FIELD_TYPES.COMBO_BOX, + deserializer: (v) => { + return isArrayOfStrings(v) ? v : []; + }, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.csvForm.targetFieldsFieldLabel', { + defaultMessage: 'Target fields', + }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.csvForm.targetFieldsHelpText', { + defaultMessage: 'The array of fields to assign extracted values to.', + }), + validations: [ + { + validator: minLengthField({ + length: 1, + message: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.csvForm.targetFieldRequiredError', + { + defaultMessage: 'A target fields value is required.', + } + ), + }), + }, + ], + }, + /* Optional fields config */ + separator: { + type: FIELD_TYPES.TEXT, + serializer: (v) => (v ? v : undefined), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.separatorFieldLabel', { + defaultMessage: 'Separator (optional)', + }), + validations: [ + { + validator: isStringLengthOne, + }, + ], + helpText: ( + {','} }} + /> + ), + }, + quote: { + type: FIELD_TYPES.TEXT, + serializer: (v) => (v ? v : undefined), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.quoteFieldLabel', { + defaultMessage: 'Quote (optional)', + }), + validations: [ + { + validator: isStringLengthOne, + }, + ], + helpText: ( + {'"'} }} + /> + ), + }, + trim: { + type: FIELD_TYPES.TOGGLE, + defaultValue: false, + deserializer: (v) => (typeof v === 'boolean' ? v : undefined), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.csvForm.trimFieldLabel', { + defaultMessage: 'Trim', + }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.csvForm.trimFieldHelpText', { + defaultMessage: 'Trim whitespaces in unquoted fields', + }), + }, + empty_value: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.emptyValueFieldLabel', { + defaultMessage: 'Empty value (optional)', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.convertForm.emptyValueFieldHelpText', + { + defaultMessage: + 'Value used to fill empty fields, empty fields will be skipped if this is not provided.', + } + ), + }, +}; + +export const CSV: FunctionComponent = () => { + return ( + <> + + + + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date.tsx new file mode 100644 index 0000000000000..424e84058ac3f --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date.tsx @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { EuiCode } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { + FIELD_TYPES, + fieldValidators, + UseField, + Field, + ComboBoxField, +} from '../../../../../../shared_imports'; + +import { FieldsConfig, isArrayOfStrings } from './shared'; +import { FieldNameField } from './common_fields/field_name_field'; + +const { minLengthField } = fieldValidators; + +const fieldsConfig: FieldsConfig = { + /* Required fields config */ + formats: { + type: FIELD_TYPES.COMBO_BOX, + deserializer: (v) => { + return isArrayOfStrings(v) ? v : []; + }, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dateForm.formatsFieldLabel', { + defaultMessage: 'Formats', + }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.dateForm.formatsFieldHelpText', { + defaultMessage: + 'An array of the expected date formats. Can be a java time pattern or one of the following formats: ISO8601, UNIX, UNIX_MS, or TAI64N.', + }), + validations: [ + { + validator: minLengthField({ + length: 1, + message: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dateForm.formatsRequiredError', + { + defaultMessage: 'A value for formats is required.', + } + ), + }), + }, + ], + }, + /* Optional fields config */ + target_field: { + type: FIELD_TYPES.TEXT, + serializer: (v) => (v ? undefined : v), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dateForm.targetFieldFieldLabel', { + defaultMessage: 'Target field (optional)', + }), + helpText: ( + {'@timestamp'}, + }} + /> + ), + }, + timezone: { + type: FIELD_TYPES.TEXT, + serializer: (v) => (v ? v : undefined), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dateForm.timezoneFieldLabel', { + defaultMessage: 'Timezone (optional)', + }), + helpText: ( + {'UTC'} }} + /> + ), + }, + locale: { + type: FIELD_TYPES.TEXT, + serializer: (v) => (v ? v : undefined), + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dateForm.localeFieldLabel', { + defaultMessage: 'Locale (optional)', + }), + helpText: ( + {'ENGLISH'} }} + /> + ), + }, +}; + +/** + * Disambiguate from global Date object + */ +export const DateProcessor: FunctionComponent = () => { + return ( + <> + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date_index_name.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date_index_name.tsx new file mode 100644 index 0000000000000..387c9ff4e0b46 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/date_index_name.tsx @@ -0,0 +1,242 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { EuiCode } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { + FIELD_TYPES, + fieldValidators, + UseField, + Field, + ComboBoxField, + SelectField, +} from '../../../../../../shared_imports'; + +import { FieldsConfig, isArrayOfStrings } from './shared'; +import { FieldNameField } from './common_fields/field_name_field'; + +const { emptyField } = fieldValidators; + +const fieldsConfig: FieldsConfig = { + /* Required fields config */ + date_rounding: { + type: FIELD_TYPES.SELECT, + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.dateRoundingFieldLabel', + { + defaultMessage: 'Date rounding', + } + ), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.dateRoundingFieldHelpText', + { + defaultMessage: 'How to round the date when formatting the date into the index name.', + } + ), + validations: [ + { + validator: emptyField( + i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.dateRoundingRequiredError', + { + defaultMessage: 'A field value is required.', + } + ) + ), + }, + ], + }, + /* Optional fields config */ + index_name_prefix: { + type: FIELD_TYPES.TEXT, + serializer: (v) => (v ? v : undefined), + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.indexNamePrefixFieldLabel', + { + defaultMessage: 'Index name prefix (optional)', + } + ), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.indexNamePrefixFieldHelpText', + { defaultMessage: 'A prefix of the index name to be prepended before the printed date.' } + ), + }, + index_name_format: { + type: FIELD_TYPES.TEXT, + serializer: (v) => (v ? v : undefined), + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.indexNameFormatFieldLabel', + { + defaultMessage: 'Index name format (optional)', + } + ), + helpText: ( + {'yyyy-MM-dd'} }} + /> + ), + }, + date_formats: { + type: FIELD_TYPES.COMBO_BOX, + serializer: (v: string[]) => { + return v.length ? v : undefined; + }, + deserializer: (v) => { + return isArrayOfStrings(v) ? v : []; + }, + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.dateFormatsFieldLabel', + { + defaultMessage: 'Date formats (optional)', + } + ), + helpText: ( + {"yyyy-MM-dd'T'HH:mm:ss.SSSXX"} }} + /> + ), + }, + timezone: { + type: FIELD_TYPES.TEXT, + serializer: (v) => (v ? v : undefined), + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.timezoneFieldLabel', + { + defaultMessage: 'Timezone (optional)', + } + ), + helpText: ( + {'UTC'} }} + /> + ), + }, + locale: { + type: FIELD_TYPES.TEXT, + serializer: (v) => (v ? v : undefined), + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.localeFieldLabel', + { + defaultMessage: 'Locale (optional)', + } + ), + helpText: ( + {'ENGLISH'} }} + /> + ), + }, +}; + +/** + * Disambiguate from global Date object + */ +export const DateIndexName: FunctionComponent = () => { + return ( + <> + + + + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dissect.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dissect.tsx new file mode 100644 index 0000000000000..5f9f55ced1a25 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dissect.tsx @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { EuiCode } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { TextEditor } from '../field_components'; + +import { + FieldConfig, + FIELD_TYPES, + fieldValidators, + UseField, + Field, +} from '../../../../../../shared_imports'; + +import { FieldNameField } from './common_fields/field_name_field'; +import { IgnoreMissingField } from './common_fields/ignore_missing_field'; + +const { emptyField } = fieldValidators; + +const fieldsConfig: Record = { + /* Required field config */ + pattern: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dissectForm.patternFieldLabel', { + defaultMessage: 'Pattern', + }), + helpText: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dissectForm.patternFieldHelpText', + { + defaultMessage: 'The pattern to apply to the field.', + } + ), + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.pipelineEditor.dissectForm.patternRequiredError', { + defaultMessage: 'A pattern value is required.', + }) + ), + }, + ], + }, + /* Optional field config */ + append_separator: { + type: FIELD_TYPES.TEXT, + label: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dissectForm.appendSeparatorparaotrFieldLabel', + { + defaultMessage: 'Append separator (optional)', + } + ), + helpText: ( + {'""'} }} + /> + ), + }, +}; + +export const Dissect: FunctionComponent = () => { + return ( + <> + + + + + + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dot_expander.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dot_expander.tsx new file mode 100644 index 0000000000000..4e50c61ac930c --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/dot_expander.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { FieldConfig, FIELD_TYPES, UseField, Field } from '../../../../../../shared_imports'; + +import { FieldNameField } from './common_fields/field_name_field'; + +const fieldsConfig: Record = { + path: { + type: FIELD_TYPES.TEXT, + label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dotExpanderForm.pathFieldLabel', { + defaultMessage: 'Path', + }), + helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.dotExpanderForm.pathHelpText', { + defaultMessage: 'Only required if the field to expand is part another object field.', + }), + }, +}; + +export const DotExpander: FunctionComponent = () => { + return ( + <> + { + if (typeof value === 'string' && value.length) { + return !value.includes('.') + ? { + message: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.dotExpanderForm.fieldNameRequiresDotError', + { defaultMessage: 'A field value requires at least one dot character.' } + ), + } + : undefined; + } + }, + }, + ]} + /> + + + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/drop.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/drop.tsx new file mode 100644 index 0000000000000..87b6cb76cdcce --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/drop.tsx @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FunctionComponent } from 'react'; + +/** + * This fields component has no unique fields + */ +export const Drop: FunctionComponent = () => { + return null; +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx index 77f85e61eff6b..3148022adaa98 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/gsub.tsx @@ -15,6 +15,7 @@ import { UseField, Field, } from '../../../../../../shared_imports'; +import { TextEditor } from '../field_components'; const { emptyField } = fieldValidators; @@ -84,15 +85,25 @@ const ignoreMissingConfig: FieldConfig = { export const Gsub: FunctionComponent = () => { return ( <> - + - + - + - + - + ); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/index.ts new file mode 100644 index 0000000000000..6996deb2d861c --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/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; + * you may not use this file except in compliance with the Elastic License. + */ + +export { Append } from './append'; +export { Bytes } from './bytes'; +export { Circle } from './circle'; +export { Convert } from './convert'; +export { CSV } from './csv'; +export { DateProcessor } from './date'; +export { DateIndexName } from './date_index_name'; +export { Dissect } from './dissect'; +export { DotExpander } from './dot_expander'; +export { Drop } from './drop'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx index 1ba6a14d0448d..88cea620ae804 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/set.tsx @@ -64,11 +64,11 @@ const overrideConfig: FieldConfig = { export const SetProcessor: FunctionComponent = () => { return ( <> - + - + - + ); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/shared.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/shared.ts new file mode 100644 index 0000000000000..a0a31dd3a8e93 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/manage_processor_form/processors/shared.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as rt from 'io-ts'; +import { isRight } from 'fp-ts/lib/Either'; +import { flow } from 'fp-ts/lib/function'; + +import { FieldConfig } from '../../../../../../shared_imports'; + +export const arrayOfStrings = rt.array(rt.string); +export const isArrayOfStrings = flow(arrayOfStrings.decode, isRight); + +export type FieldsConfig = Record; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx index 7055721fc8b07..502045084b24d 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/shared/map_processor_type_to_form.tsx @@ -7,6 +7,19 @@ import { i18n } from '@kbn/i18n'; import { FunctionComponent } from 'react'; +import { + Append, + Bytes, + Circle, + Convert, + CSV, + DateProcessor, + DateIndexName, + Dissect, + DotExpander, + Drop, +} from '../manage_processor_form/processors'; + // import { SetProcessor } from './processors/set'; // import { Gsub } from './processors/gsub'; @@ -23,70 +36,70 @@ type MapProcessorTypeToDescriptor = Record; export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = { append: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Append, docLinkPath: '/append-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.append', { defaultMessage: 'Append', }), }, bytes: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Bytes, docLinkPath: '/bytes-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.bytes', { defaultMessage: 'Bytes', }), }, circle: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Circle, docLinkPath: '/ingest-circle-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.circle', { defaultMessage: 'Circle', }), }, convert: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Convert, docLinkPath: '/convert-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.convert', { defaultMessage: 'Convert', }), }, csv: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: CSV, docLinkPath: '/csv-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.csv', { defaultMessage: 'CSV', }), }, date: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: DateProcessor, docLinkPath: '/date-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.date', { defaultMessage: 'Date', }), }, date_index_name: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: DateIndexName, docLinkPath: '/date-index-name-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.dateIndexName', { defaultMessage: 'Date Index Name', }), }, dissect: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Dissect, docLinkPath: '/dissect-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.dissect', { defaultMessage: 'Dissect', }), }, dot_expander: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: DotExpander, docLinkPath: '/dot-expand-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.dotExpander', { defaultMessage: 'Dot Expander', }), }, drop: { - FieldsComponent: undefined, // TODO: Implement + FieldsComponent: Drop, docLinkPath: '/drop-processor.html', label: i18n.translate('xpack.ingestPipelines.processors.label.drop', { defaultMessage: 'Drop', diff --git a/x-pack/plugins/ingest_pipelines/public/shared_imports.ts b/x-pack/plugins/ingest_pipelines/public/shared_imports.ts index d2c4b73a48767..936db37f0c629 100644 --- a/x-pack/plugins/ingest_pipelines/public/shared_imports.ts +++ b/x-pack/plugins/ingest_pipelines/public/shared_imports.ts @@ -43,6 +43,8 @@ export { FieldConfig, FieldHook, getFieldValidityAndErrorMessage, + ValidationFunc, + ValidationConfig, } from '../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; export { @@ -57,6 +59,9 @@ export { FormRow, ToggleField, ComboBoxField, + RadioGroupField, + NumericField, + SelectField, } from '../../../../src/plugins/es_ui_shared/static/forms/components'; export { From acc8ffed299fbba5ede703c79429f8df8c9feec5 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Thu, 13 Aug 2020 16:38:57 +0300 Subject: [PATCH 12/15] Fixed tooltip (#74074) Co-authored-by: Elastic Machine --- src/plugins/vis_type_vega/public/_vega_vis.scss | 1 + src/plugins/vis_type_vega/public/vega_view/vega_tooltip.js | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/vis_type_vega/public/_vega_vis.scss b/src/plugins/vis_type_vega/public/_vega_vis.scss index f9468d677eeed..12108c7ba3de0 100644 --- a/src/plugins/vis_type_vega/public/_vega_vis.scss +++ b/src/plugins/vis_type_vega/public/_vega_vis.scss @@ -107,6 +107,7 @@ .vgaVis__tooltip { max-width: 100%; + position: fixed; h2 { margin-bottom: $euiSizeS; diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_tooltip.js b/src/plugins/vis_type_vega/public/vega_view/vega_tooltip.js index 01386fd91abc5..7b0274478cea2 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_tooltip.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_tooltip.js @@ -85,12 +85,12 @@ export class TooltipHandler { let anchorBounds; if (item.bounds.width() > this.centerOnMark || item.bounds.height() > this.centerOnMark) { // I would expect clientX/Y, but that shows incorrectly - anchorBounds = createRect(event.pageX, event.pageY, 0, 0); + anchorBounds = createRect(event.clientX, event.clientY, 0, 0); } else { const containerBox = this.container.getBoundingClientRect(); anchorBounds = createRect( - containerBox.left + view._origin[0] + item.bounds.x1 + window.pageXOffset, - containerBox.top + view._origin[1] + item.bounds.y1 + window.pageYOffset, + containerBox.left + view._origin[0] + item.bounds.x1, + containerBox.top + view._origin[1] + item.bounds.y1, item.bounds.width(), item.bounds.height() ); From 8095c7ba1575d85a98c79ef779864fe4795a4fa5 Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Thu, 13 Aug 2020 09:32:14 -0500 Subject: [PATCH 13/15] [Metrics UI] Add Jest tests for alert previews (#74890) --- .../preview_metric_threshold_alert.test.ts | 133 ++++++++++++++++++ .../alerting/metric_threshold/test_mocks.ts | 54 +++++++ .../lib/alerting/metric_threshold/types.ts | 2 +- 3 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/infra/server/lib/alerting/metric_threshold/preview_metric_threshold_alert.test.ts diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/preview_metric_threshold_alert.test.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/preview_metric_threshold_alert.test.ts new file mode 100644 index 0000000000000..c26b44dfe8ff8 --- /dev/null +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/preview_metric_threshold_alert.test.ts @@ -0,0 +1,133 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as mocks from './test_mocks'; +import { Comparator, Aggregators, MetricExpressionParams } from './types'; +import { alertsMock, AlertServicesMock } from '../../../../../alerts/server/mocks'; +import { previewMetricThresholdAlert } from './preview_metric_threshold_alert'; + +describe('Previewing the metric threshold alert type', () => { + describe('querying the entire infrastructure', () => { + test('returns the expected results using a bucket interval equal to the alert interval', async () => { + const [ungroupedResult] = await previewMetricThresholdAlert({ + ...baseParams, + lookback: 'h', + alertInterval: '1m', + }); + const [firedResults, noDataResults, errorResults] = ungroupedResult; + expect(firedResults).toBe(30); + expect(noDataResults).toBe(0); + expect(errorResults).toBe(0); + }); + + test('returns the expected results using a bucket interval shorter than the alert interval', async () => { + const [ungroupedResult] = await previewMetricThresholdAlert({ + ...baseParams, + lookback: 'h', + alertInterval: '3m', + }); + const [firedResults, noDataResults, errorResults] = ungroupedResult; + expect(firedResults).toBe(10); + expect(noDataResults).toBe(0); + expect(errorResults).toBe(0); + }); + test('returns the expected results using a bucket interval longer than the alert interval', async () => { + const [ungroupedResult] = await previewMetricThresholdAlert({ + ...baseParams, + lookback: 'h', + alertInterval: '30s', + }); + const [firedResults, noDataResults, errorResults] = ungroupedResult; + expect(firedResults).toBe(60); + expect(noDataResults).toBe(0); + expect(errorResults).toBe(0); + }); + }); + describe('querying with a groupBy parameter', () => { + test('returns the expected results', async () => { + const [resultA, resultB] = await previewMetricThresholdAlert({ + ...baseParams, + params: { + ...baseParams.params, + groupBy: ['something'], + }, + lookback: 'h', + alertInterval: '1m', + }); + const [firedResultsA, noDataResultsA, errorResultsA] = resultA; + expect(firedResultsA).toBe(30); + expect(noDataResultsA).toBe(0); + expect(errorResultsA).toBe(0); + const [firedResultsB, noDataResultsB, errorResultsB] = resultB; + expect(firedResultsB).toBe(60); + expect(noDataResultsB).toBe(0); + expect(errorResultsB).toBe(0); + }); + }); + describe('querying a data set with a period of No Data', () => { + test('returns the expected results', async () => { + const [ungroupedResult] = await previewMetricThresholdAlert({ + ...baseParams, + params: { + ...baseParams.params, + criteria: [ + { + ...baseCriterion, + metric: 'test.metric.2', + } as MetricExpressionParams, + ], + }, + lookback: 'h', + alertInterval: '1m', + }); + const [firedResults, noDataResults, errorResults] = ungroupedResult; + expect(firedResults).toBe(25); + expect(noDataResults).toBe(10); + expect(errorResults).toBe(0); + }); + }); +}); + +const services: AlertServicesMock = alertsMock.createAlertServices(); +services.callCluster.mockImplementation(async (_: string, { body, index }: any) => { + const metric = body.query.bool.filter[1]?.exists.field; + if (body.aggs.groupings) { + if (body.aggs.groupings.composite.after) { + return mocks.compositeEndResponse; + } + return mocks.basicCompositePreviewResponse; + } + if (metric === 'test.metric.2') { + return mocks.alternateMetricPreviewResponse; + } + return mocks.basicMetricPreviewResponse; +}); + +const baseCriterion = { + aggType: Aggregators.AVERAGE, + metric: 'test.metric.1', + timeSize: 1, + timeUnit: 'm', + comparator: Comparator.GT, + threshold: [0.75], +} as MetricExpressionParams; + +const config = { + metricAlias: 'metricbeat-*', + fields: { + timefield: '@timestamp', + }, +} as any; + +const baseParams = { + callCluster: services.callCluster, + params: { + criteria: [baseCriterion], + groupBy: undefined, + filterQuery: undefined, + }, + config, +}; diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts index 164f1ed6d18e5..d1178f6766979 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts @@ -38,6 +38,13 @@ const bucketsC = [ }, ]; +const previewBucketsA = Array.from(Array(60), (_, i) => bucketsA[i % 2]); // Repeat bucketsA to a total length of 60 +const previewBucketsB = Array.from(Array(60), (_, i) => bucketsB[i % 2]); +const previewBucketsWithNulls = [ + ...Array.from(Array(10), (_, i) => ({ aggregatedValue: { value: null } })), + ...previewBucketsA.slice(10), +]; + export const basicMetricResponse = { aggregations: { aggregatedIntervals: { @@ -150,3 +157,50 @@ export const changedSourceIdResponse = { }, }, }; + +export const basicMetricPreviewResponse = { + aggregations: { + aggregatedIntervals: { + buckets: previewBucketsA, + }, + }, +}; + +export const alternateMetricPreviewResponse = { + aggregations: { + aggregatedIntervals: { + buckets: previewBucketsWithNulls, + }, + }, +}; + +export const basicCompositePreviewResponse = { + aggregations: { + groupings: { + after_key: { groupBy0: 'foo' }, + buckets: [ + { + key: { + groupBy0: 'a', + }, + aggregatedIntervals: { + buckets: previewBucketsA, + }, + }, + { + key: { + groupBy0: 'b', + }, + aggregatedIntervals: { + buckets: previewBucketsB, + }, + }, + ], + }, + }, + hits: { + total: { + value: 2, + }, + }, +}; diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/types.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/types.ts index 62ab94b7d8c83..cbe4014b24348 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/types.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/types.ts @@ -35,7 +35,7 @@ interface NonCountMetricExpressionParams extends BaseMetricExpressionParams { } interface CountMetricExpressionParams extends BaseMetricExpressionParams { - aggType: 'count'; + aggType: Aggregators.COUNT; metric: never; } From 6a85e893f759f3c897c900e71352dbc93853c4a0 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Thu, 13 Aug 2020 10:30:13 -0500 Subject: [PATCH 14/15] skip test Reporting paginates content #74922 --- .../test/functional/apps/reporting_management/report_listing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/reporting_management/report_listing.ts b/x-pack/test/functional/apps/reporting_management/report_listing.ts index 5bb36103fc6f6..476f3e73d0923 100644 --- a/x-pack/test/functional/apps/reporting_management/report_listing.ts +++ b/x-pack/test/functional/apps/reporting_management/report_listing.ts @@ -68,7 +68,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - it('Paginates content', async () => { + it.skip('Paginates content', async () => { const previousButton = await testSubjects.find('pagination-button-previous'); // previous CAN NOT be clicked From d21d10003001adfd2464c64bb655a0dae2a36939 Mon Sep 17 00:00:00 2001 From: Caroline Horn <549577+cchaos@users.noreply.github.com> Date: Thu, 13 Aug 2020 11:44:22 -0400 Subject: [PATCH 15/15] Update design-specific GH code-owners (#74877) * Update design-specific GH code-owners Created a `@elastic/stack-design` encompassing all product designers associated with the stack+solutions (Kibana repo contributors, not cloud). The `@elastic/kibana-design` team has been reduced to the actual Kibana design team. Then other individual design teams have been added as code-owners to their respective folders containing SASS changes. --- .github/CODEOWNERS | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 73fb10532fd8d..6863b91858ff6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,6 +8,7 @@ /x-pack/plugins/lens/ @elastic/kibana-app /x-pack/plugins/graph/ @elastic/kibana-app /src/plugins/dashboard/ @elastic/kibana-app +/src/plugins/dashboard/**/*.scss @elastic/kibana-core-ui /src/plugins/discover/ @elastic/kibana-app /src/plugins/input_control_vis/ @elastic/kibana-app /src/plugins/kibana_legacy/ @elastic/kibana-app @@ -58,6 +59,7 @@ # APM /x-pack/plugins/apm/ @elastic/apm-ui +/x-pack/plugins/apm/**/*.scss @elastic/observability-design /x-pack/test/functional/apps/apm/ @elastic/apm-ui /src/legacy/core_plugins/apm_oss/ @elastic/apm-ui /src/plugins/apm_oss/ @elastic/apm-ui @@ -68,6 +70,7 @@ # Canvas /x-pack/plugins/canvas/ @elastic/kibana-canvas +/x-pack/plugins/canvas/**/*.scss @elastic/kibana-core-ui /x-pack/test/functional/apps/canvas/ @elastic/kibana-canvas # Core UI @@ -77,15 +80,18 @@ /src/plugins/home/server/services/ @elastic/kibana-core-ui # Exclude tutorial resources folder for now because they are not owned by Kibana app and most will move out soon /src/legacy/core_plugins/kibana/public/home/*.ts @elastic/kibana-core-ui -/src/legacy/core_plugins/kibana/public/home/*.scss @elastic/kibana-core-ui +/src/legacy/core_plugins/kibana/public/home/**/*.scss @elastic/kibana-core-ui /src/legacy/core_plugins/kibana/public/home/np_ready/ @elastic/kibana-core-ui # Observability UIs /x-pack/legacy/plugins/infra/ @elastic/logs-metrics-ui /x-pack/plugins/infra/ @elastic/logs-metrics-ui +/x-pack/plugins/infra/**/*.scss @elastic/observability-design /x-pack/plugins/ingest_manager/ @elastic/ingest-management +/x-pack/plugins/ingest_manager/**/*.scss @elastic/observability-design /x-pack/legacy/plugins/ingest_manager/ @elastic/ingest-management /x-pack/plugins/observability/ @elastic/observability-ui +/x-pack/plugins/observability/**/*.scss @elastic/observability-design /x-pack/legacy/plugins/monitoring/ @elastic/stack-monitoring-ui /x-pack/plugins/monitoring/ @elastic/stack-monitoring-ui /x-pack/plugins/uptime @elastic/uptime @@ -159,10 +165,14 @@ # Security /src/core/server/csp/ @elastic/kibana-security @elastic/kibana-platform /x-pack/legacy/plugins/security/ @elastic/kibana-security +/x-pack/legacy/plugins/security/**/*.scss @elastic/kibana-core-ui /x-pack/legacy/plugins/spaces/ @elastic/kibana-security +/x-pack/legacy/plugins/spaces/**/*.scss @elastic/kibana-core-ui /x-pack/plugins/spaces/ @elastic/kibana-security +/x-pack/plugins/spaces/**/*.scss @elastic/kibana-core-ui /x-pack/plugins/encrypted_saved_objects/ @elastic/kibana-security /x-pack/plugins/security/ @elastic/kibana-security +/x-pack/plugins/security/**/*.scss @elastic/kibana-core-ui /x-pack/test/api_integration/apis/security/ @elastic/kibana-security # Kibana Localization @@ -234,6 +244,7 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib # Endpoint /x-pack/plugins/endpoint/ @elastic/endpoint-app-team @elastic/siem +/x-pack/plugins/endpoint/**/*.scss @elastic/security-design /x-pack/test/api_integration/apis/endpoint/ @elastic/endpoint-app-team @elastic/siem /x-pack/test/endpoint_api_integration_no_ingest/ @elastic/endpoint-app-team @elastic/siem /x-pack/test/security_solution_endpoint/ @elastic/endpoint-app-team @elastic/siem @@ -243,6 +254,7 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib # Security Solution /x-pack/plugins/security_solution/ @elastic/siem @elastic/endpoint-app-team +/x-pack/plugins/security_solution/**/*.scss @elastic/security-design /x-pack/test/detection_engine_api_integration @elastic/siem @elastic/endpoint-app-team /x-pack/test/api_integration/apis/security_solution @elastic/siem @elastic/endpoint-app-team /x-pack/plugins/case @elastic/siem @elastic/endpoint-app-team