diff --git a/renovate.json5 b/renovate.json5 index ae32043daaf5f..67454d266c190 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -1,9 +1,3 @@ -/** - * PLEASE DO NOT MODIFY - * - * This file is automatically generated by running `node scripts/build_renovate_config` - * - */ { extends: [ 'config:base', @@ -11,11 +5,6 @@ includePaths: [ 'package.json', 'x-pack/package.json', - 'x-pack/legacy/plugins/*/package.json', - 'packages/*/package.json', - 'examples/*/package.json', - 'test/plugin_functional/plugins/*/package.json', - 'test/interpreter_functional/plugins/*/package.json', ], baseBranches: [ 'master', @@ -39,7 +28,7 @@ }, separateMajorMinor: false, masterIssue: true, - masterIssueApproval: true, + masterIssueApproval: false, rangeStrategy: 'bump', npm: { lockFileMaintenance: { @@ -48,1068 +37,12 @@ packageRules: [ { groupSlug: '@elastic/charts', - groupName: '@elastic/charts related packages', - packageNames: [ - '@elastic/charts', - '@types/elastic__charts', - ], - reviewers: [ - 'markov00', - ], - masterIssueApproval: false, - }, - { - groupSlug: '@reach/router', - groupName: '@reach/router related packages', - packageNames: [ - '@reach/router', - '@types/reach__router', - ], - }, - { - groupSlug: '@testing-library/dom', - groupName: '@testing-library/dom related packages', - packageNames: [ - '@testing-library/dom', - '@types/testing-library__dom', - ], - }, - { - groupSlug: 'angular', - groupName: 'angular related packages', - packagePatterns: [ - '(\\b|_)angular(\\b|_)', - ], - }, - { - groupSlug: 'api-documenter', - groupName: 'api-documenter related packages', - packageNames: [ - '@microsoft/api-documenter', - '@types/microsoft__api-documenter', - '@microsoft/api-extractor', - '@types/microsoft__api-extractor', - ], - enabled: false, - }, - { - groupSlug: 'archiver', - groupName: 'archiver related packages', - packageNames: [ - 'archiver', - '@types/archiver', - ], - }, - { - groupSlug: 'babel', - groupName: 'babel related packages', - packagePatterns: [ - '(\\b|_)babel(\\b|_)', - ], - packageNames: [ - 'core-js', - '@types/core-js', - '@babel/preset-react', - '@types/babel__preset-react', - '@babel/preset-typescript', - '@types/babel__preset-typescript', - ], - }, - { - groupSlug: 'base64-js', - groupName: 'base64-js related packages', - packageNames: [ - 'base64-js', - '@types/base64-js', - ], - }, - { - groupSlug: 'bluebird', - groupName: 'bluebird related packages', - packageNames: [ - 'bluebird', - '@types/bluebird', - ], - }, - { - groupSlug: 'browserslist-useragent', - groupName: 'browserslist-useragent related packages', - packageNames: [ - 'browserslist-useragent', - '@types/browserslist-useragent', - ], - }, - { - groupSlug: 'chance', - groupName: 'chance related packages', - packageNames: [ - 'chance', - '@types/chance', - ], - }, - { - groupSlug: 'cheerio', - groupName: 'cheerio related packages', - packageNames: [ - 'cheerio', - '@types/cheerio', - ], - }, - { - groupSlug: 'chroma-js', - groupName: 'chroma-js related packages', - packageNames: [ - 'chroma-js', - '@types/chroma-js', - ], - }, - { - groupSlug: 'chromedriver', - groupName: 'chromedriver related packages', - packageNames: [ - 'chromedriver', - '@types/chromedriver', - ], - }, - { - groupSlug: 'classnames', - groupName: 'classnames related packages', - packageNames: [ - 'classnames', - '@types/classnames', - ], - }, - { - groupSlug: 'cmd-shim', - groupName: 'cmd-shim related packages', - packageNames: [ - 'cmd-shim', - '@types/cmd-shim', - ], - }, - { - groupSlug: 'color', - groupName: 'color related packages', - packageNames: [ - 'color', - '@types/color', - ], - }, - { - groupSlug: 'cpy', - groupName: 'cpy related packages', - packageNames: [ - 'cpy', - '@types/cpy', - ], - }, - { - groupSlug: 'cytoscape', - groupName: 'cytoscape related packages', - packageNames: [ - 'cytoscape', - '@types/cytoscape', - ], - }, - { - groupSlug: 'd3', - groupName: 'd3 related packages', - packagePatterns: [ - '(\\b|_)d3(\\b|_)', - ], - }, - { - groupSlug: 'dedent', - groupName: 'dedent related packages', - packageNames: [ - 'dedent', - '@types/dedent', - ], - }, - { - groupSlug: 'deep-freeze-strict', - groupName: 'deep-freeze-strict related packages', - packageNames: [ - 'deep-freeze-strict', - '@types/deep-freeze-strict', - ], - }, - { - groupSlug: 'delete-empty', - groupName: 'delete-empty related packages', - packageNames: [ - 'delete-empty', - '@types/delete-empty', - ], - }, - { - groupSlug: 'dragselect', - groupName: 'dragselect related packages', - packageNames: [ - 'dragselect', - '@types/dragselect', - ], - labels: [ - 'release_note:skip', - 'Team:Operations', - 'renovate', - 'v8.0.0', - 'v7.10.0', - ':ml', - ], - }, - { - groupSlug: 'elasticsearch', - groupName: 'elasticsearch related packages', - packageNames: [ - 'elasticsearch', - '@types/elasticsearch', - ], - }, - { - groupSlug: 'eslint', - groupName: 'eslint related packages', - packagePatterns: [ - '(\\b|_)eslint(\\b|_)', - ], - }, - { - groupSlug: 'estree', - groupName: 'estree related packages', - packageNames: [ - 'estree', - '@types/estree', - ], - }, - { - groupSlug: 'fancy-log', - groupName: 'fancy-log related packages', - packageNames: [ - 'fancy-log', - '@types/fancy-log', - ], - }, - { - groupSlug: 'fetch-mock', - groupName: 'fetch-mock related packages', - packageNames: [ - 'fetch-mock', - '@types/fetch-mock', - ], - }, - { - groupSlug: 'file-saver', - groupName: 'file-saver related packages', - packageNames: [ - 'file-saver', - '@types/file-saver', - ], - }, - { - groupSlug: 'flot', - groupName: 'flot related packages', - packageNames: [ - 'flot', - '@types/flot', - ], - }, - { - groupSlug: 'geojson', - groupName: 'geojson related packages', - packageNames: [ - 'geojson', - '@types/geojson', - ], - }, - { - groupSlug: 'getopts', - groupName: 'getopts related packages', - packageNames: [ - 'getopts', - '@types/getopts', - ], - }, - { - groupSlug: 'getos', - groupName: 'getos related packages', - packageNames: [ - 'getos', - '@types/getos', - ], - }, - { - groupSlug: 'git-url-parse', - groupName: 'git-url-parse related packages', - packageNames: [ - 'git-url-parse', - '@types/git-url-parse', - ], - }, - { - groupSlug: 'glob', - groupName: 'glob related packages', - packageNames: [ - 'glob', - '@types/glob', - ], - }, - { - groupSlug: 'globby', - groupName: 'globby related packages', - packageNames: [ - 'globby', - '@types/globby', - ], - }, - { - groupSlug: 'graphql', - groupName: 'graphql related packages', - packagePatterns: [ - '(\\b|_)graphql(\\b|_)', - '(\\b|_)apollo(\\b|_)', - ], - }, - { - groupSlug: 'grunt', - groupName: 'grunt related packages', - packagePatterns: [ - '(\\b|_)grunt(\\b|_)', - ], - }, - { - groupSlug: 'gulp', - groupName: 'gulp related packages', - packagePatterns: [ - '(\\b|_)gulp(\\b|_)', - ], - }, - { - groupSlug: 'hapi', - groupName: 'hapi related packages', - packagePatterns: [ - '(\\b|_)hapi(\\b|_)', - ], - packageNames: [ - 'hapi', - '@types/hapi', - 'joi', - '@types/joi', - 'boom', - '@types/boom', - 'hoek', - '@types/hoek', - 'h2o2', - '@types/h2o2', - '@elastic/good', - '@types/elastic__good', - 'good-squeeze', - '@types/good-squeeze', - 'inert', - '@types/inert', - 'accept', - '@types/accept', - ], - }, - { - groupSlug: 'has-ansi', - groupName: 'has-ansi related packages', - packageNames: [ - 'has-ansi', - '@types/has-ansi', - ], - }, - { - groupSlug: 'he', - groupName: 'he related packages', - packageNames: [ - 'he', - '@types/he', - ], - }, - { - groupSlug: 'history', - groupName: 'history related packages', - packageNames: [ - 'history', - '@types/history', - ], - }, - { - groupSlug: 'hjson', - groupName: 'hjson related packages', - packageNames: [ - 'hjson', - '@types/hjson', - ], - }, - { - groupSlug: 'inquirer', - groupName: 'inquirer related packages', - packageNames: [ - 'inquirer', - '@types/inquirer', - ], - }, - { - groupSlug: 'intl-relativeformat', - groupName: 'intl-relativeformat related packages', - packageNames: [ - 'intl-relativeformat', - '@types/intl-relativeformat', - ], - }, - { - groupSlug: 'jest', - groupName: 'jest related packages', - packagePatterns: [ - '(\\b|_)jest(\\b|_)', - ], - }, - { - groupSlug: 'jquery', - groupName: 'jquery related packages', - packageNames: [ - 'jquery', - '@types/jquery', - ], - }, - { - groupSlug: 'js-search', - groupName: 'js-search related packages', - packageNames: [ - 'js-search', - '@types/js-search', - ], - }, - { - groupSlug: 'js-yaml', - groupName: 'js-yaml related packages', - packageNames: [ - 'js-yaml', - '@types/js-yaml', - ], - }, - { - groupSlug: 'jsdom', - groupName: 'jsdom related packages', - packageNames: [ - 'jsdom', - '@types/jsdom', - ], - }, - { - groupSlug: 'json-stable-stringify', - groupName: 'json-stable-stringify related packages', - packageNames: [ - 'json-stable-stringify', - '@types/json-stable-stringify', - ], - }, - { - groupSlug: 'json5', - groupName: 'json5 related packages', - packageNames: [ - 'json5', - '@types/json5', - ], - }, - { - groupSlug: 'jsonwebtoken', - groupName: 'jsonwebtoken related packages', - packageNames: [ - 'jsonwebtoken', - '@types/jsonwebtoken', - ], - }, - { - groupSlug: 'jsts', - groupName: 'jsts related packages', - packageNames: [ - 'jsts', - '@types/jsts', - ], - allowedVersions: '^1.6.2', - }, - { - groupSlug: 'karma', - groupName: 'karma related packages', - packagePatterns: [ - '(\\b|_)karma(\\b|_)', - ], - }, - { - groupSlug: 'language server', - groupName: 'language server related packages', - packageNames: [ - 'vscode-jsonrpc', - '@types/vscode-jsonrpc', - 'vscode-languageserver', - '@types/vscode-languageserver', - 'vscode-languageserver-types', - '@types/vscode-languageserver-types', - ], - }, - { - groupSlug: 'license-checker', - groupName: 'license-checker related packages', - packageNames: [ - 'license-checker', - '@types/license-checker', - ], - }, - { - groupSlug: 'listr', - groupName: 'listr related packages', - packageNames: [ - 'listr', - '@types/listr', - ], - }, - { - groupSlug: 'lodash', - groupName: 'lodash related packages', - packageNames: [ - 'lodash', - '@types/lodash', - ], - }, - { - groupSlug: 'log-symbols', - groupName: 'log-symbols related packages', - packageNames: [ - 'log-symbols', - '@types/log-symbols', - ], - }, - { - groupSlug: 'lru-cache', - groupName: 'lru-cache related packages', - packageNames: [ - 'lru-cache', - '@types/lru-cache', - ], - }, - { - groupSlug: 'mapbox-gl', - groupName: 'mapbox-gl related packages', - packageNames: [ - 'mapbox-gl', - '@types/mapbox-gl', - ], - }, - { - groupSlug: 'markdown-it', - groupName: 'markdown-it related packages', - packageNames: [ - 'markdown-it', - '@types/markdown-it', - ], - }, - { - groupSlug: 'memoize-one', - groupName: 'memoize-one related packages', - packageNames: [ - 'memoize-one', - '@types/memoize-one', - ], - }, - { - groupSlug: 'mime', - groupName: 'mime related packages', - packageNames: [ - 'mime', - '@types/mime', - ], - }, - { - groupSlug: 'minimatch', - groupName: 'minimatch related packages', - packageNames: [ - 'minimatch', - '@types/minimatch', - ], - }, - { - groupSlug: 'mocha', - groupName: 'mocha related packages', - packagePatterns: [ - '(\\b|_)mocha(\\b|_)', - ], - }, - { - groupSlug: 'mock-fs', - groupName: 'mock-fs related packages', - packageNames: [ - 'mock-fs', - '@types/mock-fs', - ], - }, - { - groupSlug: 'moment', - groupName: 'moment related packages', - packagePatterns: [ - '(\\b|_)moment(\\b|_)', - ], - }, - { - groupSlug: 'mustache', - groupName: 'mustache related packages', - packageNames: [ - 'mustache', - '@types/mustache', - ], - }, - { - groupSlug: 'ncp', - groupName: 'ncp related packages', - packageNames: [ - 'ncp', - '@types/ncp', - ], - }, - { - groupSlug: 'nock', - groupName: 'nock related packages', - packageNames: [ - 'nock', - '@types/nock', - ], - }, - { - groupSlug: 'node', - groupName: 'node related packages', - packageNames: [ - 'node', - '@types/node', - ], - }, - { - groupSlug: 'node-fetch', - groupName: 'node-fetch related packages', - packageNames: [ - 'node-fetch', - '@types/node-fetch', - ], - }, - { - groupSlug: 'node-forge', - groupName: 'node-forge related packages', - packageNames: [ - 'node-forge', - '@types/node-forge', - ], - }, - { - groupSlug: 'node-sass', - groupName: 'node-sass related packages', - packageNames: [ - 'node-sass', - '@types/node-sass', - ], - }, - { - groupSlug: 'nodemailer', - groupName: 'nodemailer related packages', - packageNames: [ - 'nodemailer', - '@types/nodemailer', - ], - }, - { - groupSlug: 'normalize-path', - groupName: 'normalize-path related packages', - packageNames: [ - 'normalize-path', - '@types/normalize-path', - ], - }, - { - groupSlug: 'object-hash', - groupName: 'object-hash related packages', - packageNames: [ - 'object-hash', - '@types/object-hash', - ], - }, - { - groupSlug: 'opn', - groupName: 'opn related packages', - packageNames: [ - 'opn', - '@types/opn', - ], - }, - { - groupSlug: 'ora', - groupName: 'ora related packages', - packageNames: [ - 'ora', - '@types/ora', - ], - }, - { - groupSlug: 'papaparse', - groupName: 'papaparse related packages', - packageNames: [ - 'papaparse', - '@types/papaparse', - ], - }, - { - groupSlug: 'parse-link-header', - groupName: 'parse-link-header related packages', - packageNames: [ - 'parse-link-header', - '@types/parse-link-header', - ], - }, - { - groupSlug: 'pegjs', - groupName: 'pegjs related packages', - packageNames: [ - 'pegjs', - '@types/pegjs', - ], - }, - { - groupSlug: 'pngjs', - groupName: 'pngjs related packages', - packageNames: [ - 'pngjs', - '@types/pngjs', - ], - }, - { - groupSlug: 'podium', - groupName: 'podium related packages', - packageNames: [ - 'podium', - '@types/podium', - ], - }, - { - groupSlug: 'pretty-ms', - groupName: 'pretty-ms related packages', - packageNames: [ - 'pretty-ms', - '@types/pretty-ms', - ], - }, - { - groupSlug: 'proper-lockfile', - groupName: 'proper-lockfile related packages', - packageNames: [ - 'proper-lockfile', - '@types/proper-lockfile', - ], - }, - { - groupSlug: 'puppeteer', - groupName: 'puppeteer related packages', - packageNames: [ - 'puppeteer', - '@types/puppeteer', - ], - }, - { - groupSlug: 'react', - groupName: 'react related packages', - packagePatterns: [ - '(\\b|_)react(\\b|_)', - '(\\b|_)redux(\\b|_)', - '(\\b|_)enzyme(\\b|_)', - ], - packageNames: [ - 'ngreact', - '@types/ngreact', - 'recompose', - '@types/recompose', - 'prop-types', - '@types/prop-types', - 'typescript-fsa-reducers', - '@types/typescript-fsa-reducers', - 'reselect', - '@types/reselect', - ], - }, - { - groupSlug: 'read-pkg', - groupName: 'read-pkg related packages', - packageNames: [ - 'read-pkg', - '@types/read-pkg', - ], - }, - { - groupSlug: 'reduce-reducers', - groupName: 'reduce-reducers related packages', - packageNames: [ - 'reduce-reducers', - '@types/reduce-reducers', - ], - }, - { - groupSlug: 'request', - groupName: 'request related packages', - packageNames: [ - 'request', - '@types/request', - ], - }, - { - groupSlug: 'selenium-webdriver', - groupName: 'selenium-webdriver related packages', - packageNames: [ - 'selenium-webdriver', - '@types/selenium-webdriver', - ], - }, - { - groupSlug: 'semver', - groupName: 'semver related packages', - packageNames: [ - 'semver', - '@types/semver', - ], - }, - { - groupSlug: 'set-value', - groupName: 'set-value related packages', - packageNames: [ - 'set-value', - '@types/set-value', - ], - }, - { - groupSlug: 'sinon', - groupName: 'sinon related packages', - packageNames: [ - 'sinon', - '@types/sinon', - ], - }, - { - groupSlug: 'stats-lite', - groupName: 'stats-lite related packages', - packageNames: [ - 'stats-lite', - '@types/stats-lite', - ], - }, - { - groupSlug: 'storybook', - groupName: 'storybook related packages', - packagePatterns: [ - '(\\b|_)storybook(\\b|_)', - ], - }, - { - groupSlug: 'strip-ansi', - groupName: 'strip-ansi related packages', - packageNames: [ - 'strip-ansi', - '@types/strip-ansi', - ], - }, - { - groupSlug: 'strong-log-transformer', - groupName: 'strong-log-transformer related packages', - packageNames: [ - 'strong-log-transformer', - '@types/strong-log-transformer', - ], - }, - { - groupSlug: 'styled-components', - groupName: 'styled-components related packages', - packageNames: [ - 'styled-components', - '@types/styled-components', - ], - }, - { - groupSlug: 'supertest', - groupName: 'supertest related packages', - packageNames: [ - 'supertest', - '@types/supertest', - ], - }, - { - groupSlug: 'supertest-as-promised', - groupName: 'supertest-as-promised related packages', - packageNames: [ - 'supertest-as-promised', - '@types/supertest-as-promised', - ], - }, - { - groupSlug: 'tar', - groupName: 'tar related packages', - packageNames: [ - 'tar', - '@types/tar', - ], - }, - { - groupSlug: 'tar-fs', - groupName: 'tar-fs related packages', - packageNames: [ - 'tar-fs', - '@types/tar-fs', - ], - }, - { - groupSlug: 'tempy', - groupName: 'tempy related packages', - packageNames: [ - 'tempy', - '@types/tempy', - ], - }, - { - groupSlug: 'through2', - groupName: 'through2 related packages', - packageNames: [ - 'through2', - '@types/through2', - ], - }, - { - groupSlug: 'through2-map', - groupName: 'through2-map related packages', - packageNames: [ - 'through2-map', - '@types/through2-map', - ], - }, - { - groupSlug: 'tinycolor2', - groupName: 'tinycolor2 related packages', - packageNames: [ - 'tinycolor2', - '@types/tinycolor2', - ], - }, - { - groupSlug: 'type-detect', - groupName: 'type-detect related packages', - packageNames: [ - 'type-detect', - '@types/type-detect', - ], - }, - { - groupSlug: 'typescript', - groupName: 'typescript related packages', - packagePatterns: [ - '(\\b|_)ts(\\b|_)', - '(\\b|_)typescript(\\b|_)', - ], - packageNames: [ - 'tslib', - '@types/tslib', - ], - }, - { - groupSlug: 'use-resize-observer', - groupName: 'use-resize-observer related packages', - packageNames: [ - 'use-resize-observer', - '@types/use-resize-observer', - ], - }, - { - groupSlug: 'uuid', - groupName: 'uuid related packages', - packageNames: [ - 'uuid', - '@types/uuid', - ], - }, - { - groupSlug: 'vega', - groupName: 'vega related packages', - packagePatterns: [ - '(\\b|_)vega(\\b|_)', - ], - enabled: false, - }, - { - groupSlug: 'vinyl', - groupName: 'vinyl related packages', - packageNames: [ - 'vinyl', - '@types/vinyl', - ], - }, - { - groupSlug: 'vinyl-fs', - groupName: 'vinyl-fs related packages', - packageNames: [ - 'vinyl-fs', - '@types/vinyl-fs', - ], - }, - { - groupSlug: 'watchpack', - groupName: 'watchpack related packages', - packageNames: [ - 'watchpack', - '@types/watchpack', - ], - }, - { - groupSlug: 'webpack', - groupName: 'webpack related packages', - packagePatterns: [ - '(\\b|_)webpack(\\b|_)', - '(\\b|_)loader(\\b|_)', - '(\\b|_)acorn(\\b|_)', - '(\\b|_)terser(\\b|_)', - ], - packageNames: [ - 'mini-css-extract-plugin', - '@types/mini-css-extract-plugin', - 'chokidar', - '@types/chokidar', - ], - }, - { - groupSlug: 'write-pkg', - groupName: 'write-pkg related packages', - packageNames: [ - 'write-pkg', - '@types/write-pkg', - ], - }, - { - groupSlug: 'xml-crypto', - groupName: 'xml-crypto related packages', - packageNames: [ - 'xml-crypto', - '@types/xml-crypto', - ], - }, - { - groupSlug: 'xml2js', - groupName: 'xml2js related packages', - packageNames: [ - 'xml2js', - '@types/xml2js', - ], - }, - { - groupSlug: 'zen-observable', - groupName: 'zen-observable related packages', - packageNames: [ - 'zen-observable', - '@types/zen-observable', - ], + packageNames: ['@elastic/charts'], + reviewers: ['markov00'], }, { packagePatterns: [ - '^@kbn/.*', + '.*', ], enabled: false, }, diff --git a/scripts/build_renovate_config.js b/scripts/build_renovate_config.js deleted file mode 100644 index b9171c44f4a8a..0000000000000 --- a/scripts/build_renovate_config.js +++ /dev/null @@ -1,21 +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. - */ - -require('../src/setup_node_env'); -require('../src/dev/renovate/run_build_renovate_config_cli'); diff --git a/src/dev/ci_setup/setup.sh b/src/dev/ci_setup/setup.sh index 25d2afb00cd87..aabc1e75b9025 100755 --- a/src/dev/ci_setup/setup.sh +++ b/src/dev/ci_setup/setup.sh @@ -50,22 +50,6 @@ if [ "$GIT_CHANGES" ]; then exit 1 fi -### -### rebuild kbn-pm distributable to ensure it's not out of date -### -echo " -- building renovate config" -node scripts/build_renovate_config - -### -### verify no git modifications -### -GIT_CHANGES="$(git ls-files --modified)" -if [ "$GIT_CHANGES" ]; then - echo -e "\n${RED}ERROR: 'node scripts/build_renovate_config' caused changes to the following files:${C_RESET}\n" - echo -e "$GIT_CHANGES\n" - exit 1 -fi - ### ### rebuild plugin list to ensure it's not out of date ### diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index 43f0663ad0359..31a94d161a3cc 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -77,6 +77,7 @@ async function send(logF, idx, redactedEsHostUrl, client, requestBody) { const sendMsg = (actuallySent, redactedEsHostUrl, payload) => { const { index, body } = payload; return `### ${actuallySent ? 'Sent' : 'Fake Sent'}: +${payload.pipeline ? `\t### Team Assignment Pipeline: ${green(payload.pipeline)}` : ''} ${redactedEsHostUrl ? `\t### ES Host: ${redactedEsHostUrl}` : ''} \t### Index: ${green(index)} \t### payload.body: ${body} diff --git a/src/dev/renovate/config.ts b/src/dev/renovate/config.ts deleted file mode 100644 index c9688fc0ae0bd..0000000000000 --- a/src/dev/renovate/config.ts +++ /dev/null @@ -1,135 +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 { RENOVATE_PACKAGE_GROUPS } from './package_groups'; -import { PACKAGE_GLOBS } from './package_globs'; -import { wordRegExp, maybeFlatMap, maybeMap, getTypePackageName } from './utils'; - -const DEFAULT_LABELS = ['release_note:skip', 'Team:Operations', 'renovate', 'v8.0.0', 'v7.10.0']; - -export const RENOVATE_CONFIG = { - extends: ['config:base'], - - includePaths: PACKAGE_GLOBS, - - /** - * Only submit PRs to these branches, we will manually backport PRs for now - */ - baseBranches: ['master'], - - /** - * Labels added to PRs opened by renovate - */ - labels: DEFAULT_LABELS, - - /** - * Config customizations for major version upgrades - */ - major: { - labels: [...DEFAULT_LABELS, 'renovate:major'], - }, - - // TODO: remove this once we've caught up on upgrades - /** - * When there is a major and minor update available, only offer the major update, - * the list of all upgrades is too overwhelming for now. - */ - separateMajorMinor: false, - - /** - * Enable creation of a "Master Issue" within the repository. This - * Master Issue is akin to a mini dashboard and contains a list of all - * PRs pending, open, closed (unmerged) or in error. - */ - masterIssue: true, - - /** - * Whether updates should require manual approval from within the - * Master Issue before creation. - * - * We can turn this off once we've gotten through the backlog of - * outdated packages. - */ - masterIssueApproval: true, - - /** - * Policy for how to modify/update existing ranges - * bump = e.g. bump the range even if the new version satisifies the existing range, e.g. ^1.0.0 -> ^1.1.0 - */ - rangeStrategy: 'bump', - - npm: { - /** - * This deletes and re-creates the lock file, which we will only want - * to turn on once we've updated all our deps and enabled version pinning - */ - lockFileMaintenance: { enabled: false }, - - /** - * Define groups of packages that should be updated/configured together - */ - packageRules: [ - ...RENOVATE_PACKAGE_GROUPS.map((group) => ({ - groupSlug: group.name, - groupName: `${group.name} related packages`, - packagePatterns: maybeMap(group.packageWords, (word) => wordRegExp(word).source), - packageNames: maybeFlatMap(group.packageNames, (name) => [name, getTypePackageName(name)]), - labels: group.extraLabels && [...DEFAULT_LABELS, ...group.extraLabels], - enabled: group.enabled === false ? false : undefined, - allowedVersions: group.allowedVersions || undefined, - reviewers: group.reviewers || undefined, - masterIssueApproval: group.autoOpenPr ? false : undefined, - })).sort((a, b) => a.groupName.localeCompare(b.groupName)), - - // internal/local packages - { - packagePatterns: ['^@kbn/.*'], - enabled: false, - }, - ], - }, - - /** - * Limit the number of active PRs renovate will allow - * 0 (default) means no limit - */ - prConcurrentLimit: 0, - - /** - * Disable vulnerability alert handling, we handle that separately - */ - vulnerabilityAlerts: { - enabled: false, - }, - - /** - * Disable automatic rebase on each change to base branch - */ - rebaseStalePrs: false, - - /** - * Disable automatic rebase on conflicts with the base branch - */ - rebaseConflictedPrs: false, - - /** - * Disable semantic commit formating - */ - semanticCommits: false, -}; diff --git a/src/dev/renovate/package_globs.ts b/src/dev/renovate/package_globs.ts deleted file mode 100644 index 825e6ffed0ec6..0000000000000 --- a/src/dev/renovate/package_globs.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 { readFileSync } from 'fs'; - -import globby from 'globby'; - -import { REPO_ROOT } from '../constants'; - -export const PACKAGE_GLOBS = [ - 'package.json', - 'x-pack/package.json', - 'x-pack/legacy/plugins/*/package.json', - 'packages/*/package.json', - 'examples/*/package.json', - 'test/plugin_functional/plugins/*/package.json', - 'test/interpreter_functional/plugins/*/package.json', -]; - -export function getAllDepNames() { - const depNames = new Set(); - - for (const glob of PACKAGE_GLOBS) { - const files = globby.sync(glob, { - cwd: REPO_ROOT, - absolute: true, - }); - - for (const path of files) { - const pkg = JSON.parse(readFileSync(path, 'utf8')); - const deps = [ - ...Object.keys(pkg.dependencies || {}), - ...Object.keys(pkg.devDependencies || {}), - ]; - - for (const dep of deps) { - depNames.add(dep); - } - } - } - - return depNames; -} diff --git a/src/dev/renovate/package_groups.ts b/src/dev/renovate/package_groups.ts deleted file mode 100644 index d051f956d14df..0000000000000 --- a/src/dev/renovate/package_groups.ts +++ /dev/null @@ -1,230 +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 { getAllDepNames } from './package_globs'; -import { wordRegExp, unwrapTypesPackage } from './utils'; - -interface PackageGroup { - /** - * The group name, will be used for the branch name and in pr titles - */ - readonly name: string; - - /** - * Specific words that, when found in the package name, identify it as part of this group - */ - readonly packageWords?: string[]; - - /** - * Exact package names that should be included in this group - */ - readonly packageNames?: string[]; - - /** - * Extra labels to apply to PRs created for packages in this group - */ - readonly extraLabels?: string[]; - - /** - * A flag that will prevent renovatebot from telling us when there - * are updates. This should only be used in very special cases, like - * when we intend to never update a package. To just prevent a version - * upgrade consider support for the `allowedVersions` config, or just - * closing PRs to communicate to renovate that the specific upgrade - * should be ignored. - */ - readonly enabled?: false; - - /** - * A semver range defining allowed versions for a package group - * https://renovatebot.com/docs/configuration-options/#allowedversions - */ - readonly allowedVersions?: string; - - /** - * An array of users to request reviews from - */ - readonly reviewers?: string[]; - - /** - * Unless this is set to true, then PRs will only be opened when - * the corresponding checkbox is ticked in the master issue. - */ - readonly autoOpenPr?: boolean; -} - -export const RENOVATE_PACKAGE_GROUPS: PackageGroup[] = [ - { - name: 'eslint', - packageWords: ['eslint'], - }, - - { - name: 'babel', - packageWords: ['babel'], - packageNames: ['core-js', '@babel/preset-react', '@babel/preset-typescript'], - }, - - { - name: 'jest', - packageWords: ['jest'], - }, - - { - name: '@elastic/charts', - packageNames: ['@elastic/charts'], - reviewers: ['markov00'], - autoOpenPr: true, - }, - - { - name: 'mocha', - packageWords: ['mocha'], - }, - - { - name: 'karma', - packageWords: ['karma'], - }, - - { - name: 'gulp', - packageWords: ['gulp'], - }, - - { - name: 'grunt', - packageWords: ['grunt'], - }, - - { - name: 'angular', - packageWords: ['angular'], - }, - - { - name: 'd3', - packageWords: ['d3'], - }, - - { - name: 'react', - packageWords: ['react', 'redux', 'enzyme'], - packageNames: ['ngreact', 'recompose', 'prop-types', 'typescript-fsa-reducers', 'reselect'], - }, - - { - name: 'moment', - packageWords: ['moment'], - }, - - { - name: 'graphql', - packageWords: ['graphql', 'apollo'], - }, - - { - name: 'webpack', - packageWords: ['webpack', 'loader', 'acorn', 'terser'], - packageNames: ['mini-css-extract-plugin', 'chokidar'], - }, - - { - name: 'vega', - packageWords: ['vega'], - enabled: false, - }, - - { - name: 'language server', - packageNames: ['vscode-jsonrpc', 'vscode-languageserver', 'vscode-languageserver-types'], - }, - - { - name: 'hapi', - packageWords: ['hapi'], - packageNames: [ - 'hapi', - 'joi', - 'boom', - 'hoek', - 'h2o2', - '@elastic/good', - 'good-squeeze', - 'inert', - 'accept', - ], - }, - - { - name: 'dragselect', - packageNames: ['dragselect'], - extraLabels: [':ml'], - }, - - { - name: 'api-documenter', - packageNames: ['@microsoft/api-documenter', '@microsoft/api-extractor'], - enabled: false, - }, - - { - name: 'jsts', - packageNames: ['jsts'], - allowedVersions: '^1.6.2', - }, - - { - name: 'storybook', - packageWords: ['storybook'], - }, - - { - name: 'typescript', - packageWords: ['ts', 'typescript'], - packageNames: ['tslib'], - }, -]; - -/** - * Auto-define package groups for any `@types/*` deps that are not already in a group - */ -for (const dep of getAllDepNames()) { - const typesFor = unwrapTypesPackage(dep); - if (!typesFor) { - continue; - } - - // determine if one of the existing groups has typesFor in its - // packageNames or if any of the packageWords is in typesFor - const existing = RENOVATE_PACKAGE_GROUPS.some( - (group) => - (group.packageNames || []).includes(typesFor) || - (group.packageWords || []).some((word) => wordRegExp(word).test(typesFor)) - ); - - if (existing) { - continue; - } - - RENOVATE_PACKAGE_GROUPS.push({ - name: typesFor, - packageNames: [typesFor], - }); -} diff --git a/src/dev/renovate/run_build_renovate_config_cli.ts b/src/dev/renovate/run_build_renovate_config_cli.ts deleted file mode 100644 index db08bbc8a8f23..0000000000000 --- a/src/dev/renovate/run_build_renovate_config_cli.ts +++ /dev/null @@ -1,49 +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 { writeFileSync } from 'fs'; -import { resolve } from 'path'; -import json5 from 'json5'; -import dedent from 'dedent'; - -import { run } from '@kbn/dev-utils'; -import { REPO_ROOT } from '../constants'; -import { RENOVATE_CONFIG } from './config'; - -run( - async () => { - const genInfo = dedent` - /** - * PLEASE DO NOT MODIFY - * - * This file is automatically generated by running \`node scripts/build_renovate_config\` - * - */ - `; - - writeFileSync( - resolve(REPO_ROOT, 'renovate.json5'), - `${genInfo}\n${json5.stringify(RENOVATE_CONFIG, null, 2)}\n` - ); - }, - { - description: - 'Regenerate the renovate.json5 file at the root of the repo based on the config in src/dev/renovate', - } -); diff --git a/src/dev/renovate/utils.ts b/src/dev/renovate/utils.ts deleted file mode 100644 index a3c7e1b56d7b7..0000000000000 --- a/src/dev/renovate/utils.ts +++ /dev/null @@ -1,48 +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 const maybeMap = (input: T[] | undefined, fn: (i: T) => T2) => - input ? input.map(fn) : undefined; - -export const maybeFlatMap = (input: T[] | undefined, fn: (i: T) => T2[]) => - input ? input.reduce((acc, i) => [...acc, ...fn(i)], [] as T2[]) : undefined; - -export const wordRegExp = (word: string) => new RegExp(`(\\b|_)${word}(\\b|_)`); - -export const getTypePackageName = (pkgName: string) => { - const scopedPkgRe = /^@(.+?)\/(.+?)$/; - const match = pkgName.match(scopedPkgRe); - return `@types/${match ? `${match[1]}__${match[2]}` : pkgName}`; -}; - -export const unwrapTypesPackage = (pkgName: string) => { - if (!pkgName.startsWith('@types')) { - return; - } - - const typesFor = pkgName.slice('@types/'.length); - - if (!typesFor.includes('__')) { - return typesFor; - } - - // @types packages use a convention for scoped packages, @types/org__name - const [org, name] = typesFor.split('__'); - return `@${org}/${name}`; -}; diff --git a/test/functional/page_objects/login_page.ts b/test/functional/page_objects/login_page.ts index c84f47a342155..350ab8be1a274 100644 --- a/test/functional/page_objects/login_page.ts +++ b/test/functional/page_objects/login_page.ts @@ -7,26 +7,76 @@ * 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 + *    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 + * KIND, either express or implied.  See the License for the * specific language governing permissions and limitations * under the License. */ +import { delay } from 'bluebird'; import { FtrProviderContext } from '../ftr_provider_context'; export function LoginPageProvider({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); + const log = getService('log'); + const find = getService('find'); + + const regularLogin = async (user: string, pwd: string) => { + await testSubjects.setValue('loginUsername', user); + await testSubjects.setValue('loginPassword', pwd); + await testSubjects.click('loginSubmit'); + await find.waitForDeletedByCssSelector('.kibanaWelcomeLogo'); + await find.byCssSelector('[data-test-subj="kibanaChrome"]', 60000); // 60 sec waiting + }; + + const samlLogin = async (user: string, pwd: string) => { + try { + await find.clickByButtonText('Login using SAML'); + await find.setValue('input[name="email"]', user); + await find.setValue('input[type="password"]', pwd); + await find.clickByCssSelector('.auth0-label-submit'); + await find.byCssSelector('[data-test-subj="kibanaChrome"]', 60000); // 60 sec waiting + } catch (err) { + log.debug(`${err} \nFailed to find Auth0 login page, trying the Auth0 last login page`); + await find.clickByCssSelector('.auth0-lock-social-button'); + } + }; class LoginPage { async login(user: string, pwd: string) { - await testSubjects.setValue('loginUsername', user); - await testSubjects.setValue('loginPassword', pwd); - await testSubjects.click('loginSubmit'); + if ( + process.env.VM === 'ubuntu18_deb_oidc' || + process.env.VM === 'ubuntu16_deb_desktop_saml' + ) { + await samlLogin(user, pwd); + return; + } + + await regularLogin(user, pwd); + } + + async logoutLogin(user: string, pwd: string) { + await this.logout(); + await this.sleep(3002); + await this.login(user, pwd); + } + + async logout() { + await testSubjects.click('userMenuButton'); + await this.sleep(500); + await testSubjects.click('logoutLink'); + log.debug('### found and clicked log out--------------------------'); + await this.sleep(8002); + } + + async sleep(sleepMilliseconds: number) { + log.debug(`... sleep(${sleepMilliseconds}) start`); + await delay(sleepMilliseconds); + log.debug(`... sleep(${sleepMilliseconds}) end`); } } diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx index 67227f99cb5f1..f3b8822010f59 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx @@ -152,7 +152,7 @@ function getNoItemsMessage({ if (status === FETCH_STATUS.FAILURE) { return i18n.translate( 'xpack.apm.settings.anomalyDetection.jobList.failedFetchText', - { defaultMessage: 'Unabled to fetch anomaly detection jobs.' } + { defaultMessage: 'Unable to fetch anomaly detection jobs.' } ); } diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/index.ts b/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/index.ts index afad55dd22d43..485ef71e0ca36 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/index.ts +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/index.ts @@ -6,4 +6,3 @@ export * from './log_analysis_job_problem_indicator'; export * from './notices_section'; -export * from './recreate_job_button'; diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/job_configuration_outdated_callout.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/job_configuration_outdated_callout.tsx index a8a7ec4f5f44f..0489bd7d9929a 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/job_configuration_outdated_callout.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/job_configuration_outdated_callout.tsx @@ -11,10 +11,12 @@ import React from 'react'; import { RecreateJobCallout } from './recreate_job_callout'; export const JobConfigurationOutdatedCallout: React.FC<{ + hasSetupCapabilities: boolean; moduleName: string; onRecreateMlJob: () => void; -}> = ({ moduleName, onRecreateMlJob }) => ( +}> = ({ hasSetupCapabilities, moduleName, onRecreateMlJob }) => ( void; -}> = ({ moduleName, onRecreateMlJob }) => ( +}> = ({ hasSetupCapabilities, moduleName, onRecreateMlJob }) => ( = ({ hasOutdatedJobConfigurations, hasOutdatedJobDefinitions, + hasSetupCapabilities, hasStoppedJobs, isFirstUse, moduleName, @@ -32,12 +34,14 @@ export const LogAnalysisJobProblemIndicator: React.FC<{ <> {hasOutdatedJobDefinitions ? ( ) : null} {hasOutdatedJobConfigurations ? ( diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/notices_section.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/notices_section.tsx index aa72281b9fbdb..2535058322cba 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/notices_section.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/notices_section.tsx @@ -12,6 +12,7 @@ import { CategoryQualityWarnings } from './quality_warning_notices'; export const CategoryJobNoticesSection: React.FC<{ hasOutdatedJobConfigurations: boolean; hasOutdatedJobDefinitions: boolean; + hasSetupCapabilities: boolean; hasStoppedJobs: boolean; isFirstUse: boolean; moduleName: string; @@ -21,6 +22,7 @@ export const CategoryJobNoticesSection: React.FC<{ }> = ({ hasOutdatedJobConfigurations, hasOutdatedJobDefinitions, + hasSetupCapabilities, hasStoppedJobs, isFirstUse, moduleName, @@ -32,6 +34,7 @@ export const CategoryJobNoticesSection: React.FC<{ > = (props) => ( - - - -); diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/recreate_job_callout.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/recreate_job_callout.tsx index 5b872d4ee5147..cdf030a849fa1 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/recreate_job_callout.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/recreate_job_callout.tsx @@ -4,17 +4,21 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; import { EuiCallOut } from '@elastic/eui'; - -import { RecreateJobButton } from './recreate_job_button'; +import React from 'react'; +import { RecreateJobButton } from '../log_analysis_setup/create_job_button'; export const RecreateJobCallout: React.FC<{ + hasSetupCapabilities?: boolean; onRecreateMlJob: () => void; title?: React.ReactNode; -}> = ({ children, onRecreateMlJob, title }) => ( +}> = ({ children, hasSetupCapabilities, onRecreateMlJob, title }) => (

{children}

- +
); diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/create_job_button.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/create_job_button.tsx new file mode 100644 index 0000000000000..1e4473d359bba --- /dev/null +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/create_job_button.tsx @@ -0,0 +1,49 @@ +/* + * 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 { EuiButton, PropsOf } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React from 'react'; +import { MissingSetupPrivilegesToolTip } from './missing_setup_privileges_tooltip'; + +export const CreateJobButton: React.FunctionComponent< + { + hasSetupCapabilities?: boolean; + } & PropsOf +> = ({ hasSetupCapabilities = true, children, ...buttonProps }) => { + const button = ( + + {children ?? ( + + )} + + ); + + return hasSetupCapabilities ? ( + button + ) : ( + + {button} + + ); +}; + +export const RecreateJobButton: React.FunctionComponent> = ({ + children, + ...otherProps +}) => ( + + {children ?? ( + + )} + +); diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_privileges_messages.ts b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_privileges_messages.ts new file mode 100644 index 0000000000000..cca8fc03f7c2a --- /dev/null +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_privileges_messages.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const missingMlPrivilegesTitle = i18n.translate( + 'xpack.infra.logs.analysis.missingMlPrivilegesTitle', + { + defaultMessage: 'Additional Machine Learning privileges required', + } +); + +export const missingMlResultsPrivilegesDescription = i18n.translate( + 'xpack.infra.logs.analysis.missingMlResultsPrivilegesDescription', + { + defaultMessage: + 'This feature makes use of Machine Learning jobs, which require at least the read permission for the Machine Learning app in order to access their status and results.', + } +); + +export const missingMlSetupPrivilegesDescription = i18n.translate( + 'xpack.infra.logs.analysis.missingMlSetupPrivilegesDescription', + { + defaultMessage: + 'This feature makes use of Machine Learning jobs, which require all permissions for the Machine Learning app in order to be set up.', + } +); diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_results_privileges_prompt.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_results_privileges_prompt.tsx index 2d378508e2b58..3aa8b544b7b54 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_results_privileges_prompt.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_results_privileges_prompt.tsx @@ -4,34 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiEmptyPrompt, EuiCode } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiEmptyPrompt } from '@elastic/eui'; import React from 'react'; - import { euiStyled } from '../../../../../observability/public'; +import { + missingMlPrivilegesTitle, + missingMlResultsPrivilegesDescription, +} from './missing_privileges_messages'; import { UserManagementLink } from './user_management_link'; export const MissingResultsPrivilegesPrompt: React.FunctionComponent = () => ( - - - } - body={ -

- machine_learning_user, - }} - /> -

- } + title={

{missingMlPrivilegesTitle}

} + body={

{missingMlResultsPrivilegesDescription}

} actions={} /> ); diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_setup_privileges_prompt.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_setup_privileges_prompt.tsx index db89ff415a6f7..6a5a1da890418 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_setup_privileges_prompt.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_setup_privileges_prompt.tsx @@ -4,34 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiEmptyPrompt, EuiCode } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiEmptyPrompt } from '@elastic/eui'; import React from 'react'; - import { euiStyled } from '../../../../../observability/public'; +import { + missingMlPrivilegesTitle, + missingMlSetupPrivilegesDescription, +} from './missing_privileges_messages'; import { UserManagementLink } from './user_management_link'; export const MissingSetupPrivilegesPrompt: React.FunctionComponent = () => ( - - - } - body={ -

- machine_learning_admin, - }} - /> -

- } + title={

{missingMlPrivilegesTitle}

} + body={

{missingMlSetupPrivilegesDescription}

} actions={} /> ); diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_setup_privileges_tooltip.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_setup_privileges_tooltip.tsx new file mode 100644 index 0000000000000..ccd207129e471 --- /dev/null +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/missing_setup_privileges_tooltip.tsx @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiToolTip, PropsOf } from '@elastic/eui'; +import React from 'react'; +import { + missingMlPrivilegesTitle, + missingMlSetupPrivilegesDescription, +} from './missing_privileges_messages'; + +export const MissingSetupPrivilegesToolTip: React.FC, + 'content' | 'title' +>> = (props) => ( + +); diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/setup_flyout/module_list.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/setup_flyout/module_list.tsx index 8239ab4a730ff..2c68aceccaa43 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/setup_flyout/module_list.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/setup_flyout/module_list.tsx @@ -6,6 +6,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { useCallback } from 'react'; +import { useLogAnalysisCapabilitiesContext } from '../../../../containers/logs/log_analysis'; import { logEntryCategoriesModule, useLogEntryCategoriesModuleContext, @@ -20,6 +21,7 @@ import type { ModuleId } from './setup_flyout_state'; export const LogAnalysisModuleList: React.FC<{ onViewModuleSetup: (module: ModuleId) => void; }> = ({ onViewModuleSetup }) => { + const { hasLogAnalysisSetupCapabilities } = useLogAnalysisCapabilitiesContext(); const { setupStatus: logEntryRateSetupStatus } = useLogEntryRateModuleContext(); const { setupStatus: logEntryCategoriesSetupStatus } = useLogEntryCategoriesModuleContext(); @@ -35,6 +37,7 @@ export const LogAnalysisModuleList: React.FC<{ void; -}> = ({ moduleDescription, moduleName, moduleStatus, onViewSetup }) => { - const icon = +}> = ({ hasSetupCapabilities, moduleDescription, moduleName, moduleStatus, onViewSetup }) => { + const moduleIcon = moduleStatus.type === 'required' ? ( ) : ( ); - const footerContent = + + const moduleSetupButton = moduleStatus.type === 'required' ? ( - + - + ) : ( - + ); return ( {footerContent}} - icon={icon} + footer={
{moduleSetupButton}
} + icon={moduleIcon} title={moduleName} /> ); diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/user_management_link.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/user_management_link.tsx index 49ab25297c687..66fac524b0230 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/user_management_link.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/user_management_link.tsx @@ -11,8 +11,8 @@ import { useLinkProps } from '../../../hooks/use_link_props'; export const UserManagementLink: React.FunctionComponent = (props) => { const linkProps = useLinkProps({ - app: 'kibana', - hash: '/management/security/users', + app: 'management', + pathname: '/security/users', }); return ( diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx index 5e602e1f63862..028dd0d3a1a7b 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/page_results_content.tsx @@ -23,6 +23,7 @@ import { StringTimeRange, useLogEntryCategoriesResultsUrlState, } from './use_log_entry_categories_results_url_state'; +import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_analysis/log_analysis_capabilities'; const JOB_STATUS_POLLING_INTERVAL = 30000; @@ -36,6 +37,8 @@ export const LogEntryCategoriesResultsContent: React.FunctionComponent = ({ availableDatasets, + hasSetupCapabilities, isLoadingDatasets = false, isLoadingTopCategories = false, jobId, @@ -51,7 +53,11 @@ export const TopCategoriesSection: React.FunctionComponent<{
- + diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx index fb1dc7717fed0..65cc4a6c4a704 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx @@ -15,7 +15,9 @@ import { CategoryJobNoticesSection, LogAnalysisJobProblemIndicator, } from '../../../components/logging/log_analysis_job_status'; +import { DatasetsSelector } from '../../../components/logging/log_analysis_results/datasets_selector'; import { useLogAnalysisSetupFlyoutStateContext } from '../../../components/logging/log_analysis_setup/setup_flyout'; +import { useLogAnalysisCapabilitiesContext } from '../../../containers/logs/log_analysis/log_analysis_capabilities'; import { useLogEntryCategoriesModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_categories'; import { useLogEntryRateModuleContext } from '../../../containers/logs/log_analysis/modules/log_entry_rate'; import { useLogSourceContext } from '../../../containers/logs/log_source'; @@ -27,7 +29,6 @@ import { StringTimeRange, useLogAnalysisResultsUrlState, } from './use_log_entry_rate_results_url_state'; -import { DatasetsSelector } from '../../../components/logging/log_analysis_results/datasets_selector'; export const SORT_DEFAULTS = { direction: 'desc' as const, @@ -44,6 +45,8 @@ export const LogEntryRateResultsContent: React.FunctionComponent = () => { const { sourceId } = useLogSourceContext(); + const { hasLogAnalysisSetupCapabilities } = useLogAnalysisCapabilitiesContext(); + const { hasOutdatedJobConfigurations: hasOutdatedLogEntryRateJobConfigurations, hasOutdatedJobDefinitions: hasOutdatedLogEntryRateJobDefinitions, @@ -223,6 +226,7 @@ export const LogEntryRateResultsContent: React.FunctionComponent = () => { { - merge upstream master into feature-ingest - -```bash -## checkout feature branch to your fork -git checkout -B feature-ingest origin/feature-ingest - -## make sure your feature branch is current with upstream feature branch -git pull upstream feature-ingest - -## pull in changes from upstream master -git pull upstream master - -## push changes to your remote -git push origin - -# /!\ Open a DRAFT PR /!\ -# Normal PRs will re-notify authors of commits already merged -# Draft PR will trigger CI run. Once CI is green ... -# /!\ DO NOT USE THE GITHUB UI TO MERGE THE PR /!\ - -## push your changes to upstream feature branch from the terminal; not GitHub UI -git push upstream -``` - - - -See https://github.com/elastic/kibana/pull/37950 for an example. diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/config_copy_provider.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/config_copy_provider.tsx index 9776304797fd4..c1bd0846b887e 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/config_copy_provider.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/config_copy_provider.tsx @@ -99,13 +99,15 @@ export const AgentConfigCopyProvider: React.FunctionComponent = ({ childr + + + } onCancel={closeModal} onConfirm={copyAgentConfig} diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/confirm_deploy_modal.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/confirm_deploy_modal.tsx index a503beeffa8b4..51f37f72a7514 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/confirm_deploy_modal.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/confirm_deploy_modal.tsx @@ -51,15 +51,17 @@ export const ConfirmDeployConfigModal: React.FunctionComponent<{ }, })} > - + {agentConfig.name}, - }} - /> + values={{ + configName: {agentConfig.name}, + }} + /> + - {agentConfig?.name || '-'} + + {agentConfig?.name || '-'} + ) : undefined; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/package_configs/package_configs_table.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/package_configs/package_configs_table.tsx index 4da4e2cc68c9d..1aa0fd1220833 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/package_configs/package_configs_table.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/package_configs/package_configs_table.tsx @@ -104,6 +104,11 @@ export const PackageConfigsTable: React.FunctionComponent = ({ defaultMessage: 'Name', } ), + render: (value: string) => ( + + {value} + + ), }, { field: 'description', @@ -113,7 +118,11 @@ export const PackageConfigsTable: React.FunctionComponent = ({ defaultMessage: 'Description', } ), - truncateText: true, + render: (value: string) => ( + + {value} + + ), }, { field: 'packageTitle', diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx index 4ae16eb91e582..0e65cb80f07c4 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx @@ -74,7 +74,7 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => { - +

{(agentConfig && agentConfig.name) || ( { {agentConfig && agentConfig.description ? ( - + {agentConfig.description} diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx index 4e79bd4fa7997..229adb946412b 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx @@ -158,10 +158,9 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => { defaultMessage: 'Description', }), width: '35%', - truncateText: true, - render: (description: AgentConfig['description']) => ( - - {description} + render: (value: string) => ( + + {value} ), }, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/index.tsx index a6e458a4615cd..39e6d90e64bea 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/index.tsx @@ -75,7 +75,6 @@ export const DataStreamListPage: React.FunctionComponent<{}> = () => { field: 'dataset', sortable: true, width: '25%', - truncateText: true, name: i18n.translate('xpack.ingestManager.dataStreamList.datasetColumnTitle', { defaultMessage: 'Dataset', }), @@ -83,7 +82,6 @@ export const DataStreamListPage: React.FunctionComponent<{}> = () => { { field: 'type', sortable: true, - truncateText: true, name: i18n.translate('xpack.ingestManager.dataStreamList.typeColumnTitle', { defaultMessage: 'Type', }), @@ -91,7 +89,6 @@ export const DataStreamListPage: React.FunctionComponent<{}> = () => { { field: 'namespace', sortable: true, - truncateText: true, name: i18n.translate('xpack.ingestManager.dataStreamList.namespaceColumnTitle', { defaultMessage: 'Namespace', }), @@ -102,7 +99,6 @@ export const DataStreamListPage: React.FunctionComponent<{}> = () => { { field: 'package', sortable: true, - truncateText: true, name: i18n.translate('xpack.ingestManager.dataStreamList.integrationColumnTitle', { defaultMessage: 'Integration', }), diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/agent_details.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/agent_details.tsx index 03f1a67fe95ab..63d93f14c63f5 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/agent_details.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/agent_details.tsx @@ -52,7 +52,10 @@ export const AgentDetailsContent: React.FunctionComponent<{ defaultMessage: 'Agent configuration', }), description: agentConfig ? ( - + {agentConfig.name || agent.config_id} ) : ( diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/agent_events_table.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/agent_events_table.tsx index 5be728b88c3e4..5806cbdcd6811 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/agent_events_table.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/agent_events_table.tsx @@ -153,8 +153,11 @@ export const AgentEventsTable: React.FunctionComponent<{ agent: Agent }> = ({ ag name: i18n.translate('xpack.ingestManager.agentEventsList.messageColumnTitle', { defaultMessage: 'Message', }), - render: (message: string) => {message}, - truncateText: true, + render: (value: string) => ( + + {value} + + ), }, { align: RIGHT_ALIGNMENT, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx index ae9b1e1f6f433..0bd25ac8cf401 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx @@ -135,6 +135,7 @@ export const AgentDetailsPage: React.FunctionComponent = () => { ) : agentConfigData?.item ? ( {agentConfigData.item.name || agentData.item.config_id} diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/index.tsx index 3743f9b39191b..f9c9007454253 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/index.tsx @@ -23,7 +23,6 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage, FormattedRelative } from '@kbn/i18n/react'; -import { CSSProperties } from 'styled-components'; import { AgentEnrollmentFlyout } from '../components'; import { Agent, AgentConfig } from '../../../types'; import { @@ -40,11 +39,6 @@ import { AgentStatusKueryHelper } from '../../../services'; import { AGENT_SAVED_OBJECT_TYPE } from '../../../constants'; import { AgentReassignConfigFlyout, AgentHealth, AgentUnenrollProvider } from '../components'; -const NO_WRAP_TRUNCATE_STYLE: CSSProperties = Object.freeze({ - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', -}); const REFRESH_INTERVAL_MS = 5000; const statusFilters = [ @@ -279,10 +273,10 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { const configName = agentConfigs.find((p) => p.id === configId)?.name; return ( - + {configName || configId} diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/enrollment_token_list_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/enrollment_token_list_page/index.tsx index df0862be9a141..6e8796135214e 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/enrollment_token_list_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/enrollment_token_list_page/index.tsx @@ -6,16 +6,17 @@ import { i18n } from '@kbn/i18n'; import React, { useState } from 'react'; -import { CSSProperties } from 'styled-components'; import { EuiSpacer, EuiBasicTable, EuiFlexGroup, EuiFlexItem, EuiButton, - EuiButtonEmpty, + EuiButtonIcon, + EuiToolTip, EuiIcon, EuiText, + HorizontalAlignment, } from '@elastic/eui'; import { FormattedMessage, FormattedDate } from '@kbn/i18n/react'; import { ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE } from '../../../constants'; @@ -33,12 +34,6 @@ import { SearchBar } from '../../../components/search_bar'; import { NewEnrollmentTokenFlyout } from './components/new_enrollment_key_flyout'; import { ConfirmEnrollmentTokenDelete } from './components/confirm_delete_modal'; -const NO_WRAP_TRUNCATE_STYLE: CSSProperties = Object.freeze({ - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', -}); - const ApiKeyField: React.FunctionComponent<{ apiKeyId: string }> = ({ apiKeyId }) => { const { notifications } = useCore(); const [state, setState] = useState<'VISIBLE' | 'HIDDEN' | 'LOADING'>('HIDDEN'); @@ -66,24 +61,42 @@ const ApiKeyField: React.FunctionComponent<{ apiKeyId: string }> = ({ apiKeyId } }; return ( - - - {state === 'VISIBLE' ? ( - - {key} - - ) : ( - ••••••••••••••••••••• - )} + + + + {state === 'VISIBLE' + ? key + : '•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••'} + - + + + ); @@ -120,7 +133,23 @@ const DeleteButton: React.FunctionComponent<{ apiKey: EnrollmentAPIKey; refresh: onConfirm={onConfirm} /> )} - setState('CONFIRM_VISIBLE')} iconType="trash" color="danger" /> + + setState('CONFIRM_VISIBLE')} + iconType="trash" + color="danger" + /> + ); }; @@ -152,15 +181,11 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => { name: i18n.translate('xpack.ingestManager.enrollmentTokensList.nameTitle', { defaultMessage: 'Name', }), - truncateText: true, - textOnly: true, - render: (name: string) => { - return ( - - {name} - - ); - }, + render: (value: string) => ( + + {value} + + ), }, { field: 'id', @@ -179,7 +204,12 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => { }), render: (configId: string) => { const config = agentConfigs.find((c) => c.id === configId); - return <>{config ? config.name : configId}; + const value = config ? config.name : configId; + return ( + + {value} + + ); }, }, { @@ -200,12 +230,9 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => { defaultMessage: 'Active', }), width: '70px', + align: 'center' as HorizontalAlignment, render: (active: boolean) => { - return ( - - - - ); + return ; }, }, { @@ -242,7 +269,7 @@ export const EnrollmentTokenListPage: React.FunctionComponent<{}> = () => { /> - + ; diff --git a/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item.json b/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item.json index 5fbfcc10bcc3c..eede855aab199 100644 --- a/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item.json +++ b/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item.json @@ -8,7 +8,7 @@ "name": "Sample Endpoint Exception List", "entries": [ { - "field": "host.ip", + "field": "actingProcess.file.signer", "operator": "excluded", "type": "exists" }, diff --git a/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item_with_bad_ip_list.json b/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item_with_bad_ip_list.json new file mode 100644 index 0000000000000..bab435487ec25 --- /dev/null +++ b/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item_with_bad_ip_list.json @@ -0,0 +1,24 @@ +{ + "list_id": "endpoint_list", + "item_id": "endpoint_list_item_good_rock01", + "_tags": ["endpoint", "process", "malware", "os:windows"], + "tags": ["user added string for a tag", "malware"], + "type": "simple", + "description": "Don't signal when agent.name is rock01 and source.ip is in the goodguys.txt list", + "name": "Filter out good guys ip and agent.name rock01", + "comments": [], + "entries": [ + { + "field": "agent.name", + "operator": "excluded", + "type": "match", + "value": ["rock01"] + }, + { + "field": "source.ip", + "operator": "excluded", + "type": "list", + "list": { "id": "goodguys.txt", "type": "ip" } + } + ] +} diff --git a/x-pack/plugins/lists/server/scripts/lists/new/list_ip_item.json b/x-pack/plugins/lists/server/scripts/lists/new/list_ip_item.json new file mode 100644 index 0000000000000..e932892b517a4 --- /dev/null +++ b/x-pack/plugins/lists/server/scripts/lists/new/list_ip_item.json @@ -0,0 +1,4 @@ +{ + "id": "hand_inserted_item_id", + "value": "127.0.0.1" +} diff --git a/x-pack/plugins/lists/server/scripts/lists/new/list_keyword_item.json b/x-pack/plugins/lists/server/scripts/lists/new/list_keyword_item.json new file mode 100644 index 0000000000000..ed798a1dc0792 --- /dev/null +++ b/x-pack/plugins/lists/server/scripts/lists/new/list_keyword_item.json @@ -0,0 +1,4 @@ +{ + "list_id": "keyword_list", + "value": "sh" +} diff --git a/x-pack/plugins/lists/server/scripts/quick_start.sh b/x-pack/plugins/lists/server/scripts/quick_start.sh new file mode 100755 index 0000000000000..d09370bd46a52 --- /dev/null +++ b/x-pack/plugins/lists/server/scripts/quick_start.sh @@ -0,0 +1,5 @@ +./hard_reset.sh && \ +./post_list.sh lists/new/lists/keyword.json && \ +./post_list_item.sh lists/new/list_keyword_item.json && \ +./post_exception_list.sh && \ +./post_exception_list_item.sh ./exception_lists/new/exception_list_item_with_list.json diff --git a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts index c0b9c4553d01e..da28574189e6a 100644 --- a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts +++ b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts @@ -55,6 +55,7 @@ function getClusterSource(documentSource: IESSource, documentStyle: IVectorStyle geoField: documentSource.getGeoFieldName(), requestType: RENDER_AS.POINT, }); + clusterSourceDescriptor.applyGlobalQuery = documentSource.getApplyGlobalQuery(); clusterSourceDescriptor.metrics = [ { type: AGG_TYPE.COUNT, diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js index 92f6c258af597..a4dba71307b71 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js @@ -161,7 +161,6 @@ export class ESGeoGridSource extends AbstractESAggSource { bounds: makeESBbox(bufferedExtent), field: this._descriptor.geoField, precision, - size: DEFAULT_MAX_BUCKETS_LIMIT, }, }, }, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx index 8442ca13910d1..0ac237bb33e76 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { FC, Fragment, useRef, useEffect } from 'react'; +import React, { FC, Fragment, useRef, useEffect, useState } from 'react'; import { debounce } from 'lodash'; import { EuiFieldText, @@ -25,6 +25,14 @@ import { ANALYTICS_STEPS } from '../../page'; import { ml } from '../../../../../services/ml_api_service'; import { extractErrorMessage } from '../../../../../../../common/util/errors'; +const indexNameExistsMessage = i18n.translate( + 'xpack.ml.dataframe.analytics.create.destinationIndexHelpText', + { + defaultMessage: + 'An index with this name already exists. Be aware that running this analytics job will modify this destination index.', + } +); + export const DetailsStepForm: FC = ({ actions, state, @@ -36,7 +44,7 @@ export const DetailsStepForm: FC = ({ const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = docLinks; const { setFormState } = actions; - const { form, isJobCreated } = state; + const { form, cloneJob, isJobCreated } = state; const { createIndexPattern, description, @@ -52,6 +60,9 @@ export const DetailsStepForm: FC = ({ jobIdValid, resultsField, } = form; + + const [destIndexSameAsId, setDestIndexSameAsId] = useState(cloneJob === undefined); + const forceInput = useRef(null); const isStepInvalid = @@ -88,6 +99,14 @@ export const DetailsStepForm: FC = ({ }; }, [destinationIndex]); + useEffect(() => { + if (destIndexSameAsId === true && !jobIdEmpty && jobIdValid) { + setFormState({ destinationIndex: jobId }); + } else if (destIndexSameAsId === false) { + setFormState({ destinationIndex: '' }); + } + }, [destIndexSameAsId, jobId]); + return ( = ({ - {i18n.translate('xpack.ml.dataframe.analytics.create.destinationIndexInvalidError', { - defaultMessage: 'Invalid destination index name.', - })} -
- - {i18n.translate( - 'xpack.ml.dataframe.stepDetailsForm.destinationIndexInvalidErrorLink', - { - defaultMessage: 'Learn more about index name limitations.', - } - )} - -
, - ] + destIndexSameAsId === true && destinationIndexNameExists && indexNameExistsMessage } > - setFormState({ destinationIndex: e.target.value })} - aria-label={i18n.translate( - 'xpack.ml.dataframe.analytics.create.destinationIndexInputAriaLabel', - { - defaultMessage: 'Choose a unique destination index name.', - } - )} - isInvalid={!destinationIndexNameEmpty && !destinationIndexNameValid} - data-test-subj="mlAnalyticsCreateJobFlyoutDestinationIndexInput" + name="mlDataFrameAnalyticsDestIndexSameAsId" + label={i18n.translate('xpack.ml.dataframe.analytics.create.DestIndexSameAsIdLabel', { + defaultMessage: 'Destination index same as job ID', + })} + checked={destIndexSameAsId === true} + onChange={() => setDestIndexSameAsId(!destIndexSameAsId)} + data-test-subj="mlAnalyticsCreateJobWizardDestIndexSameAsIdSwitch" /> + {destIndexSameAsId === false && ( + + {i18n.translate( + 'xpack.ml.dataframe.analytics.create.destinationIndexInvalidError', + { + defaultMessage: 'Invalid destination index name.', + } + )} +
+ + {i18n.translate( + 'xpack.ml.dataframe.stepDetailsForm.destinationIndexInvalidErrorLink', + { + defaultMessage: 'Learn more about index name limitations.', + } + )} + + , + ] + } + > + setFormState({ destinationIndex: e.target.value })} + aria-label={i18n.translate( + 'xpack.ml.dataframe.analytics.create.destinationIndexInputAriaLabel', + { + defaultMessage: 'Choose a unique destination index name.', + } + )} + isInvalid={!destinationIndexNameEmpty && !destinationIndexNameValid} + data-test-subj="mlAnalyticsCreateJobFlyoutDestinationIndexInput" + /> +
+ )} { ); if (ip !== undefined) { setIndexPatternExists(true); + } else { + setIndexPatternExists(false); } } catch (e) { const { toasts } = notifications; @@ -101,7 +103,7 @@ export const useDeleteAction = () => { // Check if an user has permission to delete the index & index pattern checkUserIndexPermission(); - }, []); + }, [isModalVisible]); const closeModal = () => setModalVisible(false); const deleteAndCloseModal = () => { diff --git a/x-pack/plugins/security_solution/cypress/tasks/es_archiver.ts b/x-pack/plugins/security_solution/cypress/tasks/es_archiver.ts index 5a09a2f753dc4..c0436603a256a 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/es_archiver.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/es_archiver.ts @@ -6,7 +6,7 @@ export const esArchiverLoadEmptyKibana = () => { cy.exec( - `node ../../../scripts/es_archiver empty_kibana load empty--dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url ${Cypress.env( + `node ../../../scripts/es_archiver load empty_kibana --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url ${Cypress.env( 'ELASTICSEARCH_URL' )} --kibana-url ${Cypress.config().baseUrl}` ); @@ -30,7 +30,7 @@ export const esArchiverUnload = (folder: string) => { export const esArchiverUnloadEmptyKibana = () => { cy.exec( - `node ../../../scripts/es_archiver unload empty_kibana empty--dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url ${Cypress.env( + `node ../../../scripts/es_archiver unload empty_kibana --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url ${Cypress.env( 'ELASTICSEARCH_URL' )} --kibana-url ${Cypress.config().baseUrl}` ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts index 19fcf65ec0c5e..513d6a93d1b5b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts @@ -69,7 +69,8 @@ export const sampleDocNoSortIdNoVersion = (someUuid: string = sampleIdGuid): Sig export const sampleDocWithSortId = ( someUuid: string = sampleIdGuid, - ip?: string + ip?: string, + destIp?: string ): SignalSourceHit => ({ _index: 'myFakeSignalIndex', _type: 'doc', @@ -82,6 +83,9 @@ export const sampleDocWithSortId = ( source: { ip: ip ?? '127.0.0.1', }, + destination: { + ip: destIp ?? '127.0.0.1', + }, }, sort: ['1234567891111'], }); @@ -307,7 +311,8 @@ export const repeatedSearchResultsWithSortId = ( total: number, pageSize: number, guids: string[], - ips?: string[] + ips?: string[], + destIps?: string[] ) => ({ took: 10, timed_out: false, @@ -321,7 +326,11 @@ export const repeatedSearchResultsWithSortId = ( total, max_score: 100, hits: Array.from({ length: pageSize }).map((x, index) => ({ - ...sampleDocWithSortId(guids[index], ips ? ips[index] : '127.0.0.1'), + ...sampleDocWithSortId( + guids[index], + ips ? ips[index] : '127.0.0.1', + destIps ? destIps[index] : '127.0.0.1' + ), })), }, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filter_events_with_list.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filter_events_with_list.test.ts index 9eebb91c32652..8c39a254e4261 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filter_events_with_list.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filter_events_with_list.test.ts @@ -44,6 +44,25 @@ describe('filterEventsAgainstList', () => { expect(res.hits.hits.length).toEqual(4); }); + it('should respond with eventSearchResult if exceptionList does not contain value list exceptions', async () => { + const res = await filterEventsAgainstList({ + logger: mockLogger, + listClient, + exceptionsList: [getExceptionListItemSchemaMock()], + eventSearchResult: repeatedSearchResultsWithSortId(4, 4, someGuids.slice(0, 3), [ + '1.1.1.1', + '2.2.2.2', + '3.3.3.3', + '7.7.7.7', + ]), + buildRuleMessage, + }); + expect(res.hits.hits.length).toEqual(4); + expect(((mockLogger.debug as unknown) as jest.Mock).mock.calls[0][0]).toContain( + 'no exception items of type list found - returning original search result' + ); + }); + describe('operator_type is included', () => { it('should respond with same list if no items match value list', async () => { const exceptionItem = getExceptionListItemSchemaMock(); @@ -106,6 +125,280 @@ describe('filterEventsAgainstList', () => { 'ci-badguys.txt' ); expect(res.hits.hits.length).toEqual(2); + + // @ts-ignore + const ipVals = res.hits.hits.map((item) => item._source.source.ip); + expect(['3.3.3.3', '7.7.7.7']).toEqual(ipVals); + }); + + it('should respond with less items in the list given two exception items with entries of type list if some values match', async () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [ + { + field: 'source.ip', + operator: 'included', + type: 'list', + list: { + id: 'ci-badguys.txt', + type: 'ip', + }, + }, + ]; + + const exceptionItemAgain = getExceptionListItemSchemaMock(); + exceptionItemAgain.entries = [ + { + field: 'source.ip', + operator: 'included', + type: 'list', + list: { + id: 'ci-badguys-again.txt', + type: 'ip', + }, + }, + ]; + + // this call represents an exception list with a value list containing ['2.2.2.2', '4.4.4.4'] + (listClient.getListItemByValues as jest.Mock).mockResolvedValueOnce([ + { ...getListItemResponseMock(), value: '2.2.2.2' }, + { ...getListItemResponseMock(), value: '4.4.4.4' }, + ]); + // this call represents an exception list with a value list containing ['6.6.6.6'] + (listClient.getListItemByValues as jest.Mock).mockResolvedValueOnce([ + { ...getListItemResponseMock(), value: '6.6.6.6' }, + ]); + + const res = await filterEventsAgainstList({ + logger: mockLogger, + listClient, + exceptionsList: [exceptionItem, exceptionItemAgain], + eventSearchResult: repeatedSearchResultsWithSortId(9, 9, someGuids.slice(0, 9), [ + '1.1.1.1', + '2.2.2.2', + '3.3.3.3', + '4.4.4.4', + '5.5.5.5', + '6.6.6.6', + '7.7.7.7', + '8.8.8.8', + '9.9.9.9', + ]), + buildRuleMessage, + }); + expect(listClient.getListItemByValues as jest.Mock).toHaveBeenCalledTimes(2); + expect(res.hits.hits.length).toEqual(6); + + // @ts-ignore + const ipVals = res.hits.hits.map((item) => item._source.source.ip); + expect(['1.1.1.1', '3.3.3.3', '5.5.5.5', '7.7.7.7', '8.8.8.8', '9.9.9.9']).toEqual(ipVals); + }); + + it('should respond with less items in the list given two exception items, each with one entry of type list if some values match', async () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [ + { + field: 'source.ip', + operator: 'included', + type: 'list', + list: { + id: 'ci-badguys.txt', + type: 'ip', + }, + }, + ]; + + const exceptionItemAgain = getExceptionListItemSchemaMock(); + exceptionItemAgain.entries = [ + { + field: 'source.ip', + operator: 'included', + type: 'list', + list: { + id: 'ci-badguys-again.txt', + type: 'ip', + }, + }, + ]; + + // this call represents an exception list with a value list containing ['2.2.2.2', '4.4.4.4'] + (listClient.getListItemByValues as jest.Mock).mockResolvedValueOnce([ + { ...getListItemResponseMock(), value: '2.2.2.2' }, + ]); + // this call represents an exception list with a value list containing ['6.6.6.6'] + (listClient.getListItemByValues as jest.Mock).mockResolvedValueOnce([ + { ...getListItemResponseMock(), value: '6.6.6.6' }, + ]); + + const res = await filterEventsAgainstList({ + logger: mockLogger, + listClient, + exceptionsList: [exceptionItem, exceptionItemAgain], + eventSearchResult: repeatedSearchResultsWithSortId(9, 9, someGuids.slice(0, 9), [ + '1.1.1.1', + '2.2.2.2', + '3.3.3.3', + '4.4.4.4', + '5.5.5.5', + '6.6.6.6', + '7.7.7.7', + '8.8.8.8', + '9.9.9.9', + ]), + buildRuleMessage, + }); + expect(listClient.getListItemByValues as jest.Mock).toHaveBeenCalledTimes(2); + // @ts-ignore + const ipVals = res.hits.hits.map((item) => item._source.source.ip); + expect(res.hits.hits.length).toEqual(7); + + expect(['1.1.1.1', '3.3.3.3', '4.4.4.4', '5.5.5.5', '7.7.7.7', '8.8.8.8', '9.9.9.9']).toEqual( + ipVals + ); + }); + + it('should respond with less items in the list given one exception item with two entries of type list only if source.ip and destination.ip are in the events', async () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [ + { + field: 'source.ip', + operator: 'included', + type: 'list', + list: { + id: 'ci-badguys.txt', + type: 'ip', + }, + }, + { + field: 'destination.ip', + operator: 'included', + type: 'list', + list: { + id: 'ci-badguys-again.txt', + type: 'ip', + }, + }, + ]; + + // this call represents an exception list with a value list containing ['2.2.2.2'] + (listClient.getListItemByValues as jest.Mock).mockResolvedValueOnce([ + { ...getListItemResponseMock(), value: '2.2.2.2' }, + ]); + // this call represents an exception list with a value list containing ['4.4.4.4'] + (listClient.getListItemByValues as jest.Mock).mockResolvedValueOnce([ + { ...getListItemResponseMock(), value: '4.4.4.4' }, + ]); + + const res = await filterEventsAgainstList({ + logger: mockLogger, + listClient, + exceptionsList: [exceptionItem], + eventSearchResult: repeatedSearchResultsWithSortId( + 9, + 9, + someGuids.slice(0, 9), + [ + '1.1.1.1', + '2.2.2.2', + '3.3.3.3', + '4.4.4.4', + '5.5.5.5', + '6.6.6.6', + '2.2.2.2', + '8.8.8.8', + '9.9.9.9', + ], + [ + '2.2.2.2', + '2.2.2.2', + '2.2.2.2', + '2.2.2.2', + '2.2.2.2', + '2.2.2.2', + '4.4.4.4', + '2.2.2.2', + '2.2.2.2', + ] + ), + buildRuleMessage, + }); + expect(listClient.getListItemByValues as jest.Mock).toHaveBeenCalledTimes(2); + expect(res.hits.hits.length).toEqual(8); + + // @ts-ignore + const ipVals = res.hits.hits.map((item) => item._source.source.ip); + expect([ + '1.1.1.1', + '2.2.2.2', + '3.3.3.3', + '4.4.4.4', + '5.5.5.5', + '6.6.6.6', + '8.8.8.8', + '9.9.9.9', + ]).toEqual(ipVals); + }); + + it('should respond with the same items in the list given one exception item with two entries of type list where the entries are included and excluded', async () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [ + { + field: 'source.ip', + operator: 'included', + type: 'list', + list: { + id: 'ci-badguys.txt', + type: 'ip', + }, + }, + { + field: 'source.ip', + operator: 'excluded', + type: 'list', + list: { + id: 'ci-badguys-again.txt', + type: 'ip', + }, + }, + ]; + + // this call represents an exception list with a value list containing ['2.2.2.2', '4.4.4.4'] + (listClient.getListItemByValues as jest.Mock).mockResolvedValue([ + { ...getListItemResponseMock(), value: '2.2.2.2' }, + ]); + + const res = await filterEventsAgainstList({ + logger: mockLogger, + listClient, + exceptionsList: [exceptionItem], + eventSearchResult: repeatedSearchResultsWithSortId(9, 9, someGuids.slice(0, 9), [ + '1.1.1.1', + '2.2.2.2', + '3.3.3.3', + '4.4.4.4', + '5.5.5.5', + '6.6.6.6', + '7.7.7.7', + '8.8.8.8', + '9.9.9.9', + ]), + buildRuleMessage, + }); + expect(listClient.getListItemByValues as jest.Mock).toHaveBeenCalledTimes(2); + expect(res.hits.hits.length).toEqual(9); + + // @ts-ignore + const ipVals = res.hits.hits.map((item) => item._source.source.ip); + expect([ + '1.1.1.1', + '2.2.2.2', + '3.3.3.3', + '4.4.4.4', + '5.5.5.5', + '6.6.6.6', + '7.7.7.7', + '8.8.8.8', + '9.9.9.9', + ]).toEqual(ipVals); }); }); describe('operator type is excluded', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filter_events_with_list.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filter_events_with_list.ts index ea52aecb379fa..262af5d88e227 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filter_events_with_list.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/filter_events_with_list.ts @@ -10,9 +10,10 @@ import { ListClient } from '../../../../../lists/server'; import { SignalSearchResponse, SearchTypes } from './types'; import { BuildRuleMessage } from './rule_messages'; import { - entriesList, EntryList, ExceptionListItemSchema, + entriesList, + Type, } from '../../../../../lists/common/schemas'; import { hasLargeValueList } from '../../../../common/detection_engine/utils'; @@ -24,6 +25,51 @@ interface FilterEventsAgainstList { buildRuleMessage: BuildRuleMessage; } +export const createSetToFilterAgainst = async ({ + events, + field, + listId, + listType, + listClient, + logger, + buildRuleMessage, +}: { + events: SignalSearchResponse['hits']['hits']; + field: string; + listId: string; + listType: Type; + listClient: ListClient; + logger: Logger; + buildRuleMessage: BuildRuleMessage; +}): Promise> => { + // narrow unioned type to be single + const isStringableType = (val: SearchTypes) => + ['string', 'number', 'boolean'].includes(typeof val); + const valuesFromSearchResultField = events.reduce((acc, searchResultItem) => { + const valueField = get(field, searchResultItem._source); + if (valueField != null && isStringableType(valueField)) { + acc.add(valueField.toString()); + } + return acc; + }, new Set()); + logger.debug( + `number of distinct values from ${field}: ${[...valuesFromSearchResultField].length}` + ); + + // matched will contain any list items that matched with the + // values passed in from the Set. + const matchedListItems = await listClient.getListItemByValues({ + listId, + type: listType, + value: [...valuesFromSearchResultField], + }); + + logger.debug(`number of matched items from list with id ${listId}: ${matchedListItems.length}`); + // create a set of list values that were a hit - easier to work with + const matchedListItemsSet = new Set(matchedListItems.map((item) => item.value)); + return matchedListItemsSet; +}; + export const filterEventsAgainstList = async ({ listClient, exceptionsList, @@ -32,7 +78,6 @@ export const filterEventsAgainstList = async ({ buildRuleMessage, }: FilterEventsAgainstList): Promise => { try { - logger.debug(buildRuleMessage(`exceptionsList: ${JSON.stringify(exceptionsList, null, 2)}`)); if (exceptionsList == null || exceptionsList.length === 0) { logger.debug(buildRuleMessage('about to return original search result')); return eventSearchResult; @@ -51,87 +96,97 @@ export const filterEventsAgainstList = async ({ ); if (exceptionItemsWithLargeValueLists.length === 0) { - logger.debug(buildRuleMessage('about to return original search result')); + logger.debug( + buildRuleMessage('no exception items of type list found - returning original search result') + ); return eventSearchResult; } - // narrow unioned type to be single - const isStringableType = (val: SearchTypes) => - ['string', 'number', 'boolean'].includes(typeof val); - // grab the signals with values found in the given exception lists. - const filteredHitsPromises = exceptionItemsWithLargeValueLists.map( - async (exceptionItem: ExceptionListItemSchema) => { - const { entries } = exceptionItem; - - const filteredHitsEntries = entries - .filter((t): t is EntryList => entriesList.is(t)) - .map(async (entry) => { + const valueListExceptionItems = exceptionsList.filter((listItem: ExceptionListItemSchema) => { + return listItem.entries.every((entry) => entriesList.is(entry)); + }); + + // now that we have all the exception items which are value lists (whether single entry or have multiple entries) + const res = await valueListExceptionItems.reduce>( + async ( + filteredAccum: Promise, + exceptionItem: ExceptionListItemSchema + ) => { + // 1. acquire the values from the specified fields to check + // e.g. if the value list is checking against source.ip, gather + // all the values for source.ip from the search response events. + + // 2. search against the value list with the values found in the search result + // and see if there are any matches. For every match, add that value to a set + // that represents the "matched" values + + // 3. filter the search result against the set from step 2 using the + // given operator (included vs excluded). + // acquire the list values we are checking for in the field. + const filtered = await filteredAccum; + const typedEntries = exceptionItem.entries.filter((entry): entry is EntryList => + entriesList.is(entry) + ); + const fieldAndSetTuples = await Promise.all( + typedEntries.map(async (entry) => { const { list, field, operator } = entry; const { id, type } = list; - - // acquire the list values we are checking for. - const valuesOfGivenType = eventSearchResult.hits.hits.reduce( - (acc, searchResultItem) => { - const valueField = get(field, searchResultItem._source); - - if (valueField != null && isStringableType(valueField)) { - acc.add(valueField.toString()); - } - return acc; - }, - new Set() - ); - - // matched will contain any list items that matched with the - // values passed in from the Set. - const matchedListItems = await listClient.getListItemByValues({ + const matchedSet = await createSetToFilterAgainst({ + events: filtered, + field, listId: id, - type, - value: [...valuesOfGivenType], + listType: type, + listClient, + logger, + buildRuleMessage, }); - // create a set of list values that were a hit - easier to work with - const matchedListItemsSet = new Set( - matchedListItems.map((item) => item.value) - ); - - // do a single search after with these values. - // painless script to do nested query in elasticsearch - // filter out the search results that match with the values found in the list. - const filteredEvents = eventSearchResult.hits.hits.filter((item) => { - const eventItem = get(entry.field, item._source); - if (operator === 'included') { - if (eventItem != null) { - return !matchedListItemsSet.has(eventItem); - } - } else if (operator === 'excluded') { - if (eventItem != null) { - return matchedListItemsSet.has(eventItem); - } + return Promise.resolve({ field, operator, matchedSet }); + }) + ); + + // check if for each tuple, the entry is not in both for when two value list entries exist. + // need to re-write this as a reduce. + const filteredEvents = filtered.filter((item) => { + const vals = fieldAndSetTuples.map((tuple) => { + const eventItem = get(tuple.field, item._source); + if (tuple.operator === 'included') { + // only create a signal if the event is not in the value list + if (eventItem != null) { + return !tuple.matchedSet.has(eventItem); } - return false; - }); - const diff = eventSearchResult.hits.hits.length - filteredEvents.length; - logger.debug(buildRuleMessage(`Lists filtered out ${diff} events`)); - return filteredEvents; + return true; + } else if (tuple.operator === 'excluded') { + // only create a signal if the event is in the value list + if (eventItem != null) { + return tuple.matchedSet.has(eventItem); + } + return true; + } + return false; }); - - return (await Promise.all(filteredHitsEntries)).flat(); - } + return vals.some((value) => value); + }); + const diff = eventSearchResult.hits.hits.length - filteredEvents.length; + logger.debug( + buildRuleMessage(`Exception with id ${exceptionItem.id} filtered out ${diff} events`) + ); + const toReturn = filteredEvents; + return toReturn; + }, + Promise.resolve(eventSearchResult.hits.hits) ); - const filteredHits = await Promise.all(filteredHitsPromises); const toReturn: SignalSearchResponse = { took: eventSearchResult.took, timed_out: eventSearchResult.timed_out, _shards: eventSearchResult._shards, hits: { - total: filteredHits.length, + total: res.length, max_score: eventSearchResult.hits.max_score, - hits: filteredHits.flat(), + hits: res, }, }; - return toReturn; } catch (exc) { throw new Error(`Failed to query lists index. Reason: ${exc.message}`); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts index 3312191c3b41b..58dcd7f6bd1c1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts @@ -475,7 +475,7 @@ describe('searchAfterAndBulkCreate', () => { expect(lastLookBackDate).toEqual(new Date('2020-04-20T21:27:45+0000')); // I don't like testing log statements since logs change but this is the best // way I can think of to ensure this section is getting hit with this test case. - expect(((mockLogger.debug as unknown) as jest.Mock).mock.calls[7][0]).toContain( + expect(((mockLogger.debug as unknown) as jest.Mock).mock.calls[8][0]).toContain( 'sortIds was empty on searchResult' ); }); @@ -558,7 +558,7 @@ describe('searchAfterAndBulkCreate', () => { expect(lastLookBackDate).toEqual(new Date('2020-04-20T21:27:45+0000')); // I don't like testing log statements since logs change but this is the best // way I can think of to ensure this section is getting hit with this test case. - expect(((mockLogger.debug as unknown) as jest.Mock).mock.calls[12][0]).toContain( + expect(((mockLogger.debug as unknown) as jest.Mock).mock.calls[15][0]).toContain( 'sortIds was empty on filteredEvents' ); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts index 3d4e7384714eb..74709f31563ee 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts @@ -83,6 +83,7 @@ export const singleBulkCreate = async ({ throttle, }: SingleBulkCreateParams): Promise => { filteredEvents.hits.hits = filterDuplicateRules(id, filteredEvents); + logger.debug(`about to bulk create ${filteredEvents.hits.hits.length} events`); if (filteredEvents.hits.hits.length === 0) { logger.debug(`all events were duplicates`); return { success: true, createdItemsCount: 0 }; @@ -135,6 +136,8 @@ export const singleBulkCreate = async ({ logger.debug(`took property says bulk took: ${response.took} milliseconds`); if (response.errors) { + const duplicateSignalsCount = countBy(response.items, 'create.status')['409']; + logger.debug(`ignored ${duplicateSignalsCount} duplicate signals`); const errorCountByMessage = errorAggregator(response, [409]); if (!isEmpty(errorCountByMessage)) { logger.error( @@ -144,6 +147,6 @@ export const singleBulkCreate = async ({ } const createdItemsCount = countBy(response.items, 'create.status')['201'] ?? 0; - + logger.debug(`bulk created ${createdItemsCount} signals`); return { success: true, bulkCreateDuration: makeFloatString(end - start), createdItemsCount }; }; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1d8d93e7c961d..d07d92a028d8d 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -7415,10 +7415,6 @@ "xpack.infra.logs.analysis.anomalySectionNoDataTitle": "表示するデータがありません。", "xpack.infra.logs.analysis.jobStoppedCalloutMessage": "ML ジョブが手動またはリソース不足により停止しました。新しいログエントリーはジョブが再起動するまで処理されません。", "xpack.infra.logs.analysis.jobStoppedCalloutTitle": "ML ジョブが停止しました", - "xpack.infra.logs.analysis.missingMlResultsPrivilegesBody": "本機能は機械学習ジョブを利用し、そのステータスと結果にアクセスするためには、少なくとも{machineLearningUserRole}ロールが必要です。", - "xpack.infra.logs.analysis.missingMlResultsPrivilegesTitle": "追加の機械学習の権限が必要です", - "xpack.infra.logs.analysis.missingMlSetupPrivilegesBody": "本機能は機械学習ジョブを利用し、設定には{machineLearningAdminRole}ロールが必要です。", - "xpack.infra.logs.analysis.missingMlSetupPrivilegesTitle": "追加の機械学習の権限が必要です", "xpack.infra.logs.analysis.mlAppButton": "機械学習を開く", "xpack.infra.logs.analysis.mlUnavailableBody": "詳細は{machineLearningAppLink}をご覧ください。", "xpack.infra.logs.analysis.mlUnavailableTitle": "この機能には機械学習が必要です", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 0ea2c9f17e257..8f844de735dc6 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -7420,10 +7420,6 @@ "xpack.infra.logs.analysis.anomalySectionNoDataTitle": "没有可显示的数据。", "xpack.infra.logs.analysis.jobStoppedCalloutMessage": "ML 作业已手动停止或由于缺乏资源而停止。作业重新启动后,才会处理新的日志条目。", "xpack.infra.logs.analysis.jobStoppedCalloutTitle": "ML 作业已停止", - "xpack.infra.logs.analysis.missingMlResultsPrivilegesBody": "此功能使用 Machine Learning 作业,要访问这些作业的状态和结果,至少需要 {machineLearningUserRole} 角色。", - "xpack.infra.logs.analysis.missingMlResultsPrivilegesTitle": "需要额外的 Machine Learning 权限", - "xpack.infra.logs.analysis.missingMlSetupPrivilegesBody": "此功能使用 Machine Learning 作业,这需要 {machineLearningAdminRole} 角色才能设置。", - "xpack.infra.logs.analysis.missingMlSetupPrivilegesTitle": "需要额外的 Machine Learning 权限", "xpack.infra.logs.analysis.mlAppButton": "打开 Machine Learning", "xpack.infra.logs.analysis.mlUnavailableBody": "查看 {machineLearningAppLink} 以获取更多信息。", "xpack.infra.logs.analysis.mlUnavailableTitle": "此功能需要 Machine Learning", diff --git a/x-pack/plugins/uptime/public/state/actions/__tests__/__snapshots__/overview_filters.test.ts.snap b/x-pack/plugins/uptime/public/state/actions/__tests__/__snapshots__/overview_filters.test.ts.snap index 6fe2c8eaa362d..1e7ea536bae79 100644 --- a/x-pack/plugins/uptime/public/state/actions/__tests__/__snapshots__/overview_filters.test.ts.snap +++ b/x-pack/plugins/uptime/public/state/actions/__tests__/__snapshots__/overview_filters.test.ts.snap @@ -2,6 +2,7 @@ exports[`overview filters action creators creates a fail action 1`] = ` Object { + "error": true, "payload": [Error: There was an error retrieving the overview filters], "type": "FETCH_OVERVIEW_FILTERS_FAIL", } diff --git a/x-pack/plugins/uptime/public/state/actions/overview_filters.ts b/x-pack/plugins/uptime/public/state/actions/overview_filters.ts index 8eefa701a240a..1dcf49414c413 100644 --- a/x-pack/plugins/uptime/public/state/actions/overview_filters.ts +++ b/x-pack/plugins/uptime/public/state/actions/overview_filters.ts @@ -4,13 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ +import { createAction } from 'redux-actions'; import { OverviewFilters } from '../../../common/runtime_types'; -export const FETCH_OVERVIEW_FILTERS = 'FETCH_OVERVIEW_FILTERS'; -export const FETCH_OVERVIEW_FILTERS_FAIL = 'FETCH_OVERVIEW_FILTERS_FAIL'; -export const FETCH_OVERVIEW_FILTERS_SUCCESS = 'FETCH_OVERVIEW_FILTERS_SUCCESS'; -export const SET_OVERVIEW_FILTERS = 'SET_OVERVIEW_FILTERS'; - export interface GetOverviewFiltersPayload { dateRangeStart: string; dateRangeEnd: string; @@ -22,52 +18,16 @@ export interface GetOverviewFiltersPayload { tags: string[]; } -interface GetOverviewFiltersFetchAction { - type: typeof FETCH_OVERVIEW_FILTERS; - payload: GetOverviewFiltersPayload; -} - -interface GetOverviewFiltersSuccessAction { - type: typeof FETCH_OVERVIEW_FILTERS_SUCCESS; - payload: OverviewFilters; -} - -interface GetOverviewFiltersFailAction { - type: typeof FETCH_OVERVIEW_FILTERS_FAIL; - payload: Error; -} - -interface SetOverviewFiltersAction { - type: typeof SET_OVERVIEW_FILTERS; - payload: OverviewFilters; -} - -export type OverviewFiltersAction = - | GetOverviewFiltersFetchAction - | GetOverviewFiltersSuccessAction - | GetOverviewFiltersFailAction - | SetOverviewFiltersAction; +export type OverviewFiltersPayload = GetOverviewFiltersPayload & Error & OverviewFilters; -export const fetchOverviewFilters = ( - payload: GetOverviewFiltersPayload -): GetOverviewFiltersFetchAction => ({ - type: FETCH_OVERVIEW_FILTERS, - payload, -}); +export const fetchOverviewFilters = createAction( + 'FETCH_OVERVIEW_FILTERS' +); -export const fetchOverviewFiltersFail = (error: Error): GetOverviewFiltersFailAction => ({ - type: FETCH_OVERVIEW_FILTERS_FAIL, - payload: error, -}); +export const fetchOverviewFiltersFail = createAction('FETCH_OVERVIEW_FILTERS_FAIL'); -export const fetchOverviewFiltersSuccess = ( - filters: OverviewFilters -): GetOverviewFiltersSuccessAction => ({ - type: FETCH_OVERVIEW_FILTERS_SUCCESS, - payload: filters, -}); +export const fetchOverviewFiltersSuccess = createAction( + 'FETCH_OVERVIEW_FILTERS_SUCCESS' +); -export const setOverviewFilters = (filters: OverviewFilters): SetOverviewFiltersAction => ({ - type: SET_OVERVIEW_FILTERS, - payload: filters, -}); +export const setOverviewFilters = createAction('SET_OVERVIEW_FILTERS'); diff --git a/x-pack/plugins/uptime/public/state/effects/overview_filters.ts b/x-pack/plugins/uptime/public/state/effects/overview_filters.ts index 92b578bafed2d..9149f20f233c6 100644 --- a/x-pack/plugins/uptime/public/state/effects/overview_filters.ts +++ b/x-pack/plugins/uptime/public/state/effects/overview_filters.ts @@ -6,7 +6,7 @@ import { takeLatest } from 'redux-saga/effects'; import { - FETCH_OVERVIEW_FILTERS, + fetchOverviewFilters as fetchAction, fetchOverviewFiltersFail, fetchOverviewFiltersSuccess, } from '../actions'; @@ -15,7 +15,7 @@ import { fetchEffectFactory } from './fetch_effect'; export function* fetchOverviewFiltersEffect() { yield takeLatest( - FETCH_OVERVIEW_FILTERS, + String(fetchAction), fetchEffectFactory(fetchOverviewFilters, fetchOverviewFiltersSuccess, fetchOverviewFiltersFail) ); } diff --git a/x-pack/plugins/uptime/public/state/reducers/overview_filters.ts b/x-pack/plugins/uptime/public/state/reducers/overview_filters.ts index 4548627d9dcb8..702518b69cba5 100644 --- a/x-pack/plugins/uptime/public/state/reducers/overview_filters.ts +++ b/x-pack/plugins/uptime/public/state/reducers/overview_filters.ts @@ -4,13 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ +import { handleActions, Action } from 'redux-actions'; import { OverviewFilters } from '../../../common/runtime_types'; import { - FETCH_OVERVIEW_FILTERS, - FETCH_OVERVIEW_FILTERS_FAIL, - FETCH_OVERVIEW_FILTERS_SUCCESS, - OverviewFiltersAction, - SET_OVERVIEW_FILTERS, + fetchOverviewFilters, + fetchOverviewFiltersFail, + fetchOverviewFiltersSuccess, + setOverviewFilters, + GetOverviewFiltersPayload, + OverviewFiltersPayload, } from '../actions'; export interface OverviewFiltersState { @@ -30,34 +32,29 @@ const initialState: OverviewFiltersState = { loading: false, }; -export function overviewFiltersReducer( - state = initialState, - action: OverviewFiltersAction -): OverviewFiltersState { - switch (action.type) { - case FETCH_OVERVIEW_FILTERS: - return { - ...state, - loading: true, - }; - case FETCH_OVERVIEW_FILTERS_SUCCESS: - return { - ...state, - filters: action.payload, - loading: false, - }; - case FETCH_OVERVIEW_FILTERS_FAIL: - return { - ...state, - errors: [...state.errors, action.payload], - loading: false, - }; - case SET_OVERVIEW_FILTERS: - return { - ...state, - filters: action.payload, - }; - default: - return state; - } -} +export const overviewFiltersReducer = handleActions( + { + [String(fetchOverviewFilters)]: (state, _action: Action) => ({ + ...state, + loading: true, + }), + + [String(fetchOverviewFiltersSuccess)]: (state, action: Action) => ({ + ...state, + filters: action.payload, + loading: false, + }), + + [String(fetchOverviewFiltersFail)]: (state, action: Action) => ({ + ...state, + errors: [...state.errors, action.payload], + loading: false, + }), + + [String(setOverviewFilters)]: (state, action: Action) => ({ + ...state, + filters: action.payload, + }), + }, + initialState +); diff --git a/x-pack/test/alerting_api_integration/common/lib/get_event_log.ts b/x-pack/test/alerting_api_integration/common/lib/get_event_log.ts index 69eeaafbf64fa..99f51ff244546 100644 --- a/x-pack/test/alerting_api_integration/common/lib/get_event_log.ts +++ b/x-pack/test/alerting_api_integration/common/lib/get_event_log.ts @@ -22,6 +22,7 @@ interface GetEventLogParams { export async function getEventLog(params: GetEventLogParams): Promise { const { getService, spaceId, type, id, provider, actions } = params; const supertest = getService('supertest'); + const actionsSet = new Set(actions); const spacePrefix = getUrlPrefix(spaceId); const url = `${spacePrefix}/api/event_log/${type}/${id}/_find`; @@ -31,11 +32,13 @@ export async function getEventLog(params: GetEventLogParams): Promise event?.event?.provider === provider - ); + // filter events to matching provider and requested actions + const events: IValidatedEvent[] = (result.data as IValidatedEvent[]) + .filter((event) => event?.event?.provider === provider) + .filter((event) => event?.event?.action) + .filter((event) => actionsSet.has(event?.event?.action!)); const foundActions = new Set( - events.map((event) => event?.event?.action).filter((event) => !!event) + events.map((event) => event?.event?.action).filter((action) => !!action) ); for (const action of actions) { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts index ffa9855478a05..8d8bc066a9b1a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts @@ -31,8 +31,7 @@ export default function alertTests({ getService }: FtrProviderContext) { const esTestIndexTool = new ESTestIndexTool(es, retry); const taskManagerUtils = new TaskManagerUtils(es, retry); - // FLAKY: https://github.com/elastic/kibana/issues/72207 - describe.skip('alerts', () => { + describe('alerts', () => { const authorizationIndex = '.kibana-test-authorization'; const objectRemover = new ObjectRemover(supertest); diff --git a/x-pack/test/api_integration/apis/endpoint/artifacts/index.ts b/x-pack/test/api_integration/apis/endpoint/artifacts/index.ts index ba68b9b7ba6ee..b37522ed52b5c 100644 --- a/x-pack/test/api_integration/apis/endpoint/artifacts/index.ts +++ b/x-pack/test/api_integration/apis/endpoint/artifacts/index.ts @@ -9,7 +9,10 @@ import { createHash } from 'crypto'; import { inflateSync } from 'zlib'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { getSupertestWithoutAuth, setupIngest } from '../../fleet/agents/services'; +import { + getSupertestWithoutAuth, + setupIngest, +} from '../../../../ingest_manager_api_integration/apis/fleet/agents/services'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; diff --git a/x-pack/test/api_integration/apis/index.js b/x-pack/test/api_integration/apis/index.js index ce0e534d8a750..05b305ccd833f 100644 --- a/x-pack/test/api_integration/apis/index.js +++ b/x-pack/test/api_integration/apis/index.js @@ -26,11 +26,9 @@ export default function ({ loadTestFile }) { loadTestFile(require.resolve('./security_solution')); loadTestFile(require.resolve('./short_urls')); loadTestFile(require.resolve('./lens')); - loadTestFile(require.resolve('./fleet')); loadTestFile(require.resolve('./ml')); loadTestFile(require.resolve('./transform')); loadTestFile(require.resolve('./endpoint')); - loadTestFile(require.resolve('./ingest_manager')); loadTestFile(require.resolve('./lists')); loadTestFile(require.resolve('./upgrade_assistant')); }); diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts index 2c6edeba2129f..4566e9aed61b4 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts @@ -115,7 +115,13 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataFrameAnalyticsCreation.setJobDescription(testData.jobDescription); }); - it('inputs the destination index', async () => { + it('should default the set destination index to job id switch to true', async () => { + await ml.dataFrameAnalyticsCreation.assertDestIndexSameAsIdSwitchExists(); + await ml.dataFrameAnalyticsCreation.assertDestIndexSameAsIdCheckState(true); + }); + + it('should input the destination index', async () => { + await ml.dataFrameAnalyticsCreation.setDestIndexSameAsIdCheckState(false); await ml.dataFrameAnalyticsCreation.assertDestIndexInputExists(); await ml.dataFrameAnalyticsCreation.setDestIndex(testData.destinationIndex); }); diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts index 4ae93296f9be0..0320354b99ff0 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts @@ -133,7 +133,13 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataFrameAnalyticsCreation.setJobDescription(testData.jobDescription); }); - it('inputs the destination index', async () => { + it('should default the set destination index to job id switch to true', async () => { + await ml.dataFrameAnalyticsCreation.assertDestIndexSameAsIdSwitchExists(); + await ml.dataFrameAnalyticsCreation.assertDestIndexSameAsIdCheckState(true); + }); + + it('should input the destination index', async () => { + await ml.dataFrameAnalyticsCreation.setDestIndexSameAsIdCheckState(false); await ml.dataFrameAnalyticsCreation.assertDestIndexInputExists(); await ml.dataFrameAnalyticsCreation.setDestIndex(testData.destinationIndex); }); diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts index 03117d4cc419d..1aa505e26e1e9 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts @@ -115,7 +115,13 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataFrameAnalyticsCreation.setJobDescription(testData.jobDescription); }); - it('inputs the destination index', async () => { + it('should default the set destination index to job id switch to true', async () => { + await ml.dataFrameAnalyticsCreation.assertDestIndexSameAsIdSwitchExists(); + await ml.dataFrameAnalyticsCreation.assertDestIndexSameAsIdCheckState(true); + }); + + it('should input the destination index', async () => { + await ml.dataFrameAnalyticsCreation.setDestIndexSameAsIdCheckState(false); await ml.dataFrameAnalyticsCreation.assertDestIndexInputExists(); await ml.dataFrameAnalyticsCreation.setDestIndex(testData.destinationIndex); }); diff --git a/x-pack/test/functional/apps/security/doc_level_security_roles.js b/x-pack/test/functional/apps/security/doc_level_security_roles.js index d8a3e40ccc010..72f463be48fd5 100644 --- a/x-pack/test/functional/apps/security/doc_level_security_roles.js +++ b/x-pack/test/functional/apps/security/doc_level_security_roles.js @@ -15,8 +15,7 @@ export default function ({ getService, getPageObjects }) { const screenshot = getService('screenshots'); const PageObjects = getPageObjects(['security', 'common', 'header', 'discover', 'settings']); - // Skipped as failing on ES Promotion: https://github.com/elastic/kibana/issues/70818 - describe.skip('dls', function () { + describe('dls', function () { before('initialize tests', async () => { await esArchiver.load('empty_kibana'); await esArchiver.loadIfNeeded('security/dlstest'); diff --git a/x-pack/test/functional/apps/security/field_level_security.js b/x-pack/test/functional/apps/security/field_level_security.js index 20b13ad935f93..7b22d72885c9d 100644 --- a/x-pack/test/functional/apps/security/field_level_security.js +++ b/x-pack/test/functional/apps/security/field_level_security.js @@ -14,8 +14,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const PageObjects = getPageObjects(['security', 'settings', 'common', 'discover', 'header']); - // Skipped as it was failing on ES Promotion: https://github.com/elastic/kibana/issues/70880 - describe.skip('field_level_security', () => { + describe('field_level_security', () => { before('initialize tests', async () => { await esArchiver.loadIfNeeded('security/flstest/data'); //( data) await esArchiver.load('security/flstest/kibana'); //(savedobject) diff --git a/x-pack/test/functional/page_objects/gis_page.js b/x-pack/test/functional/page_objects/gis_page.js index 8a0b4aaefa888..b8f4faf3ebfd8 100644 --- a/x-pack/test/functional/page_objects/gis_page.js +++ b/x-pack/test/functional/page_objects/gis_page.js @@ -17,6 +17,7 @@ export function GisPageProvider({ getService, getPageObjects }) { const find = getService('find'); const queryBar = getService('queryBar'); const comboBox = getService('comboBox'); + const renderable = getService('renderable'); function escapeLayerName(layerName) { return layerName.split(' ').join('_'); @@ -135,6 +136,7 @@ export function GisPageProvider({ getService, getPageObjects }) { // Navigate directly because we don't need to go through the map listing // page. The listing page is skipped if there are no saved objects await PageObjects.common.navigateToUrlWithBrowserHistory(APP_ID, '/map'); + await renderable.waitForRender(); } async saveMap(name) { diff --git a/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts b/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts index e36855a4e769e..5f3d21b80a830 100644 --- a/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts +++ b/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts @@ -199,7 +199,9 @@ export function MachineLearningDataFrameAnalyticsCreationProvider( // }, async assertDestIndexInputExists() { - await testSubjects.existOrFail('mlAnalyticsCreateJobFlyoutDestinationIndexInput'); + await retry.tryForTime(4000, async () => { + await testSubjects.existOrFail('mlAnalyticsCreateJobFlyoutDestinationIndexInput'); + }); }, async assertDestIndexValue(expectedValue: string) { @@ -417,6 +419,35 @@ export function MachineLearningDataFrameAnalyticsCreationProvider( ); }, + async getDestIndexSameAsIdSwitchCheckState(): Promise { + const state = await testSubjects.getAttribute( + 'mlAnalyticsCreateJobWizardDestIndexSameAsIdSwitch', + 'aria-checked' + ); + return state === 'true'; + }, + + async assertDestIndexSameAsIdCheckState(expectedCheckState: boolean) { + const actualCheckState = await this.getDestIndexSameAsIdSwitchCheckState(); + expect(actualCheckState).to.eql( + expectedCheckState, + `Destination index same as job id check state should be '${expectedCheckState}' (got '${actualCheckState}')` + ); + }, + + async assertDestIndexSameAsIdSwitchExists() { + await testSubjects.existOrFail(`mlAnalyticsCreateJobWizardDestIndexSameAsIdSwitch`, { + allowHidden: true, + }); + }, + + async setDestIndexSameAsIdCheckState(checkState: boolean) { + if ((await this.getDestIndexSameAsIdSwitchCheckState()) !== checkState) { + await testSubjects.click('mlAnalyticsCreateJobWizardDestIndexSameAsIdSwitch'); + } + await this.assertDestIndexSameAsIdCheckState(checkState); + }, + async setCreateIndexPatternSwitchState(checkState: boolean) { if ((await this.getCreateIndexPatternSwitchCheckState()) !== checkState) { await testSubjects.click('mlAnalyticsCreateJobWizardCreateIndexPatternSwitch'); diff --git a/x-pack/test/api_integration/apis/ingest_manager/agent_config.ts b/x-pack/test/ingest_manager_api_integration/apis/agent_config/agent_config.ts similarity index 97% rename from x-pack/test/api_integration/apis/ingest_manager/agent_config.ts rename to x-pack/test/ingest_manager_api_integration/apis/agent_config/agent_config.ts index 8bf3efbdaf501..89258600c85e1 100644 --- a/x-pack/test/api_integration/apis/ingest_manager/agent_config.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/agent_config/agent_config.ts @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../ftr_provider_context'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/ingest_manager/index.js b/x-pack/test/ingest_manager_api_integration/apis/agent_config/index.js similarity index 100% rename from x-pack/test/api_integration/apis/ingest_manager/index.js rename to x-pack/test/ingest_manager_api_integration/apis/agent_config/index.js diff --git a/x-pack/test/api_integration/apis/fleet/agents/acks.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/acks.ts similarity index 98% rename from x-pack/test/api_integration/apis/fleet/agents/acks.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/agents/acks.ts index a040ef20081a8..c9fa80c88762b 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/acks.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/acks.ts @@ -6,8 +6,7 @@ import expect from '@kbn/expect'; import uuid from 'uuid'; - -import { FtrProviderContext } from '../../../ftr_provider_context'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; import { getSupertestWithoutAuth } from './services'; export default function (providerContext: FtrProviderContext) { diff --git a/x-pack/test/api_integration/apis/fleet/agents/actions.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/actions.ts similarity index 96% rename from x-pack/test/api_integration/apis/fleet/agents/actions.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/agents/actions.ts index c0b2aedf5c244..8dc4e5c232b80 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/actions.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/actions.ts @@ -5,8 +5,7 @@ */ import expect from '@kbn/expect'; - -import { FtrProviderContext } from '../../../ftr_provider_context'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; diff --git a/x-pack/test/api_integration/apis/fleet/agents/checkin.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/checkin.ts similarity index 94% rename from x-pack/test/api_integration/apis/fleet/agents/checkin.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/agents/checkin.ts index 70147f602e9c7..79f6cfae175e1 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/checkin.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/checkin.ts @@ -7,8 +7,9 @@ import expect from '@kbn/expect'; import uuid from 'uuid'; -import { FtrProviderContext } from '../../../ftr_provider_context'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; import { getSupertestWithoutAuth, setupIngest } from './services'; +import { skipIfNoDockerRegistry } from '../../../helpers'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; @@ -19,6 +20,7 @@ export default function (providerContext: FtrProviderContext) { let apiKey: { id: string; api_key: string }; describe('fleet_agents_checkin', () => { + skipIfNoDockerRegistry(providerContext); before(async () => { await esArchiver.loadIfNeeded('fleet/agents'); diff --git a/x-pack/test/api_integration/apis/fleet/agent_flow.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts similarity index 96% rename from x-pack/test/api_integration/apis/fleet/agent_flow.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts index da472ca912d40..8d7472f0ecd8b 100644 --- a/x-pack/test/api_integration/apis/fleet/agent_flow.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/complete_flow.ts @@ -6,8 +6,9 @@ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../ftr_provider_context'; -import { setupIngest, getSupertestWithoutAuth } from './agents/services'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; +import { setupIngest, getSupertestWithoutAuth } from './services'; +import { skipIfNoDockerRegistry } from '../../../helpers'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; @@ -19,6 +20,7 @@ export default function (providerContext: FtrProviderContext) { const esClient = getService('es'); describe('fleet_agent_flow', () => { + skipIfNoDockerRegistry(providerContext); before(async () => { await esArchiver.load('empty_kibana'); }); diff --git a/x-pack/test/api_integration/apis/fleet/delete_agent.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/delete.ts similarity index 97% rename from x-pack/test/api_integration/apis/fleet/delete_agent.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/agents/delete.ts index eefdc35338cb4..dc05b7a4dd792 100644 --- a/x-pack/test/api_integration/apis/fleet/delete_agent.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/delete.ts @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../ftr_provider_context'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); diff --git a/x-pack/test/api_integration/apis/fleet/agents/enroll.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/enroll.ts similarity index 96% rename from x-pack/test/api_integration/apis/fleet/agents/enroll.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/agents/enroll.ts index 58440a34457d0..ef9f2b2e61500 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/enroll.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/enroll.ts @@ -7,8 +7,9 @@ import expect from '@kbn/expect'; import uuid from 'uuid'; -import { FtrProviderContext } from '../../../ftr_provider_context'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; import { getSupertestWithoutAuth, setupIngest, getEsClientForAPIKey } from './services'; +import { skipIfNoDockerRegistry } from '../../../helpers'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; @@ -21,8 +22,8 @@ export default function (providerContext: FtrProviderContext) { let apiKey: { id: string; api_key: string }; let kibanaVersion: string; - // Flaky: https://github.com/elastic/kibana/issues/60865 - describe.skip('fleet_agents_enroll', () => { + describe('fleet_agents_enroll', () => { + skipIfNoDockerRegistry(providerContext); before(async () => { await esArchiver.loadIfNeeded('fleet/agents'); diff --git a/x-pack/test/api_integration/apis/fleet/agents/events.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/events.ts similarity index 93% rename from x-pack/test/api_integration/apis/fleet/agents/events.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/agents/events.ts index 44fc4389cab3c..93147091dc430 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/events.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/events.ts @@ -6,7 +6,7 @@ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../../ftr_provider_context'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); diff --git a/x-pack/test/api_integration/apis/fleet/list_agent.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/list.ts similarity index 97% rename from x-pack/test/api_integration/apis/fleet/list_agent.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/agents/list.ts index 59ecb8f2579b1..23563c6f43bbe 100644 --- a/x-pack/test/api_integration/apis/fleet/list_agent.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/list.ts @@ -6,7 +6,7 @@ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../ftr_provider_context'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); diff --git a/x-pack/test/api_integration/apis/fleet/agents/services.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/services.ts similarity index 94% rename from x-pack/test/api_integration/apis/fleet/agents/services.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/agents/services.ts index 86c5fb5032c7f..70d59ecc0b0da 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/services.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/services.ts @@ -8,7 +8,7 @@ import supertestAsPromised from 'supertest-as-promised'; import { Client } from '@elastic/elasticsearch'; import { format as formatUrl } from 'url'; -import { FtrProviderContext } from '../../../ftr_provider_context'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; export function getSupertestWithoutAuth({ getService }: FtrProviderContext) { const config = getService('config'); diff --git a/x-pack/test/api_integration/apis/fleet/unenroll_agent.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/unenroll.ts similarity index 93% rename from x-pack/test/api_integration/apis/fleet/unenroll_agent.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/agents/unenroll.ts index bbbce3314e4cc..d1ff8731183ba 100644 --- a/x-pack/test/api_integration/apis/fleet/unenroll_agent.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/agents/unenroll.ts @@ -7,8 +7,9 @@ import expect from '@kbn/expect'; import uuid from 'uuid'; -import { FtrProviderContext } from '../../ftr_provider_context'; -import { setupIngest } from './agents/services'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; +import { setupIngest } from './services'; +import { skipIfNoDockerRegistry } from '../../../helpers'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; @@ -17,6 +18,7 @@ export default function (providerContext: FtrProviderContext) { const esClient = getService('es'); describe('fleet_unenroll_agent', () => { + skipIfNoDockerRegistry(providerContext); let accessAPIKeyId: string; let outputAPIKeyId: string; before(async () => { diff --git a/x-pack/test/api_integration/apis/fleet/enrollment_api_keys/crud.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/enrollment_api_keys/crud.ts similarity index 95% rename from x-pack/test/api_integration/apis/fleet/enrollment_api_keys/crud.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/enrollment_api_keys/crud.ts index e9685d663aac6..bc9182627326b 100644 --- a/x-pack/test/api_integration/apis/fleet/enrollment_api_keys/crud.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/enrollment_api_keys/crud.ts @@ -6,8 +6,9 @@ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../../ftr_provider_context'; +import { FtrProviderContext } from '../../../../api_integration/ftr_provider_context'; import { setupIngest, getEsClientForAPIKey } from '../agents/services'; +import { skipIfNoDockerRegistry } from '../../../helpers'; const ENROLLMENT_KEY_ID = 'ed22ca17-e178-4cfe-8b02-54ea29fbd6d0'; @@ -21,11 +22,14 @@ export default function (providerContext: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('fleet/agents'); }); - setupIngest({ getService } as FtrProviderContext); + after(async () => { await esArchiver.unload('fleet/agents'); }); + skipIfNoDockerRegistry(providerContext); + setupIngest(providerContext); + describe('GET /fleet/enrollment-api-keys', async () => { it('should list existing api keys', async () => { const { body: apiResponse } = await supertest diff --git a/x-pack/test/api_integration/apis/fleet/index.js b/x-pack/test/ingest_manager_api_integration/apis/fleet/index.js similarity index 77% rename from x-pack/test/api_integration/apis/fleet/index.js rename to x-pack/test/ingest_manager_api_integration/apis/fleet/index.js index df81b826132a9..3a72fe6d9f12b 100644 --- a/x-pack/test/api_integration/apis/fleet/index.js +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/index.js @@ -7,16 +7,16 @@ export default function loadTests({ loadTestFile }) { describe('Fleet Endpoints', () => { loadTestFile(require.resolve('./setup')); - loadTestFile(require.resolve('./delete_agent')); - loadTestFile(require.resolve('./list_agent')); - loadTestFile(require.resolve('./unenroll_agent')); + loadTestFile(require.resolve('./agents/delete')); + loadTestFile(require.resolve('./agents/list')); loadTestFile(require.resolve('./agents/enroll')); + loadTestFile(require.resolve('./agents/unenroll')); loadTestFile(require.resolve('./agents/checkin')); loadTestFile(require.resolve('./agents/events')); loadTestFile(require.resolve('./agents/acks')); + loadTestFile(require.resolve('./agents/complete_flow')); loadTestFile(require.resolve('./enrollment_api_keys/crud')); loadTestFile(require.resolve('./install')); loadTestFile(require.resolve('./agents/actions')); - loadTestFile(require.resolve('./agent_flow')); }); } diff --git a/x-pack/test/api_integration/apis/fleet/install.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/install.ts similarity index 92% rename from x-pack/test/api_integration/apis/fleet/install.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/install.ts index 59b040e30fb48..98758ae3ac65e 100644 --- a/x-pack/test/api_integration/apis/fleet/install.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/install.ts @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../ftr_provider_context'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; import { setupIngest } from './agents/services'; export default function (providerContext: FtrProviderContext) { diff --git a/x-pack/test/api_integration/apis/fleet/setup.ts b/x-pack/test/ingest_manager_api_integration/apis/fleet/setup.ts similarity index 92% rename from x-pack/test/api_integration/apis/fleet/setup.ts rename to x-pack/test/ingest_manager_api_integration/apis/fleet/setup.ts index 4fcf39886e202..64c014dc6fb3d 100644 --- a/x-pack/test/api_integration/apis/fleet/setup.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/fleet/setup.ts @@ -5,13 +5,16 @@ */ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../ftr_provider_context'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { skipIfNoDockerRegistry } from '../../helpers'; -export default function ({ getService }: FtrProviderContext) { +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; const supertest = getService('supertest'); const es = getService('es'); describe('fleet_setup', () => { + skipIfNoDockerRegistry(providerContext); beforeEach(async () => { try { await es.security.deleteUser({ diff --git a/x-pack/test/ingest_manager_api_integration/apis/index.js b/x-pack/test/ingest_manager_api_integration/apis/index.js index 81848917f9b05..c0c8ce3ff082c 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/index.js +++ b/x-pack/test/ingest_manager_api_integration/apis/index.js @@ -8,6 +8,9 @@ export default function ({ loadTestFile }) { describe('Ingest Manager Endpoints', function () { this.tags('ciGroup7'); + // Fleet + loadTestFile(require.resolve('./fleet/index')); + // EPM loadTestFile(require.resolve('./epm/list')); loadTestFile(require.resolve('./epm/file')); @@ -18,5 +21,7 @@ export default function ({ loadTestFile }) { // Package configs loadTestFile(require.resolve('./package_config/create')); loadTestFile(require.resolve('./package_config/update')); + // Agent config + loadTestFile(require.resolve('./agent_config/index')); }); } diff --git a/x-pack/test/ingest_manager_api_integration/apis/package_config/update.ts b/x-pack/test/ingest_manager_api_integration/apis/package_config/update.ts index 0251fef5f767c..7b0ad4f524bad 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/package_config/update.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/package_config/update.ts @@ -6,10 +6,10 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; -import { warnAndSkipTest } from '../../helpers'; +import { skipIfNoDockerRegistry } from '../../helpers'; -export default function ({ getService }: FtrProviderContext) { - const log = getService('log'); +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; const supertest = getService('supertest'); const dockerServers = getService('dockerServers'); @@ -19,11 +19,15 @@ export default function ({ getService }: FtrProviderContext) { // see https://mochajs.org/#arrow-functions describe('Package Config - update', async function () { + skipIfNoDockerRegistry(providerContext); let agentConfigId: string; let packageConfigId: string; let packageConfigId2: string; before(async function () { + if (!server.enabled) { + return; + } const { body: agentConfigResponse } = await supertest .post(`/api/ingest_manager/agent_configs`) .set('kbn-xsrf', 'xxxx') @@ -73,55 +77,47 @@ export default function ({ getService }: FtrProviderContext) { }); it('should work with valid values', async function () { - if (server.enabled) { - const { body: apiResponse } = await supertest - .put(`/api/ingest_manager/package_configs/${packageConfigId}`) - .set('kbn-xsrf', 'xxxx') - .send({ - name: 'filetest-1', - description: '', - namespace: 'updated_namespace', - config_id: agentConfigId, - enabled: true, - output_id: '', - inputs: [], - package: { - name: 'filetest', - title: 'For File Tests', - version: '0.1.0', - }, - }) - .expect(200); + const { body: apiResponse } = await supertest + .put(`/api/ingest_manager/package_configs/${packageConfigId}`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'filetest-1', + description: '', + namespace: 'updated_namespace', + config_id: agentConfigId, + enabled: true, + output_id: '', + inputs: [], + package: { + name: 'filetest', + title: 'For File Tests', + version: '0.1.0', + }, + }) + .expect(200); - expect(apiResponse.success).to.be(true); - } else { - warnAndSkipTest(this, log); - } + expect(apiResponse.success).to.be(true); }); it('should return a 500 if there is another package config with the same name', async function () { - if (server.enabled) { - await supertest - .put(`/api/ingest_manager/package_configs/${packageConfigId2}`) - .set('kbn-xsrf', 'xxxx') - .send({ - name: 'filetest-1', - description: '', - namespace: 'updated_namespace', - config_id: agentConfigId, - enabled: true, - output_id: '', - inputs: [], - package: { - name: 'filetest', - title: 'For File Tests', - version: '0.1.0', - }, - }) - .expect(500); - } else { - warnAndSkipTest(this, log); - } + await supertest + .put(`/api/ingest_manager/package_configs/${packageConfigId2}`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'filetest-1', + description: '', + namespace: 'updated_namespace', + config_id: agentConfigId, + enabled: true, + output_id: '', + inputs: [], + package: { + name: 'filetest', + title: 'For File Tests', + version: '0.1.0', + }, + }) + .expect(500); }); }); } diff --git a/x-pack/test/ingest_manager_api_integration/config.ts b/x-pack/test/ingest_manager_api_integration/config.ts index e3cdf0eff4b3a..6f5d8eed43519 100644 --- a/x-pack/test/ingest_manager_api_integration/config.ts +++ b/x-pack/test/ingest_manager_api_integration/config.ts @@ -8,6 +8,7 @@ import path from 'path'; import { FtrConfigProviderContext } from '@kbn/test/types/ftr'; import { defineDockerServersConfig } from '@kbn/test'; +import { services } from '../api_integration/services'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { const xPackAPITestsConfig = await readConfigFile(require.resolve('../api_integration/config.ts')); @@ -46,7 +47,9 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { waitForLogLine: 'package manifests loaded', }, }), + esArchiver: xPackAPITestsConfig.get('esArchiver'), services: { + ...services, supertest: xPackAPITestsConfig.get('services.supertest'), es: xPackAPITestsConfig.get('services.es'), }, diff --git a/x-pack/test/ingest_manager_api_integration/helpers.ts b/x-pack/test/ingest_manager_api_integration/helpers.ts index 121630249621b..b1755e30f61f5 100644 --- a/x-pack/test/ingest_manager_api_integration/helpers.ts +++ b/x-pack/test/ingest_manager_api_integration/helpers.ts @@ -6,6 +6,7 @@ import { Context } from 'mocha'; import { ToolingLog } from '@kbn/dev-utils'; +import { FtrProviderContext } from '../api_integration/ftr_provider_context'; export function warnAndSkipTest(mochaContext: Context, log: ToolingLog) { log.warning( @@ -13,3 +14,17 @@ export function warnAndSkipTest(mochaContext: Context, log: ToolingLog) { ); mochaContext.skip(); } + +export function skipIfNoDockerRegistry(providerContext: FtrProviderContext) { + const { getService } = providerContext; + const dockerServers = getService('dockerServers'); + + const server = dockerServers.get('registry'); + const log = getService('log'); + + beforeEach(function beforeSetupWithDockerRegistyry() { + if (!server.enabled) { + warnAndSkipTest(this, log); + } + }); +}